diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index fbb64e077..e205a41c8 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -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 storedCPUBuffer[VTXTYPE_COUNT]; - void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[VTXTYPE_COUNT]; - size_t vtx_cnt[VTXTYPE_COUNT], idx_cnt[VTXTYPE_COUNT]; - std::map 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 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 VBOGatherer::getBase(scene::IMeshBuffer *mb) +std::pair VAOManager::getBase(scene::IMeshBuffer *mb) { VTXTYPE tp = getVTXTYPE(mb->getVertexType()); if (mappedBaseVertex[tp].find(mb) == mappedBaseVertex[tp].end()) @@ -747,36 +732,6 @@ std::pair VBOGatherer::getBase(scene::IMeshBuffer *mb) return std::pair(vtx, It->second); } -static VBOGatherer *gatherersingleton = 0; - -std::pair 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; diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index 20d0f425d..034af4090 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -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 getVAOOffsetAndBase(scene::IMeshBuffer *mb); -unsigned getVAO(video::E_VERTEX_TYPE type); -unsigned getVBO(video::E_VERTEX_TYPE type); -void resetVAO(); +class VAOManager : public Singleton +{ + enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT }; + GLuint vbo[VTXTYPE_COUNT], ibo[VTXTYPE_COUNT], vao[VTXTYPE_COUNT]; + std::vector storedCPUBuffer[VTXTYPE_COUNT]; + void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[VTXTYPE_COUNT]; + size_t vtx_cnt[VTXTYPE_COUNT], idx_cnt[VTXTYPE_COUNT]; + std::map 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 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); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index ad3dcad4f..7cac587c1 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -768,7 +768,7 @@ void IrrDriver::renderGlow(std::vector& 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]; diff --git a/src/graphics/render_geometry.cpp b/src/graphics/render_geometry.cpp index d925742e8..ec27ac576 100644 --- a/src/graphics/render_geometry.cpp +++ b/src/graphics/render_geometry.cpp @@ -119,7 +119,7 @@ template &TexUnits, std::vector > *meshes) { glUseProgram(Shader::getInstance()->Program); - glBindVertexArray(getVAO(VertexType)); + glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType)); for (unsigned i = 0; i < meshes->size(); i++) { std::vector Textures; @@ -292,7 +292,7 @@ template &TexUnits, std::vector > *meshes) { glUseProgram(Shader::getInstance()->Program); - glBindVertexArray(getVAO(VertexType)); + glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType)); for (unsigned i = 0; i < meshes->size(); i++) { std::vector Textures; @@ -473,7 +473,7 @@ template static void renderMeshNormals(std::vector > *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 TextureUnits, const std::vector > *t) { glUseProgram(T::getInstance()->Program); - glBindVertexArray(getVAO(VertexType)); + glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType)); for (unsigned i = 0; i < t->size(); i++) { std::vector Textures; @@ -815,7 +815,7 @@ template &TextureUnits, std::vector > *t) { glUseProgram(T::getInstance()->Program); - glBindVertexArray(getVAO(VertexType)); + glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType)); for (unsigned i = 0; i < t->size(); i++) { std::vector Textures; diff --git a/src/graphics/stkanimatedmesh.cpp b/src/graphics/stkanimatedmesh.cpp index e88550d38..1b07ba301 100644 --- a/src/graphics/stkanimatedmesh.cpp +++ b/src/graphics/stkanimatedmesh.cpp @@ -100,7 +100,7 @@ void STKAnimatedMesh::render() MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType()); MeshSolidMaterial[MatType].push_back(&mesh); } - std::pair p = getVAOOffsetAndBase(mb); + std::pair 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); diff --git a/src/graphics/stkmeshscenenode.cpp b/src/graphics/stkmeshscenenode.cpp index 4640ac59a..0a8aabddd 100644 --- a/src/graphics/stkmeshscenenode.cpp +++ b/src/graphics/stkmeshscenenode.cpp @@ -95,7 +95,7 @@ void STKMeshSceneNode::setFirstTimeMaterial() if (!immediate_draw) { - std::pair p = getVAOOffsetAndBase(mb); + std::pair 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; diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index f5546d85f..36aab33c8 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -270,7 +270,7 @@ void Track::cleanup() { QuadGraph::destroy(); ItemManager::destroy(); - resetVAO(); + VAOManager::kill(); ParticleKindManager::get()->cleanUpTrackSpecificGfx(); // Clear reminder of transformed textures