Now drawing geometry in front-to-back order for opaque surfaces and back-to-front order for transparent surfaces. This solves some sorting issues with transparent blended textures stacking. Additionally, it improves the efficiency of the occlusion culling algorithm.
--HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40107
This commit is contained in:
@@ -29,6 +29,8 @@
|
||||
// or implied, of Kearwood Gilbert.
|
||||
//
|
||||
|
||||
#define KRENGINE_SWAP_INT(x,y) {int t;t=x;x=y;y=t;}
|
||||
|
||||
#import <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -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<KRAABB> 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<KRAABB> 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<KRAABB> 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));
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ KRScene::~KRScene() {
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
void KRScene::render(KRCamera *pCamera, std::set<KRAABB> &visibleBounds, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds) {
|
||||
void KRScene::render(KRCamera *pCamera, int childOrder[], std::set<KRAABB> &visibleBounds, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds) {
|
||||
|
||||
updateOctree();
|
||||
|
||||
@@ -116,10 +116,10 @@ void KRScene::render(KRCamera *pCamera, std::set<KRAABB> &visibleBounds, KRConte
|
||||
newRemainingOctrees.clear();
|
||||
newRemainingOctreesTestResults.clear();
|
||||
for(std::vector<KROctreeNode *>::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<KROctreeNode *>::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<KRAABB> &visibleBounds, KRConte
|
||||
newRemainingOctrees.clear();
|
||||
newRemainingOctreesTestResults.clear();
|
||||
for(std::vector<KROctreeNode *>::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<KRAABB> &visibleBounds, KRConte
|
||||
}
|
||||
}
|
||||
|
||||
void KRScene::render(KROctreeNode *pOctreeNode, std::set<KRAABB> &visibleBounds, KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, std::set<KRAABB> &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly)
|
||||
void KRScene::render(int childOrder[], KROctreeNode *pOctreeNode, std::set<KRAABB> &visibleBounds, KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, std::set<KRAABB> &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly)
|
||||
{
|
||||
if(pOctreeNode) {
|
||||
|
||||
@@ -285,7 +285,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, std::set<KRAABB> &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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,9 +64,9 @@ public:
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
void render(KRCamera *pCamera, std::set<KRAABB> &visibleBounds, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds);
|
||||
void render(KRCamera *pCamera, int childOrder[], std::set<KRAABB> &visibleBounds, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds);
|
||||
|
||||
void render(KROctreeNode *pOctreeNode, std::set<KRAABB> &visibleBounds, KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, std::set<KRAABB> &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly);
|
||||
void render(int childOrder[], KROctreeNode *pOctreeNode, std::set<KRAABB> &visibleBounds, KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, std::set<KRAABB> &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user