diff --git a/KREngine/KREngine/Classes/KRCamera.cpp b/KREngine/KREngine/Classes/KRCamera.cpp index fdf8674..d703663 100644 --- a/KREngine/KREngine/Classes/KRCamera.cpp +++ b/KREngine/KREngine/Classes/KRCamera.cpp @@ -349,7 +349,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); - // Render all transparent geometry + // Render all flares scene.render(this, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FLARES); // Re-enable z-buffer write diff --git a/KREngine/KREngine/Classes/KRDirectionalLight.cpp b/KREngine/KREngine/Classes/KRDirectionalLight.cpp index f3e2774..f660c06 100644 --- a/KREngine/KREngine/Classes/KRDirectionalLight.cpp +++ b/KREngine/KREngine/Classes/KRDirectionalLight.cpp @@ -67,7 +67,7 @@ void KRDirectionalLight::render(KRCamera *pCamera, KRContext *pContext, KRBoundi light_direction_view_space = KRMat4::Dot(matModelToView, light_direction_view_space); light_direction_view_space.normalize(); - KRShader *pShader = pContext->getShaderManager()->getShader("light_directional", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, renderPass); + KRShader *pShader = pContext->getShaderManager()->getShader("light_directional", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, renderPass); pShader->bind(pCamera, matModelToView, mvpmatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, 0, renderPass); diff --git a/KREngine/KREngine/Classes/KRInstance.cpp b/KREngine/KREngine/Classes/KRInstance.cpp index a70ec56..ab8bc9f 100644 --- a/KREngine/KREngine/Classes/KRInstance.cpp +++ b/KREngine/KREngine/Classes/KRInstance.cpp @@ -78,7 +78,7 @@ void KRInstance::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume KRNode::render(pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass); - if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT && renderPass != KRNode::RENDER_PASS_FLARES) { + if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && (renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT || this->hasTransparency()) && renderPass != KRNode::RENDER_PASS_FLARES) { // Don't render meshes on second pass of the deferred lighting renderer, as only lights will be applied loadModel(); diff --git a/KREngine/KREngine/Classes/KRLight.cpp b/KREngine/KREngine/Classes/KRLight.cpp index 2179231..7dd2512 100644 --- a/KREngine/KREngine/Classes/KRLight.cpp +++ b/KREngine/KREngine/Classes/KRLight.cpp @@ -144,7 +144,7 @@ void KRLight::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &f // Render light flare on transparency pass - KRShader *pShader = pContext->getShaderManager()->getShader("flare", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, renderPass); + KRShader *pShader = pContext->getShaderManager()->getShader("flare", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, renderPass); pShader->bind(pCamera, matModelToView, mvpmatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, 0, renderPass); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_pFlareTexture->getName()); diff --git a/KREngine/KREngine/Classes/KRMaterial.cpp b/KREngine/KREngine/Classes/KRMaterial.cpp index 2f1da70..9d81742 100644 --- a/KREngine/KREngine/Classes/KRMaterial.cpp +++ b/KREngine/KREngine/Classes/KRMaterial.cpp @@ -158,6 +158,10 @@ void KRMaterial::setAlphaMode(KRMaterial::alpha_mode_type alpha_mode) { m_alpha_mode = alpha_mode; } +KRMaterial::alpha_mode_type KRMaterial::getAlphaMode() { + return m_alpha_mode; +} + void KRMaterial::setAmbient(const KRVector3 &c) { m_ambientColor = c; } @@ -220,8 +224,9 @@ void KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC bool bSpecMap = m_pSpecularMap != NULL && pCamera->bEnableSpecMap; bool bReflectionMap = m_pReflectionMap != NULL && pCamera->bEnableReflectionMap; bool bAlphaTest = (m_alpha_mode == KRMATERIAL_ALPHA_MODE_TEST) && bDiffuseMap; + bool bAlphaBlend = (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE) || (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE); - KRShader *pShader = pContext->getShaderManager()->getShader("ObjectShader", pCamera, bDiffuseMap, bNormalMap, bSpecMap, cShadowBuffers, bLightMap, m_diffuseMapScale != default_scale && bDiffuseMap, m_specularMapScale != default_scale && bSpecMap, m_normalMapScale != default_scale && bNormalMap, m_diffuseMapOffset != default_offset && bDiffuseMap, m_specularMapOffset != default_offset && bSpecMap, m_normalMapOffset != default_offset && bNormalMap, bAlphaTest, renderPass); + KRShader *pShader = pContext->getShaderManager()->getShader("ObjectShader", pCamera, bDiffuseMap, bNormalMap, bSpecMap, cShadowBuffers, bLightMap, m_diffuseMapScale != default_scale && bDiffuseMap, m_specularMapScale != default_scale && bSpecMap, m_normalMapScale != default_scale && bNormalMap, m_diffuseMapOffset != default_offset && bDiffuseMap, m_specularMapOffset != default_offset && bSpecMap, m_normalMapOffset != default_offset && bNormalMap, bAlphaTest, bAlphaBlend, renderPass); bool bSameShader = strcmp(pShader->getKey(), szPrevShaderKey) == 0; if(!bSameShader) { diff --git a/KREngine/KREngine/Classes/KRMaterial.h b/KREngine/KREngine/Classes/KRMaterial.h index 26026b0..2e50a49 100644 --- a/KREngine/KREngine/Classes/KRMaterial.h +++ b/KREngine/KREngine/Classes/KRMaterial.h @@ -82,6 +82,7 @@ public: void setShininess(GLfloat s); void setReflectionFactor(GLfloat r); void setAlphaMode(alpha_mode_type blend_mode); + alpha_mode_type getAlphaMode(); bool isTransparent(); diff --git a/KREngine/KREngine/Classes/KRModel.cpp b/KREngine/KREngine/Classes/KRModel.cpp index 292ee53..977e207 100644 --- a/KREngine/KREngine/Classes/KRModel.cpp +++ b/KREngine/KREngine/Classes/KRModel.cpp @@ -52,18 +52,11 @@ KRModel::KRModel(KRContext &context, std::string name, std::string path) : KRCon } void KRModel::loadPack(std::string path) { + m_hasTransparency = false; m_materials.clear(); m_uniqueMaterials.clear(); m_pMesh = new KRMesh(*m_pContext, KRResource::GetFileBase(path)); m_pMesh->loadPack(path); - - m_hasTransparency = false; - for(std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { - if((*mat_itr)->isTransparent()) { - m_hasTransparency = true; - break; - } - } } std::string KRModel::getName() { @@ -87,6 +80,14 @@ void KRModel::render(KRCamera *pCamera, KRContext *pContext, KRMat4 &matModelToV m_materials.push_back(pMaterial); m_uniqueMaterials.insert(pMaterial); } + + m_hasTransparency = false; + for(std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { + if((*mat_itr)->isTransparent()) { + m_hasTransparency = true; + break; + } + } } KRMaterial *pPrevBoundMaterial = NULL; @@ -116,7 +117,27 @@ void KRModel::render(KRCamera *pCamera, KRContext *pContext, KRMat4 &matModelToV if(pMaterial != NULL && pMaterial == (*mat_itr)) { if((!pMaterial->isTransparent() && renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT) || (pMaterial->isTransparent() && renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) { pMaterial->bind(&pPrevBoundMaterial, szPrevShaderKey, pCamera, matModelToView, mvpMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, pContext, pLightMap, renderPass); - m_pMesh->renderSubmesh(iSubmesh, &iPrevBuffer); + + switch(pMaterial->getAlphaMode()) { + case KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE: // Non-transparent materials + case KRMaterial::KRMATERIAL_ALPHA_MODE_TEST: // Alpha in diffuse texture is interpreted as punch-through when < 0.5 + m_pMesh->renderSubmesh(iSubmesh, &iPrevBuffer); + break; + case KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE: // Blended alpha with backface culling + m_pMesh->renderSubmesh(iSubmesh, &iPrevBuffer); + break; + case KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE: // Blended alpha rendered in two passes. First pass renders backfaces; second pass renders frontfaces. + // Render back faces first + glCullFace(GL_BACK); + m_pMesh->renderSubmesh(iSubmesh, &iPrevBuffer); + + // Render front faces second + glCullFace(GL_BACK); + m_pMesh->renderSubmesh(iSubmesh, &iPrevBuffer); + break; + } + + } } } diff --git a/KREngine/KREngine/Classes/KRPointLight.cpp b/KREngine/KREngine/Classes/KRPointLight.cpp index fbd33f7..9c5d426 100644 --- a/KREngine/KREngine/Classes/KRPointLight.cpp +++ b/KREngine/KREngine/Classes/KRPointLight.cpp @@ -74,7 +74,7 @@ void KRPointLight::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolu if(influence_extents.test_intersect(frustrumVolumeNoNearClip)) { // Cull out any lights not within the view frustrum - KRShader *pShader = pContext->getShaderManager()->getShader("light_point", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, renderPass); + KRShader *pShader = pContext->getShaderManager()->getShader("light_point", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, renderPass); pShader->bind(pCamera, matModelToView, mvpmatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, 0, renderPass); glUniform3f( pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR], diff --git a/KREngine/KREngine/Classes/KRShaderManager.cpp b/KREngine/KREngine/Classes/KRShaderManager.cpp index 99dc190..f10dea1 100644 --- a/KREngine/KREngine/Classes/KRShaderManager.cpp +++ b/KREngine/KREngine/Classes/KRShaderManager.cpp @@ -45,10 +45,10 @@ KRShaderManager::~KRShaderManager() { } -KRShader *KRShaderManager::getShader(std::string shader_name, KRCamera *pCamera, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, int iShadowQuality, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bAlphaTest, KRNode::RenderPass renderPass) { +KRShader *KRShaderManager::getShader(std::string shader_name, KRCamera *pCamera, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, int iShadowQuality, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass) { char szKey[256]; - sprintf(szKey, "%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%i_%s", pCamera->bEnablePerPixel, bAlphaTest, bDiffuseMap, bNormalMap, bSpecMap, pCamera->bDebugPSSM, iShadowQuality, pCamera->bEnableAmbient, pCamera->bEnableDiffuse, pCamera->bEnableSpecular, bLightMap, bDiffuseMapScale, bSpecMapScale, bNormalMapScale, bDiffuseMapOffset, bSpecMapOffset, bNormalMapOffset, renderPass, shader_name.c_str()); + sprintf(szKey, "%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%i_%s", pCamera->bEnablePerPixel, bAlphaTest, bAlphaBlend, bDiffuseMap, bNormalMap, bSpecMap, pCamera->bDebugPSSM, iShadowQuality, pCamera->bEnableAmbient, pCamera->bEnableDiffuse, pCamera->bEnableSpecular, bLightMap, bDiffuseMapScale, bSpecMapScale, bNormalMapScale, bDiffuseMapOffset, bSpecMapOffset, bNormalMapOffset, renderPass, shader_name.c_str()); /* @@ -69,6 +69,7 @@ KRShader *KRShaderManager::getShader(std::string shader_name, KRCamera *pCamera, stream << "#define HAS_DIFFUSE_MAP " << (bDiffuseMap ? "1" : "0"); stream << "\n#define ALPHA_TEST " << (bAlphaTest ? "1" : "0"); + stream << "\n#define ALPHA_BLEND " << (bAlphaBlend ? "1" : "0"); stream << "\n#define HAS_NORMAL_MAP " << (bNormalMap ? "1" : "0"); stream << "\n#define HAS_SPEC_MAP " << (bSpecMap ? "1" : "0"); stream << "\n#define HAS_LIGHT_MAP " << (bLightMap ? "1" : "0"); diff --git a/KREngine/KREngine/Classes/KRShaderManager.h b/KREngine/KREngine/Classes/KRShaderManager.h index 23435ab..58454a9 100644 --- a/KREngine/KREngine/Classes/KRShaderManager.h +++ b/KREngine/KREngine/Classes/KRShaderManager.h @@ -56,7 +56,7 @@ public: const std::string &getVertShaderSource(const std::string &name); - KRShader *getShader(std::string shader_name, KRCamera *pCamera, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, int iShadowQuality, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bAlphaTest, KRNode::RenderPass renderPass); + KRShader *getShader(std::string shader_name, KRCamera *pCamera, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, int iShadowQuality, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass); private: std::map m_shaders; diff --git a/KREngine/KREngine/Shaders/ObjectShader.fsh b/KREngine/KREngine/Shaders/ObjectShader.fsh index 80d0ae5..56533c1 100644 --- a/KREngine/KREngine/Shaders/ObjectShader.fsh +++ b/KREngine/KREngine/Shaders/ObjectShader.fsh @@ -161,11 +161,11 @@ void main() #if ALPHA_TEST diffuseMaterial.a = 1.0; #else - mediump vec4 diffuseMaterial = vec4(vec3(texture2D(diffuseTexture, diffuse_uv)), material_alpha); + mediump vec4 diffuseMaterial = texture2D(diffuseTexture, diffuse_uv); #endif #else - mediump vec4 diffuseMaterial = vec4(vec3(1.0), material_alpha); + mediump vec4 diffuseMaterial = vec4(1.0); #endif #if ENABLE_PER_PIXEL == 1 @@ -249,14 +249,16 @@ void main() #if ENABLE_AMBIENT // -------------------- Add ambient light and alpha component -------------------- - gl_FragColor = vec4(vec3(diffuseMaterial) * material_ambient, material_alpha); + gl_FragColor = vec4(vec3(diffuseMaterial) * material_ambient, 0.0); #else - gl_FragColor = vec4(0.0, 0.0, 0.0, material_alpha); + gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); #endif #if ENABLE_DIFFUSE // -------------------- Add diffuse light -------------------- - gl_FragColor += vec4(vec3(diffuseMaterial) * material_diffuse * lamberFactor, 0.0); + gl_FragColor += diffuseMaterial * vec4(material_diffuse, 1.0) * vec4(vec3(lamberFactor), 1.0); + + //gl_FragColor += vec4(vec3(diffuseMaterial) * material_diffuse * lamberFactor, 0.0); #endif #if ENABLE_SPECULAR @@ -270,12 +272,15 @@ void main() #endif + #if ALPHA_BLEND + gl_FragColor.a = gl_FragColor.a * material_alpha; + #endif // -------------------- Multiply light map -------------------- #if HAS_LIGHT_MAP mediump vec3 lightMapColor = vec3(texture2D(shadowTexture1, lightmap_uv)); - gl_FragColor = vec4(gl_FragColor.r * lightMapColor.r, gl_FragColor.g * lightMapColor.g, gl_FragColor.b * lightMapColor.b, 1.0); + gl_FragColor = vec4(gl_FragColor.r * lightMapColor.r, gl_FragColor.g * lightMapColor.g, gl_FragColor.b * lightMapColor.b, gl_FragColor.a); #endif #endif }