Use singleton template for VAOManager (ex VBOGatherer)

This commit is contained in:
Vincent Lejeune 2014-08-20 23:04:02 +02:00
parent c2cf83bb6a
commit 04f6c7e729
7 changed files with 62 additions and 90 deletions

View File

@ -548,40 +548,7 @@ void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum
glGetError(); glGetError();
} }
class VBOGatherer VAOManager::VAOManager()
{
enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT };
GLuint vbo[VTXTYPE_COUNT], ibo[VTXTYPE_COUNT], vao[VTXTYPE_COUNT];
std::vector<scene::IMeshBuffer *> storedCPUBuffer[VTXTYPE_COUNT];
void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[VTXTYPE_COUNT];
size_t vtx_cnt[VTXTYPE_COUNT], idx_cnt[VTXTYPE_COUNT];
std::map<scene::IMeshBuffer*, unsigned> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
void regenerateBuffer(enum VTXTYPE);
void regenerateVAO(enum VTXTYPE);
size_t getVertexPitch(enum VTXTYPE) const;
VTXTYPE getVTXTYPE(video::E_VERTEX_TYPE type);
void append(scene::IMeshBuffer *, VBOGatherer::VTXTYPE tp);
public:
VBOGatherer();
std::pair<unsigned, unsigned> getBase(scene::IMeshBuffer *);
unsigned getVBO(video::E_VERTEX_TYPE type) { return vbo[getVTXTYPE(type)]; }
unsigned getVAO(video::E_VERTEX_TYPE type) { return vao[getVTXTYPE(type)]; }
~VBOGatherer()
{
for (unsigned i = 0; i < VTXTYPE_COUNT; i++)
{
if (vbo[i])
glDeleteBuffers(1, &vbo[i]);
if (ibo[i])
glDeleteBuffers(1, &ibo[i]);
if (vao[i])
glDeleteVertexArrays(1, &vao[i]);
}
}
};
VBOGatherer::VBOGatherer()
{ {
vao[0] = vao[1] = vao[2] = 0; vao[0] = vao[1] = vao[2] = 0;
vbo[0] = vbo[1] = vbo[2] = 0; vbo[0] = vbo[1] = vbo[2] = 0;
@ -592,7 +559,25 @@ VBOGatherer::VBOGatherer()
idx_mirror[0] = idx_mirror[1] = idx_mirror[2] = NULL; idx_mirror[0] = idx_mirror[1] = idx_mirror[2] = NULL;
} }
void VBOGatherer::regenerateBuffer(enum VTXTYPE tp) VAOManager::~VAOManager()
{
for (unsigned i = 0; i < 3; i++)
{
if (vtx_mirror[i])
free(vtx_mirror[i]);
if (idx_mirror[i])
free(idx_mirror[i]);
if (vbo[i])
glDeleteBuffers(1, &vbo[i]);
if (ibo[i])
glDeleteBuffers(1, &ibo[i]);
if (vao[i])
glDeleteVertexArrays(1, &vao[i]);
}
}
void VAOManager::regenerateBuffer(enum VTXTYPE tp)
{ {
glBindVertexArray(0); glBindVertexArray(0);
if (vbo[tp]) if (vbo[tp])
@ -611,7 +596,7 @@ void VBOGatherer::regenerateBuffer(enum VTXTYPE tp)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
} }
void VBOGatherer::regenerateVAO(enum VTXTYPE tp) void VAOManager::regenerateVAO(enum VTXTYPE tp)
{ {
if (vao[tp]) if (vao[tp])
glDeleteVertexArrays(1, &vao[tp]); glDeleteVertexArrays(1, &vao[tp]);
@ -677,7 +662,7 @@ void VBOGatherer::regenerateVAO(enum VTXTYPE tp)
glBindVertexArray(0); glBindVertexArray(0);
} }
size_t VBOGatherer::getVertexPitch(enum VTXTYPE tp) const size_t VAOManager::getVertexPitch(enum VTXTYPE tp) const
{ {
switch (tp) switch (tp)
{ {
@ -693,22 +678,22 @@ size_t VBOGatherer::getVertexPitch(enum VTXTYPE tp) const
} }
} }
VBOGatherer::VTXTYPE VBOGatherer::getVTXTYPE(video::E_VERTEX_TYPE type) VAOManager::VTXTYPE VAOManager::getVTXTYPE(video::E_VERTEX_TYPE type)
{ {
switch (type) switch (type)
{ {
default:
assert(0 && "Wrong vtxtype");
case video::EVT_STANDARD: case video::EVT_STANDARD:
return VTXTYPE_STANDARD; return VTXTYPE_STANDARD;
case video::EVT_2TCOORDS: case video::EVT_2TCOORDS:
return VTXTYPE_TCOORD; return VTXTYPE_TCOORD;
case video::EVT_TANGENTS: case video::EVT_TANGENTS:
return VTXTYPE_TANGENT; return VTXTYPE_TANGENT;
default:
assert(0 && "Wrong vtxtype");
} }
}; };
void VBOGatherer::append(scene::IMeshBuffer *mb, VBOGatherer::VTXTYPE tp) void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp)
{ {
size_t old_vtx_cnt = vtx_cnt[tp]; size_t old_vtx_cnt = vtx_cnt[tp];
vtx_cnt[tp] += mb->getVertexCount(); vtx_cnt[tp] += mb->getVertexCount();
@ -726,7 +711,7 @@ void VBOGatherer::append(scene::IMeshBuffer *mb, VBOGatherer::VTXTYPE tp)
mappedBaseIndex[tp][mb] = old_idx_cnt * sizeof(u16); mappedBaseIndex[tp][mb] = old_idx_cnt * sizeof(u16);
} }
std::pair<unsigned, unsigned> VBOGatherer::getBase(scene::IMeshBuffer *mb) std::pair<unsigned, unsigned> VAOManager::getBase(scene::IMeshBuffer *mb)
{ {
VTXTYPE tp = getVTXTYPE(mb->getVertexType()); VTXTYPE tp = getVTXTYPE(mb->getVertexType());
if (mappedBaseVertex[tp].find(mb) == mappedBaseVertex[tp].end()) if (mappedBaseVertex[tp].find(mb) == mappedBaseVertex[tp].end())
@ -747,36 +732,6 @@ std::pair<unsigned, unsigned> VBOGatherer::getBase(scene::IMeshBuffer *mb)
return std::pair<unsigned, unsigned>(vtx, It->second); return std::pair<unsigned, unsigned>(vtx, It->second);
} }
static VBOGatherer *gatherersingleton = 0;
std::pair<unsigned, unsigned> getVAOOffsetAndBase(scene::IMeshBuffer *mb)
{
if (!gatherersingleton)
gatherersingleton = new VBOGatherer();
return gatherersingleton->getBase(mb);
}
unsigned getVBO(video::E_VERTEX_TYPE type)
{
if (gatherersingleton)
return gatherersingleton->getVBO(type);
return 0;
}
unsigned getVAO(video::E_VERTEX_TYPE type)
{
if (gatherersingleton)
return gatherersingleton->getVAO(type);
return 0;
}
void resetVAO()
{
if (gatherersingleton)
delete gatherersingleton;
gatherersingleton = 0;
}
ScopedGPUTimer::ScopedGPUTimer(GPUTimer &timer) ScopedGPUTimer::ScopedGPUTimer(GPUTimer &timer)
{ {
if (!UserConfigParams::m_profiler_enabled) return; if (!UserConfigParams::m_profiler_enabled) return;

View File

@ -139,10 +139,27 @@ void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha = f
bool loadCompressedTexture(const std::string& compressed_tex); bool loadCompressedTexture(const std::string& compressed_tex);
void saveCompressedTexture(const std::string& compressed_tex); void saveCompressedTexture(const std::string& compressed_tex);
std::pair<unsigned, unsigned> getVAOOffsetAndBase(scene::IMeshBuffer *mb); class VAOManager : public Singleton<VAOManager>
unsigned getVAO(video::E_VERTEX_TYPE type); {
unsigned getVBO(video::E_VERTEX_TYPE type); enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT };
void resetVAO(); GLuint vbo[VTXTYPE_COUNT], ibo[VTXTYPE_COUNT], vao[VTXTYPE_COUNT];
std::vector<scene::IMeshBuffer *> storedCPUBuffer[VTXTYPE_COUNT];
void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[VTXTYPE_COUNT];
size_t vtx_cnt[VTXTYPE_COUNT], idx_cnt[VTXTYPE_COUNT];
std::map<scene::IMeshBuffer*, unsigned> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
void regenerateBuffer(enum VTXTYPE);
void regenerateVAO(enum VTXTYPE);
size_t getVertexPitch(enum VTXTYPE) const;
VTXTYPE getVTXTYPE(video::E_VERTEX_TYPE type);
void append(scene::IMeshBuffer *, VTXTYPE tp);
public:
VAOManager();
std::pair<unsigned, unsigned> getBase(scene::IMeshBuffer *);
unsigned getVBO(video::E_VERTEX_TYPE type) { return vbo[getVTXTYPE(type)]; }
unsigned getVAO(video::E_VERTEX_TYPE type) { return vao[getVTXTYPE(type)]; }
~VAOManager();
};
void draw3DLine(const core::vector3df& start, void draw3DLine(const core::vector3df& start,
const core::vector3df& end, irr::video::SColor color); const core::vector3df& end, irr::video::SColor color);

View File

@ -768,7 +768,7 @@ void IrrDriver::renderGlow(std::vector<GlowData>& glows)
glDepthMask(GL_FALSE); glDepthMask(GL_FALSE);
glDisable(GL_BLEND); glDisable(GL_BLEND);
glBindVertexArray(getVAO(EVT_STANDARD)); glBindVertexArray(VAOManager::getInstance()->getVAO(EVT_STANDARD));
for (u32 i = 0; i < glowcount; i++) for (u32 i = 0; i < glowcount; i++)
{ {
const GlowData &dat = glows[i]; const GlowData &dat = glows[i];

View File

@ -119,7 +119,7 @@ template<typename Shader, enum E_VERTEX_TYPE VertexType, int ...List, typename..
void renderMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::Tuple<TupleType...> > *meshes) void renderMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::Tuple<TupleType...> > *meshes)
{ {
glUseProgram(Shader::getInstance()->Program); glUseProgram(Shader::getInstance()->Program);
glBindVertexArray(getVAO(VertexType)); glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
for (unsigned i = 0; i < meshes->size(); i++) for (unsigned i = 0; i < meshes->size(); i++)
{ {
std::vector<GLuint> Textures; std::vector<GLuint> Textures;
@ -292,7 +292,7 @@ template<typename Shader, enum E_VERTEX_TYPE VertexType, int...List, typename...
void renderMeshes2ndPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::Tuple<TupleType...> > *meshes) void renderMeshes2ndPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::Tuple<TupleType...> > *meshes)
{ {
glUseProgram(Shader::getInstance()->Program); glUseProgram(Shader::getInstance()->Program);
glBindVertexArray(getVAO(VertexType)); glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
for (unsigned i = 0; i < meshes->size(); i++) for (unsigned i = 0; i < meshes->size(); i++)
{ {
std::vector<GLuint> Textures; std::vector<GLuint> Textures;
@ -473,7 +473,7 @@ template<enum E_VERTEX_TYPE VertexType, typename... TupleType>
static void renderMeshNormals(std::vector<STK::Tuple<TupleType...> > *meshes) static void renderMeshNormals(std::vector<STK::Tuple<TupleType...> > *meshes)
{ {
glUseProgram(MeshShader::NormalVisualizer::getInstance()->Program); glUseProgram(MeshShader::NormalVisualizer::getInstance()->Program);
glBindVertexArray(getVAO(VertexType)); glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
for (unsigned i = 0; i < meshes->size(); i++) for (unsigned i = 0; i < meshes->size(); i++)
{ {
GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i))); GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i)));
@ -522,7 +522,7 @@ void IrrDriver::renderTransparent()
ListDisplacement::getInstance()->clear(); ListDisplacement::getInstance()->clear();
m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT); m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT);
glBindVertexArray(getVAO(EVT_STANDARD)); glBindVertexArray(VAOManager::getInstance()->getVAO(EVT_STANDARD));
if (World::getWorld() && World::getWorld()->isFogEnabled()) if (World::getWorld() && World::getWorld()->isFogEnabled())
{ {
@ -568,7 +568,7 @@ void IrrDriver::renderTransparent()
glStencilFunc(GL_ALWAYS, 1, 0xFF); glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glBindVertexArray(getVAO(EVT_2TCOORDS)); glBindVertexArray(VAOManager::getInstance()->getVAO(EVT_2TCOORDS));
// Generate displace mask // Generate displace mask
// Use RTT_TMP4 as displace mask // Use RTT_TMP4 as displace mask
irr_driver->getFBO(FBO_TMP1_WITH_DS).Bind(); irr_driver->getFBO(FBO_TMP1_WITH_DS).Bind();
@ -666,7 +666,7 @@ template<typename T, enum E_VERTEX_TYPE VertexType, int...List, typename... Args
void renderShadow(const std::vector<GLuint> TextureUnits, const std::vector<STK::Tuple<Args...> > *t) void renderShadow(const std::vector<GLuint> TextureUnits, const std::vector<STK::Tuple<Args...> > *t)
{ {
glUseProgram(T::getInstance()->Program); glUseProgram(T::getInstance()->Program);
glBindVertexArray(getVAO(VertexType)); glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
for (unsigned i = 0; i < t->size(); i++) for (unsigned i = 0; i < t->size(); i++)
{ {
std::vector<GLuint> Textures; std::vector<GLuint> Textures;
@ -815,7 +815,7 @@ template<typename T, enum E_VERTEX_TYPE VertexType, int... Selector, typename...
void drawRSM(const core::matrix4 & rsm_matrix, const std::vector<GLuint> &TextureUnits, std::vector<STK::Tuple<Args...> > *t) void drawRSM(const core::matrix4 & rsm_matrix, const std::vector<GLuint> &TextureUnits, std::vector<STK::Tuple<Args...> > *t)
{ {
glUseProgram(T::getInstance()->Program); glUseProgram(T::getInstance()->Program);
glBindVertexArray(getVAO(VertexType)); glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
for (unsigned i = 0; i < t->size(); i++) for (unsigned i = 0; i < t->size(); i++)
{ {
std::vector<GLuint> Textures; std::vector<GLuint> Textures;

View File

@ -100,7 +100,7 @@ void STKAnimatedMesh::render()
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType()); MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
MeshSolidMaterial[MatType].push_back(&mesh); MeshSolidMaterial[MatType].push_back(&mesh);
} }
std::pair<unsigned, unsigned> p = getVAOOffsetAndBase(mb); std::pair<unsigned, unsigned> p = VAOManager::getInstance()->getBase(mb);
mesh.vaoBaseVertex = p.first; mesh.vaoBaseVertex = p.first;
mesh.vaoOffset = p.second; mesh.vaoOffset = p.second;
mesh.VAOType = mb->getVertexType(); mesh.VAOType = mb->getVertexType();
@ -118,7 +118,7 @@ void STKAnimatedMesh::render()
{ {
glBindVertexArray(0); glBindVertexArray(0);
size_t size = mb->getVertexCount() * GLmeshes[i].Stride; size_t size = mb->getVertexCount() * GLmeshes[i].Stride;
glBindBuffer(GL_ARRAY_BUFFER, getVBO(mb->getVertexType())); glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getVBO(mb->getVertexType()));
GLbitfield bitfield = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT; GLbitfield bitfield = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
void * buf = glMapBufferRange(GL_ARRAY_BUFFER, GLmeshes[i].vaoBaseVertex * GLmeshes[i].Stride, size, bitfield); void * buf = glMapBufferRange(GL_ARRAY_BUFFER, GLmeshes[i].vaoBaseVertex * GLmeshes[i].Stride, size, bitfield);
memcpy(buf, mb->getVertices(), size); memcpy(buf, mb->getVertices(), size);

View File

@ -95,7 +95,7 @@ void STKMeshSceneNode::setFirstTimeMaterial()
if (!immediate_draw) if (!immediate_draw)
{ {
std::pair<unsigned, unsigned> p = getVAOOffsetAndBase(mb); std::pair<unsigned, unsigned> p = VAOManager::getInstance()->getBase(mb);
mesh.vaoBaseVertex = p.first; mesh.vaoBaseVertex = p.first;
mesh.vaoOffset = p.second; mesh.vaoOffset = p.second;
mesh.VAOType = mb->getVertexType(); mesh.VAOType = mb->getVertexType();
@ -300,7 +300,7 @@ void STKMeshSceneNode::render()
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
if (!mb) if (!mb)
continue; continue;
glBindVertexArray(getVAO(video::EVT_STANDARD)); glBindVertexArray(VAOManager::getInstance()->getVAO(video::EVT_STANDARD));
drawGlow(GLmeshes[i]); drawGlow(GLmeshes[i]);
} }
} }
@ -413,7 +413,7 @@ void STKMeshSceneNode::render()
if (!TransparentMesh[TM_BUBBLE].empty()) if (!TransparentMesh[TM_BUBBLE].empty())
glUseProgram(MeshShader::BubbleShader::Program); glUseProgram(MeshShader::BubbleShader::Program);
glBindVertexArray(getVAO(video::EVT_STANDARD)); glBindVertexArray(VAOManager::getInstance()->getVAO(video::EVT_STANDARD));
for_in(mesh, TransparentMesh[TM_BUBBLE]) for_in(mesh, TransparentMesh[TM_BUBBLE])
drawBubble(*mesh, ModelViewProjectionMatrix); drawBubble(*mesh, ModelViewProjectionMatrix);
return; return;

View File

@ -270,7 +270,7 @@ void Track::cleanup()
{ {
QuadGraph::destroy(); QuadGraph::destroy();
ItemManager::destroy(); ItemManager::destroy();
resetVAO(); VAOManager::kill();
ParticleKindManager::get()->cleanUpTrackSpecificGfx(); ParticleKindManager::get()->cleanUpTrackSpecificGfx();
// Clear reminder of transformed textures // Clear reminder of transformed textures