diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 7cac587c1..f3f830fd6 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -768,7 +768,8 @@ void IrrDriver::renderGlow(std::vector& glows) glDepthMask(GL_FALSE); glDisable(GL_BLEND); - glBindVertexArray(VAOManager::getInstance()->getVAO(EVT_STANDARD)); + if (irr_driver->hasARB_base_instance()) + 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 335d5a73b..a46f59331 100644 --- a/src/graphics/render_geometry.cpp +++ b/src/graphics/render_geometry.cpp @@ -120,12 +120,15 @@ template &TexUnits, std::vector > *meshes) { glUseProgram(Shader::getInstance()->Program); - glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType)); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType)); for (unsigned i = 0; i < meshes->size(); i++) { std::vector Textures; std::vector Handles; GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i))); + if (!irr_driver->hasARB_base_instance()) + glBindVertexArray(mesh.vao); for (unsigned j = 0; j < TexUnits.size(); j++) { if (UserConfigParams::m_azdo) @@ -388,12 +391,15 @@ void renderMeshes2ndPass(const std::vector &TexUnits, std::vector &Prefilled_Tex) { glUseProgram(Shader::getInstance()->Program); - glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType)); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType)); for (unsigned i = 0; i < meshes->size(); i++) { std::vector Handles(Prefilled_Handle); std::vector Textures(Prefilled_Tex); GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i))); + if (!irr_driver->hasARB_base_instance()) + glBindVertexArray(mesh.vao); for (unsigned j = 0; j < TexUnits.size(); j++) { if (UserConfigParams::m_azdo) @@ -615,12 +621,15 @@ template &TexUnits, std::vector > *meshes) { glUseProgram(Shader::getInstance()->Program); - glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType)); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType)); for (unsigned i = 0; i < meshes->size(); i++) { std::vector Handles; std::vector Textures; GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i))); + if (!irr_driver->hasARB_base_instance()) + glBindVertexArray(mesh.vao); for (unsigned j = 0; j < TexUnits.size(); j++) { if (!mesh.textures[TexUnits[j].m_id]) @@ -674,7 +683,8 @@ void IrrDriver::renderTransparent() ListDisplacement::getInstance()->clear(); m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT); - glBindVertexArray(VAOManager::getInstance()->getVAO(EVT_STANDARD)); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getVAO(EVT_STANDARD)); if (World::getWorld() && World::getWorld()->isFogEnabled()) { @@ -716,13 +726,16 @@ void IrrDriver::renderTransparent() glStencilFunc(GL_ALWAYS, 1, 0xFF); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - glBindVertexArray(VAOManager::getInstance()->getVAO(EVT_2TCOORDS)); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getVAO(EVT_2TCOORDS)); // Generate displace mask // Use RTT_TMP4 as displace mask irr_driver->getFBO(FBO_TMP1_WITH_DS).Bind(); for (unsigned i = 0; i < ListDisplacement::getInstance()->size(); i++) { const GLMesh &mesh = *(STK::tuple_get<0>(ListDisplacement::getInstance()->at(i))); + if (!irr_driver->hasARB_base_instance()) + glBindVertexArray(mesh.vao); const core::matrix4 &AbsoluteTransformation = STK::tuple_get<1>(ListDisplacement::getInstance()->at(i)); if (mesh.VAOType != video::EVT_2TCOORDS) { @@ -747,6 +760,8 @@ void IrrDriver::renderTransparent() for (unsigned i = 0; i < ListDisplacement::getInstance()->size(); i++) { const GLMesh &mesh = *(STK::tuple_get<0>(ListDisplacement::getInstance()->at(i))); + if (!irr_driver->hasARB_base_instance()) + glBindVertexArray(mesh.vao); const core::matrix4 &AbsoluteTransformation = STK::tuple_get<1>(ListDisplacement::getInstance()->at(i)); if (mesh.VAOType != video::EVT_2TCOORDS) continue; @@ -814,12 +829,15 @@ template TextureUnits, unsigned cascade, const std::vector > *t) { glUseProgram(T::getInstance()->Program); - glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType)); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType)); for (unsigned i = 0; i < t->size(); i++) { std::vector Handles; std::vector Textures; GLMesh *mesh = STK::tuple_get<0>(t->at(i)); + if (!irr_driver->hasARB_base_instance()) + glBindVertexArray(mesh->vao); for (unsigned j = 0; j < TextureUnits.size(); j++) { compressTexture(mesh->textures[TextureUnits[j]], true); @@ -882,7 +900,7 @@ void renderInstancedShadow(const std::vector TextureUnits, unsigned casc std::vector Textures; GLMesh *mesh = STK::tuple_get<0>(t->at(i)); if (!irr_driver->hasARB_base_instance()) - glBindVertexArray(mesh->vao_shadow_pass); + glBindVertexArray(mesh->vao); for (unsigned j = 0; j < TextureUnits.size(); j++) Textures.push_back(getTextureGLuint(mesh->textures[TextureUnits[j]])); @@ -1062,11 +1080,14 @@ template &TextureUnits, std::vector > *t) { glUseProgram(T::getInstance()->Program); - glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType)); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType)); for (unsigned i = 0; i < t->size(); i++) { std::vector Textures; GLMesh *mesh = STK::tuple_get<0>(t->at(i)); + if (!irr_driver->hasARB_base_instance()) + glBindVertexArray(mesh->vao); for (unsigned j = 0; j < TextureUnits.size(); j++) Textures.push_back(getTextureGLuint(mesh->textures[TextureUnits[j]])); T::getInstance()->SetTextureUnits(Textures); diff --git a/src/graphics/stkanimatedmesh.cpp b/src/graphics/stkanimatedmesh.cpp index 54ad2a5c3..6c9cf872c 100644 --- a/src/graphics/stkanimatedmesh.cpp +++ b/src/graphics/stkanimatedmesh.cpp @@ -33,6 +33,8 @@ void STKAnimatedMesh::cleanGLMeshes() glDeleteVertexArrays(1, &(mesh.vao)); glDeleteBuffers(1, &(mesh.vertex_buffer)); glDeleteBuffers(1, &(mesh.index_buffer)); + if (mesh.instance_buffer) + glDeleteBuffers(1, &(mesh.instance_buffer)); #ifdef Bindless_Texture_Support for (unsigned j = 0; j < 6; j++) { @@ -108,10 +110,29 @@ void STKAnimatedMesh::render() MeshSolidMaterial[MatType].push_back(&mesh); InitTextures(mesh, MatType); } - std::pair p = VAOManager::getInstance()->getBase(mb); - mesh.vaoBaseVertex = p.first; - mesh.vaoOffset = p.second; - mesh.VAOType = mb->getVertexType(); + + if (irr_driver->hasARB_base_instance()) + { + std::pair p = VAOManager::getInstance()->getBase(mb); + mesh.vaoBaseVertex = p.first; + mesh.vaoOffset = p.second; + } + else + { + fillLocalBuffer(mesh, mb); + mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType()); + glGenBuffers(1, &(mesh.instance_buffer)); + glBindBuffer(GL_ARRAY_BUFFER, mesh.instance_buffer); + glEnableVertexAttribArray(7); + glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0); + glVertexAttribDivisor(7, 1); + glEnableVertexAttribArray(8); + glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float))); + glVertexAttribDivisor(8, 1); + glEnableVertexAttribArray(9); + glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float))); + glVertexAttribDivisor(9, 1); + } } } firstTime = false; @@ -126,7 +147,10 @@ void STKAnimatedMesh::render() { glBindVertexArray(0); size_t size = mb->getVertexCount() * GLmeshes[i].Stride; - glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getVBO(mb->getVertexType())); + if (irr_driver->hasARB_base_instance()) + glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getVBO(mb->getVertexType())); + else + glBindBuffer(GL_ARRAY_BUFFER, GLmeshes[i].vertex_buffer); 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/stkinstancedscenenode.cpp b/src/graphics/stkinstancedscenenode.cpp index 27ebb01d7..cde162d82 100644 --- a/src/graphics/stkinstancedscenenode.cpp +++ b/src/graphics/stkinstancedscenenode.cpp @@ -27,10 +27,12 @@ void STKInstancedSceneNode::cleanGL() continue; if (mesh.vao) glDeleteVertexArrays(1, &(mesh.vao)); - if (mesh.vao_shadow_pass) - glDeleteVertexArrays(1, &(mesh.vao_shadow_pass)); - glDeleteBuffers(1, &(mesh.vertex_buffer)); - glDeleteBuffers(1, &(mesh.index_buffer)); + if (mesh.vertex_buffer) + glDeleteBuffers(1, &(mesh.vertex_buffer)); + if (mesh.index_buffer) + glDeleteBuffers(1, &(mesh.index_buffer)); + if (mesh.instance_buffer) + glDeleteBuffers(1, &(mesh.instance_buffer)); #ifdef Bindless_Texture_Support for (unsigned j = 0; i < 6; i++) { @@ -39,7 +41,6 @@ void STKInstancedSceneNode::cleanGL() } #endif } - glDeleteBuffers(1, &instances_vbo); } STKInstancedSceneNode::~STKInstancedSceneNode() @@ -63,7 +64,6 @@ void STKInstancedSceneNode::createGLMeshes() std::pair p = VAOManager::getInstance()->getBase(mb); mesh.vaoBaseVertex = p.first; mesh.vaoOffset = p.second; - mesh.VAOType = mb->getVertexType(); } else fillLocalBuffer(mesh, mb); @@ -77,8 +77,8 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, const std::vecto if (!irr_driver->hasARB_base_instance()) { mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, getVTXTYPEFromStride(mesh.Stride)); - glGenBuffers(1, &instances_vbo); - glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); + glGenBuffers(1, &(mesh.instance_buffer)); + glBindBuffer(GL_ARRAY_BUFFER, mesh.instance_buffer); glBufferData(GL_ARRAY_BUFFER, instances.size() * sizeof(InstanceData), instances.data(), GL_STATIC_DRAW); glEnableVertexAttribArray(7); @@ -90,19 +90,6 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, const std::vecto glEnableVertexAttribArray(9); glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float))); glVertexAttribDivisor(9, 1); - - mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, getVTXTYPEFromStride(mesh.Stride)); - glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); - glEnableVertexAttribArray(7); - glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0); - glVertexAttribDivisor(7, 1); - glEnableVertexAttribArray(8); - glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float))); - glVertexAttribDivisor(8, 1); - glEnableVertexAttribArray(9); - glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float))); - glVertexAttribDivisor(9, 1); - glBindVertexArray(0); } } diff --git a/src/graphics/stkinstancedscenenode.hpp b/src/graphics/stkinstancedscenenode.hpp index 74dbc719d..466d0f96c 100644 --- a/src/graphics/stkinstancedscenenode.hpp +++ b/src/graphics/stkinstancedscenenode.hpp @@ -24,7 +24,6 @@ protected: std::vector GLmeshes; std::vector > instanceData; core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView; - GLuint instances_vbo; void createGLMeshes(); bool isMaterialInitialized; void setFirstTimeMaterial(); diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index fee55f00e..a8a9f6ffe 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -178,6 +178,7 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb) for (unsigned i = 0; i < 6; i++) result.textures[i] = mb->getMaterial().getTexture(i); result.TextureMatrix = 0; + result.VAOType = mb->getVertexType(); return result; } diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index c47f8b601..5df7f83ab 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -35,9 +35,9 @@ enum TransparentMaterial struct GLMesh { GLuint vao; - GLuint vao_shadow_pass; GLuint vertex_buffer; GLuint index_buffer; + GLuint instance_buffer; video::ITexture *textures[6]; GLenum PrimitiveType; GLenum IndexType; diff --git a/src/graphics/stkmeshscenenode.cpp b/src/graphics/stkmeshscenenode.cpp index da3e39cd1..7d6b6fb78 100644 --- a/src/graphics/stkmeshscenenode.cpp +++ b/src/graphics/stkmeshscenenode.cpp @@ -70,38 +70,42 @@ void STKMeshSceneNode::setFirstTimeMaterial() if (rnd->isTransparent()) { TransparentMaterial TranspMat = MaterialTypeToTransparentMaterial(type, MaterialTypeParam); - if (immediate_draw) - { - fillLocalBuffer(mesh, mb); - mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType()); - glBindVertexArray(0); - } - else + if (!immediate_draw) TransparentMesh[TranspMat].push_back(&mesh); } else { assert(!isDisplacement); MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType()); - if (immediate_draw) - { - fillLocalBuffer(mesh, mb); - mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType()); - glBindVertexArray(0); - } - else + if (!immediate_draw) { InitTextures(mesh, MatType); MeshSolidMaterials[MatType].push_back(&mesh); } } - if (!immediate_draw) + if (!immediate_draw && irr_driver->hasARB_base_instance()) { std::pair p = VAOManager::getInstance()->getBase(mb); mesh.vaoBaseVertex = p.first; mesh.vaoOffset = p.second; - mesh.VAOType = mb->getVertexType(); + } + else + { + fillLocalBuffer(mesh, mb); + mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType()); + glGenBuffers(1, &(mesh.instance_buffer)); + glBindBuffer(GL_ARRAY_BUFFER, mesh.instance_buffer); + glEnableVertexAttribArray(7); + glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0); + glVertexAttribDivisor(7, 1); + glEnableVertexAttribArray(8); + glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float))); + glVertexAttribDivisor(8, 1); + glEnableVertexAttribArray(9); + glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float))); + glVertexAttribDivisor(9, 1); + glBindVertexArray(0); } } isMaterialInitialized = true; @@ -116,8 +120,12 @@ void STKMeshSceneNode::cleanGLMeshes() continue; if (mesh.vao) glDeleteVertexArrays(1, &(mesh.vao)); - glDeleteBuffers(1, &(mesh.vertex_buffer)); - glDeleteBuffers(1, &(mesh.index_buffer)); + if (mesh.vertex_buffer) + glDeleteBuffers(1, &(mesh.vertex_buffer)); + if (mesh.index_buffer) + glDeleteBuffers(1, &(mesh.index_buffer)); + if (mesh.instance_buffer) + glDeleteBuffers(1, &(mesh.instance_buffer)); #ifdef Bindless_Texture_Support for (unsigned j = 0; j < 6; j++) { @@ -310,7 +318,10 @@ void STKMeshSceneNode::render() scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); if (!mb) continue; - glBindVertexArray(VAOManager::getInstance()->getVAO(video::EVT_STANDARD)); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getVAO(video::EVT_STANDARD)); + else + glBindVertexArray(GLmeshes[i].vao); drawGlow(GLmeshes[i]); } } @@ -445,9 +456,14 @@ void STKMeshSceneNode::render() if (!TransparentMesh[TM_BUBBLE].empty()) glUseProgram(MeshShader::BubbleShader::Program); - glBindVertexArray(VAOManager::getInstance()->getVAO(video::EVT_STANDARD)); + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(VAOManager::getInstance()->getVAO(video::EVT_STANDARD)); for_in(mesh, TransparentMesh[TM_BUBBLE]) + { + if (irr_driver->hasARB_base_instance()) + glBindVertexArray(mesh->vao); drawBubble(*mesh, ModelViewProjectionMatrix); + } return; } }