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
This commit is contained in:
kearwood
2012-08-23 16:55:46 +00:00
parent 6d7e7d9abb
commit 1efbb63ecf
16 changed files with 157 additions and 71 deletions

View File

@@ -96,7 +96,7 @@ KRCamera::KRCamera(KRContext &context, GLint width, GLint height) : KRNotified(c
m_postShaderProgram = 0; m_postShaderProgram = 0;
m_iFrame = 0; m_iFrame = 0;
createBuffers(context); createBuffers();
} }
KRCamera::~KRCamera() { KRCamera::~KRCamera() {
@@ -126,7 +126,7 @@ void KRCamera::setPosition(const KRVector3 &position) {
m_position = position; m_position = position;
} }
void KRCamera::renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatrix) void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix)
{ {
KRMat4 invViewMatrix = viewMatrix; KRMat4 invViewMatrix = viewMatrix;
invViewMatrix.invert(); invViewMatrix.invert();
@@ -157,12 +157,12 @@ void KRCamera::renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatri
KRMat4 newShadowMVP; KRMat4 newShadowMVP;
if(shadowMaxDepths[m_cShadowBuffers - 1][iShadow] == 0.0) { 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 { } 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]); 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)) { if(!(shadowmvpmatrix[iShadow] == newShadowMVP)) {
@@ -173,19 +173,19 @@ void KRCamera::renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatri
shadowValid[iShadow] = true; shadowValid[iShadow] = true;
shadowmvpmatrix[iShadow] = newShadowMVP; shadowmvpmatrix[iShadow] = newShadowMVP;
renderShadowBuffer(context, scene, iShadow); renderShadowBuffer(scene, iShadow);
break; break;
} }
} }
renderFrame(context, scene, viewMatrix, lightDirection, cameraPosition); renderFrame(scene, viewMatrix, lightDirection, cameraPosition);
renderPost(context); renderPost();
m_iFrame++; 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)); setViewportSize(KRVector2(backingWidth, backingHeight));
KRBoundingVolume frustrumVolume = KRBoundingVolume(viewMatrix, perspective_fov, getViewportSize().x / getViewportSize().y, perspective_nearz, perspective_farz); 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); glDisable(GL_BLEND);
// Render the geometry // 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 ----====---- // ----====---- Opaque Geometry, Deferred rendering Pass 2 ----====----
// Set render target // Set render target
@@ -237,7 +237,7 @@ void KRCamera::renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatri
// Render the geometry // 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 ----====---- // ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====----
// Set render target // Set render target
@@ -267,7 +267,7 @@ void KRCamera::renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatri
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
// Render the geometry // 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 // Deactivate source buffer texture units
glActiveTexture(GL_TEXTURE6); glActiveTexture(GL_TEXTURE6);
@@ -302,7 +302,7 @@ void KRCamera::renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatri
// Render the geometry // 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 ----====---- // ----====---- 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); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Render all transparent geometry // 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 ----====---- // ----====---- Flares ----====----
@@ -350,7 +350,7 @@ void KRCamera::renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatri
glBlendFunc(GL_ONE, GL_ONE); glBlendFunc(GL_ONE, GL_ONE);
// Render all transparent geometry // 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 // Re-enable z-buffer write
glDepthMask(GL_TRUE); 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 ===== // ===== Create offscreen compositing framebuffer object =====
glGenFramebuffers(1, &compositeFramebuffer); glGenFramebuffers(1, &compositeFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, 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); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, lightAccumulationTexture, 0);
allocateShadowBuffers(); allocateShadowBuffers();
loadShaders(context); loadShaders();
} }
void KRCamera::allocateShadowBuffers() { 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]); glBindFramebuffer(GL_FRAMEBUFFER, shadowFramebuffer[iShadow]);
@@ -539,7 +539,7 @@ void KRCamera::renderShadowBuffer(KRContext &context, KRScene &scene, int iShado
KRVector3 cameraPosition; KRVector3 cameraPosition;
KRVector3 lightDirection; KRVector3 lightDirection;
KRBoundingVolume shadowVolume = KRBoundingVolume(vertices); 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); glViewport(0, 0, backingWidth, backingHeight);
} }
@@ -565,7 +565,7 @@ bool KRCamera::ValidateProgram(GLuint prog)
return true; return true;
} }
void KRCamera::renderPost(KRContext &context) void KRCamera::renderPost()
{ {
glBindFramebuffer(GL_FRAMEBUFFER, 1); // renderFramebuffer glBindFramebuffer(GL_FRAMEBUFFER, 1); // renderFramebuffer
@@ -605,7 +605,7 @@ void KRCamera::renderPost(KRContext &context)
}; };
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
bindPostShader(context); bindPostShader();
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, compositeDepthTexture); glBindTexture(GL_TEXTURE_2D, compositeDepthTexture);
@@ -667,7 +667,7 @@ void KRCamera::renderPost(KRContext &context)
const char *szText = m_debug_text.c_str(); const char *szText = m_debug_text.c_str();
if(*szText) { if(*szText) {
KRTexture *pFontTexture = context.getTextureManager()->getTexture("font"); KRTexture *pFontTexture = m_pContext->getTextureManager()->getTexture("font");
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glUseProgram(m_postShaderProgram); glUseProgram(m_postShaderProgram);
@@ -724,7 +724,7 @@ void KRCamera::renderPost(KRContext &context)
} }
void KRCamera::bindPostShader(KRContext &context) void KRCamera::bindPostShader()
{ {
if(!m_postShaderProgram) { if(!m_postShaderProgram) {
std::stringstream stream; std::stringstream stream;
@@ -743,7 +743,7 @@ void KRCamera::bindPostShader(KRContext &context)
stream << "\n#define VIGNETTE_FALLOFF " << vignette_falloff; stream << "\n#define VIGNETTE_FALLOFF " << vignette_falloff;
stream << "\n"; stream << "\n";
LoadShader(context, "PostShader", &m_postShaderProgram, stream.str()); LoadShader(*m_pContext, "PostShader", &m_postShaderProgram, stream.str());
} }
glUseProgram(m_postShaderProgram); 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"); 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) void KRCamera::notify_sceneGraphCreate(KRNode *pNode)
{ {
fprintf(stderr, "KRCamera - notify_sceneGraphCreate"); fprintf(stderr, "KRCamera - notify_sceneGraphCreate");
KRInstance *pInstance = dynamic_cast<KRInstance *>(pNode);
if(pInstance) {
if(pInstance->hasTransparency()) {
KRInstanceDistance transparentInstanceDistance = KRInstanceDistance(pInstance, 0.0f);
m_transparentInstances.push_back(transparentInstanceDistance);
}
}
} }
void KRCamera::notify_sceneGraphDelete(KRNode *pNode) void KRCamera::notify_sceneGraphDelete(KRNode *pNode)
{ {
fprintf(stderr, "KRCamera - notify_sceneGraphDelete"); fprintf(stderr, "KRCamera - notify_sceneGraphDelete");
KRInstance *pInstance = dynamic_cast<KRInstance *>(pNode);
if(pInstance) {
m_transparentInstances.remove_if(KRInstanceDistance::InstanceEqualsPredicate(pInstance));
}
} }
void KRCamera::notify_sceneGraphModify(KRNode *pNode) void KRCamera::notify_sceneGraphModify(KRNode *pNode)
{ {
fprintf(stderr, "KRCamera - notify_sceneGraphModify"); fprintf(stderr, "KRCamera - notify_sceneGraphModify");
KRInstance *pInstance = dynamic_cast<KRInstance *>(pNode);
if(pInstance) {
m_transparentInstances.remove_if(KRInstanceDistance::InstanceEqualsPredicate(pInstance));
if(pInstance->hasTransparency()) {
KRInstanceDistance transparentInstanceDistance = KRInstanceDistance(pInstance, 0.0f);
m_transparentInstances.push_back(transparentInstanceDistance);
}
}
} }

View File

@@ -54,12 +54,12 @@ public:
GLint backingWidth, backingHeight; GLint backingWidth, backingHeight;
void renderFrame(KRContext &context, KRScene &scene, KRMat4 &viewMatrix); void renderFrame(KRScene &scene, KRMat4 &viewMatrix);
void renderShadowBuffer(KRContext &context, KRScene &scene, int iShadow); void renderShadowBuffer(KRScene &scene, int iShadow);
void invalidatePostShader(); void invalidatePostShader();
void invalidateShadowBuffers(); void invalidateShadowBuffers();
void allocateShadowBuffers(); void allocateShadowBuffers();
void createBuffers(KRContext &context); void createBuffers();
KRVector3 getPosition() const; KRVector3 getPosition() const;
void setPosition(const KRVector3 &position); void setPosition(const KRVector3 &position);
@@ -105,7 +105,6 @@ public:
KRVector2 m_viewportSize; KRVector2 m_viewportSize;
std::vector<KRInstance *> m_transparentInstances;
int m_cShadowBuffers; int m_cShadowBuffers;
std::string m_debug_text; std::string m_debug_text;
@@ -159,14 +158,14 @@ private:
GLuint m_postShaderProgram; GLuint m_postShaderProgram;
GLuint m_shadowShaderProgram; GLuint m_shadowShaderProgram;
void renderPost(KRContext &context); void renderPost();
void bindPostShader(KRContext &context); void bindPostShader();
void destroyBuffers(); 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 // Code using these shader functions will later be refactored to integrate with KRShaderManager
static bool ValidateProgram(GLuint prog); 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 CompileShader(GLuint *shader, GLenum type, const std::string &shader_source, const std::string &options);
static bool LinkProgram(GLuint prog); 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<KRInstanceDistance> m_transparentInstances;
}; };
#endif #endif

View File

@@ -88,6 +88,9 @@ void KRContext::loadResource(std::string path) {
void KRContext::registerNotified(KRNotified *pNotified) void KRContext::registerNotified(KRNotified *pNotified)
{ {
m_notifiedObjects.insert(pNotified); m_notifiedObjects.insert(pNotified);
for(std::set<KRNode *>::iterator itr=m_allNodes.begin(); itr != m_allNodes.end(); itr++) {
pNotified->notify_sceneGraphCreate(*itr);
}
} }
void KRContext::unregisterNotified(KRNotified *pNotified) void KRContext::unregisterNotified(KRNotified *pNotified)
@@ -95,18 +98,25 @@ void KRContext::unregisterNotified(KRNotified *pNotified)
m_notifiedObjects.erase(pNotified); m_notifiedObjects.erase(pNotified);
} }
void KRContext::notify_sceneGraphCreate(KRNode *pNode) void KRContext::notify_sceneGraphCreate(KRNode *pNode)
{ {
m_allNodes.insert(pNode);
for(std::set<KRNotified *>::iterator itr = m_notifiedObjects.begin(); itr != m_notifiedObjects.end(); itr++) { for(std::set<KRNotified *>::iterator itr = m_notifiedObjects.begin(); itr != m_notifiedObjects.end(); itr++) {
(*itr)->notify_sceneGraphCreate(pNode); (*itr)->notify_sceneGraphCreate(pNode);
} }
} }
void KRContext::notify_sceneGraphDelete(KRNode *pNode) void KRContext::notify_sceneGraphDelete(KRNode *pNode)
{ {
for(std::set<KRNotified *>::iterator itr = m_notifiedObjects.begin(); itr != m_notifiedObjects.end(); itr++) {
(*itr)->notify_sceneGraphDelete(pNode);
}
m_allNodes.erase(pNode);
} }
void KRContext::notify_sceneGraphModify(KRNode *pNode) void KRContext::notify_sceneGraphModify(KRNode *pNode)
{ {
for(std::set<KRNotified *>::iterator itr = m_notifiedObjects.begin(); itr != m_notifiedObjects.end(); itr++) {
(*itr)->notify_sceneGraphModify(pNode);
}
} }

View File

@@ -46,6 +46,7 @@ private:
KRModelManager *m_pModelManager; KRModelManager *m_pModelManager;
std::set<KRNotified *> m_notifiedObjects; std::set<KRNotified *> m_notifiedObjects;
std::set<KRNode *> m_allNodes;
}; };
#endif #endif

View File

@@ -15,6 +15,7 @@
#import <vector> #import <vector>
#import <string> #import <string>
#import <set> #import <set>
#import <list>
#ifdef __APPLE__ #ifdef __APPLE__
#include "TargetConditionals.h" #include "TargetConditionals.h"

View File

@@ -58,7 +58,7 @@ double const PI = 3.141592653589793f;
if ((self = [super init])) { if ((self = [super init])) {
_context = new KRContext(); _context = new KRContext();
_camera = new KRCamera(*_context, width, height); _camera = new KRCamera(*_context, width, height);
_parameter_names = @{ _parameter_names = [@{
@"camera_fov" : @0, @"camera_fov" : @0,
@"shadow_quality" : @1, @"shadow_quality" : @1,
@"enable_per_pixel" : @2, @"enable_per_pixel" : @2,
@@ -90,7 +90,7 @@ double const PI = 3.141592653589793f;
@"debug_enable_specular" : @28, @"debug_enable_specular" : @28,
@"debug_super_shiny" : @29, @"debug_super_shiny" : @29,
@"enable_deferred_lighting" : @30 @"enable_deferred_lighting" : @30
}; } copy];
[self loadShaders]; [self loadShaders];
} }
@@ -112,7 +112,7 @@ double const PI = 3.141592653589793f;
- (void)renderScene: (KRScene *)pScene WithViewMatrix: (KRMat4)viewMatrix - (void)renderScene: (KRScene *)pScene WithViewMatrix: (KRMat4)viewMatrix
{ {
viewMatrix.rotate(-90 * 0.0174532925199, Z_AXIS); viewMatrix.rotate(-90 * 0.0174532925199, Z_AXIS);
_camera->renderFrame(*_context, *pScene, viewMatrix); _camera->renderFrame(*pScene, viewMatrix);
} }

View File

@@ -65,6 +65,15 @@ KRMat4 &KRInstance::getModelMatrix() {
#if TARGET_OS_IPHONE #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) { 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); 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) { 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 // Don't render meshes on second pass of the deferred lighting renderer, as only lights will be applied
loadModel();
if(m_pModel == NULL) {
m_pModel = pContext->getModelManager()->getModel(m_model_name.c_str());
}
if(m_pModel != NULL && (getExtents(pContext).test_intersect(frustrumVolume) || renderPass == RENDER_PASS_SHADOWMAP)) { 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) { void KRInstance::calcExtents(KRContext *pContext) {
KRNode::calcExtents(pContext); KRNode::calcExtents(pContext);
if(m_pModel == NULL) { loadModel();
m_pModel = pContext->getModelManager()->getModel(m_model_name.c_str());
}
assert(m_pModel != NULL);
KRMesh *pMesh = m_pModel->getMesh(); 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); KRBoundingVolume mesh_bounds = KRBoundingVolume(KRVector3(pMesh->getMinX(), pMesh->getMinY(), pMesh->getMinZ()), KRVector3(pMesh->getMaxX(), pMesh->getMaxY(), pMesh->getMaxZ()), m_modelMatrix);
if(m_pExtents) { if(m_pExtents) {
@@ -132,4 +134,13 @@ void KRInstance::calcExtents(KRContext *pContext) {
} else { } else {
m_pExtents = new KRBoundingVolume(mesh_bounds); m_pExtents = new KRBoundingVolume(mesh_bounds);
} }
}
bool KRInstance::hasTransparency() {
if(m_pModel) {
return m_pModel->hasTransparency();
} else {
return false;
}
} }

View File

@@ -68,12 +68,16 @@ public:
KRMat4 &getModelMatrix(); KRMat4 &getModelMatrix();
bool hasTransparency();
private: private:
KRModel *m_pModel; KRModel *m_pModel;
KRMat4 m_modelMatrix; KRMat4 m_modelMatrix;
KRTexture *m_pLightMap; KRTexture *m_pLightMap;
std::string m_lightMap; std::string m_lightMap;
std::string m_model_name; std::string m_model_name;
void loadModel();
}; };

View File

@@ -187,8 +187,9 @@ void KRMaterial::setReflectionFactor(GLfloat r) {
} }
bool KRMaterial::isTransparent() { 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 #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) { 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; bool bSameMaterial = *prevBoundMaterial == this;

View File

@@ -56,6 +56,14 @@ void KRModel::loadPack(std::string path) {
m_uniqueMaterials.clear(); m_uniqueMaterials.clear();
m_pMesh = new KRMesh(*m_pContext, KRResource::GetFileBase(path)); m_pMesh = new KRMesh(*m_pContext, KRResource::GetFileBase(path));
m_pMesh->loadPack(path); m_pMesh->loadPack(path);
m_hasTransparency = false;
for(std::set<KRMaterial *>::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() { std::string KRModel::getName() {
@@ -124,3 +132,7 @@ KRMesh *KRModel::getMesh() {
return m_pMesh; return m_pMesh;
} }
bool KRModel::hasTransparency() {
return m_hasTransparency;
}

View File

@@ -55,6 +55,8 @@ public:
KRModel(KRContext &context, std::string name, std::string path); KRModel(KRContext &context, std::string name, std::string path);
virtual ~KRModel(); virtual ~KRModel();
bool hasTransparency();
#if TARGET_OS_IPHONE #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); 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<KRMaterial *> m_uniqueMaterials; set<KRMaterial *> m_uniqueMaterials;
KRMesh *m_pMesh; KRMesh *m_pMesh;
std::string m_name; std::string m_name;
bool m_hasTransparency;
}; };

View File

@@ -27,6 +27,7 @@ KRNode::KRNode(KRContext &context, std::string name) : KRContextObject(context)
} }
KRNode::~KRNode() { KRNode::~KRNode() {
m_pContext->notify_sceneGraphDelete(this);
for(std::vector<KRNode *>::iterator itr=m_childNodes.begin(); itr < m_childNodes.end(); ++itr) { for(std::vector<KRNode *>::iterator itr=m_childNodes.begin(); itr < m_childNodes.end(); ++itr) {
delete *itr; delete *itr;
} }
@@ -39,6 +40,7 @@ void KRNode::addChild(KRNode *child) {
child->m_parentNode = this; child->m_parentNode = this;
m_childNodes.push_back(child); m_childNodes.push_back(child);
clearExtents(); clearExtents();
m_pContext->notify_sceneGraphCreate(child);
} }
tinyxml2::XMLElement *KRNode::saveXML(tinyxml2::XMLNode *parent) { tinyxml2::XMLElement *KRNode::saveXML(tinyxml2::XMLNode *parent) {

View File

@@ -34,7 +34,7 @@
KRNotified::KRNotified(KRContext &context) : KRContextObject(context) KRNotified::KRNotified(KRContext &context) : KRContextObject(context)
{ {
context.registerNotified(this);
} }
KRNotified::~KRNotified() KRNotified::~KRNotified()

View File

@@ -46,9 +46,6 @@ public:
virtual void notify_sceneGraphCreate(KRNode *pNode) = 0; virtual void notify_sceneGraphCreate(KRNode *pNode) = 0;
virtual void notify_sceneGraphDelete(KRNode *pNode) = 0; virtual void notify_sceneGraphDelete(KRNode *pNode) = 0;
virtual void notify_sceneGraphModify(KRNode *pNode) = 0; virtual void notify_sceneGraphModify(KRNode *pNode) = 0;
protected:
KRContext *m_pContext;
}; };
#endif #endif

View File

@@ -36,26 +36,25 @@ uniform mediump vec4 viewport;
void main() 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); 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 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( mediump vec3 view_space_vertex_position = vec3(
((2.0 * gl_FragCoord.xy) - (2.0 * viewport.xy)) / (viewport.zw) - 1.0, ((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) (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; 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 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); 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;
} }

View File

@@ -42,10 +42,10 @@ uniform highp vec3 view_space_light_position;
void main() 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); 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 gbuffer_specular_exponent = gbuffer_sample.a * 100.0;
mediump vec4 clip_space_vertex_position = vec4( 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_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 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 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; 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)); 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;
} }