From 1efbb63ecf0068fde80ab8331fc8a581e1deb5fb Mon Sep 17 00:00:00 2001 From: kearwood Date: Thu, 23 Aug 2012 16:55:46 +0000 Subject: [PATCH] Performance optimizations in deferred lighting shaders Created structures for alpha transparency and occlusion culling Fixed memory allocation issue in KREngine.mm (pointer to NSDictionary allocated on stack retained and later dereferenced when popped) --HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%4074 --- KREngine/KREngine/Classes/KRCamera.cpp | 74 ++++++++++++------- KREngine/KREngine/Classes/KRCamera.h | 38 ++++++++-- KREngine/KREngine/Classes/KRContext.cpp | 16 +++- KREngine/KREngine/Classes/KRContext.h | 1 + KREngine/KREngine/Classes/KREngine-common.h | 1 + KREngine/KREngine/Classes/KREngine.mm | 6 +- KREngine/KREngine/Classes/KRInstance.cpp | 29 +++++--- KREngine/KREngine/Classes/KRInstance.h | 4 + KREngine/KREngine/Classes/KRMaterial.cpp | 3 +- KREngine/KREngine/Classes/KRModel.cpp | 12 +++ KREngine/KREngine/Classes/KRModel.h | 4 + KREngine/KREngine/Classes/KRNode.cpp | 2 + KREngine/KREngine/Classes/KRNotified.cpp | 2 +- KREngine/KREngine/Classes/KRNotified.h | 3 - .../KREngine/Shaders/light_directional.fsh | 19 +++-- KREngine/KREngine/Shaders/light_point.fsh | 14 ++-- 16 files changed, 157 insertions(+), 71 deletions(-) diff --git a/KREngine/KREngine/Classes/KRCamera.cpp b/KREngine/KREngine/Classes/KRCamera.cpp index 1e64de6..fdf8674 100644 --- a/KREngine/KREngine/Classes/KRCamera.cpp +++ b/KREngine/KREngine/Classes/KRCamera.cpp @@ -96,7 +96,7 @@ KRCamera::KRCamera(KRContext &context, GLint width, GLint height) : KRNotified(c m_postShaderProgram = 0; m_iFrame = 0; - createBuffers(context); + createBuffers(); } KRCamera::~KRCamera() { @@ -126,7 +126,7 @@ void KRCamera::setPosition(const KRVector3 &position) { m_position = position; } -void KRCamera::renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatrix) +void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix) { KRMat4 invViewMatrix = viewMatrix; invViewMatrix.invert(); @@ -157,12 +157,12 @@ void KRCamera::renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatri KRMat4 newShadowMVP; if(shadowMaxDepths[m_cShadowBuffers - 1][iShadow] == 0.0) { - KRBoundingVolume ext = KRBoundingVolume(scene.getExtents(&context)); + KRBoundingVolume ext = KRBoundingVolume(scene.getExtents(m_pContext)); - newShadowMVP = ext.calcShadowProj(&scene, &context, scene.sun_yaw, scene.sun_pitch); + newShadowMVP = ext.calcShadowProj(&scene, m_pContext, scene.sun_yaw, scene.sun_pitch); } else { KRBoundingVolume frustrumSliceVolume = KRBoundingVolume(viewMatrix, perspective_fov, getViewportSize().x / getViewportSize().y, perspective_nearz + (perspective_farz - perspective_nearz) * shadowMinDepths[m_cShadowBuffers - 1][iShadow], perspective_nearz + (perspective_farz - perspective_nearz) * shadowMaxDepths[m_cShadowBuffers - 1][iShadow]); - newShadowMVP = frustrumSliceVolume.calcShadowProj(&scene, &context, scene.sun_yaw, scene.sun_pitch); + newShadowMVP = frustrumSliceVolume.calcShadowProj(&scene, m_pContext, scene.sun_yaw, scene.sun_pitch); } if(!(shadowmvpmatrix[iShadow] == newShadowMVP)) { @@ -173,19 +173,19 @@ void KRCamera::renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatri shadowValid[iShadow] = true; shadowmvpmatrix[iShadow] = newShadowMVP; - renderShadowBuffer(context, scene, iShadow); + renderShadowBuffer(scene, iShadow); break; } } - renderFrame(context, scene, viewMatrix, lightDirection, cameraPosition); - renderPost(context); + renderFrame(scene, viewMatrix, lightDirection, cameraPosition); + renderPost(); m_iFrame++; } -void KRCamera::renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightDirection, KRVector3 &cameraPosition) { +void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightDirection, KRVector3 &cameraPosition) { setViewportSize(KRVector2(backingWidth, backingHeight)); KRBoundingVolume frustrumVolume = KRBoundingVolume(viewMatrix, perspective_fov, getViewportSize().x / getViewportSize().y, perspective_nearz, perspective_farz); @@ -213,7 +213,7 @@ void KRCamera::renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatri glDisable(GL_BLEND); // Render the geometry - scene.render(this, &context, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_GBUFFER); + scene.render(this, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_GBUFFER); // ----====---- Opaque Geometry, Deferred rendering Pass 2 ----====---- // Set render target @@ -237,7 +237,7 @@ void KRCamera::renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatri // Render the geometry - scene.render(this, &context, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, 0, KRNode::RENDER_PASS_DEFERRED_LIGHTS); + scene.render(this, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, 0, KRNode::RENDER_PASS_DEFERRED_LIGHTS); // ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====---- // Set render target @@ -267,7 +267,7 @@ void KRCamera::renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatri glDepthMask(GL_TRUE); // Render the geometry - scene.render(this, &context, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_OPAQUE); + scene.render(this, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_OPAQUE); // Deactivate source buffer texture units glActiveTexture(GL_TEXTURE6); @@ -302,7 +302,7 @@ void KRCamera::renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatri // Render the geometry - scene.render(this, &context, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_OPAQUE); + scene.render(this, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_OPAQUE); } // ----====---- Transparent Geometry, Forward Rendering ----====---- @@ -327,7 +327,7 @@ void KRCamera::renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatri glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Render all transparent geometry - scene.render(this, &context, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); + scene.render(this, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); // ----====---- Flares ----====---- @@ -350,7 +350,7 @@ void KRCamera::renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatri glBlendFunc(GL_ONE, GL_ONE); // Render all transparent geometry - scene.render(this, &context, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FLARES); + scene.render(this, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FLARES); // Re-enable z-buffer write glDepthMask(GL_TRUE); @@ -358,7 +358,7 @@ void KRCamera::renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatri } -void KRCamera::createBuffers(KRContext &context) { +void KRCamera::createBuffers() { // ===== Create offscreen compositing framebuffer object ===== glGenFramebuffers(1, &compositeFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, compositeFramebuffer); @@ -400,7 +400,7 @@ void KRCamera::createBuffers(KRContext &context) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, lightAccumulationTexture, 0); allocateShadowBuffers(); - loadShaders(context); + loadShaders(); } void KRCamera::allocateShadowBuffers() { @@ -473,7 +473,7 @@ void KRCamera::destroyBuffers() } -void KRCamera::renderShadowBuffer(KRContext &context, KRScene &scene, int iShadow) +void KRCamera::renderShadowBuffer(KRScene &scene, int iShadow) { glBindFramebuffer(GL_FRAMEBUFFER, shadowFramebuffer[iShadow]); @@ -539,7 +539,7 @@ void KRCamera::renderShadowBuffer(KRContext &context, KRScene &scene, int iShado KRVector3 cameraPosition; KRVector3 lightDirection; KRBoundingVolume shadowVolume = KRBoundingVolume(vertices); - scene.render(this, &context, shadowVolume, shadowmvpmatrix[iShadow], cameraPosition, lightDirection, shadowmvpmatrix, NULL, m_cShadowBuffers, KRNode::RENDER_PASS_SHADOWMAP); + scene.render(this, m_pContext, shadowVolume, shadowmvpmatrix[iShadow], cameraPosition, lightDirection, shadowmvpmatrix, NULL, m_cShadowBuffers, KRNode::RENDER_PASS_SHADOWMAP); glViewport(0, 0, backingWidth, backingHeight); } @@ -565,7 +565,7 @@ bool KRCamera::ValidateProgram(GLuint prog) return true; } -void KRCamera::renderPost(KRContext &context) +void KRCamera::renderPost() { glBindFramebuffer(GL_FRAMEBUFFER, 1); // renderFramebuffer @@ -605,7 +605,7 @@ void KRCamera::renderPost(KRContext &context) }; glDisable(GL_DEPTH_TEST); - bindPostShader(context); + bindPostShader(); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, compositeDepthTexture); @@ -667,7 +667,7 @@ void KRCamera::renderPost(KRContext &context) const char *szText = m_debug_text.c_str(); if(*szText) { - KRTexture *pFontTexture = context.getTextureManager()->getTexture("font"); + KRTexture *pFontTexture = m_pContext->getTextureManager()->getTexture("font"); glDisable(GL_DEPTH_TEST); glUseProgram(m_postShaderProgram); @@ -724,7 +724,7 @@ void KRCamera::renderPost(KRContext &context) } -void KRCamera::bindPostShader(KRContext &context) +void KRCamera::bindPostShader() { if(!m_postShaderProgram) { std::stringstream stream; @@ -743,7 +743,7 @@ void KRCamera::bindPostShader(KRContext &context) stream << "\n#define VIGNETTE_FALLOFF " << vignette_falloff; stream << "\n"; - LoadShader(context, "PostShader", &m_postShaderProgram, stream.str()); + LoadShader(*m_pContext, "PostShader", &m_postShaderProgram, stream.str()); } glUseProgram(m_postShaderProgram); } @@ -898,9 +898,9 @@ bool KRCamera::LinkProgram(GLuint prog) } -void KRCamera::loadShaders(KRContext &context) +void KRCamera::loadShaders() { - LoadShader(context, "ShadowShader", &m_shadowShaderProgram, ""); + LoadShader(*m_pContext, "ShadowShader", &m_shadowShaderProgram, ""); m_shadowUniforms[KRENGINE_UNIFORM_SHADOWMVP1] = glGetUniformLocation(m_shadowShaderProgram, "shadow_mvp1"); } @@ -909,14 +909,36 @@ void KRCamera::loadShaders(KRContext &context) void KRCamera::notify_sceneGraphCreate(KRNode *pNode) { fprintf(stderr, "KRCamera - notify_sceneGraphCreate"); + + KRInstance *pInstance = dynamic_cast(pNode); + if(pInstance) { + if(pInstance->hasTransparency()) { + KRInstanceDistance transparentInstanceDistance = KRInstanceDistance(pInstance, 0.0f); + m_transparentInstances.push_back(transparentInstanceDistance); + } + } } void KRCamera::notify_sceneGraphDelete(KRNode *pNode) { fprintf(stderr, "KRCamera - notify_sceneGraphDelete"); + + KRInstance *pInstance = dynamic_cast(pNode); + if(pInstance) { + m_transparentInstances.remove_if(KRInstanceDistance::InstanceEqualsPredicate(pInstance)); + } } void KRCamera::notify_sceneGraphModify(KRNode *pNode) { fprintf(stderr, "KRCamera - notify_sceneGraphModify"); + + KRInstance *pInstance = dynamic_cast(pNode); + if(pInstance) { + m_transparentInstances.remove_if(KRInstanceDistance::InstanceEqualsPredicate(pInstance)); + if(pInstance->hasTransparency()) { + KRInstanceDistance transparentInstanceDistance = KRInstanceDistance(pInstance, 0.0f); + m_transparentInstances.push_back(transparentInstanceDistance); + } + } } \ No newline at end of file diff --git a/KREngine/KREngine/Classes/KRCamera.h b/KREngine/KREngine/Classes/KRCamera.h index f5698fd..38636bd 100644 --- a/KREngine/KREngine/Classes/KRCamera.h +++ b/KREngine/KREngine/Classes/KRCamera.h @@ -54,12 +54,12 @@ public: GLint backingWidth, backingHeight; - void renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatrix); - void renderShadowBuffer(KRContext &context, KRScene &scene, int iShadow); + void renderFrame(KRScene &scene, KRMat4 &viewMatrix); + void renderShadowBuffer(KRScene &scene, int iShadow); void invalidatePostShader(); void invalidateShadowBuffers(); void allocateShadowBuffers(); - void createBuffers(KRContext &context); + void createBuffers(); KRVector3 getPosition() const; void setPosition(const KRVector3 &position); @@ -105,7 +105,6 @@ public: KRVector2 m_viewportSize; - std::vector m_transparentInstances; int m_cShadowBuffers; std::string m_debug_text; @@ -159,14 +158,14 @@ private: GLuint m_postShaderProgram; GLuint m_shadowShaderProgram; - void renderPost(KRContext &context); - void bindPostShader(KRContext &context); + void renderPost(); + void bindPostShader(); void destroyBuffers(); - void renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightDirection, KRVector3 &cameraPosition); + void renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightDirection, KRVector3 &cameraPosition); - void loadShaders(KRContext &context); + void loadShaders(); // Code using these shader functions will later be refactored to integrate with KRShaderManager static bool ValidateProgram(GLuint prog); @@ -174,6 +173,29 @@ private: static bool CompileShader(GLuint *shader, GLenum type, const std::string &shader_source, const std::string &options); static bool LinkProgram(GLuint prog); + + class KRInstanceDistance { + public: + KRInstanceDistance(KRInstance *pInstance, float distance) : m_pInstance(pInstance), m_distance(distance) {}; + ~KRInstanceDistance() {}; + + // a predicate implemented as a class: + class InstanceEqualsPredicate + { + public: + InstanceEqualsPredicate(KRInstance *pInstance) : m_pInstance(pInstance) {}; + bool operator() (const KRInstanceDistance& value) {return value.m_pInstance == m_pInstance; } + + private: + KRInstance *m_pInstance; + }; + + KRInstance *m_pInstance; + float m_distance; + }; + + std::list m_transparentInstances; + }; #endif diff --git a/KREngine/KREngine/Classes/KRContext.cpp b/KREngine/KREngine/Classes/KRContext.cpp index 503533b..0cb3876 100644 --- a/KREngine/KREngine/Classes/KRContext.cpp +++ b/KREngine/KREngine/Classes/KRContext.cpp @@ -88,6 +88,9 @@ void KRContext::loadResource(std::string path) { void KRContext::registerNotified(KRNotified *pNotified) { m_notifiedObjects.insert(pNotified); + for(std::set::iterator itr=m_allNodes.begin(); itr != m_allNodes.end(); itr++) { + pNotified->notify_sceneGraphCreate(*itr); + } } void KRContext::unregisterNotified(KRNotified *pNotified) @@ -95,18 +98,25 @@ void KRContext::unregisterNotified(KRNotified *pNotified) m_notifiedObjects.erase(pNotified); } - void KRContext::notify_sceneGraphCreate(KRNode *pNode) { + m_allNodes.insert(pNode); for(std::set::iterator itr = m_notifiedObjects.begin(); itr != m_notifiedObjects.end(); itr++) { (*itr)->notify_sceneGraphCreate(pNode); } } + void KRContext::notify_sceneGraphDelete(KRNode *pNode) { - + for(std::set::iterator itr = m_notifiedObjects.begin(); itr != m_notifiedObjects.end(); itr++) { + (*itr)->notify_sceneGraphDelete(pNode); + } + m_allNodes.erase(pNode); } + void KRContext::notify_sceneGraphModify(KRNode *pNode) { - + for(std::set::iterator itr = m_notifiedObjects.begin(); itr != m_notifiedObjects.end(); itr++) { + (*itr)->notify_sceneGraphModify(pNode); + } } \ No newline at end of file diff --git a/KREngine/KREngine/Classes/KRContext.h b/KREngine/KREngine/Classes/KRContext.h index 6ba01ce..4b29af0 100644 --- a/KREngine/KREngine/Classes/KRContext.h +++ b/KREngine/KREngine/Classes/KRContext.h @@ -46,6 +46,7 @@ private: KRModelManager *m_pModelManager; std::set m_notifiedObjects; + std::set m_allNodes; }; #endif diff --git a/KREngine/KREngine/Classes/KREngine-common.h b/KREngine/KREngine/Classes/KREngine-common.h index c8ec589..1056550 100644 --- a/KREngine/KREngine/Classes/KREngine-common.h +++ b/KREngine/KREngine/Classes/KREngine-common.h @@ -15,6 +15,7 @@ #import #import #import +#import #ifdef __APPLE__ #include "TargetConditionals.h" diff --git a/KREngine/KREngine/Classes/KREngine.mm b/KREngine/KREngine/Classes/KREngine.mm index 3f0a62d..a2b6e05 100644 --- a/KREngine/KREngine/Classes/KREngine.mm +++ b/KREngine/KREngine/Classes/KREngine.mm @@ -58,7 +58,7 @@ double const PI = 3.141592653589793f; if ((self = [super init])) { _context = new KRContext(); _camera = new KRCamera(*_context, width, height); - _parameter_names = @{ + _parameter_names = [@{ @"camera_fov" : @0, @"shadow_quality" : @1, @"enable_per_pixel" : @2, @@ -90,7 +90,7 @@ double const PI = 3.141592653589793f; @"debug_enable_specular" : @28, @"debug_super_shiny" : @29, @"enable_deferred_lighting" : @30 - }; + } copy]; [self loadShaders]; } @@ -112,7 +112,7 @@ double const PI = 3.141592653589793f; - (void)renderScene: (KRScene *)pScene WithViewMatrix: (KRMat4)viewMatrix { viewMatrix.rotate(-90 * 0.0174532925199, Z_AXIS); - _camera->renderFrame(*_context, *pScene, viewMatrix); + _camera->renderFrame(*pScene, viewMatrix); } diff --git a/KREngine/KREngine/Classes/KRInstance.cpp b/KREngine/KREngine/Classes/KRInstance.cpp index b051624..a70ec56 100644 --- a/KREngine/KREngine/Classes/KRInstance.cpp +++ b/KREngine/KREngine/Classes/KRInstance.cpp @@ -65,6 +65,15 @@ KRMat4 &KRInstance::getModelMatrix() { #if TARGET_OS_IPHONE +void KRInstance::loadModel() { + if(m_pModel == NULL) { + m_pModel = m_pContext->getModelManager()->getModel(m_model_name.c_str()); + if(m_pModel->hasTransparency()) { + m_pContext->notify_sceneGraphModify(this); + } + } +} + void KRInstance::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) { KRNode::render(pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass); @@ -72,10 +81,7 @@ void KRInstance::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT && renderPass != KRNode::RENDER_PASS_FLARES) { // Don't render meshes on second pass of the deferred lighting renderer, as only lights will be applied - - if(m_pModel == NULL) { - m_pModel = pContext->getModelManager()->getModel(m_model_name.c_str()); - } + loadModel(); if(m_pModel != NULL && (getExtents(pContext).test_intersect(frustrumVolume) || renderPass == RENDER_PASS_SHADOWMAP)) { @@ -120,11 +126,7 @@ void KRInstance::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume void KRInstance::calcExtents(KRContext *pContext) { KRNode::calcExtents(pContext); - if(m_pModel == NULL) { - m_pModel = pContext->getModelManager()->getModel(m_model_name.c_str()); - } - assert(m_pModel != NULL); - + loadModel(); KRMesh *pMesh = m_pModel->getMesh(); KRBoundingVolume mesh_bounds = KRBoundingVolume(KRVector3(pMesh->getMinX(), pMesh->getMinY(), pMesh->getMinZ()), KRVector3(pMesh->getMaxX(), pMesh->getMaxY(), pMesh->getMaxZ()), m_modelMatrix); if(m_pExtents) { @@ -132,4 +134,13 @@ void KRInstance::calcExtents(KRContext *pContext) { } else { m_pExtents = new KRBoundingVolume(mesh_bounds); } +} + +bool KRInstance::hasTransparency() { + if(m_pModel) { + return m_pModel->hasTransparency(); + } else { + return false; + } + } \ No newline at end of file diff --git a/KREngine/KREngine/Classes/KRInstance.h b/KREngine/KREngine/Classes/KRInstance.h index f94e713..a3844db 100644 --- a/KREngine/KREngine/Classes/KRInstance.h +++ b/KREngine/KREngine/Classes/KRInstance.h @@ -68,12 +68,16 @@ public: KRMat4 &getModelMatrix(); + bool hasTransparency(); + private: KRModel *m_pModel; KRMat4 m_modelMatrix; KRTexture *m_pLightMap; std::string m_lightMap; std::string m_model_name; + + void loadModel(); }; diff --git a/KREngine/KREngine/Classes/KRMaterial.cpp b/KREngine/KREngine/Classes/KRMaterial.cpp index 24dbdb1..2f1da70 100644 --- a/KREngine/KREngine/Classes/KRMaterial.cpp +++ b/KREngine/KREngine/Classes/KRMaterial.cpp @@ -187,8 +187,9 @@ void KRMaterial::setReflectionFactor(GLfloat r) { } bool KRMaterial::isTransparent() { - return m_tr != 0.0; + return m_tr != 0.0 || m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE || m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE; } + #if TARGET_OS_IPHONE void KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRCamera *pCamera, KRMat4 &matModelToView, KRMat4 &mvpMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRContext *pContext, KRTexture *pLightMap, KRNode::RenderPass renderPass) { bool bSameMaterial = *prevBoundMaterial == this; diff --git a/KREngine/KREngine/Classes/KRModel.cpp b/KREngine/KREngine/Classes/KRModel.cpp index 6728045..292ee53 100644 --- a/KREngine/KREngine/Classes/KRModel.cpp +++ b/KREngine/KREngine/Classes/KRModel.cpp @@ -56,6 +56,14 @@ void KRModel::loadPack(std::string path) { 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() { @@ -124,3 +132,7 @@ KRMesh *KRModel::getMesh() { return m_pMesh; } +bool KRModel::hasTransparency() { + return m_hasTransparency; +} + diff --git a/KREngine/KREngine/Classes/KRModel.h b/KREngine/KREngine/Classes/KRModel.h index f339280..05fa46b 100644 --- a/KREngine/KREngine/Classes/KRModel.h +++ b/KREngine/KREngine/Classes/KRModel.h @@ -55,6 +55,8 @@ public: KRModel(KRContext &context, std::string name, std::string path); virtual ~KRModel(); + bool hasTransparency(); + #if TARGET_OS_IPHONE void render(KRCamera *pCamera, KRContext *pContext, KRMat4 &matModelToView, KRMat4 &mvpMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRTexture *pLightMap, KRNode::RenderPass renderPass); @@ -71,6 +73,8 @@ private: set m_uniqueMaterials; KRMesh *m_pMesh; std::string m_name; + + bool m_hasTransparency; }; diff --git a/KREngine/KREngine/Classes/KRNode.cpp b/KREngine/KREngine/Classes/KRNode.cpp index 1d92ae7..38c9bb2 100644 --- a/KREngine/KREngine/Classes/KRNode.cpp +++ b/KREngine/KREngine/Classes/KRNode.cpp @@ -27,6 +27,7 @@ KRNode::KRNode(KRContext &context, std::string name) : KRContextObject(context) } KRNode::~KRNode() { + m_pContext->notify_sceneGraphDelete(this); for(std::vector::iterator itr=m_childNodes.begin(); itr < m_childNodes.end(); ++itr) { delete *itr; } @@ -39,6 +40,7 @@ void KRNode::addChild(KRNode *child) { child->m_parentNode = this; m_childNodes.push_back(child); clearExtents(); + m_pContext->notify_sceneGraphCreate(child); } tinyxml2::XMLElement *KRNode::saveXML(tinyxml2::XMLNode *parent) { diff --git a/KREngine/KREngine/Classes/KRNotified.cpp b/KREngine/KREngine/Classes/KRNotified.cpp index 69291c9..9302ed8 100644 --- a/KREngine/KREngine/Classes/KRNotified.cpp +++ b/KREngine/KREngine/Classes/KRNotified.cpp @@ -34,7 +34,7 @@ KRNotified::KRNotified(KRContext &context) : KRContextObject(context) { - context.registerNotified(this); + } KRNotified::~KRNotified() diff --git a/KREngine/KREngine/Classes/KRNotified.h b/KREngine/KREngine/Classes/KRNotified.h index 997f567..0491020 100644 --- a/KREngine/KREngine/Classes/KRNotified.h +++ b/KREngine/KREngine/Classes/KRNotified.h @@ -46,9 +46,6 @@ public: virtual void notify_sceneGraphCreate(KRNode *pNode) = 0; virtual void notify_sceneGraphDelete(KRNode *pNode) = 0; virtual void notify_sceneGraphModify(KRNode *pNode) = 0; - -protected: - KRContext *m_pContext; }; #endif diff --git a/KREngine/KREngine/Shaders/light_directional.fsh b/KREngine/KREngine/Shaders/light_directional.fsh index 3f27e56..bb28b56 100644 --- a/KREngine/KREngine/Shaders/light_directional.fsh +++ b/KREngine/KREngine/Shaders/light_directional.fsh @@ -36,26 +36,25 @@ uniform mediump vec4 viewport; void main() { - mediump vec2 gbuffer_uv = vec2(gl_FragCoord.xy / viewport.zw); + lowp vec2 gbuffer_uv = vec2(gl_FragCoord.xy / viewport.zw); lowp vec4 gbuffer_sample = texture2D(gbuffer_frame, gbuffer_uv); - mediump vec3 gbuffer_normal = 2.0 * gbuffer_sample.rgb - 1.0; + mediump vec3 gbuffer_normal = normalize(2.0 * gbuffer_sample.rgb - 1.0); mediump float gbuffer_specular_exponent = gbuffer_sample.a * 100.0; - mediump float lamberFactor = max(0.0,dot(light_direction_view_space, gbuffer_normal)); - - mediump vec3 view_space_vertex_position = vec3( ((2.0 * gl_FragCoord.xy) - (2.0 * viewport.xy)) / (viewport.zw) - 1.0, (2.0 * -texture2D(gbuffer_depth, gbuffer_uv).r - gl_DepthRange.near - gl_DepthRange.far) / (gl_DepthRange.far - gl_DepthRange.near) ); + //mediump float lamberFactor = max(0.0,dot(light_direction_view_space, gbuffer_normal)) * 0.2; + mediump float lamberFactor = dot(light_direction_view_space, gbuffer_normal) * 0.2; mediump float specularFactor = 0.0; - if(gbuffer_specular_exponent > 0.0) { - mediump vec3 halfVec = normalize((normalize(- view_space_vertex_position) + light_direction_view_space)); // Normalizing anyways, no need to divide by 2 - specularFactor = clamp(pow(dot(halfVec,normalize(gbuffer_normal)), gbuffer_specular_exponent), 0.0, 1.0); - } + + mediump vec3 halfVec = normalize((normalize(- view_space_vertex_position) + light_direction_view_space)); // Normalizing anyways, no need to divide by 2 + specularFactor = pow(dot(halfVec,gbuffer_normal), gbuffer_specular_exponent); + - gl_FragColor = vec4(light_color * lamberFactor * 0.2, specularFactor) * light_intensity; + gl_FragColor = vec4(light_color * lamberFactor, specularFactor) * light_intensity; } diff --git a/KREngine/KREngine/Shaders/light_point.fsh b/KREngine/KREngine/Shaders/light_point.fsh index 33b1974..844e3ed 100644 --- a/KREngine/KREngine/Shaders/light_point.fsh +++ b/KREngine/KREngine/Shaders/light_point.fsh @@ -42,10 +42,10 @@ uniform highp vec3 view_space_light_position; void main() { - mediump vec2 gbuffer_uv = vec2(gl_FragCoord.xy / viewport.zw); + lowp vec2 gbuffer_uv = vec2(gl_FragCoord.xy / viewport.zw); lowp vec4 gbuffer_sample = texture2D(gbuffer_frame, gbuffer_uv); - mediump vec3 gbuffer_normal = 2.0 * gbuffer_sample.rgb - 1.0; + mediump vec3 gbuffer_normal = normalize(2.0 * gbuffer_sample.rgb - 1.0); mediump float gbuffer_specular_exponent = gbuffer_sample.a * 100.0; mediump vec4 clip_space_vertex_position = vec4( @@ -61,13 +61,13 @@ void main() mediump float light_distance = max(0.0, distance(view_space_light_position.xyz, view_space_vertex_position.xyz) - light_decay_start); mediump float light_attenuation = (light_intensity / ((light_distance + 1.0) * (light_distance + 1.0)) - light_cutoff) / (1.0 - light_cutoff); mediump vec3 light_vec = normalize(view_space_light_position.xyz - view_space_vertex_position.xyz); - mediump float lamberFactor = clamp(dot(light_vec, gbuffer_normal), 0.0, 1.0); + mediump float lamberFactor = dot(light_vec, gbuffer_normal) * 0.2; mediump float specularFactor = 0.0; - if(gbuffer_specular_exponent > 0.0) { + //if(gbuffer_specular_exponent > 0.0) { mediump vec3 halfVec = normalize((normalize(- view_space_vertex_position.xyz) + light_vec)); - specularFactor = clamp(pow(dot(halfVec,normalize(gbuffer_normal)), gbuffer_specular_exponent), 0.0, 1.0); - } + specularFactor = pow(dot(halfVec,gbuffer_normal), gbuffer_specular_exponent); + //} - gl_FragColor = vec4(light_color * lamberFactor * 0.2, specularFactor) * light_attenuation; + gl_FragColor = vec4(light_color * lamberFactor, specularFactor) * light_attenuation; }