diff --git a/KREngine/KREngine/Classes/KRCamera.cpp b/KREngine/KREngine/Classes/KRCamera.cpp index 3cf0297..e06d3c7 100644 --- a/KREngine/KREngine/Classes/KRCamera.cpp +++ b/KREngine/KREngine/Classes/KRCamera.cpp @@ -29,6 +29,8 @@ // or implied, of Kearwood Gilbert. // +#define KRENGINE_SWAP_INT(x,y) {int t;t=x;x=y;y=t;} + #import #include #include @@ -188,9 +190,52 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix) m_iFrame++; } + + void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightDirection, KRVector3 &cameraPosition) { setViewportSize(KRVector2(backingWidth, backingHeight)); + + KRMat4 invViewMatrix = viewMatrix; + invViewMatrix.invert(); + + KRVector3 vecCameraDirection = KRMat4::Dot(invViewMatrix, KRVector3(0.0, 0.0, 1.0)) - KRMat4::Dot(invViewMatrix, KRVector3(0.0, 0.0, 0.0)); + + + int frontToBackOrder[8]; + int backToFrontOrder[8]; + for(int i=0; i<8; i++) { + frontToBackOrder[i] = i; + } + + if(vecCameraDirection.x > 0.0) { + KRENGINE_SWAP_INT(frontToBackOrder[0], frontToBackOrder[1]); + KRENGINE_SWAP_INT(frontToBackOrder[2], frontToBackOrder[3]); + KRENGINE_SWAP_INT(frontToBackOrder[4], frontToBackOrder[5]); + KRENGINE_SWAP_INT(frontToBackOrder[6], frontToBackOrder[7]); + } + + if(vecCameraDirection.y > 0.0) { + KRENGINE_SWAP_INT(frontToBackOrder[0], frontToBackOrder[2]); + KRENGINE_SWAP_INT(frontToBackOrder[1], frontToBackOrder[3]); + KRENGINE_SWAP_INT(frontToBackOrder[4], frontToBackOrder[6]); + KRENGINE_SWAP_INT(frontToBackOrder[5], frontToBackOrder[7]); + } + + if(vecCameraDirection.z > 0.0) { + KRENGINE_SWAP_INT(frontToBackOrder[0], frontToBackOrder[4]); + KRENGINE_SWAP_INT(frontToBackOrder[1], frontToBackOrder[5]); + KRENGINE_SWAP_INT(frontToBackOrder[2], frontToBackOrder[6]); + KRENGINE_SWAP_INT(frontToBackOrder[3], frontToBackOrder[7]); + } + + + for(int i=0; i<8; i++) { + backToFrontOrder[i] = frontToBackOrder[7-i]; + } + + fprintf(stderr, "Draw Order: %i%i%i%i%i%i%i%i ", frontToBackOrder[0], frontToBackOrder[1], frontToBackOrder[2], frontToBackOrder[3], frontToBackOrder[4], frontToBackOrder[5], frontToBackOrder[6], frontToBackOrder[7]); + KRBoundingVolume frustrumVolume = KRBoundingVolume(viewMatrix, perspective_fov, getViewportSize().x / getViewportSize().y, perspective_nearz, perspective_farz); std::set newVisibleBounds; @@ -219,7 +264,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD GLDEBUG(glDisable(GL_BLEND)); // Render the geometry - scene.render(this, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_GBUFFER, newVisibleBounds); + scene.render(this, frontToBackOrder, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_GBUFFER, newVisibleBounds); // ----====---- Opaque Geometry, Deferred rendering Pass 2 ----====---- // Set render target @@ -245,7 +290,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD // Render the geometry - scene.render(this, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, 0, KRNode::RENDER_PASS_DEFERRED_LIGHTS, newVisibleBounds); + scene.render(this, frontToBackOrder, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, 0, KRNode::RENDER_PASS_DEFERRED_LIGHTS, newVisibleBounds); // ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====---- // Set render target @@ -277,7 +322,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD // Render the geometry std::set emptyBoundsSet; // At this point, we only render octree nodes that produced fragments during the 1st pass into the GBuffer - scene.render(this, emptyBoundsSet, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_OPAQUE, newVisibleBounds); + scene.render(this, frontToBackOrder, emptyBoundsSet, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_OPAQUE, newVisibleBounds); // Deactivate source buffer texture units m_pContext->getTextureManager()->selectTexture(6, NULL); @@ -314,7 +359,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD // Render the geometry - scene.render(this, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_OPAQUE, newVisibleBounds); + scene.render(this, frontToBackOrder, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_OPAQUE, newVisibleBounds); } // ----====---- Transparent Geometry, Forward Rendering ----====---- @@ -339,7 +384,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD GLDEBUG(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); // Render all transparent geometry - scene.render(this, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, newVisibleBounds); + scene.render(this, backToFrontOrder, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, newVisibleBounds); // ----====---- Flares ----====---- @@ -363,7 +408,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD GLDEBUG(glBlendFunc(GL_ONE, GL_ONE)); // Render all flares - scene.render(this, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FLARES, newVisibleBounds); + scene.render(this, backToFrontOrder, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FLARES, newVisibleBounds); // ----====---- Debug Overlay ----====---- @@ -573,8 +618,15 @@ void KRCamera::renderShadowBuffer(KRScene &scene, int iShadow) KRVector3 lightDirection; KRBoundingVolume shadowVolume = KRBoundingVolume(vertices); + int frontToBackOrder[8]; + int backToFrontOrder[8]; + for(int i=0; i<8; i++) { + frontToBackOrder[i] = i; + } + + std::set newVisibleBounds; - scene.render(this, m_shadowVisibleBounds[iShadow], m_pContext, shadowVolume, shadowmvpmatrix[iShadow], cameraPosition, lightDirection, shadowmvpmatrix, NULL, m_cShadowBuffers, KRNode::RENDER_PASS_SHADOWMAP, newVisibleBounds); + scene.render(this, frontToBackOrder, m_shadowVisibleBounds[iShadow], m_pContext, shadowVolume, shadowmvpmatrix[iShadow], cameraPosition, lightDirection, shadowmvpmatrix, NULL, m_cShadowBuffers, KRNode::RENDER_PASS_SHADOWMAP, newVisibleBounds); m_shadowVisibleBounds[iShadow] = newVisibleBounds; GLDEBUG(glViewport(0, 0, backingWidth, backingHeight)); } diff --git a/KREngine/KREngine/Classes/KRScene.cpp b/KREngine/KREngine/Classes/KRScene.cpp index 50e2ebe..d4c0927 100644 --- a/KREngine/KREngine/Classes/KRScene.cpp +++ b/KREngine/KREngine/Classes/KRScene.cpp @@ -56,7 +56,7 @@ KRScene::~KRScene() { #if TARGET_OS_IPHONE -void KRScene::render(KRCamera *pCamera, std::set &visibleBounds, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::set &newVisibleBounds) { +void KRScene::render(KRCamera *pCamera, int childOrder[], std::set &visibleBounds, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::set &newVisibleBounds) { updateOctree(); @@ -116,10 +116,10 @@ void KRScene::render(KRCamera *pCamera, std::set &visibleBounds, KRConte newRemainingOctrees.clear(); newRemainingOctreesTestResults.clear(); for(std::vector::iterator octree_itr = remainingOctrees.begin(); octree_itr != remainingOctrees.end(); octree_itr++) { - render(*octree_itr, visibleBounds, pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false); + render(childOrder, *octree_itr, visibleBounds, pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false); } for(std::vector::iterator octree_itr = remainingOctreesTestResults.begin(); octree_itr != remainingOctreesTestResults.end(); octree_itr++) { - render(*octree_itr, visibleBounds, pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, false); + render(childOrder, *octree_itr, visibleBounds, pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, false); } remainingOctrees = newRemainingOctrees; remainingOctreesTestResults = newRemainingOctreesTestResults; @@ -128,7 +128,7 @@ void KRScene::render(KRCamera *pCamera, std::set &visibleBounds, KRConte newRemainingOctrees.clear(); newRemainingOctreesTestResults.clear(); for(std::vector::iterator octree_itr = remainingOctreesTestResultsOnly.begin(); octree_itr != remainingOctreesTestResultsOnly.end(); octree_itr++) { - render(*octree_itr, visibleBounds, pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, true); + render(childOrder, *octree_itr, visibleBounds, pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, true); } @@ -137,7 +137,7 @@ void KRScene::render(KRCamera *pCamera, std::set &visibleBounds, KRConte } } -void KRScene::render(KROctreeNode *pOctreeNode, std::set &visibleBounds, KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::vector &remainingOctrees, std::vector &remainingOctreesTestResults, std::vector &remainingOctreesTestResultsOnly, std::set &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly) +void KRScene::render(int childOrder[], KROctreeNode *pOctreeNode, std::set &visibleBounds, KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::vector &remainingOctrees, std::vector &remainingOctreesTestResults, std::vector &remainingOctreesTestResultsOnly, std::set &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly) { if(pOctreeNode) { @@ -285,7 +285,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, std::set &visibleBounds, } for(int i=0; i<8; i++) { - render(pOctreeNode->getChildren()[i], visibleBounds, pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, remainingOctrees, remainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false); + render(childOrder, pOctreeNode->getChildren()[childOrder[i]], visibleBounds, pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, remainingOctrees, remainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false); } } } diff --git a/KREngine/KREngine/Classes/KRScene.h b/KREngine/KREngine/Classes/KRScene.h index 44a0d21..b855e4c 100644 --- a/KREngine/KREngine/Classes/KRScene.h +++ b/KREngine/KREngine/Classes/KRScene.h @@ -64,9 +64,9 @@ public: #if TARGET_OS_IPHONE - void render(KRCamera *pCamera, std::set &visibleBounds, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::set &newVisibleBounds); + void render(KRCamera *pCamera, int childOrder[], std::set &visibleBounds, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::set &newVisibleBounds); - void render(KROctreeNode *pOctreeNode, std::set &visibleBounds, KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::vector &remainingOctrees, std::vector &remainingOctreesTestResults, std::vector &remainingOctreesTestResultsOnly, std::set &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly); + void render(int childOrder[], KROctreeNode *pOctreeNode, std::set &visibleBounds, KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::vector &remainingOctrees, std::vector &remainingOctreesTestResults, std::vector &remainingOctreesTestResultsOnly, std::set &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly); #endif