diff --git a/KREngine/KREngine.xcodeproj/project.pbxproj b/KREngine/KREngine.xcodeproj/project.pbxproj index 79d2d82..ac7526a 100644 --- a/KREngine/KREngine.xcodeproj/project.pbxproj +++ b/KREngine/KREngine.xcodeproj/project.pbxproj @@ -456,8 +456,8 @@ E491018613C99BDC0098455B /* KRTexture.h */, E491018113C99BDC0098455B /* KRTexture.cpp */, E47C25A113F4F65A00FF4370 /* KRShaderManager.h */, - E47C25A413F4F66F00FF4370 /* KRShader.h */, E47C25A613F4F6AB00FF4370 /* KRShaderManager.cpp */, + E47C25A413F4F66F00FF4370 /* KRShader.h */, E47C25A813F4F6DD00FF4370 /* KRShader.cpp */, E48B3CBC14393DF5000C50E2 /* KRCamera.h */, E48B3CBF14393E2F000C50E2 /* KRCamera.cpp */, diff --git a/KREngine/KREngine/Classes/KRDirectionalLight.cpp b/KREngine/KREngine/Classes/KRDirectionalLight.cpp index 4a3a4d9..73ab377 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, renderPass); + KRShader *pShader = pContext->getShaderManager()->getShader("light_directional", pCamera, false, false, false, 0, 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/KRLight.cpp b/KREngine/KREngine/Classes/KRLight.cpp index ea5d889..669e6a3 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, renderPass); + KRShader *pShader = pContext->getShaderManager()->getShader("flare", pCamera, false, false, false, 0, 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 0fe1f04..b207a42 100644 --- a/KREngine/KREngine/Classes/KRMaterial.cpp +++ b/KREngine/KREngine/Classes/KRMaterial.cpp @@ -66,6 +66,7 @@ KRMaterial::KRMaterial(const char *szName) : KRResource(szName) { m_reflectionMapOffset = KRVector2(0.0f, 0.0f); m_reflectionMapScale = KRVector2(1.0f, 1.0f); m_reflectionFactor = 0.0f; + m_bAlphaTest = false; } KRMaterial::~KRMaterial() { @@ -104,6 +105,9 @@ bool KRMaterial::save(const std::string& path) { if(m_reflectionMap.size()) { fprintf(f, "map_Reflection %s.pvr -s %f %f -o %f %f\n", m_reflectionMap.c_str(), m_reflectionMapScale.x, m_reflectionMapScale.y, m_reflectionMapOffset.x, m_reflectionMapOffset.y); } + if(m_bAlphaTest) { + fprintf(f, "alpha_test true"); + } fclose(f); return true; } @@ -139,6 +143,10 @@ void KRMaterial::setReflectionMap(std::string texture_name, KRVector2 texture_sc m_reflectionMapOffset = texture_offset; } +void KRMaterial::setAlphaTest(bool bAlphaTest) { + m_bAlphaTest = bAlphaTest; +} + void KRMaterial::setAmbient(const KRVector3 &c) { m_ambientColor = c; } @@ -199,8 +207,9 @@ void KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC bool bNormalMap = m_pNormalMap != NULL && pCamera->bEnableNormalMap; bool bSpecMap = m_pSpecularMap != NULL && pCamera->bEnableSpecMap; bool bReflectionMap = m_pReflectionMap != NULL && pCamera->bEnableReflectionMap; + bool bAlphaTest = m_bAlphaTest && bDiffuseMap; - 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, 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, 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 0b4ccb7..7b286fe 100644 --- a/KREngine/KREngine/Classes/KRMaterial.h +++ b/KREngine/KREngine/Classes/KRMaterial.h @@ -74,6 +74,7 @@ public: void setTransparency(GLfloat a); void setShininess(GLfloat s); void setReflectionFactor(GLfloat r); + void setAlphaTest(bool bAlphaTest); bool isTransparent(); @@ -122,6 +123,8 @@ private: GLfloat m_tr; // Transparency GLfloat m_ns; // Shininess GLfloat m_reflectionFactor; // Level of reflectivity + + bool m_bAlphaTest; // When true, alpha in diffuse texture is interpreted as punch-through when < 0.5 }; #endif diff --git a/KREngine/KREngine/Classes/KRMaterialManager.cpp b/KREngine/KREngine/Classes/KRMaterialManager.cpp index e611f92..9500988 100644 --- a/KREngine/KREngine/Classes/KRMaterialManager.cpp +++ b/KREngine/KREngine/Classes/KRMaterialManager.cpp @@ -116,7 +116,11 @@ bool KRMaterialManager::loadFile(const char *szPath) { m_materials[szSymbol[1]] = pMaterial; } if(pMaterial != NULL) { - if(strcmp(szSymbol[0], "Ka") == 0) { + if(strcmp(szSymbol[0], "alpha_test") == 0) { + if(cSymbols == 2) { + pMaterial->setAlphaTest(strcmp(szSymbol[1], "true") == 0); + } + } else if(strcmp(szSymbol[0], "Ka") == 0) { char *pScan2 = szSymbol[1]; double r = strtof(pScan2, &pScan2); if(cSymbols == 2) { diff --git a/KREngine/KREngine/Classes/KRPointLight.cpp b/KREngine/KREngine/Classes/KRPointLight.cpp index 1c79428..7b8e54b 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, renderPass); + KRShader *pShader = pContext->getShaderManager()->getShader("light_point", pCamera, false, false, false, 0, 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 da8f2d1..b079c65 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, 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, KRNode::RenderPass renderPass) { char szKey[256]; - sprintf(szKey, "%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%i_%s", pCamera->bEnablePerPixel, 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_%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()); /* @@ -68,6 +68,7 @@ KRShader *KRShaderManager::getShader(std::string shader_name, KRCamera *pCamera, stream.precision(std::numeric_limits::digits10); stream << "#define HAS_DIFFUSE_MAP " << (bDiffuseMap ? "1" : "0"); + stream << "\n#define ALPHA_TEST " << (bAlphaTest ? "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 cfd0090..8dca7a1 100644 --- a/KREngine/KREngine/Classes/KRShaderManager.h +++ b/KREngine/KREngine/Classes/KRShaderManager.h @@ -54,7 +54,7 @@ public: void loadVertexShader(const std::string &name, const std::string &path); - 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, 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, KRNode::RenderPass renderPass); private: std::map m_shaders; diff --git a/KREngine/KREngine/Shaders/ObjectShader.fsh b/KREngine/KREngine/Shaders/ObjectShader.fsh index a5fcc55..80d0ae5 100644 --- a/KREngine/KREngine/Shaders/ObjectShader.fsh +++ b/KREngine/KREngine/Shaders/ObjectShader.fsh @@ -25,7 +25,6 @@ // or implied, of Kearwood Gilbert. // - #if ENABLE_PER_PIXEL == 1 || GBUFFER_PASS == 1 uniform mediump float material_shininess; #if HAS_NORMAL_MAP == 1 @@ -60,6 +59,15 @@ #else uniform highp mat4 model_normal_to_view_matrix; #endif + + #if HAS_DIFFUSE_MAP == 1 && ALPHA_TEST == 1 + uniform sampler2D diffuseTexture; + #if HAS_DIFFUSE_MAP_OFFSET == 1 || HAS_DIFFUSE_MAP_SCALE == 1 + varying highp vec2 diffuse_uv; + #else + #define diffuse_uv texCoord + #endif + #endif #else uniform lowp vec3 material_ambient, material_diffuse, material_specular; uniform lowp float material_alpha; @@ -120,6 +128,15 @@ uniform mediump vec4 viewport; void main() { + #if ALPHA_TEST == 1 && HAS_DIFFUSE_MAP == 1 + mediump vec4 diffuseMaterial = texture2D(diffuseTexture, diffuse_uv); + if(diffuseMaterial.a < 0.5) discard; + #endif + + #if GBUFFER_PASS == 1 && ALPHA_TEST + if(texture2D(diffuseTexture, diffuse_uv).a < 0.5) discard; + #endif + #if GBUFFER_PASS == 2 || GBUFFER_PASS == 3 mediump vec2 gbuffer_uv = vec2(gl_FragCoord.xy / viewport.zw); #endif @@ -141,7 +158,12 @@ void main() gl_FragColor = vec4(view_space_normal * 0.5 + 0.5, material_shininess / 100.0); #else #if HAS_DIFFUSE_MAP == 1 - mediump vec4 diffuseMaterial = vec4(vec3(texture2D(diffuseTexture, diffuse_uv)), material_alpha); + #if ALPHA_TEST + diffuseMaterial.a = 1.0; + #else + mediump vec4 diffuseMaterial = vec4(vec3(texture2D(diffuseTexture, diffuse_uv)), material_alpha); + #endif + #else mediump vec4 diffuseMaterial = vec4(vec3(1.0), material_alpha); #endif diff --git a/KREngine/KREngine/Shaders/ObjectShader.vsh b/KREngine/KREngine/Shaders/ObjectShader.vsh index 93bb3d4..7f6f6c5 100644 --- a/KREngine/KREngine/Shaders/ObjectShader.vsh +++ b/KREngine/KREngine/Shaders/ObjectShader.vsh @@ -151,6 +151,22 @@ void main() #endif + #if GBUFFER_PASS != 1 || ALPHA_TEST == 1 + // Scaled and translated diffuse map UV's + #if HAS_DIFFUSE_MAP_OFFSET == 1 || HAS_DIFFUSE_MAP_SCALE == 1 + diffuse_uv = texCoord; + + #if HAS_DIFFUSE_MAP_OFFSET == 1 + diffuse_uv + diffuseTexture_Offset; + #endif + + #if HAS_DIFFUSE_MAP_SCALE == 1 + diffuse_uv *= diffuseTexture_Scale; + #endif + #endif + #endif + + #if GBUFFER_PASS == 1 #if HAS_NORMAL_MAP == 1 mediump vec3 a_bitangent = cross(vertex_normal, vertex_tangent); @@ -166,18 +182,7 @@ void main() lightmap_uv = vertex_lightmap_uv.st; #endif - // Scaled and translated diffuse map UV's - #if HAS_DIFFUSE_MAP_OFFSET == 1 || HAS_DIFFUSE_MAP_SCALE == 1 - diffuse_uv = texCoord; - - #if HAS_DIFFUSE_MAP_OFFSET == 1 - diffuse_uv + diffuseTexture_Offset; - #endif - - #if HAS_DIFFUSE_MAP_SCALE == 1 - diffuse_uv *= diffuseTexture_Scale; - #endif - #endif + #if ENABLE_PER_PIXEL == 1 // Scaled and translated specular map UV's