Implemented system to cull out redundant glUniform calls

This commit is contained in:
2013-05-08 17:47:27 -07:00
parent e42eeb5392
commit 6fe549b3ba
13 changed files with 311 additions and 210 deletions

View File

@@ -119,15 +119,9 @@ void KRDirectionalLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &
KRShader *pShader = getContext().getShaderManager()->getShader("light_directional", pCamera, std::vector<KRPointLight *>(), this_light, std::vector<KRSpotLight *>(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); KRShader *pShader = getContext().getShaderManager()->getShader("light_directional", pCamera, std::vector<KRPointLight *>(), this_light, std::vector<KRSpotLight *>(), 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<KRPointLight *>(), this_light, std::vector<KRSpotLight *>(), 0, renderPass)) { if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), std::vector<KRPointLight *>(), this_light, std::vector<KRSpotLight *>(), 0, renderPass)) {
light_direction_view_space.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE]); pShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE, light_direction_view_space);
m_color.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR]); pShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_COLOR, m_color);
pShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_INTENSITY, m_intensity * 0.01f);
if(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_INTENSITY] != -1) {
GLDEBUG(glUniform1f(
pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_INTENSITY],
m_intensity / 100.0f
));
}
// Disable z-buffer write // Disable z-buffer write
GLDEBUG(glDepthMask(GL_FALSE)); GLDEBUG(glDepthMask(GL_FALSE));

View File

@@ -85,7 +85,7 @@ void kraken::set_parameter(const std::string &parameter_name, float parameter_va
KRContext::KRENGINE_MAX_VBO_HANDLES = 10000; 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_HANDLES = 10000;
KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048; KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048;
KRContext::KRENGINE_MIN_TEXTURE_DIM = 64; KRContext::KRENGINE_MIN_TEXTURE_DIM = 64;
@@ -130,7 +130,7 @@ void kraken::set_parameter(const std::string &parameter_name, float parameter_va
#else #else
KRContext::KRENGINE_MAX_VBO_HANDLES = 10000; KRContext::KRENGINE_MAX_VBO_HANDLES = 10000;
KRContext::KRENGINE_MAX_VBO_MEM = 256000000; 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_HANDLES = 10000;
KRContext::KRENGINE_MAX_TEXTURE_MEM = 512000000; KRContext::KRENGINE_MAX_TEXTURE_MEM = 512000000;
KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 384000000; KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 384000000;

View File

@@ -222,12 +222,9 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_light
if(getContext().getShaderManager()->selectShader(*pCamera, pParticleShader, viewport, particleModelMatrix, this_point_light, this_directional_light, this_spot_light, 0, renderPass)) { 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]); 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()));
KRMat4::DotWDiv(KRMat4::Invert(particleModelMatrix), KRVector3::Zero()).setUniform(pParticleShader->m_uniforms[KRShader::KRENGINE_UNIFORM_PARTICLE_ORIGIN]); pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_dust_particle_size);
if(pParticleShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE] != -1) {
GLDEBUG(glUniform1f(pParticleShader->m_uniforms[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); 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)); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3));
@@ -266,8 +263,8 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_light
float slice_far = -pCamera->settings.volumetric_environment_max_distance; float slice_far = -pCamera->settings.volumetric_environment_max_distance;
float slice_spacing = (slice_far - slice_near) / slice_count; float slice_spacing = (slice_far - slice_near) / slice_count;
KRVector2(slice_near, slice_spacing).setUniform(pFogShader->m_uniforms[KRShader::KRENGINE_UNIFORM_SLICE_DEPTH_SCALE]); pFogShader->setUniform(KRShader::KRENGINE_UNIFORM_SLICE_DEPTH_SCALE, KRVector2(slice_near, slice_spacing));
(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_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); 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)); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, slice_count*6));
@@ -340,12 +337,7 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_light
// Render light flare on transparency pass // 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); 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(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) { pShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_flareSize);
GLDEBUG(glUniform1f(
pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE],
m_flareSize
));
}
m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture); 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); 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)); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));

View File

@@ -328,72 +328,68 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC
} }
if(!bSameAmbient) { 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(!bSameDiffuse) {
if(renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE) { if(renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE) {
// We pre-multiply the light color with the material color in the forward renderer // 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 { } else {
m_diffuseColor.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_DIFFUSE]); pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_DIFFUSE, m_diffuseColor);
} }
} }
if(!bSameSpecular) { if(!bSameSpecular) {
if(renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE) { if(renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE) {
// We pre-multiply the light color with the material color in the forward renderer // 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 { } else {
m_specularColor.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_SPECULAR]); pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_SPECULAR, m_specularColor);
} }
} }
if(!bSameShininess) { if(!bSameShininess) {
if(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_SHININESS] != -1) { pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_SHININESS, m_ns);
GLDEBUG(glUniform1f(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_SHININESS], m_ns));
}
} }
if(!bSameReflection) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_ALPHA, m_tr);
GLDEBUG(glUniform1f(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_ALPHA], m_tr));
}
if(bDiffuseMap) { if(bDiffuseMap) {
m_pContext->getTextureManager()->selectTexture(0, m_pDiffuseMap); m_pContext->getTextureManager()->selectTexture(0, m_pDiffuseMap);

View File

@@ -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; int start_index_offset, start_vertex_offset, index_count, vertex_count;
getIndexedRange(index_group++, 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)); int vertex_draw_count = cVertexes;
m_pContext->getModelManager()->log_draw_call(renderPass, object_name, material_name, index_count); if(vertex_draw_count > index_count - index_group_offset) vertex_draw_count = index_count - index_group_offset;
cVertexes -= 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; index_group_offset = 0;
} }
@@ -930,6 +933,7 @@ void KRMesh::convertToIndexed()
std::vector<__uint16_t> vertex_indexes; std::vector<__uint16_t> vertex_indexes;
std::vector<std::pair<int, int> > vertex_index_bases; std::vector<std::pair<int, int> > vertex_index_bases;
int vertex_index_offset = 0; int vertex_index_offset = 0;
int vertex_index_base_start_vertex = 0;
std::vector<KRVector3> vertices; std::vector<KRVector3> vertices;
std::vector<KRVector2> uva; std::vector<KRVector2> uva;
@@ -952,22 +956,24 @@ void KRMesh::convertToIndexed()
material_names.push_back(getSubmesh(submesh_index)->szName); material_names.push_back(getSubmesh(submesh_index)->szName);
int vertexes_remaining = getVertexCount(submesh_index); int vertexes_remaining = getVertexCount(submesh_index);
submesh_starts.push_back(vertex_index_bases.size() + (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<int, int>(vertex_indexes.size(), vertices.size()));
vertex_index_offset = 0;
int vertex_count = vertexes_remaining; int vertex_count = vertexes_remaining;
if(vertex_count > 0xffff) { if(vertex_count > 0xffff) {
vertex_count = 0xffff; vertex_count = 0xffff;
} }
int vertex_index_base_start_vertex = vertices.size(); if(submesh_index == 0 || vertex_index_offset + vertex_count > 0xffff) {
vertex_index_bases.push_back(std::pair<int, int>(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) {
std::map<std::pair<std::vector<float>, std::vector<int> >, int> prev_indexes = std::map<std::pair<std::vector<float>, std::vector<int> >, int>(); std::map<std::pair<std::vector<float>, std::vector<int> >, int> prev_indexes = std::map<std::pair<std::vector<float>, std::vector<int> >, int>();
@@ -1063,11 +1069,25 @@ void KRMesh::convertToIndexed()
} }
vertex_indexes.push_back(found_index); 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++; source_index++;
} }
vertexes_remaining -= vertex_count; 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<int, int>(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; int start_index_offset, start_vertex_offset, index_count, vertex_count;
getIndexedRange(index_group++, 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; int vertexes_to_process = vertexes_remaining;
index_count -= index_group_offset; if(vertexes_to_process + index_group_offset > 0xffff) {
index_group_offset = 0; vertexes_to_process = 0xffff - index_group_offset;
}
__uint16_t *index_data_start = index_data + start_index_offset + 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 ----====---- // ----====---- 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 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, index_count * sizeof(__uint16_t)); memcpy(index_data_start, new_indices, vertexes_to_process * sizeof(__uint16_t));
vertexes_remaining -= index_count; 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 ----====---- // ----====---- Step 2: Re-order the vertex data to maintain cache coherency ----====----
for(int i=0; i < vertex_count; i++) { for(int i=0; i < vertex_count; i++) {
vertex_mapping[i] = i; vertex_mapping[i] = i;
@@ -1194,6 +1218,10 @@ void KRMesh::optimizeIndexes()
} }
memcpy(vertex_data_start, new_vertex_data, vertex_count * m_vertex_size); memcpy(vertex_data_start, new_vertex_data, vertex_count * m_vertex_size);
*/ */
index_group_offset = 0;
} }
} }

View File

@@ -135,8 +135,8 @@ public:
typedef struct { typedef struct {
union { union {
struct { // For Indexed triangles / strips struct { // For Indexed triangles / strips
int16_t index_group; uint16_t index_group;
int16_t index_group_offset; uint16_t index_group_offset;
}; };
int32_t start_vertex; // For non-indexed trigangles / strips int32_t start_vertex; // For non-indexed trigangles / strips
}; };

View File

@@ -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) { 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()) { if(m_vbosActive.find(data) != m_vbosActive.end()) {
m_currentVBO = m_vbosActive[data]; m_currentVBO = m_vbosActive[data];

View File

@@ -75,12 +75,7 @@ void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vector<KRPointLig
KRShader *pParticleShader = m_pContext->getShaderManager()->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); KRShader *pParticleShader = m_pContext->getShaderManager()->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(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) { pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, 1.0f);
GLDEBUG(glUniform1f(
pParticleShader->m_uniforms[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); 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)); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3));

View File

@@ -73,32 +73,12 @@ void KRPointLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_
if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, this_light, std::vector<KRDirectionalLight *>(), std::vector<KRSpotLight *>(), 0, renderPass)) { if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, this_light, std::vector<KRDirectionalLight *>(), std::vector<KRSpotLight *>(), 0, renderPass)) {
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);
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]);
}
if(bVisualize) { if(bVisualize) {
// Enable additive blending // Enable additive blending

View File

@@ -108,6 +108,8 @@ KRShader::KRShader(KRContext &context, char *szKey, std::string options, std::st
{ {
strcpy(m_szKey, szKey); strcpy(m_szKey, szKey);
m_iProgram = 0; m_iProgram = 0;
GLuint vertexShader = 0, fragShader = 0; GLuint vertexShader = 0, fragShader = 0;
try { try {
const GLchar *vertSource[2] = {options.c_str(), vertShaderSource.c_str()}; 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 // Get uniform locations
for(int i=0; i < KRENGINE_NUM_UNIFORMS; i++ ){ for(int i=0; i < KRENGINE_NUM_UNIFORMS; i++ ){
GLDEBUG(m_uniforms[i] = glGetUniformLocation(m_iProgram, KRENGINE_UNIFORM_NAMES[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() { KRShader::~KRShader() {
if(m_iProgram) { if(m_iProgram) {
GLDEBUG(glDeleteProgram(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<KRPointLight *> &point_lights, const std::vector<KRDirectionalLight *> &directional_lights, const std::vector<KRSpotLight *>&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<KRPointLight *> &point_lights, const std::vector<KRDirectionalLight *> &directional_lights, const std::vector<KRSpotLight *>&spot_lights, const KRNode::RenderPass &renderPass) {
if(m_iProgram == 0) { if(m_iProgram == 0) {
return false; return false;
} }
bool need_to_validate = false;
if(getContext().getShaderManager()->m_active_shader != this) {
getContext().getShaderManager()->m_active_shader = this;
GLDEBUG(glUseProgram(m_iProgram)); GLDEBUG(glUseProgram(m_iProgram));
need_to_validate = true;
if(m_uniforms[KRENGINE_UNIFORM_ABSOLUTE_TIME] != -1) {
GLDEBUG(glUniform1f(m_uniforms[KRENGINE_UNIFORM_ABSOLUTE_TIME], getContext().getAbsoluteTime()));
} }
setUniform(KRENGINE_UNIFORM_ABSOLUTE_TIME, getContext().getAbsoluteTime());
int light_directional_count = 0; int light_directional_count = 0;
int light_point_count = 0; int light_point_count = 0;
int light_spot_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.translate(1.0, 1.0, 1.0);
matBias.scale(0.5); matBias.scale(0.5);
for(int iShadow=0; iShadow < cShadowBuffers; iShadow++) { 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) { 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 // Bind the light direction vector
KRVector3 lightDirObject = KRMat4::Dot(inverseModelMatrix, directional_light->getWorldLightDirection()); KRVector3 lightDirObject = KRMat4::Dot(inverseModelMatrix, directional_light->getWorldLightDirection());
lightDirObject.normalize(); 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) { if(m_uniforms[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE] != -1) {
// Transform location of camera to object space for calculation of specular halfVec // Transform location of camera to object space for calculation of specular halfVec
KRVector3 cameraPosObject = KRMat4::Dot(inverseModelMatrix, viewport.getCameraPosition()); 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) { 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 // Bind our modelmatrix variable to be a uniform called mvpmatrix in our shaderprogram
KRMat4 mvpMatrix = matModel * viewport.getViewProjectionMatrix(); 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) { 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) { 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(); 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) { 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 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) { if(m_uniforms[KRENGINE_UNIFORM_MODEL_VIEW_INVERSE_TRANSPOSE] != -1) {
KRMat4 matModelViewInverseTranspose = matModelView; KRMat4 matModelViewInverseTranspose = matModelView;
matModelViewInverseTranspose.transpose(); matModelViewInverseTranspose.transpose();
matModelViewInverseTranspose.invert(); 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; KRMat4 matModelInverseTranspose = matModel;
matModelInverseTranspose.transpose(); matModelInverseTranspose.transpose();
matModelInverseTranspose.invert(); 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) { 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) { if(m_uniforms[KRShader::KRENGINE_UNIFORM_INVMVP_NO_TRANSLATE] != -1) {
@@ -368,102 +487,64 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &
matInvMVPNoTranslate.getPointer()[15] = 1.0; matInvMVPNoTranslate.getPointer()[15] = 1.0;
matInvMVPNoTranslate = matInvMVPNoTranslate * viewport.getProjectionMatrix(); matInvMVPNoTranslate = matInvMVPNoTranslate * viewport.getProjectionMatrix();
matInvMVPNoTranslate.invert(); 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) { 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) { if(m_uniforms[KRENGINE_UNIFORM_VIEWPORT] != -1) {
GLDEBUG(glUniform4f( setUniform(KRENGINE_UNIFORM_VIEWPORT, KRVector4(
m_uniforms[KRENGINE_UNIFORM_VIEWPORT],
(GLfloat)0.0, (GLfloat)0.0,
(GLfloat)0.0, (GLfloat)0.0,
(GLfloat)viewport.getSize().x, (GLfloat)viewport.getSize().x,
(GLfloat)viewport.getSize().y (GLfloat)viewport.getSize().y
)); )
);
} }
// Fog parameters // Fog parameters
if(m_uniforms[KRENGINE_UNIFORM_FOG_NEAR] != -1) { setUniform(KRENGINE_UNIFORM_FOG_NEAR, camera.settings.fog_near);
GLDEBUG(glUniform1f(m_uniforms[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);
if(m_uniforms[KRENGINE_UNIFORM_FOG_FAR] != -1) { setUniform(KRENGINE_UNIFORM_FOG_COLOR, camera.settings.fog_color);
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]);
}
if(m_uniforms[KRENGINE_UNIFORM_FOG_SCALE] != -1) { 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) { 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) { 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 // Sets the diffuseTexture variable to the first texture unit
if(m_uniforms[KRENGINE_UNIFORM_DIFFUSETEXTURE] != -1) { setUniform(KRENGINE_UNIFORM_DIFFUSETEXTURE, 0);
GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_DIFFUSETEXTURE], 0));
}
// Sets the specularTexture variable to the second texture unit // Sets the specularTexture variable to the second texture unit
if(m_uniforms[KRENGINE_UNIFORM_SPECULARTEXTURE] != -1) { setUniform(KRENGINE_UNIFORM_SPECULARTEXTURE, 1);
GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_SPECULARTEXTURE], 1));
}
// Sets the normalTexture variable to the third texture unit // Sets the normalTexture variable to the third texture unit
if(m_uniforms[KRENGINE_UNIFORM_NORMALTEXTURE] != -1) { setUniform(KRENGINE_UNIFORM_NORMALTEXTURE, 2);
GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_NORMALTEXTURE], 2));
}
// Sets the shadowTexture variable to the fourth texture unit // Sets the shadowTexture variable to the fourth texture unit
if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE1] != -1) { setUniform(KRENGINE_UNIFORM_SHADOWTEXTURE1, 3);
GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE1], 3)); setUniform(KRENGINE_UNIFORM_SHADOWTEXTURE2, 4);
} setUniform(KRENGINE_UNIFORM_SHADOWTEXTURE3, 5);
if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE2] != -1) { setUniform(KRENGINE_UNIFORM_REFLECTIONCUBETEXTURE, 4);
GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE2], 4)); setUniform(KRENGINE_UNIFORM_LIGHTMAPTEXTURE, 5);
} setUniform(KRENGINE_UNIFORM_GBUFFER_FRAME, 6);
if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE3] != -1) { 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
GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE3], 5)); 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);
if(m_uniforms[KRENGINE_UNIFORM_REFLECTIONCUBETEXTURE] != -1) { setUniform(KRENGINE_UNIFORM_VOLUMETRIC_ENVIRONMENT_FRAME, 2);
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));
}
#if DEBUG #if DEBUG
if(need_to_validate) {
GLint logLength; GLint logLength;
GLint validate_status = GL_FALSE; GLint validate_status = GL_FALSE;
@@ -483,6 +564,7 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &
} }
return false; return false;
} }
}
#endif #endif
return true; return true;

View File

@@ -47,7 +47,7 @@ public:
virtual ~KRShader(); virtual ~KRShader();
const char *getKey() const; const char *getKey() const;
bool bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &matModel, const std::vector<KRPointLight *> &point_lights, const std::vector<KRDirectionalLight *> &directional_lights, const std::vector<KRSpotLight *>&spot_lights, const KRNode::RenderPass &renderPass) const; bool bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &matModel, const std::vector<KRPointLight *> &point_lights, const std::vector<KRDirectionalLight *> &directional_lights, const std::vector<KRSpotLight *>&spot_lights, const KRNode::RenderPass &renderPass);
enum { enum {
KRENGINE_UNIFORM_MATERIAL_AMBIENT = 0, KRENGINE_UNIFORM_MATERIAL_AMBIENT = 0,
@@ -116,10 +116,41 @@ public:
KRENGINE_UNIFORM_BONE_TRANSFORMS, KRENGINE_UNIFORM_BONE_TRANSFORMS,
KRENGINE_NUM_UNIFORMS 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[]; static const char *KRENGINE_UNIFORM_NAMES[];
GLint m_uniforms[KRENGINE_NUM_UNIFORMS]; GLint m_uniforms[KRENGINE_NUM_UNIFORMS];
int m_uniform_value_index[KRENGINE_NUM_UNIFORMS];
std::vector<float> m_uniform_value_float;
std::vector<int> m_uniform_value_int;
std::vector<KRVector2> m_uniform_value_vector2;
std::vector<KRVector3> m_uniform_value_vector3;
std::vector<KRVector4> m_uniform_value_vector4;
std::vector<KRMat4> m_uniform_value_mat4;
char m_szKey[256]; 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: private:
GLuint m_iProgram; GLuint m_iProgram;
}; };

View File

@@ -41,6 +41,7 @@ using namespace std;
KRShaderManager::KRShaderManager(KRContext &context) : KRContextObject(context) { KRShaderManager::KRShaderManager(KRContext &context) : KRContextObject(context) {
m_szCurrentShaderKey[0] = '\0'; m_szCurrentShaderKey[0] = '\0';
m_active_shader = NULL;
} }
KRShaderManager::~KRShaderManager() { 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); 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<KRPointLight *> &point_lights, const std::vector<KRDirectionalLight *> &directional_lights, const std::vector<KRSpotLight *>&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<KRPointLight *> &point_lights, const std::vector<KRDirectionalLight *> &directional_lights, const std::vector<KRSpotLight *>&spot_lights, int bone_count, const KRNode::RenderPass &renderPass)
{ {
if(pShader) { if(pShader) {
bool bSameShader = strcmp(pShader->getKey(), m_szCurrentShaderKey) == 0; bool bSameShader = strcmp(pShader->getKey(), m_szCurrentShaderKey) == 0;

View File

@@ -60,12 +60,14 @@ public:
KRShader *getShader(const std::string &shader_name, KRCamera *pCamera, const std::vector<KRPointLight *> &point_lights, const std::vector<KRDirectionalLight *> &directional_lights, const std::vector<KRSpotLight *>&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); KRShader *getShader(const std::string &shader_name, KRCamera *pCamera, const std::vector<KRPointLight *> &point_lights, const std::vector<KRDirectionalLight *> &directional_lights, const std::vector<KRSpotLight *>&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<KRPointLight *> &point_lights, const std::vector<KRDirectionalLight *> &directional_lights, const std::vector<KRSpotLight *>&spot_lights, int bone_count, const KRNode::RenderPass &renderPass); bool selectShader(KRCamera &camera, KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector<KRPointLight *> &point_lights, const std::vector<KRDirectionalLight *> &directional_lights, const std::vector<KRSpotLight *>&spot_lights, int bone_count, const KRNode::RenderPass &renderPass);
bool selectShader(const std::string &shader_name, KRCamera &camera, const std::vector<KRPointLight *> &point_lights, const std::vector<KRDirectionalLight *> &directional_lights, const std::vector<KRSpotLight *>&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); bool selectShader(const std::string &shader_name, KRCamera &camera, const std::vector<KRPointLight *> &point_lights, const std::vector<KRDirectionalLight *> &directional_lights, const std::vector<KRSpotLight *>&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(); long getShaderHandlesUsed();
KRShader *m_active_shader;
private: private:
//unordered_map<std::string, KRShader *> m_shaders; //unordered_map<std::string, KRShader *> m_shaders;
std::map<std::pair<std::string, std::vector<int> >, KRShader *> m_shaders; std::map<std::pair<std::string, std::vector<int> >, KRShader *> m_shaders;
@@ -73,7 +75,7 @@ private:
unordered_map<std::string, std::string> m_fragShaderSource; unordered_map<std::string, std::string> m_fragShaderSource;
unordered_map<std::string, std::string> m_vertShaderSource; unordered_map<std::string, std::string> m_vertShaderSource;
KRShader *m_pShader;
char m_szCurrentShaderKey[256]; char m_szCurrentShaderKey[256];
}; };