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();
}
class VBOGatherer
{
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()
VAOManager::VAOManager()
{
vao[0] = vao[1] = vao[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;
}
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);
if (vbo[tp])
@ -611,7 +596,7 @@ void VBOGatherer::regenerateBuffer(enum VTXTYPE tp)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void VBOGatherer::regenerateVAO(enum VTXTYPE tp)
void VAOManager::regenerateVAO(enum VTXTYPE tp)
{
if (vao[tp])
glDeleteVertexArrays(1, &vao[tp]);
@ -677,7 +662,7 @@ void VBOGatherer::regenerateVAO(enum VTXTYPE tp)
glBindVertexArray(0);
}
size_t VBOGatherer::getVertexPitch(enum VTXTYPE tp) const
size_t VAOManager::getVertexPitch(enum VTXTYPE tp) const
{
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)
{
default:
assert(0 && "Wrong vtxtype");
case video::EVT_STANDARD:
return VTXTYPE_STANDARD;
case video::EVT_2TCOORDS:
return VTXTYPE_TCOORD;
case video::EVT_TANGENTS:
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];
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);
}
std::pair<unsigned, unsigned> VBOGatherer::getBase(scene::IMeshBuffer *mb)
std::pair<unsigned, unsigned> VAOManager::getBase(scene::IMeshBuffer *mb)
{
VTXTYPE tp = getVTXTYPE(mb->getVertexType());
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);
}
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)
{
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);
void saveCompressedTexture(const std::string& compressed_tex);
std::pair<unsigned, unsigned> getVAOOffsetAndBase(scene::IMeshBuffer *mb);
unsigned getVAO(video::E_VERTEX_TYPE type);
unsigned getVBO(video::E_VERTEX_TYPE type);
void resetVAO();
class VAOManager : public Singleton<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 *, 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,
const core::vector3df& end, irr::video::SColor color);

View File

@ -768,7 +768,7 @@ void IrrDriver::renderGlow(std::vector<GlowData>& glows)
glDepthMask(GL_FALSE);
glDisable(GL_BLEND);
glBindVertexArray(getVAO(EVT_STANDARD));
glBindVertexArray(VAOManager::getInstance()->getVAO(EVT_STANDARD));
for (u32 i = 0; i < glowcount; 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)
{
glUseProgram(Shader::getInstance()->Program);
glBindVertexArray(getVAO(VertexType));
glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
for (unsigned i = 0; i < meshes->size(); i++)
{
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)
{
glUseProgram(Shader::getInstance()->Program);
glBindVertexArray(getVAO(VertexType));
glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
for (unsigned i = 0; i < meshes->size(); i++)
{
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)
{
glUseProgram(MeshShader::NormalVisualizer::getInstance()->Program);
glBindVertexArray(getVAO(VertexType));
glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
for (unsigned i = 0; i < meshes->size(); i++)
{
GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i)));
@ -522,7 +522,7 @@ void IrrDriver::renderTransparent()
ListDisplacement::getInstance()->clear();
m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT);
glBindVertexArray(getVAO(EVT_STANDARD));
glBindVertexArray(VAOManager::getInstance()->getVAO(EVT_STANDARD));
if (World::getWorld() && World::getWorld()->isFogEnabled())
{
@ -568,7 +568,7 @@ void IrrDriver::renderTransparent()
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glBindVertexArray(getVAO(EVT_2TCOORDS));
glBindVertexArray(VAOManager::getInstance()->getVAO(EVT_2TCOORDS));
// Generate displace mask
// Use RTT_TMP4 as displace mask
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)
{
glUseProgram(T::getInstance()->Program);
glBindVertexArray(getVAO(VertexType));
glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
for (unsigned i = 0; i < t->size(); i++)
{
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)
{
glUseProgram(T::getInstance()->Program);
glBindVertexArray(getVAO(VertexType));
glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
for (unsigned i = 0; i < t->size(); i++)
{
std::vector<GLuint> Textures;

View File

@ -100,7 +100,7 @@ void STKAnimatedMesh::render()
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
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.vaoOffset = p.second;
mesh.VAOType = mb->getVertexType();
@ -118,7 +118,7 @@ void STKAnimatedMesh::render()
{
glBindVertexArray(0);
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;
void * buf = glMapBufferRange(GL_ARRAY_BUFFER, GLmeshes[i].vaoBaseVertex * GLmeshes[i].Stride, size, bitfield);
memcpy(buf, mb->getVertices(), size);

View File

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

View File

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