From efb2fd2695f0f205c8e6a9dbc32f0d6b53736741 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Sun, 13 Jul 2014 14:03:18 +0200 Subject: [PATCH] GLMeta: Add vertex array object support --- mkxp.pro | 7 ++- src/etc-internal.h | 64 ----------------------- src/gl-fun.h | 1 + src/gl-meta.cpp | 124 ++++++++++++++++++++++++++++++++++++++++++++ src/gl-meta.h | 52 ++++++++++--------- src/quad.h | 32 ++++-------- src/quadarray.h | 47 ++++------------- src/sharedstate.cpp | 16 +++--- src/sharedstate.h | 2 +- src/tilemap.cpp | 66 +++++++++-------------- src/vertex.cpp | 63 ++++++++++++++++++++++ src/vertex.h | 69 ++++++++++++++++++++++++ 12 files changed, 344 insertions(+), 199 deletions(-) create mode 100644 src/gl-meta.cpp create mode 100644 src/vertex.cpp create mode 100644 src/vertex.h diff --git a/mkxp.pro b/mkxp.pro index 35079c7..a438f47 100644 --- a/mkxp.pro +++ b/mkxp.pro @@ -125,7 +125,8 @@ HEADERS += \ src/boost-hash.h \ src/debugwriter.h \ src/gl-fun.h \ - src/gl-meta.h + src/gl-meta.h \ + src/vertex.h SOURCES += \ src/main.cpp \ @@ -153,7 +154,9 @@ SOURCES += \ src/config.cpp \ src/tileatlas.cpp \ src/sharedstate.cpp \ - src/gl-fun.cpp + src/gl-fun.cpp \ + src/gl-meta.cpp \ + src/vertex.cpp EMBED = \ shader/transSimple.frag \ diff --git a/src/etc-internal.h b/src/etc-internal.h index 5c3ab22..87e4e6f 100644 --- a/src/etc-internal.h +++ b/src/etc-internal.h @@ -91,70 +91,6 @@ struct Vec2i } }; -/* Simple Vertex */ -struct SVertex -{ - Vec2 pos; - Vec2 texPos; - - static const void *posOffset() - { - return (const void*) 0; - } - - static const void *texPosOffset() - { - return (const void*) sizeof(Vec2); - } -}; - -/* Color Vertex */ -struct CVertex -{ - Vec2 pos; - Vec4 color; - - CVertex() - : color(1, 1, 1, 1) - {} - - static const void *posOffset() - { - return (const void*) 0; - } - - static const void *colorOffset() - { - return (const void*) sizeof(Vec2); - } -}; - -struct Vertex -{ - Vec2 pos; - Vec2 texPos; - Vec4 color; - - Vertex() - : color(1, 1, 1, 1) - {} - - static const void *posOffset() - { - return (const void*) 0; - } - - static const void *texPosOffset() - { - return (const void*) sizeof(Vec2); - } - - static const void *colorOffset() - { - return (const void*) sizeof(SVertex); - } -}; - struct IntRect { int x, y, w, h; diff --git a/src/gl-fun.h b/src/gl-fun.h index 611d7e3..48de5ec 100644 --- a/src/gl-fun.h +++ b/src/gl-fun.h @@ -111,6 +111,7 @@ typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, co /* Vertex attribute */ \ GL_FUN(BindAttribLocation, PFNGLBINDATTRIBLOCATIONPROC) \ GL_FUN(EnableVertexAttribArray, PFNGLENABLEVERTEXATTRIBARRAYPROC) \ + GL_FUN(DisableVertexAttribArray, PFNGLDISABLEVERTEXATTRIBARRAYPROC) \ GL_FUN(VertexAttribPointer, PFNGLVERTEXATTRIBPOINTERPROC) #define GL_FBO_FUN \ diff --git a/src/gl-meta.cpp b/src/gl-meta.cpp new file mode 100644 index 0000000..5f208ea --- /dev/null +++ b/src/gl-meta.cpp @@ -0,0 +1,124 @@ +/* +** gl-meta.cpp +** +** This file is part of mkxp. +** +** Copyright (C) 2014 Jonas Kulla +** +** mkxp is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** mkxp is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with mkxp. If not, see . +*/ + +#include "gl-meta.h" +#include "gl-fun.h" + +namespace GLMeta +{ + +void subRectImageUpload(GLint srcW, GLint srcX, GLint srcY, + GLint dstX, GLint dstY, GLsizei dstW, GLsizei dstH, + SDL_Surface *src, GLenum format) +{ + if (gl.unpack_subimage) + { + PixelStore::setupSubImage(srcW, srcX, srcY); + TEX::uploadSubImage(dstX, dstY, dstW, dstH, src->pixels, format); + } + else + { + SDL_PixelFormat *form = src->format; + SDL_Surface *tmp = SDL_CreateRGBSurface(0, dstW, dstH, form->BitsPerPixel, + form->Rmask, form->Gmask, form->Bmask, form->Amask); + SDL_Rect srcRect = { srcX, srcY, dstW, dstH }; + + SDL_BlitSurface(src, &srcRect, tmp, 0); + + TEX::uploadSubImage(dstX, dstY, dstW, dstH, tmp->pixels, format); + + SDL_FreeSurface(tmp); + } +} + +void subRectImageFinish() +{ + if (gl.unpack_subimage) + PixelStore::reset(); +} + +#define HAVE_NATIVE_VAO gl.GenVertexArrays + +static void vaoBindRes(VAO &vao) +{ + VBO::bind(vao.vbo); + IBO::bind(vao.ibo); + + for (size_t i = 0; i < vao.attrCount; ++i) + { + const VertexAttribute &va = vao.attr[i]; + + gl.EnableVertexAttribArray(va.index); + gl.VertexAttribPointer(va.index, va.size, va.type, GL_FALSE, vao.vertSize, va.offset); + } +} + +void vaoInit(VAO &vao, bool keepBound) +{ + if (HAVE_NATIVE_VAO) + { + vao.vao = ::VAO::gen(); + ::VAO::bind(vao.vao); + vaoBindRes(vao); + if (!keepBound) + ::VAO::unbind(); + } + else + { + if (keepBound) + { + VBO::bind(vao.vbo); + IBO::bind(vao.ibo); + } + } +} + +void vaoFini(VAO &vao) +{ + if (HAVE_NATIVE_VAO) + ::VAO::del(vao.vao); +} + +void vaoBind(VAO &vao) +{ + if (HAVE_NATIVE_VAO) + ::VAO::bind(vao.vao); + else + vaoBindRes(vao); +} + +void vaoUnbind(VAO &vao) +{ + if (HAVE_NATIVE_VAO) + { + ::VAO::unbind(); + } + else + { + for (size_t i = 0; i < vao.attrCount; ++i) + gl.DisableVertexAttribArray(vao.attr[i].index); + + VBO::unbind(); + IBO::unbind(); + } +} + +} diff --git a/src/gl-meta.h b/src/gl-meta.h index e29498e..4dc585d 100644 --- a/src/gl-meta.h +++ b/src/gl-meta.h @@ -24,41 +24,45 @@ #include "gl-fun.h" #include "gl-util.h" +#include "vertex.h" #include namespace GLMeta { -inline void subRectImageUpload(GLint srcW, GLint srcX, GLint srcY, - GLint dstX, GLint dstY, GLsizei dstW, GLsizei dstH, - SDL_Surface *src, GLenum format) +/* EXT_unpack_subimage */ +void subRectImageUpload(GLint srcW, GLint srcX, GLint srcY, + GLint dstX, GLint dstY, GLsizei dstW, GLsizei dstH, + SDL_Surface *src, GLenum format); +void subRectImageFinish(); + +/* ARB_vertex_array_object */ +struct VAO { - if (gl.unpack_subimage) - { - PixelStore::setupSubImage(srcW, srcX, srcY); - TEX::uploadSubImage(dstX, dstY, dstW, dstH, src->pixels, format); - } - else - { - SDL_PixelFormat *form = src->format; - SDL_Surface *tmp = SDL_CreateRGBSurface(0, dstW, dstH, form->BitsPerPixel, - form->Rmask, form->Gmask, form->Bmask, form->Amask); - SDL_Rect srcRect = { srcX, srcY, dstW, dstH }; + /* Set manually, then call vaoInit() */ + const VertexAttribute *attr; + size_t attrCount; + GLsizei vertSize; + VBO::ID vbo; + IBO::ID ibo; - SDL_BlitSurface(src, &srcRect, tmp, 0); + /* Don't touch */ + ::VAO::ID vao; +}; - TEX::uploadSubImage(dstX, dstY, dstW, dstH, tmp->pixels, format); - - SDL_FreeSurface(tmp); - } +template +inline void vaoFillInVertexData(VAO &vao) +{ + vao.attr = VertexTraits::attr; + vao.attrCount = VertexTraits::attrCount; + vao.vertSize = sizeof(VertexType); } -inline void subRectImageFinish() -{ - if (gl.unpack_subimage) - PixelStore::reset(); -} +void vaoInit(VAO &vao, bool keepBound = false); +void vaoFini(VAO &vao); +void vaoBind(VAO &vao); +void vaoUnbind(VAO &vao); } diff --git a/src/quad.h b/src/quad.h index c7a784d..a26ac3a 100644 --- a/src/quad.h +++ b/src/quad.h @@ -22,8 +22,9 @@ #ifndef QUAD_H #define QUAD_H -#include "etc-internal.h" +#include "vertex.h" #include "gl-util.h" +#include "gl-meta.h" #include "sharedstate.h" #include "global-ibo.h" #include "shader.h" @@ -32,7 +33,7 @@ struct Quad { Vertex vert[4]; VBO::ID vbo; - VAO::ID vao; + GLMeta::VAO vao; bool vboDirty; static void setPosRect(CVertex *vert, const FloatRect &r) @@ -104,33 +105,22 @@ struct Quad Quad() : vbo(VBO::gen()), - vao(VAO::gen()), vboDirty(true) { - VAO::bind(vao); - VBO::bind(vbo); - shState->bindQuadIBO(); + GLMeta::vaoFillInVertexData(vao); + vao.vbo = vbo; + vao.ibo = shState->globalIBO().ibo; + GLMeta::vaoInit(vao, true); VBO::allocEmpty(sizeof(Vertex[4]), GL_DYNAMIC_DRAW); - - gl.EnableVertexAttribArray(Shader::Color); - gl.EnableVertexAttribArray(Shader::Position); - gl.EnableVertexAttribArray(Shader::TexCoord); - - gl.VertexAttribPointer(Shader::Color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::colorOffset()); - gl.VertexAttribPointer(Shader::Position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::posOffset()); - gl.VertexAttribPointer(Shader::TexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::texPosOffset()); - - VAO::unbind(); - VBO::unbind(); - IBO::unbind(); + GLMeta::vaoUnbind(vao); setColor(Vec4(1, 1, 1, 1)); } ~Quad() { - VAO::del(vao); + GLMeta::vaoFini(vao); VBO::del(vbo); } @@ -175,9 +165,9 @@ struct Quad vboDirty = false; } - VAO::bind(vao); + GLMeta::vaoBind(vao); gl.DrawElements(GL_TRIANGLES, 6, _GL_INDEX_TYPE, 0); - VAO::unbind(); + GLMeta::vaoUnbind(vao); } }; diff --git a/src/quadarray.h b/src/quadarray.h index 635bfd7..66a44fb 100644 --- a/src/quadarray.h +++ b/src/quadarray.h @@ -22,43 +22,23 @@ #ifndef QUADARRAY_H #define QUADARRAY_H +#include "vertex.h" #include "gl-util.h" +#include "gl-meta.h" #include "sharedstate.h" #include "global-ibo.h" #include "shader.h" #include - #include -/* A small hack to get mutable QuadArray constructors */ -inline void initBufferBindings(Vertex *) -{ - gl.EnableVertexAttribArray(Shader::Color); - gl.EnableVertexAttribArray(Shader::Position); - gl.EnableVertexAttribArray(Shader::TexCoord); - - gl.VertexAttribPointer(Shader::Color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::colorOffset()); - gl.VertexAttribPointer(Shader::Position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::posOffset()); - gl.VertexAttribPointer(Shader::TexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::texPosOffset()); -} - -inline void initBufferBindings(SVertex *) -{ - gl.EnableVertexAttribArray(Shader::Position); - gl.EnableVertexAttribArray(Shader::TexCoord); - - gl.VertexAttribPointer(Shader::Position, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), SVertex::posOffset()); - gl.VertexAttribPointer(Shader::TexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), SVertex::texPosOffset()); -} - template struct QuadArray { std::vector vertices; VBO::ID vbo; - VAO::ID vao; + GLMeta::VAO vao; int quadCount; GLsizeiptr vboSize; @@ -68,25 +48,18 @@ struct QuadArray vboSize(-1) { vbo = VBO::gen(); - vao = VAO::gen(); - VAO::bind(vao); - VBO::bind(vbo); - shState->bindQuadIBO(); + GLMeta::vaoFillInVertexData(vao); + vao.vbo = vbo; + vao.ibo = shState->globalIBO().ibo; - /* Call correct implementation here via overloading */ - VertexType *dummy = 0; - initBufferBindings(dummy); - - VAO::unbind(); - IBO::unbind(); - VBO::unbind(); + GLMeta::vaoInit(vao); } ~QuadArray() { + GLMeta::vaoFini(vao); VBO::del(vbo); - VAO::del(vao); } void resize(int size) @@ -129,12 +102,12 @@ struct QuadArray void draw(size_t offset, size_t count) { - VAO::bind(vao); + GLMeta::vaoBind(vao); const char *_offset = (const char*) 0 + offset * 6 * sizeof(index_t); gl.DrawElements(GL_TRIANGLES, count * 6, _GL_INDEX_TYPE, _offset); - VAO::unbind(); + GLMeta::vaoUnbind(vao); } void draw() diff --git a/src/sharedstate.cpp b/src/sharedstate.cpp index c681776..23ade67 100644 --- a/src/sharedstate.cpp +++ b/src/sharedstate.cpp @@ -42,7 +42,7 @@ #include SharedState *SharedState::instance = 0; -static GlobalIBO *globalIBO = 0; +static GlobalIBO *_globalIBO = 0; #define GAME_ARCHIVE "Game.rgssad" @@ -153,8 +153,8 @@ void SharedState::initInstance(RGSSThreadData *threadData) * SharedState depends on GlobalIBO existing, * Font depends on SharedState existing */ - globalIBO = new GlobalIBO(); - globalIBO->ensureSize(1); + _globalIBO = new GlobalIBO(); + _globalIBO->ensureSize(1); SharedState::instance = 0; Font *defaultFont = 0; @@ -166,7 +166,7 @@ void SharedState::initInstance(RGSSThreadData *threadData) } catch (const Exception &exc) { - delete globalIBO; + delete _globalIBO; delete SharedState::instance; delete defaultFont; @@ -182,7 +182,7 @@ void SharedState::finiInstance() delete SharedState::instance; - delete globalIBO; + delete _globalIBO; } void SharedState::setScreen(Scene &screen) @@ -219,12 +219,12 @@ void SharedState::setBindingData(void *data) void SharedState::ensureQuadIBO(int minSize) { - globalIBO->ensureSize(minSize); + _globalIBO->ensureSize(minSize); } -void SharedState::bindQuadIBO() +GlobalIBO &SharedState::globalIBO() { - IBO::bind(globalIBO->ibo); + return *_globalIBO; } void SharedState::bindTex() diff --git a/src/sharedstate.h b/src/sharedstate.h index 9b1c22a..62689e7 100644 --- a/src/sharedstate.h +++ b/src/sharedstate.h @@ -85,7 +85,7 @@ struct SharedState /* Returns global quad IBO, and ensures it has indices * for at least minSize quads */ void ensureQuadIBO(int minSize); - void bindQuadIBO(); + GlobalIBO &globalIBO(); /* Global general purpose texture */ void bindTex(); diff --git a/src/tilemap.cpp b/src/tilemap.cpp index bc74838..70d2df6 100644 --- a/src/tilemap.cpp +++ b/src/tilemap.cpp @@ -34,6 +34,7 @@ #include "quadarray.h" #include "texpool.h" #include "quad.h" +#include "vertex.h" #include "tileatlas.h" #include @@ -282,7 +283,7 @@ struct TilemapPrivate /* Shared buffers for all tiles */ struct { - VAO::ID vao; + GLMeta::VAO vao; VBO::ID vbo; bool animated; @@ -294,7 +295,7 @@ struct TilemapPrivate /* Flash buffers */ struct { - VAO::ID vao; + GLMeta::VAO vao; VBO::ID vbo; size_t quadCount; uint8_t alphaIdx; @@ -375,45 +376,24 @@ struct TilemapPrivate /* Init tile buffers */ tiles.vbo = VBO::gen(); - tiles.vao = VAO::gen(); - VAO::bind(tiles.vao); + GLMeta::vaoFillInVertexData(tiles.vao); + tiles.vao.vbo = tiles.vbo; + tiles.vao.ibo = shState->globalIBO().ibo; - gl.EnableVertexAttribArray(Shader::Position); - gl.EnableVertexAttribArray(Shader::TexCoord); - - VBO::bind(tiles.vbo); - shState->bindQuadIBO(); - - gl.VertexAttribPointer(Shader::Position, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), SVertex::posOffset()); - gl.VertexAttribPointer(Shader::TexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), SVertex::texPosOffset()); - - VAO::unbind(); - VBO::unbind(); - IBO::unbind(); + GLMeta::vaoInit(tiles.vao); /* Init flash buffers */ flash.vbo = VBO::gen(); - flash.vao = VAO::gen(); + + GLMeta::vaoFillInVertexData(flash.vao); + flash.vao.vbo = flash.vbo; + flash.vao.ibo = shState->globalIBO().ibo; + + GLMeta::vaoInit(flash.vao); + flash.quadCount = 0; flash.alphaIdx = 0; - VAO::bind(flash.vao); - - gl.EnableVertexAttribArray(Shader::Color); - gl.EnableVertexAttribArray(Shader::Position); - - VBO::bind(flash.vbo); - shState->bindQuadIBO(); - - gl.VertexAttribPointer(Shader::Color, 4, GL_FLOAT, GL_FALSE, sizeof(CVertex), CVertex::colorOffset()); - gl.VertexAttribPointer(Shader::Position, 2, GL_FLOAT, GL_FALSE, sizeof(CVertex), CVertex::posOffset()); - - VAO::unbind(); - VBO::unbind(); - IBO::unbind(); - - elem.ground = 0; - elem.groundStamp = shState->genTimeStamp(); elem.scanrowStamp = shState->genTimeStamp(); @@ -436,11 +416,11 @@ struct TilemapPrivate shState->releaseAtlasTex(atlas.gl); /* Destroy tile buffers */ - VAO::del(tiles.vao); + GLMeta::vaoFini(tiles.vao); VBO::del(tiles.vbo); /* Destroy flash buffers */ - VAO::del(flash.vao); + GLMeta::vaoFini(flash.vao); VBO::del(flash.vbo); /* Disconnect signal handlers */ @@ -1099,14 +1079,16 @@ void GroundLayer::draw() p->bindShader(shader); p->bindAtlas(*shader); - VAO::bind(p->tiles.vao); + GLMeta::vaoBind(p->tiles.vao); shader->setTranslation(p->dispPos); drawInt(); + GLMeta::vaoUnbind(p->tiles.vao); + if (p->flash.quadCount > 0) { - VAO::bind(p->flash.vao); + GLMeta::vaoBind(p->flash.vao); glState.blendMode.pushSet(BlendAddition); FlashMapShader &shader = shState->shaders().flashMap; @@ -1118,9 +1100,9 @@ void GroundLayer::draw() drawFlashInt(); glState.blendMode.pop(); - } - VAO::unbind(); + GLMeta::vaoUnbind(p->flash.vao); + } } void GroundLayer::drawInt() @@ -1169,12 +1151,12 @@ void ScanRow::draw() p->bindShader(shader); p->bindAtlas(*shader); - VAO::bind(p->tiles.vao); + GLMeta::vaoBind(p->tiles.vao); shader->setTranslation(p->dispPos); drawInt(); - VAO::unbind(); + GLMeta::vaoUnbind(p->tiles.vao); } void ScanRow::drawInt() diff --git a/src/vertex.cpp b/src/vertex.cpp new file mode 100644 index 0000000..9232c50 --- /dev/null +++ b/src/vertex.cpp @@ -0,0 +1,63 @@ +/* +** vertex.cpp +** +** This file is part of mkxp. +** +** Copyright (C) 2014 Jonas Kulla +** +** mkxp is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** mkxp is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with mkxp. If not, see . +*/ + +#include "vertex.h" + +#include + +CVertex::CVertex() + : color(1, 1, 1, 1) +{} + +Vertex::Vertex() + : color(1, 1, 1, 1) +{} + +#define o(type, mem) ((const GLvoid*) offsetof(type, mem)) + +static const VertexAttribute SVertexAttribs[] = +{ + { Shader::Position, 2, GL_FLOAT, o(SVertex, pos) }, + { Shader::TexCoord, 2, GL_FLOAT, o(SVertex, texPos) } +}; + +static const VertexAttribute CVertexAttribs[] = +{ + { Shader::Color, 4, GL_FLOAT, o(CVertex, color) }, + { Shader::Position, 2, GL_FLOAT, o(CVertex, pos) } +}; + +static const VertexAttribute VertexAttribs[] = +{ + { Shader::Color, 4, GL_FLOAT, o(Vertex, color) }, + { Shader::Position, 2, GL_FLOAT, o(Vertex, pos) }, + { Shader::TexCoord, 2, GL_FLOAT, o(Vertex, texPos) } +}; + +#define DEF_TRAITS(VertType) \ + template<> \ + const VertexAttribute *VertexTraits::attr = VertType##Attribs; \ + template<> \ + const GLsizei VertexTraits::attrCount = sizeof(VertType##Attribs) / sizeof(VertType##Attribs[0]) + +DEF_TRAITS(SVertex); +DEF_TRAITS(CVertex); +DEF_TRAITS(Vertex); diff --git a/src/vertex.h b/src/vertex.h new file mode 100644 index 0000000..610acc8 --- /dev/null +++ b/src/vertex.h @@ -0,0 +1,69 @@ +/* +** vertex.h +** +** This file is part of mkxp. +** +** Copyright (C) 2014 Jonas Kulla +** +** mkxp is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** mkxp is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with mkxp. If not, see . +*/ + +#ifndef VERTEX_H +#define VERTEX_H + +#include "etc-internal.h" +#include "gl-fun.h" +#include "shader.h" + +/* Simple Vertex */ +struct SVertex +{ + Vec2 pos; + Vec2 texPos; +}; + +/* Color Vertex */ +struct CVertex +{ + Vec2 pos; + Vec4 color; + + CVertex(); +}; + +struct Vertex +{ + Vec2 pos; + Vec2 texPos; + Vec4 color; + + Vertex(); +}; + +struct VertexAttribute +{ + Shader::Attribute index; + GLint size; + GLenum type; + const GLvoid *offset; +}; + +template +struct VertexTraits +{ + static const VertexAttribute *attr; + static const GLsizei attrCount; +}; + +#endif // VERTEX_H