GLMeta: Add vertex array object support

This commit is contained in:
Jonas Kulla 2014-07-13 14:03:18 +02:00
parent dac1407120
commit efb2fd2695
12 changed files with 344 additions and 199 deletions

View File

@ -125,7 +125,8 @@ HEADERS += \
src/boost-hash.h \ src/boost-hash.h \
src/debugwriter.h \ src/debugwriter.h \
src/gl-fun.h \ src/gl-fun.h \
src/gl-meta.h src/gl-meta.h \
src/vertex.h
SOURCES += \ SOURCES += \
src/main.cpp \ src/main.cpp \
@ -153,7 +154,9 @@ SOURCES += \
src/config.cpp \ src/config.cpp \
src/tileatlas.cpp \ src/tileatlas.cpp \
src/sharedstate.cpp \ src/sharedstate.cpp \
src/gl-fun.cpp src/gl-fun.cpp \
src/gl-meta.cpp \
src/vertex.cpp
EMBED = \ EMBED = \
shader/transSimple.frag \ shader/transSimple.frag \

View File

@ -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 struct IntRect
{ {
int x, y, w, h; int x, y, w, h;

View File

@ -111,6 +111,7 @@ typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, co
/* Vertex attribute */ \ /* Vertex attribute */ \
GL_FUN(BindAttribLocation, PFNGLBINDATTRIBLOCATIONPROC) \ GL_FUN(BindAttribLocation, PFNGLBINDATTRIBLOCATIONPROC) \
GL_FUN(EnableVertexAttribArray, PFNGLENABLEVERTEXATTRIBARRAYPROC) \ GL_FUN(EnableVertexAttribArray, PFNGLENABLEVERTEXATTRIBARRAYPROC) \
GL_FUN(DisableVertexAttribArray, PFNGLDISABLEVERTEXATTRIBARRAYPROC) \
GL_FUN(VertexAttribPointer, PFNGLVERTEXATTRIBPOINTERPROC) GL_FUN(VertexAttribPointer, PFNGLVERTEXATTRIBPOINTERPROC)
#define GL_FBO_FUN \ #define GL_FBO_FUN \

124
src/gl-meta.cpp Normal file
View File

@ -0,0 +1,124 @@
/*
** gl-meta.cpp
**
** This file is part of mkxp.
**
** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com>
**
** 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 <http://www.gnu.org/licenses/>.
*/
#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();
}
}
}

View File

@ -24,41 +24,45 @@
#include "gl-fun.h" #include "gl-fun.h"
#include "gl-util.h" #include "gl-util.h"
#include "vertex.h"
#include <SDL_surface.h> #include <SDL_surface.h>
namespace GLMeta namespace GLMeta
{ {
inline void subRectImageUpload(GLint srcW, GLint srcX, GLint srcY, /* EXT_unpack_subimage */
void subRectImageUpload(GLint srcW, GLint srcX, GLint srcY,
GLint dstX, GLint dstY, GLsizei dstW, GLsizei dstH, GLint dstX, GLint dstY, GLsizei dstW, GLsizei dstH,
SDL_Surface *src, GLenum format) SDL_Surface *src, GLenum format);
void subRectImageFinish();
/* ARB_vertex_array_object */
struct VAO
{ {
if (gl.unpack_subimage) /* Set manually, then call vaoInit() */
{ const VertexAttribute *attr;
PixelStore::setupSubImage(srcW, srcX, srcY); size_t attrCount;
TEX::uploadSubImage(dstX, dstY, dstW, dstH, src->pixels, format); GLsizei vertSize;
} VBO::ID vbo;
else IBO::ID ibo;
{
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); /* Don't touch */
::VAO::ID vao;
};
TEX::uploadSubImage(dstX, dstY, dstW, dstH, tmp->pixels, format); template<class VertexType>
inline void vaoFillInVertexData(VAO &vao)
SDL_FreeSurface(tmp); {
} vao.attr = VertexTraits<VertexType>::attr;
vao.attrCount = VertexTraits<VertexType>::attrCount;
vao.vertSize = sizeof(VertexType);
} }
inline void subRectImageFinish() void vaoInit(VAO &vao, bool keepBound = false);
{ void vaoFini(VAO &vao);
if (gl.unpack_subimage) void vaoBind(VAO &vao);
PixelStore::reset(); void vaoUnbind(VAO &vao);
}
} }

View File

@ -22,8 +22,9 @@
#ifndef QUAD_H #ifndef QUAD_H
#define QUAD_H #define QUAD_H
#include "etc-internal.h" #include "vertex.h"
#include "gl-util.h" #include "gl-util.h"
#include "gl-meta.h"
#include "sharedstate.h" #include "sharedstate.h"
#include "global-ibo.h" #include "global-ibo.h"
#include "shader.h" #include "shader.h"
@ -32,7 +33,7 @@ struct Quad
{ {
Vertex vert[4]; Vertex vert[4];
VBO::ID vbo; VBO::ID vbo;
VAO::ID vao; GLMeta::VAO vao;
bool vboDirty; bool vboDirty;
static void setPosRect(CVertex *vert, const FloatRect &r) static void setPosRect(CVertex *vert, const FloatRect &r)
@ -104,33 +105,22 @@ struct Quad
Quad() Quad()
: vbo(VBO::gen()), : vbo(VBO::gen()),
vao(VAO::gen()),
vboDirty(true) vboDirty(true)
{ {
VAO::bind(vao); GLMeta::vaoFillInVertexData<Vertex>(vao);
VBO::bind(vbo); vao.vbo = vbo;
shState->bindQuadIBO(); vao.ibo = shState->globalIBO().ibo;
GLMeta::vaoInit(vao, true);
VBO::allocEmpty(sizeof(Vertex[4]), GL_DYNAMIC_DRAW); VBO::allocEmpty(sizeof(Vertex[4]), GL_DYNAMIC_DRAW);
GLMeta::vaoUnbind(vao);
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();
setColor(Vec4(1, 1, 1, 1)); setColor(Vec4(1, 1, 1, 1));
} }
~Quad() ~Quad()
{ {
VAO::del(vao); GLMeta::vaoFini(vao);
VBO::del(vbo); VBO::del(vbo);
} }
@ -175,9 +165,9 @@ struct Quad
vboDirty = false; vboDirty = false;
} }
VAO::bind(vao); GLMeta::vaoBind(vao);
gl.DrawElements(GL_TRIANGLES, 6, _GL_INDEX_TYPE, 0); gl.DrawElements(GL_TRIANGLES, 6, _GL_INDEX_TYPE, 0);
VAO::unbind(); GLMeta::vaoUnbind(vao);
} }
}; };

View File

@ -22,43 +22,23 @@
#ifndef QUADARRAY_H #ifndef QUADARRAY_H
#define QUADARRAY_H #define QUADARRAY_H
#include "vertex.h"
#include "gl-util.h" #include "gl-util.h"
#include "gl-meta.h"
#include "sharedstate.h" #include "sharedstate.h"
#include "global-ibo.h" #include "global-ibo.h"
#include "shader.h" #include "shader.h"
#include <vector> #include <vector>
#include <stdint.h> #include <stdint.h>
/* 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<class VertexType> template<class VertexType>
struct QuadArray struct QuadArray
{ {
std::vector<VertexType> vertices; std::vector<VertexType> vertices;
VBO::ID vbo; VBO::ID vbo;
VAO::ID vao; GLMeta::VAO vao;
int quadCount; int quadCount;
GLsizeiptr vboSize; GLsizeiptr vboSize;
@ -68,25 +48,18 @@ struct QuadArray
vboSize(-1) vboSize(-1)
{ {
vbo = VBO::gen(); vbo = VBO::gen();
vao = VAO::gen();
VAO::bind(vao); GLMeta::vaoFillInVertexData<VertexType>(vao);
VBO::bind(vbo); vao.vbo = vbo;
shState->bindQuadIBO(); vao.ibo = shState->globalIBO().ibo;
/* Call correct implementation here via overloading */ GLMeta::vaoInit(vao);
VertexType *dummy = 0;
initBufferBindings(dummy);
VAO::unbind();
IBO::unbind();
VBO::unbind();
} }
~QuadArray() ~QuadArray()
{ {
GLMeta::vaoFini(vao);
VBO::del(vbo); VBO::del(vbo);
VAO::del(vao);
} }
void resize(int size) void resize(int size)
@ -129,12 +102,12 @@ struct QuadArray
void draw(size_t offset, size_t count) 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); const char *_offset = (const char*) 0 + offset * 6 * sizeof(index_t);
gl.DrawElements(GL_TRIANGLES, count * 6, _GL_INDEX_TYPE, _offset); gl.DrawElements(GL_TRIANGLES, count * 6, _GL_INDEX_TYPE, _offset);
VAO::unbind(); GLMeta::vaoUnbind(vao);
} }
void draw() void draw()

View File

@ -42,7 +42,7 @@
#include <string> #include <string>
SharedState *SharedState::instance = 0; SharedState *SharedState::instance = 0;
static GlobalIBO *globalIBO = 0; static GlobalIBO *_globalIBO = 0;
#define GAME_ARCHIVE "Game.rgssad" #define GAME_ARCHIVE "Game.rgssad"
@ -153,8 +153,8 @@ void SharedState::initInstance(RGSSThreadData *threadData)
* SharedState depends on GlobalIBO existing, * SharedState depends on GlobalIBO existing,
* Font depends on SharedState existing */ * Font depends on SharedState existing */
globalIBO = new GlobalIBO(); _globalIBO = new GlobalIBO();
globalIBO->ensureSize(1); _globalIBO->ensureSize(1);
SharedState::instance = 0; SharedState::instance = 0;
Font *defaultFont = 0; Font *defaultFont = 0;
@ -166,7 +166,7 @@ void SharedState::initInstance(RGSSThreadData *threadData)
} }
catch (const Exception &exc) catch (const Exception &exc)
{ {
delete globalIBO; delete _globalIBO;
delete SharedState::instance; delete SharedState::instance;
delete defaultFont; delete defaultFont;
@ -182,7 +182,7 @@ void SharedState::finiInstance()
delete SharedState::instance; delete SharedState::instance;
delete globalIBO; delete _globalIBO;
} }
void SharedState::setScreen(Scene &screen) void SharedState::setScreen(Scene &screen)
@ -219,12 +219,12 @@ void SharedState::setBindingData(void *data)
void SharedState::ensureQuadIBO(int minSize) 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() void SharedState::bindTex()

View File

@ -85,7 +85,7 @@ struct SharedState
/* Returns global quad IBO, and ensures it has indices /* Returns global quad IBO, and ensures it has indices
* for at least minSize quads */ * for at least minSize quads */
void ensureQuadIBO(int minSize); void ensureQuadIBO(int minSize);
void bindQuadIBO(); GlobalIBO &globalIBO();
/* Global general purpose texture */ /* Global general purpose texture */
void bindTex(); void bindTex();

View File

@ -34,6 +34,7 @@
#include "quadarray.h" #include "quadarray.h"
#include "texpool.h" #include "texpool.h"
#include "quad.h" #include "quad.h"
#include "vertex.h"
#include "tileatlas.h" #include "tileatlas.h"
#include <sigc++/connection.h> #include <sigc++/connection.h>
@ -282,7 +283,7 @@ struct TilemapPrivate
/* Shared buffers for all tiles */ /* Shared buffers for all tiles */
struct struct
{ {
VAO::ID vao; GLMeta::VAO vao;
VBO::ID vbo; VBO::ID vbo;
bool animated; bool animated;
@ -294,7 +295,7 @@ struct TilemapPrivate
/* Flash buffers */ /* Flash buffers */
struct struct
{ {
VAO::ID vao; GLMeta::VAO vao;
VBO::ID vbo; VBO::ID vbo;
size_t quadCount; size_t quadCount;
uint8_t alphaIdx; uint8_t alphaIdx;
@ -375,45 +376,24 @@ struct TilemapPrivate
/* Init tile buffers */ /* Init tile buffers */
tiles.vbo = VBO::gen(); tiles.vbo = VBO::gen();
tiles.vao = VAO::gen(); GLMeta::vaoFillInVertexData<SVertex>(tiles.vao);
VAO::bind(tiles.vao); tiles.vao.vbo = tiles.vbo;
tiles.vao.ibo = shState->globalIBO().ibo;
gl.EnableVertexAttribArray(Shader::Position); GLMeta::vaoInit(tiles.vao);
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();
/* Init flash buffers */ /* Init flash buffers */
flash.vbo = VBO::gen(); flash.vbo = VBO::gen();
flash.vao = VAO::gen();
GLMeta::vaoFillInVertexData<CVertex>(flash.vao);
flash.vao.vbo = flash.vbo;
flash.vao.ibo = shState->globalIBO().ibo;
GLMeta::vaoInit(flash.vao);
flash.quadCount = 0; flash.quadCount = 0;
flash.alphaIdx = 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.groundStamp = shState->genTimeStamp();
elem.scanrowStamp = shState->genTimeStamp(); elem.scanrowStamp = shState->genTimeStamp();
@ -436,11 +416,11 @@ struct TilemapPrivate
shState->releaseAtlasTex(atlas.gl); shState->releaseAtlasTex(atlas.gl);
/* Destroy tile buffers */ /* Destroy tile buffers */
VAO::del(tiles.vao); GLMeta::vaoFini(tiles.vao);
VBO::del(tiles.vbo); VBO::del(tiles.vbo);
/* Destroy flash buffers */ /* Destroy flash buffers */
VAO::del(flash.vao); GLMeta::vaoFini(flash.vao);
VBO::del(flash.vbo); VBO::del(flash.vbo);
/* Disconnect signal handlers */ /* Disconnect signal handlers */
@ -1099,14 +1079,16 @@ void GroundLayer::draw()
p->bindShader(shader); p->bindShader(shader);
p->bindAtlas(*shader); p->bindAtlas(*shader);
VAO::bind(p->tiles.vao); GLMeta::vaoBind(p->tiles.vao);
shader->setTranslation(p->dispPos); shader->setTranslation(p->dispPos);
drawInt(); drawInt();
GLMeta::vaoUnbind(p->tiles.vao);
if (p->flash.quadCount > 0) if (p->flash.quadCount > 0)
{ {
VAO::bind(p->flash.vao); GLMeta::vaoBind(p->flash.vao);
glState.blendMode.pushSet(BlendAddition); glState.blendMode.pushSet(BlendAddition);
FlashMapShader &shader = shState->shaders().flashMap; FlashMapShader &shader = shState->shaders().flashMap;
@ -1118,9 +1100,9 @@ void GroundLayer::draw()
drawFlashInt(); drawFlashInt();
glState.blendMode.pop(); glState.blendMode.pop();
}
VAO::unbind(); GLMeta::vaoUnbind(p->flash.vao);
}
} }
void GroundLayer::drawInt() void GroundLayer::drawInt()
@ -1169,12 +1151,12 @@ void ScanRow::draw()
p->bindShader(shader); p->bindShader(shader);
p->bindAtlas(*shader); p->bindAtlas(*shader);
VAO::bind(p->tiles.vao); GLMeta::vaoBind(p->tiles.vao);
shader->setTranslation(p->dispPos); shader->setTranslation(p->dispPos);
drawInt(); drawInt();
VAO::unbind(); GLMeta::vaoUnbind(p->tiles.vao);
} }
void ScanRow::drawInt() void ScanRow::drawInt()

63
src/vertex.cpp Normal file
View File

@ -0,0 +1,63 @@
/*
** vertex.cpp
**
** This file is part of mkxp.
**
** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com>
**
** 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 <http://www.gnu.org/licenses/>.
*/
#include "vertex.h"
#include <cstddef>
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<VertType>::attr = VertType##Attribs; \
template<> \
const GLsizei VertexTraits<VertType>::attrCount = sizeof(VertType##Attribs) / sizeof(VertType##Attribs[0])
DEF_TRAITS(SVertex);
DEF_TRAITS(CVertex);
DEF_TRAITS(Vertex);

69
src/vertex.h Normal file
View File

@ -0,0 +1,69 @@
/*
** vertex.h
**
** This file is part of mkxp.
**
** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com>
**
** 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 <http://www.gnu.org/licenses/>.
*/
#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<class VertType>
struct VertexTraits
{
static const VertexAttribute *attr;
static const GLsizei attrCount;
};
#endif // VERTEX_H