From 6fe549b3ba432848f5d598ac5aeb1f7a4976abd5 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Wed, 8 May 2013 17:47:27 -0700 Subject: [PATCH] Implemented system to cull out redundant glUniform calls --- KREngine/kraken/KRDirectionalLight.cpp | 12 +- KREngine/kraken/KREngine.mm | 4 +- KREngine/kraken/KRLight.cpp | 20 +- KREngine/kraken/KRMaterial.cpp | 36 +-- KREngine/kraken/KRMesh.cpp | 72 +++-- KREngine/kraken/KRMesh.h | 4 +- KREngine/kraken/KRMeshManager.cpp | 2 +- KREngine/kraken/KRParticleSystemNewtonian.cpp | 7 +- KREngine/kraken/KRPointLight.cpp | 32 +- KREngine/kraken/KRShader.cpp | 290 +++++++++++------- KREngine/kraken/KRShader.h | 33 +- KREngine/kraken/KRShaderManager.cpp | 3 +- KREngine/kraken/KRShaderManager.h | 6 +- 13 files changed, 311 insertions(+), 210 deletions(-) diff --git a/KREngine/kraken/KRDirectionalLight.cpp b/KREngine/kraken/KRDirectionalLight.cpp index dd16d90..c070856 100644 --- a/KREngine/kraken/KRDirectionalLight.cpp +++ b/KREngine/kraken/KRDirectionalLight.cpp @@ -119,15 +119,9 @@ void KRDirectionalLight::render(KRCamera *pCamera, std::vector & KRShader *pShader = getContext().getShaderManager()->getShader("light_directional", pCamera, std::vector(), this_light, std::vector(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), std::vector(), this_light, std::vector(), 0, renderPass)) { - light_direction_view_space.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE]); - m_color.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR]); - - if(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_INTENSITY] != -1) { - GLDEBUG(glUniform1f( - pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_INTENSITY], - m_intensity / 100.0f - )); - } + pShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE, light_direction_view_space); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_COLOR, m_color); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_INTENSITY, m_intensity * 0.01f); // Disable z-buffer write GLDEBUG(glDepthMask(GL_FALSE)); diff --git a/KREngine/kraken/KREngine.mm b/KREngine/kraken/KREngine.mm index e518a45..999fbd9 100644 --- a/KREngine/kraken/KREngine.mm +++ b/KREngine/kraken/KREngine.mm @@ -85,7 +85,7 @@ void kraken::set_parameter(const std::string ¶meter_name, float parameter_va KRContext::KRENGINE_MAX_VBO_HANDLES = 10000; - KRContext::KRENGINE_MAX_SHADER_HANDLES = 100; + KRContext::KRENGINE_MAX_SHADER_HANDLES = 4000; KRContext::KRENGINE_MAX_TEXTURE_HANDLES = 10000; KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048; KRContext::KRENGINE_MIN_TEXTURE_DIM = 64; @@ -130,7 +130,7 @@ void kraken::set_parameter(const std::string ¶meter_name, float parameter_va #else KRContext::KRENGINE_MAX_VBO_HANDLES = 10000; KRContext::KRENGINE_MAX_VBO_MEM = 256000000; - KRContext::KRENGINE_MAX_SHADER_HANDLES = 100; + KRContext::KRENGINE_MAX_SHADER_HANDLES = 4000; KRContext::KRENGINE_MAX_TEXTURE_HANDLES = 10000; KRContext::KRENGINE_MAX_TEXTURE_MEM = 512000000; KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 384000000; diff --git a/KREngine/kraken/KRLight.cpp b/KREngine/kraken/KRLight.cpp index d2438ea..398c32c 100644 --- a/KREngine/kraken/KRLight.cpp +++ b/KREngine/kraken/KRLight.cpp @@ -222,12 +222,9 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light if(getContext().getShaderManager()->selectShader(*pCamera, pParticleShader, viewport, particleModelMatrix, this_point_light, this_directional_light, this_spot_light, 0, renderPass)) { - (m_color * pCamera->settings.dust_particle_intensity * m_dust_particle_intensity * m_intensity).setUniform(pParticleShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR]); - - KRMat4::DotWDiv(KRMat4::Invert(particleModelMatrix), KRVector3::Zero()).setUniform(pParticleShader->m_uniforms[KRShader::KRENGINE_UNIFORM_PARTICLE_ORIGIN]); - if(pParticleShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE] != -1) { - GLDEBUG(glUniform1f(pParticleShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE], m_dust_particle_size)); - } + pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_COLOR, m_color * pCamera->settings.dust_particle_intensity * m_dust_particle_intensity * m_intensity); + pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_PARTICLE_ORIGIN, KRMat4::DotWDiv(KRMat4::Invert(particleModelMatrix), KRVector3::Zero())); + pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_dust_particle_size); m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), KRMeshManager::KRENGINE_MAX_RANDOM_PARTICLES * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, true, false, false, true, false, false, false, true); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3)); @@ -266,8 +263,8 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light float slice_far = -pCamera->settings.volumetric_environment_max_distance; float slice_spacing = (slice_far - slice_near) / slice_count; - KRVector2(slice_near, slice_spacing).setUniform(pFogShader->m_uniforms[KRShader::KRENGINE_UNIFORM_SLICE_DEPTH_SCALE]); - (m_color * pCamera->settings.volumetric_environment_intensity * m_intensity * -slice_spacing / 1000.0f).setUniform(pFogShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR]); + pFogShader->setUniform(KRShader::KRENGINE_UNIFORM_SLICE_DEPTH_SCALE, KRVector2(slice_near, slice_spacing)); + pFogShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_COLOR, (m_color * pCamera->settings.volumetric_environment_intensity * m_intensity * -slice_spacing / 1000.0f)); m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getVolumetricLightingVertexes(), KRMeshManager::KRENGINE_MAX_VOLUMETRIC_PLANES * 6 * sizeof(KRMeshManager::VolumetricLightingVertexData), NULL, 0, true, false, false, false, false, false, false, true); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, slice_count*6)); @@ -340,12 +337,7 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light // Render light flare on transparency pass KRShader *pShader = getContext().getShaderManager()->getShader("flare", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) { - if(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE] != -1) { - GLDEBUG(glUniform1f( - pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE], - m_flareSize - )); - } + pShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_flareSize); m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture); m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, true, false, false, true, false, false, false, true); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); diff --git a/KREngine/kraken/KRMaterial.cpp b/KREngine/kraken/KRMaterial.cpp index 855a698..59414fb 100644 --- a/KREngine/kraken/KRMaterial.cpp +++ b/KREngine/kraken/KRMaterial.cpp @@ -328,72 +328,68 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC } if(!bSameAmbient) { - (m_ambientColor + pCamera->settings.ambient_intensity).setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_AMBIENT]); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_AMBIENT, m_ambientColor + pCamera->settings.ambient_intensity); } if(!bSameDiffuse) { if(renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE) { // We pre-multiply the light color with the material color in the forward renderer - KRVector3(m_diffuseColor.x * pCamera->settings.light_intensity.x, m_diffuseColor.y * pCamera->settings.light_intensity.y, m_diffuseColor.z * pCamera->settings.light_intensity.z).setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_DIFFUSE]); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_DIFFUSE, KRVector3(m_diffuseColor.x * pCamera->settings.light_intensity.x, m_diffuseColor.y * pCamera->settings.light_intensity.y, m_diffuseColor.z * pCamera->settings.light_intensity.z)); } else { - m_diffuseColor.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_DIFFUSE]); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_DIFFUSE, m_diffuseColor); } } if(!bSameSpecular) { if(renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE) { // We pre-multiply the light color with the material color in the forward renderer - KRVector3(m_specularColor.x * pCamera->settings.light_intensity.x, m_specularColor.y * pCamera->settings.light_intensity.y, m_specularColor.z * pCamera->settings.light_intensity.z).setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_SPECULAR]); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_SPECULAR, KRVector3(m_specularColor.x * pCamera->settings.light_intensity.x, m_specularColor.y * pCamera->settings.light_intensity.y, m_specularColor.z * pCamera->settings.light_intensity.z)); } else { - m_specularColor.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_SPECULAR]); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_SPECULAR, m_specularColor); } } if(!bSameShininess) { - if(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_SHININESS] != -1) { - GLDEBUG(glUniform1f(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_SHININESS], m_ns)); - } + pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_SHININESS, m_ns); } if(!bSameReflection) { - m_reflectionColor.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_REFLECTION]); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_REFLECTION, m_reflectionColor); } if(bDiffuseMap && !bSameDiffuseScale && m_diffuseMapScale != default_scale) { - m_diffuseMapScale.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_DIFFUSETEXTURE_SCALE]); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_DIFFUSETEXTURE_SCALE, m_diffuseMapScale); } if(bSpecMap && !bSameSpecularScale && m_specularMapScale != default_scale) { - m_specularMapScale.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_SPECULARTEXTURE_SCALE]); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_SPECULARTEXTURE_SCALE, m_specularMapScale); } if(bReflectionMap && !bSameReflectionScale && m_reflectionMapScale != default_scale) { - m_reflectionMapScale.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_REFLECTIONTEXTURE_SCALE]); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_REFLECTIONTEXTURE_SCALE, m_reflectionMapScale); } if(bNormalMap && !bSameNormalScale && m_normalMapScale != default_scale) { - m_normalMapScale.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_NORMALTEXTURE_SCALE]); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_NORMALTEXTURE_SCALE, m_normalMapScale); } if(bDiffuseMap && !bSameDiffuseOffset && m_diffuseMapOffset != default_offset) { - m_diffuseMapOffset.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_DIFFUSETEXTURE_OFFSET]); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_DIFFUSETEXTURE_OFFSET, m_diffuseMapOffset); } if(bSpecMap && !bSameSpecularOffset && m_specularMapOffset != default_offset) { - m_specularMapOffset.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_SPECULARTEXTURE_OFFSET]); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_SPECULARTEXTURE_OFFSET, m_specularMapOffset); } if(bReflectionMap && !bSameReflectionOffset && m_reflectionMapOffset != default_offset) { - m_reflectionMapOffset.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_REFLECTIONTEXTURE_OFFSET]); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_REFLECTIONTEXTURE_OFFSET, m_reflectionMapOffset); } if(bNormalMap && !bSameNormalOffset && m_normalMapOffset != default_offset) { - m_normalMapOffset.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_NORMALTEXTURE_OFFSET]); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_NORMALTEXTURE_OFFSET, m_normalMapOffset); } - if(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_ALPHA] != -1) { - GLDEBUG(glUniform1f(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_ALPHA], m_tr)); - } + pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_ALPHA, m_tr); if(bDiffuseMap) { m_pContext->getTextureManager()->selectTexture(0, m_pDiffuseMap); diff --git a/KREngine/kraken/KRMesh.cpp b/KREngine/kraken/KRMesh.cpp index 0033caa..dfd3f80 100644 --- a/KREngine/kraken/KRMesh.cpp +++ b/KREngine/kraken/KRMesh.cpp @@ -271,11 +271,14 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st int start_index_offset, start_vertex_offset, index_count, vertex_count; getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); - m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + start_vertex_offset * m_vertex_size, m_vertex_size * vertex_count, index_data + start_index_offset, index_count * 4, has_vertex_attribute(KRENGINE_ATTRIB_VERTEX), has_vertex_attribute(KRENGINE_ATTRIB_NORMAL), has_vertex_attribute(KRENGINE_ATTRIB_TANGENT), has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA), has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB), has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES), has_vertex_attribute(KRENGINE_ATTRIB_BONEWEIGHTS), true); + m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size, index_data + start_index_offset, index_count * 2, has_vertex_attribute(KRENGINE_ATTRIB_VERTEX), has_vertex_attribute(KRENGINE_ATTRIB_NORMAL), has_vertex_attribute(KRENGINE_ATTRIB_TANGENT), has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA), has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB), has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES), has_vertex_attribute(KRENGINE_ATTRIB_BONEWEIGHTS), true); - glDrawElements(GL_TRIANGLES, index_count - index_group_offset, GL_UNSIGNED_SHORT, (void *)(index_group_offset * m_vertex_size)); - m_pContext->getModelManager()->log_draw_call(renderPass, object_name, material_name, index_count); - cVertexes -= index_count - index_group_offset; + int vertex_draw_count = cVertexes; + if(vertex_draw_count > index_count - index_group_offset) vertex_draw_count = index_count - index_group_offset; + + glDrawElements(GL_TRIANGLES, vertex_draw_count, GL_UNSIGNED_SHORT, BUFFER_OFFSET(index_group_offset * 2)); + m_pContext->getModelManager()->log_draw_call(renderPass, object_name, material_name, vertex_draw_count); + cVertexes -= vertex_draw_count; index_group_offset = 0; } @@ -930,6 +933,7 @@ void KRMesh::convertToIndexed() std::vector<__uint16_t> vertex_indexes; std::vector > vertex_index_bases; int vertex_index_offset = 0; + int vertex_index_base_start_vertex = 0; std::vector vertices; std::vector uva; @@ -952,22 +956,24 @@ void KRMesh::convertToIndexed() material_names.push_back(getSubmesh(submesh_index)->szName); int vertexes_remaining = getVertexCount(submesh_index); - submesh_starts.push_back(vertex_index_bases.size() + (vertex_index_offset << 16)); + + int vertex_count = vertexes_remaining; + if(vertex_count > 0xffff) { + vertex_count = 0xffff; + } + + if(submesh_index == 0 || vertex_index_offset + vertex_count > 0xffff) { + vertex_index_bases.push_back(std::pair(vertex_indexes.size(), vertices.size())); + vertex_index_offset = 0; + vertex_index_base_start_vertex = vertices.size(); + } + + submesh_starts.push_back(vertex_index_bases.size() - 1 + (vertex_index_offset << 16)); submesh_lengths.push_back(vertexes_remaining); int source_index = getSubmesh(submesh_index)->start_vertex; while(vertexes_remaining) { - vertex_index_bases.push_back(std::pair(vertex_indexes.size(), vertices.size())); - vertex_index_offset = 0; - - - int vertex_count = vertexes_remaining; - if(vertex_count > 0xffff) { - vertex_count = 0xffff; - } - - int vertex_index_base_start_vertex = vertices.size(); std::map, std::vector >, int> prev_indexes = std::map, std::vector >, int>(); @@ -1063,11 +1069,25 @@ void KRMesh::convertToIndexed() } vertex_indexes.push_back(found_index); + //fprintf(stderr, "Submesh: %6i IndexBase: %3i Index: %6i\n", submesh_index, vertex_index_bases.size(), found_index); source_index++; } vertexes_remaining -= vertex_count; + vertex_index_offset += vertex_count; + + + vertex_count = vertexes_remaining; + if(vertex_count > 0xffff) { + vertex_count = 0xffff; + } + + if(vertex_index_offset + vertex_count > 0xffff) { + vertex_index_bases.push_back(std::pair(vertex_indexes.size(), vertices.size())); + vertex_index_offset = 0; + vertex_index_base_start_vertex = vertices.size(); + } } } @@ -1149,19 +1169,23 @@ void KRMesh::optimizeIndexes() int start_index_offset, start_vertex_offset, index_count, vertex_count; getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); - start_index_offset += index_group_offset; - index_count -= index_group_offset; - index_group_offset = 0; + int vertexes_to_process = vertexes_remaining; + if(vertexes_to_process + index_group_offset > 0xffff) { + vertexes_to_process = 0xffff - index_group_offset; + } __uint16_t *index_data_start = index_data + start_index_offset + index_group_offset; - unsigned char * vertex_data_start = vertex_data + start_vertex_offset; + // ----====---- Step 1: Optimize triangle drawing order to maximize use of the GPU's post-transform vertex cache ----====---- - Forsyth::OptimizeFaces(index_data_start, index_count, vertex_count, new_indices, 16); // FINDME, TODO - GPU post-transform vertex cache size of 16 should be configureable - memcpy(index_data_start, new_indices, index_count * sizeof(__uint16_t)); - vertexes_remaining -= index_count; + Forsyth::OptimizeFaces(index_data_start, vertexes_to_process, vertex_count, new_indices, 16); // FINDME, TODO - GPU post-transform vertex cache size of 16 should be configureable + memcpy(index_data_start, new_indices, vertexes_to_process * sizeof(__uint16_t)); + vertexes_remaining -= vertexes_to_process; /* + + unsigned char * vertex_data_start = vertex_data + start_vertex_offset; + // ----====---- Step 2: Re-order the vertex data to maintain cache coherency ----====---- for(int i=0; i < vertex_count; i++) { vertex_mapping[i] = i; @@ -1194,6 +1218,10 @@ void KRMesh::optimizeIndexes() } memcpy(vertex_data_start, new_vertex_data, vertex_count * m_vertex_size); */ + + + + index_group_offset = 0; } } diff --git a/KREngine/kraken/KRMesh.h b/KREngine/kraken/KRMesh.h index ec1dfc8..f6d07b1 100644 --- a/KREngine/kraken/KRMesh.h +++ b/KREngine/kraken/KRMesh.h @@ -135,8 +135,8 @@ public: typedef struct { union { struct { // For Indexed triangles / strips - int16_t index_group; - int16_t index_group_offset; + uint16_t index_group; + uint16_t index_group_offset; }; int32_t start_vertex; // For non-indexed trigangles / strips }; diff --git a/KREngine/kraken/KRMeshManager.cpp b/KREngine/kraken/KRMeshManager.cpp index 88f6b98..fbb7b31 100644 --- a/KREngine/kraken/KRMeshManager.cpp +++ b/KREngine/kraken/KRMeshManager.cpp @@ -149,7 +149,7 @@ void KRMeshManager::releaseVBO(GLvoid *data) void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, GLsizeiptr index_data_size, bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb, bool enable_bone_indexes, bool enable_bone_weights, bool static_vbo) { - if(m_currentVBO.data != data || m_currentVBO.size != size) { + if(m_currentVBO.data != data || m_currentVBO.size != size + index_data_size) { if(m_vbosActive.find(data) != m_vbosActive.end()) { m_currentVBO = m_vbosActive[data]; diff --git a/KREngine/kraken/KRParticleSystemNewtonian.cpp b/KREngine/kraken/KRParticleSystemNewtonian.cpp index 7602fe4..b36f499 100644 --- a/KREngine/kraken/KRParticleSystemNewtonian.cpp +++ b/KREngine/kraken/KRParticleSystemNewtonian.cpp @@ -75,12 +75,7 @@ void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vectorgetShaderManager()->getShader("dust_particle", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); if(getContext().getShaderManager()->selectShader(*pCamera, pParticleShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) { - if(pParticleShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE] != -1) { - GLDEBUG(glUniform1f( - pParticleShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE], - 1.0f - )); - } + pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, 1.0f); m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, true, false, false, true, false, false, false, false); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3)); diff --git a/KREngine/kraken/KRPointLight.cpp b/KREngine/kraken/KRPointLight.cpp index 0ebd33c..7480a28 100644 --- a/KREngine/kraken/KRPointLight.cpp +++ b/KREngine/kraken/KRPointLight.cpp @@ -73,32 +73,12 @@ void KRPointLight::render(KRCamera *pCamera, std::vector &point_ if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, this_light, std::vector(), std::vector(), 0, renderPass)) { - - m_color.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR]); - - if(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_INTENSITY] != -1) { - GLDEBUG(glUniform1f( - pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_INTENSITY], - m_intensity / 100.0f - )); - } - - if(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_DECAY_START] != -1) { - GLDEBUG(glUniform1f( - pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_DECAY_START], - getDecayStart() - )); - } - if(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_CUTOFF] != -1) { - GLDEBUG(glUniform1f( - pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_CUTOFF], - KRLIGHT_MIN_INFLUENCE - )); - } - - if(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_POSITION] != -1) { - light_position.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_POSITION]); - } + pShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_COLOR, m_color); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_INTENSITY, m_intensity * 0.01f); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_DECAY_START, getDecayStart()); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_CUTOFF, KRLIGHT_MIN_INFLUENCE); + pShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_POSITION, light_position); + if(bVisualize) { // Enable additive blending diff --git a/KREngine/kraken/KRShader.cpp b/KREngine/kraken/KRShader.cpp index b02fc83..3c26261 100644 --- a/KREngine/kraken/KRShader.cpp +++ b/KREngine/kraken/KRShader.cpp @@ -108,6 +108,8 @@ KRShader::KRShader(KRContext &context, char *szKey, std::string options, std::st { strcpy(m_szKey, szKey); m_iProgram = 0; + + GLuint vertexShader = 0, fragShader = 0; try { const GLchar *vertSource[2] = {options.c_str(), vertShaderSource.c_str()}; @@ -190,6 +192,7 @@ KRShader::KRShader(KRContext &context, char *szKey, std::string options, std::st // Get uniform locations for(int i=0; i < KRENGINE_NUM_UNIFORMS; i++ ){ GLDEBUG(m_uniforms[i] = glGetUniformLocation(m_iProgram, KRENGINE_UNIFORM_NAMES[i])); + m_uniform_value_index[i] = -1; } } @@ -220,22 +223,138 @@ KRShader::KRShader(KRContext &context, char *szKey, std::string options, std::st KRShader::~KRShader() { if(m_iProgram) { GLDEBUG(glDeleteProgram(m_iProgram)); + if(getContext().getShaderManager()->m_active_shader == this) { + getContext().getShaderManager()->m_active_shader = NULL; + } } } -bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, const KRNode::RenderPass &renderPass) const { +void KRShader::setUniform(int location, float value) +{ + if(m_uniforms[location] != -1) { + int value_index = m_uniform_value_index[location]; + bool needs_update = true; + if(value_index == -1) { + m_uniform_value_index[location] = m_uniform_value_float.size(); + m_uniform_value_float.push_back(value); + } else if(m_uniform_value_float[value_index] == value) { + needs_update = false; + } else { + m_uniform_value_float[value_index] = value; + } + if(needs_update) { + GLDEBUG(glUniform1f(m_uniforms[location], value)); + } + } +} +void KRShader::setUniform(int location, int value) +{ + if(m_uniforms[location] != -1) { + int value_index = m_uniform_value_index[location]; + bool needs_update = true; + if(value_index == -1) { + m_uniform_value_index[location] = m_uniform_value_int.size(); + m_uniform_value_int.push_back(value); + } else if(m_uniform_value_int[value_index] == value) { + needs_update = false; + } else { + m_uniform_value_int[value_index] = value; + } + if(needs_update) { + GLDEBUG(glUniform1i(m_uniforms[location], value)); + } + } +} + +void KRShader::setUniform(int location, const KRVector2 &value) +{ + if(m_uniforms[location] != -1) { + int value_index = m_uniform_value_index[location]; + bool needs_update = true; + if(value_index == -1) { + m_uniform_value_index[location] = m_uniform_value_vector2.size(); + m_uniform_value_vector2.push_back(value); + } else if(m_uniform_value_vector2[value_index] == value) { + needs_update = false; + } else { + m_uniform_value_vector2[value_index] = value; + } + if(needs_update) { + GLDEBUG(glUniform2f(m_uniforms[location], value.x, value.y)); + } + } +} +void KRShader::setUniform(int location, const KRVector3 &value) +{ + if(m_uniforms[location] != -1) { + int value_index = m_uniform_value_index[location]; + bool needs_update = true; + if(value_index == -1) { + m_uniform_value_index[location] = m_uniform_value_vector3.size(); + m_uniform_value_vector3.push_back(value); + } else if(m_uniform_value_vector3[value_index] == value) { + needs_update = false; + } else { + m_uniform_value_vector3[value_index] = value; + } + if(needs_update) { + GLDEBUG(glUniform3f(m_uniforms[location], value.x, value.y, value.z)); + } + } +} +void KRShader::setUniform(int location, const KRVector4 &value) +{ + if(m_uniforms[location] != -1) { + int value_index = m_uniform_value_index[location]; + bool needs_update = true; + if(value_index == -1) { + m_uniform_value_index[location] = m_uniform_value_vector4.size(); + m_uniform_value_vector4.push_back(value); + } else if(m_uniform_value_vector4[value_index] == value) { + needs_update = false; + } else { + m_uniform_value_vector4[value_index] = value; + } + if(needs_update) { + GLDEBUG(glUniform4f(m_uniforms[location], value.x, value.y, value.z, value.w)); + } + } +} + +void KRShader::setUniform(int location, const KRMat4 &value) +{ + if(m_uniforms[location] != -1) { + int value_index = m_uniform_value_index[location]; + bool needs_update = true; + if(value_index == -1) { + m_uniform_value_index[location] = m_uniform_value_mat4.size(); + m_uniform_value_mat4.push_back(value); + } else if(m_uniform_value_mat4[value_index] == value) { + needs_update = false; + } else { + m_uniform_value_mat4[value_index] = value; + } + if(needs_update) { + GLDEBUG(glUniformMatrix4fv(m_uniforms[location], 1, GL_FALSE, value.c)); + } + } +} + +bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, const KRNode::RenderPass &renderPass) { if(m_iProgram == 0) { return false; } - - - GLDEBUG(glUseProgram(m_iProgram)); - - if(m_uniforms[KRENGINE_UNIFORM_ABSOLUTE_TIME] != -1) { - GLDEBUG(glUniform1f(m_uniforms[KRENGINE_UNIFORM_ABSOLUTE_TIME], getContext().getAbsoluteTime())); + bool need_to_validate = false; + if(getContext().getShaderManager()->m_active_shader != this) { + getContext().getShaderManager()->m_active_shader = this; + GLDEBUG(glUseProgram(m_iProgram)); + need_to_validate = true; } + + setUniform(KRENGINE_UNIFORM_ABSOLUTE_TIME, getContext().getAbsoluteTime()); + int light_directional_count = 0; int light_point_count = 0; int light_spot_count = 0; @@ -283,7 +402,7 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 & matBias.translate(1.0, 1.0, 1.0); matBias.scale(0.5); for(int iShadow=0; iShadow < cShadowBuffers; iShadow++) { - (matModel * directional_light->getShadowViewports()[iShadow].getViewProjectionMatrix() * matBias).setUniform(m_uniforms[KRENGINE_UNIFORM_SHADOWMVP1 + iShadow]); + setUniform(KRENGINE_UNIFORM_SHADOWMVP1 + iShadow, matModel * directional_light->getShadowViewports()[iShadow].getViewProjectionMatrix() * matBias); } if(m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION_MODEL_SPACE] != -1) { @@ -293,7 +412,7 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 & // Bind the light direction vector KRVector3 lightDirObject = KRMat4::Dot(inverseModelMatrix, directional_light->getWorldLightDirection()); lightDirObject.normalize(); - lightDirObject.setUniform(m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION_MODEL_SPACE]); + setUniform(KRENGINE_UNIFORM_LIGHT_DIRECTION_MODEL_SPACE, lightDirObject); } } @@ -313,35 +432,35 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 & if(m_uniforms[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE] != -1) { // Transform location of camera to object space for calculation of specular halfVec KRVector3 cameraPosObject = KRMat4::Dot(inverseModelMatrix, viewport.getCameraPosition()); - cameraPosObject.setUniform(m_uniforms[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE]); + setUniform(KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE, cameraPosObject); } } if(m_uniforms[KRENGINE_UNIFORM_MVP] != -1 || m_uniforms[KRShader::KRENGINE_UNIFORM_INVMVP] != -1) { // Bind our modelmatrix variable to be a uniform called mvpmatrix in our shaderprogram KRMat4 mvpMatrix = matModel * viewport.getViewProjectionMatrix(); - mvpMatrix.setUniform(m_uniforms[KRENGINE_UNIFORM_MVP]); + setUniform(KRENGINE_UNIFORM_MVP, mvpMatrix); if(m_uniforms[KRShader::KRENGINE_UNIFORM_INVMVP] != -1) { - KRMat4::Invert(mvpMatrix).setUniform(m_uniforms[KRShader::KRENGINE_UNIFORM_INVMVP]); + setUniform(KRShader::KRENGINE_UNIFORM_INVMVP, KRMat4::Invert(mvpMatrix)); } } if(m_uniforms[KRShader::KRENGINE_UNIFORM_VIEW_SPACE_MODEL_ORIGIN] != -1 || m_uniforms[KRENGINE_UNIFORM_MODEL_VIEW_INVERSE_TRANSPOSE] != -1 || m_uniforms[KRShader::KRENGINE_UNIFORM_MODEL_VIEW] != -1) { KRMat4 matModelView = matModel * viewport.getViewMatrix(); - matModelView.setUniform(m_uniforms[KRShader::KRENGINE_UNIFORM_MODEL_VIEW]); + setUniform(KRENGINE_UNIFORM_MODEL_VIEW, matModelView); if(m_uniforms[KRShader::KRENGINE_UNIFORM_VIEW_SPACE_MODEL_ORIGIN] != -1) { KRVector3 view_space_model_origin = KRMat4::Dot(matModelView, KRVector3::Zero()); // Origin point of model space is the light source position. No perspective, so no w divide required - view_space_model_origin.setUniform(m_uniforms[KRShader::KRENGINE_UNIFORM_VIEW_SPACE_MODEL_ORIGIN]); + setUniform(KRENGINE_UNIFORM_VIEW_SPACE_MODEL_ORIGIN, view_space_model_origin); } if(m_uniforms[KRENGINE_UNIFORM_MODEL_VIEW_INVERSE_TRANSPOSE] != -1) { KRMat4 matModelViewInverseTranspose = matModelView; matModelViewInverseTranspose.transpose(); matModelViewInverseTranspose.invert(); - matModelViewInverseTranspose.setUniform(m_uniforms[KRENGINE_UNIFORM_MODEL_VIEW_INVERSE_TRANSPOSE]); + setUniform(KRENGINE_UNIFORM_MODEL_VIEW_INVERSE_TRANSPOSE, matModelViewInverseTranspose); } } @@ -349,11 +468,11 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 & KRMat4 matModelInverseTranspose = matModel; matModelInverseTranspose.transpose(); matModelInverseTranspose.invert(); - matModelInverseTranspose.setUniform(m_uniforms[KRENGINE_UNIFORM_MODEL_INVERSE_TRANSPOSE]); + setUniform(KRENGINE_UNIFORM_MODEL_INVERSE_TRANSPOSE, matModelInverseTranspose); } if(m_uniforms[KRShader::KRENGINE_UNIFORM_INVP] != -1) { - viewport.getInverseProjectionMatrix().setUniform(m_uniforms[KRShader::KRENGINE_UNIFORM_INVP]); + setUniform(KRENGINE_UNIFORM_INVP, viewport.getInverseProjectionMatrix()); } if(m_uniforms[KRShader::KRENGINE_UNIFORM_INVMVP_NO_TRANSLATE] != -1) { @@ -368,120 +487,83 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 & matInvMVPNoTranslate.getPointer()[15] = 1.0; matInvMVPNoTranslate = matInvMVPNoTranslate * viewport.getProjectionMatrix(); matInvMVPNoTranslate.invert(); - matInvMVPNoTranslate.setUniform(m_uniforms[KRShader::KRENGINE_UNIFORM_INVMVP_NO_TRANSLATE]); + setUniform(KRENGINE_UNIFORM_INVMVP_NO_TRANSLATE, matInvMVPNoTranslate); } - matModel.setUniform(m_uniforms[KRShader::KRENGINE_UNIFORM_MODEL_MATRIX]); + setUniform(KRENGINE_UNIFORM_MODEL_MATRIX, matModel); if(m_uniforms[KRENGINE_UNIFORM_PROJECTION_MATRIX] != -1) { - viewport.getProjectionMatrix().setUniform(m_uniforms[KRENGINE_UNIFORM_PROJECTION_MATRIX]); + setUniform(KRENGINE_UNIFORM_PROJECTION_MATRIX, viewport.getProjectionMatrix()); } if(m_uniforms[KRENGINE_UNIFORM_VIEWPORT] != -1) { - GLDEBUG(glUniform4f( - m_uniforms[KRENGINE_UNIFORM_VIEWPORT], - (GLfloat)0.0, - (GLfloat)0.0, - (GLfloat)viewport.getSize().x, - (GLfloat)viewport.getSize().y - )); + setUniform(KRENGINE_UNIFORM_VIEWPORT, KRVector4( + (GLfloat)0.0, + (GLfloat)0.0, + (GLfloat)viewport.getSize().x, + (GLfloat)viewport.getSize().y + ) + ); } // Fog parameters - if(m_uniforms[KRENGINE_UNIFORM_FOG_NEAR] != -1) { - GLDEBUG(glUniform1f(m_uniforms[KRENGINE_UNIFORM_FOG_NEAR], camera.settings.fog_near)); - } - if(m_uniforms[KRENGINE_UNIFORM_FOG_FAR] != -1) { - GLDEBUG(glUniform1f(m_uniforms[KRENGINE_UNIFORM_FOG_FAR], camera.settings.fog_far)); - } - if(m_uniforms[KRENGINE_UNIFORM_FOG_DENSITY] != -1) { - GLDEBUG(glUniform1f(m_uniforms[KRENGINE_UNIFORM_FOG_DENSITY], camera.settings.fog_density)); - } - if(m_uniforms[KRENGINE_UNIFORM_FOG_COLOR] != -1) { - camera.settings.fog_color.setUniform(m_uniforms[KRENGINE_UNIFORM_FOG_COLOR]); - } - + setUniform(KRENGINE_UNIFORM_FOG_NEAR, camera.settings.fog_near); + setUniform(KRENGINE_UNIFORM_FOG_FAR, camera.settings.fog_far); + setUniform(KRENGINE_UNIFORM_FOG_DENSITY, camera.settings.fog_density); + setUniform(KRENGINE_UNIFORM_FOG_COLOR, camera.settings.fog_color); if(m_uniforms[KRENGINE_UNIFORM_FOG_SCALE] != -1) { - GLDEBUG(glUniform1f(m_uniforms[KRENGINE_UNIFORM_FOG_SCALE], 1.0f / (camera.settings.fog_far - camera.settings.fog_near))); + setUniform(KRENGINE_UNIFORM_FOG_SCALE, 1.0f / (camera.settings.fog_far - camera.settings.fog_near)); } if(m_uniforms[KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_EXPONENTIAL] != -1) { - GLDEBUG(glUniform1f(m_uniforms[KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_EXPONENTIAL], -camera.settings.fog_density * 1.442695f)); // -fog_density / log(2) + setUniform(KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_EXPONENTIAL, -camera.settings.fog_density * 1.442695f); // -fog_density / log(2) } if(m_uniforms[KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_SQUARED] != -1) { - GLDEBUG(glUniform1f(m_uniforms[KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_SQUARED], -camera.settings.fog_density * camera.settings.fog_density * 1.442695)); // -fog_density * fog_density / log(2) + setUniform(KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_SQUARED, (float)(-camera.settings.fog_density * camera.settings.fog_density * 1.442695)); // -fog_density * fog_density / log(2) } // Sets the diffuseTexture variable to the first texture unit - if(m_uniforms[KRENGINE_UNIFORM_DIFFUSETEXTURE] != -1) { - GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_DIFFUSETEXTURE], 0)); - } + setUniform(KRENGINE_UNIFORM_DIFFUSETEXTURE, 0); // Sets the specularTexture variable to the second texture unit - if(m_uniforms[KRENGINE_UNIFORM_SPECULARTEXTURE] != -1) { - GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_SPECULARTEXTURE], 1)); - } + setUniform(KRENGINE_UNIFORM_SPECULARTEXTURE, 1); // Sets the normalTexture variable to the third texture unit - if(m_uniforms[KRENGINE_UNIFORM_NORMALTEXTURE] != -1) { - GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_NORMALTEXTURE], 2)); - } + setUniform(KRENGINE_UNIFORM_NORMALTEXTURE, 2); // Sets the shadowTexture variable to the fourth texture unit - if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE1] != -1) { - GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE1], 3)); - } - if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE2] != -1) { - GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE2], 4)); - } - if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE3] != -1) { - GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE3], 5)); - } - - if(m_uniforms[KRENGINE_UNIFORM_REFLECTIONCUBETEXTURE] != -1) { - GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_REFLECTIONCUBETEXTURE], 4)); - } - if(m_uniforms[KRENGINE_UNIFORM_LIGHTMAPTEXTURE] != -1) { - GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_LIGHTMAPTEXTURE], 5)); - } - if(m_uniforms[KRENGINE_UNIFORM_GBUFFER_FRAME] != -1) { - GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_GBUFFER_FRAME], 6)); - } - if(m_uniforms[KRENGINE_UNIFORM_GBUFFER_DEPTH] != -1) { - GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_GBUFFER_DEPTH], 7)); // Texture unit 7 is used for reading the depth buffer in gBuffer pass #2 and in post-processing pass - } - if(m_uniforms[KRENGINE_UNIFORM_REFLECTIONTEXTURE] != -1) { - GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_REFLECTIONTEXTURE], 7)); // Texture unit 7 is used for the reflection map textures in gBuffer pass #3 and when using forward rendering - } - - if(m_uniforms[KRENGINE_UNIFORM_DEPTH_FRAME] != -1) { - GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_DEPTH_FRAME], 0)); - } - if(m_uniforms[KRENGINE_UNIFORM_RENDER_FRAME] != -1) { - GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_RENDER_FRAME], 1)); - } - if(m_uniforms[KRENGINE_UNIFORM_VOLUMETRIC_ENVIRONMENT_FRAME] != -1) { - GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_VOLUMETRIC_ENVIRONMENT_FRAME], 2)); - } + setUniform(KRENGINE_UNIFORM_SHADOWTEXTURE1, 3); + setUniform(KRENGINE_UNIFORM_SHADOWTEXTURE2, 4); + setUniform(KRENGINE_UNIFORM_SHADOWTEXTURE3, 5); + setUniform(KRENGINE_UNIFORM_REFLECTIONCUBETEXTURE, 4); + setUniform(KRENGINE_UNIFORM_LIGHTMAPTEXTURE, 5); + setUniform(KRENGINE_UNIFORM_GBUFFER_FRAME, 6); + setUniform(KRENGINE_UNIFORM_GBUFFER_DEPTH, 7); // Texture unit 7 is used for reading the depth buffer in gBuffer pass #2 and in post-processing pass + setUniform(KRENGINE_UNIFORM_REFLECTIONTEXTURE, 7); // Texture unit 7 is used for the reflection map textures in gBuffer pass #3 and when using forward rendering + setUniform(KRENGINE_UNIFORM_DEPTH_FRAME, 0); + setUniform(KRENGINE_UNIFORM_RENDER_FRAME, 1); + setUniform(KRENGINE_UNIFORM_VOLUMETRIC_ENVIRONMENT_FRAME, 2); #if DEBUG - GLint logLength; - - GLint validate_status = GL_FALSE; - GLDEBUG(glValidateProgram(m_iProgram)); - GLDEBUG(glGetProgramiv(m_iProgram, GL_VALIDATE_STATUS, &validate_status)); - if(validate_status != GL_TRUE) { - fprintf(stderr, "KREngine - Failed to validate shader program: %s\n", m_szKey); - GLDEBUG(glGetProgramiv(m_iProgram, GL_INFO_LOG_LENGTH, &logLength)); - if (logLength > 0) - { - GLchar *log = (GLchar *)malloc(logLength); - assert(log != NULL); - GLDEBUG(glGetProgramInfoLog(m_iProgram, logLength, &logLength, log)); - fprintf(stderr, "Program validate log:\n%s", log); - free(log); - + if(need_to_validate) { + GLint logLength; + + GLint validate_status = GL_FALSE; + GLDEBUG(glValidateProgram(m_iProgram)); + GLDEBUG(glGetProgramiv(m_iProgram, GL_VALIDATE_STATUS, &validate_status)); + if(validate_status != GL_TRUE) { + fprintf(stderr, "KREngine - Failed to validate shader program: %s\n", m_szKey); + GLDEBUG(glGetProgramiv(m_iProgram, GL_INFO_LOG_LENGTH, &logLength)); + if (logLength > 0) + { + GLchar *log = (GLchar *)malloc(logLength); + assert(log != NULL); + GLDEBUG(glGetProgramInfoLog(m_iProgram, logLength, &logLength, log)); + fprintf(stderr, "Program validate log:\n%s", log); + free(log); + + } + return false; } - return false; } #endif diff --git a/KREngine/kraken/KRShader.h b/KREngine/kraken/KRShader.h index 6576af4..06e4fe2 100644 --- a/KREngine/kraken/KRShader.h +++ b/KREngine/kraken/KRShader.h @@ -47,7 +47,7 @@ public: virtual ~KRShader(); const char *getKey() const; - bool bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, const KRNode::RenderPass &renderPass) const; + bool bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, const KRNode::RenderPass &renderPass); enum { KRENGINE_UNIFORM_MATERIAL_AMBIENT = 0, @@ -116,10 +116,41 @@ public: KRENGINE_UNIFORM_BONE_TRANSFORMS, KRENGINE_NUM_UNIFORMS }; + /* + typedef enum { + KRENGINE_UNIFORM_TYPE_UNKNOWN, + KRENGINE_UNIFORM_TYPE_FLOAT, + KRENGINE_UNIFORM_TYPE_INT, + KRENGINE_UNIFORM_TYPE_VECTOR2, + KRENGINE_UNIFORM_TYPE_VECTOR3, + KRENGINE_UNIFORM_TYPE_VECTOR4, + KRENGINE_UNIFORM_TYPE_MAT4 + } uniform_type_t; + uniform_type_t m_uniform_type[KRENGINE_NUM_UNIFORMS]; + */ + static const char *KRENGINE_UNIFORM_NAMES[]; GLint m_uniforms[KRENGINE_NUM_UNIFORMS]; + + int m_uniform_value_index[KRENGINE_NUM_UNIFORMS]; + + std::vector m_uniform_value_float; + std::vector m_uniform_value_int; + std::vector m_uniform_value_vector2; + std::vector m_uniform_value_vector3; + std::vector m_uniform_value_vector4; + std::vector m_uniform_value_mat4; + + char m_szKey[256]; + void setUniform(int location, float value); + void setUniform(int location, int value); + void setUniform(int location, const KRVector2 &value); + void setUniform(int location, const KRVector3 &value); + void setUniform(int location, const KRVector4 &value); + void setUniform(int location, const KRMat4 &value); + private: GLuint m_iProgram; }; diff --git a/KREngine/kraken/KRShaderManager.cpp b/KREngine/kraken/KRShaderManager.cpp index b68d0a4..e691328 100644 --- a/KREngine/kraken/KRShaderManager.cpp +++ b/KREngine/kraken/KRShaderManager.cpp @@ -41,6 +41,7 @@ using namespace std; KRShaderManager::KRShaderManager(KRContext &context) : KRContextObject(context) { m_szCurrentShaderKey[0] = '\0'; + m_active_shader = NULL; } KRShaderManager::~KRShaderManager() { @@ -244,7 +245,7 @@ bool KRShaderManager::selectShader(const std::string &shader_name, KRCamera &cam return selectShader(camera, pShader, viewport, matModel, point_lights, directional_lights, spot_lights, bone_count, renderPass); } -bool KRShaderManager::selectShader(KRCamera &camera, const KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, const KRNode::RenderPass &renderPass) +bool KRShaderManager::selectShader(KRCamera &camera, KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, const KRNode::RenderPass &renderPass) { if(pShader) { bool bSameShader = strcmp(pShader->getKey(), m_szCurrentShaderKey) == 0; diff --git a/KREngine/kraken/KRShaderManager.h b/KREngine/kraken/KRShaderManager.h index c69b541..59b762d 100644 --- a/KREngine/kraken/KRShaderManager.h +++ b/KREngine/kraken/KRShaderManager.h @@ -60,12 +60,14 @@ public: KRShader *getShader(const std::string &shader_name, KRCamera *pCamera, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass); - bool selectShader(KRCamera &camera, const KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, const KRNode::RenderPass &renderPass); + bool selectShader(KRCamera &camera, KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, const KRNode::RenderPass &renderPass); bool selectShader(const std::string &shader_name, KRCamera &camera, const std::vector &point_lights, const std::vector &directional_lights, const std::vector&spot_lights, int bone_count, const KRViewport &viewport, const KRMat4 &matModel, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass); long getShaderHandlesUsed(); + KRShader *m_active_shader; + private: //unordered_map m_shaders; std::map >, KRShader *> m_shaders; @@ -73,7 +75,7 @@ private: unordered_map m_fragShaderSource; unordered_map m_vertShaderSource; - KRShader *m_pShader; + char m_szCurrentShaderKey[256]; };