Performance optimizations, reducing repeated matrix calculations

--HG--
extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40143
This commit is contained in:
kearwood
2012-10-26 19:31:27 +00:00
parent 2c429b8579
commit 0e174d99ba
8 changed files with 127 additions and 114 deletions

View File

@@ -138,37 +138,6 @@ bool KRAABB::visible(const KRMat4 &matViewProjection) const
} }
} }
// for(int iCorner=0; iCorner<8; iCorner++) {
// KRVector3 sourceCornerVertex = KRVector3(
// (iCorner & 1) == 0 ? min.x : max.x,
// (iCorner & 2) == 0 ? min.y : max.y,
// (iCorner & 4) == 0 ? min.z : max.z);
//
// KRVector3 cornerVertex = KRMat4::Dot(matViewProjection, sourceCornerVertex);
// float cornerVertexW = KRMat4::DotW(matViewProjection, sourceCornerVertex);
// cornerVertex /= cornerVertexW;
//
//
// if(cornerVertex.x < -1.0) {
// outside_count[0]++;
// }
// if(cornerVertex.y < -1.0) {
// outside_count[1]++;
// }
// if(cornerVertex.z < -1.0) {
// outside_count[2]++;
// }
// if(cornerVertex.x > 1.0) {
// outside_count[3]++;
// }
// if(cornerVertex.y > 1.0) {
// outside_count[4]++;
// }
// if(cornerVertex.z > 1.0) {
// outside_count[5]++;
// }
// }
bool is_visible = true; bool is_visible = true;
for(int iFace=0; iFace < 6; iFace++) { for(int iFace=0; iFace < 6; iFace++) {
if(outside_count[iFace] == 8) { if(outside_count[iFace] == 8) {

View File

@@ -29,8 +29,6 @@
// or implied, of Kearwood Gilbert. // or implied, of Kearwood Gilbert.
// //
#define KRENGINE_SWAP_INT(x,y) {int t;t=x;x=y;y=t;}
#import <string> #import <string>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
@@ -206,46 +204,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix)
void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection) { void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection) {
KRVector3 vecCameraDirection = m_viewport.getCameraDirection();
KRMat4 invViewMatrix = m_viewport.getViewMatrix();
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]);
std::set<KRAABB> newVisibleBounds; std::set<KRAABB> newVisibleBounds;
@@ -273,7 +232,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection) {
GLDEBUG(glDisable(GL_BLEND)); GLDEBUG(glDisable(GL_BLEND));
// Render the geometry // Render the geometry
scene.render(this, frontToBackOrder, m_visibleBounds, m_pContext, m_viewport, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_GBUFFER, newVisibleBounds); scene.render(this, m_visibleBounds, m_pContext, m_viewport, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_GBUFFER, newVisibleBounds);
// ----====---- Opaque Geometry, Deferred rendering Pass 2 ----====---- // ----====---- Opaque Geometry, Deferred rendering Pass 2 ----====----
// Set render target // Set render target
@@ -299,7 +258,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection) {
// Render the geometry // Render the geometry
scene.render(this, frontToBackOrder, m_visibleBounds, m_pContext, m_viewport, lightDirection, shadowmvpmatrix, shadowDepthTexture, 0, KRNode::RENDER_PASS_DEFERRED_LIGHTS, newVisibleBounds); scene.render(this, m_visibleBounds, m_pContext, m_viewport, lightDirection, shadowmvpmatrix, shadowDepthTexture, 0, KRNode::RENDER_PASS_DEFERRED_LIGHTS, newVisibleBounds);
// ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====---- // ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====----
// Set render target // Set render target
@@ -331,7 +290,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection) {
// Render the geometry // 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 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, frontToBackOrder, emptyBoundsSet, m_pContext, m_viewport, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_OPAQUE, newVisibleBounds); scene.render(this, emptyBoundsSet, m_pContext, m_viewport, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_OPAQUE, newVisibleBounds);
// Deactivate source buffer texture units // Deactivate source buffer texture units
m_pContext->getTextureManager()->selectTexture(6, NULL, 0); m_pContext->getTextureManager()->selectTexture(6, NULL, 0);
@@ -369,7 +328,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection) {
// Render the geometry // Render the geometry
scene.render(this, frontToBackOrder, m_visibleBounds, m_pContext, m_viewport, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_OPAQUE, newVisibleBounds); scene.render(this, m_visibleBounds, m_pContext, m_viewport, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_OPAQUE, newVisibleBounds);
} }
// ----====---- Sky Box ----====---- // ----====---- Sky Box ----====----
@@ -429,7 +388,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection) {
GLDEBUG(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); GLDEBUG(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
// Render all transparent geometry // Render all transparent geometry
scene.render(this, backToFrontOrder, m_visibleBounds, m_pContext, m_viewport, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, newVisibleBounds); scene.render(this, m_visibleBounds, m_pContext, m_viewport, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, newVisibleBounds);
// ----====---- Flares ----====---- // ----====---- Flares ----====----
@@ -453,7 +412,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection) {
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE)); GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
// Render all flares // Render all flares
scene.render(this, backToFrontOrder, m_visibleBounds, m_pContext, m_viewport, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FLARES, newVisibleBounds); scene.render(this, m_visibleBounds, m_pContext, m_viewport, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FLARES, newVisibleBounds);
// ----====---- Debug Overlay ----====---- // ----====---- Debug Overlay ----====----
@@ -670,16 +629,9 @@ void KRCamera::renderShadowBuffer(KRScene &scene, int iShadow)
KRVector3 lightDirection; KRVector3 lightDirection;
KRBoundingVolume shadowVolume = KRBoundingVolume(vertices); KRBoundingVolume shadowVolume = KRBoundingVolume(vertices);
int frontToBackOrder[8];
int backToFrontOrder[8];
for(int i=0; i<8; i++) {
frontToBackOrder[i] = i;
}
std::set<KRAABB> newVisibleBounds; std::set<KRAABB> newVisibleBounds;
viewport = KRViewport(m_viewport.getSize(), KRMat4(), shadowmvpmatrix[iShadow]); viewport = KRViewport(m_viewport.getSize(), KRMat4(), shadowmvpmatrix[iShadow]);
scene.render(this, frontToBackOrder, m_shadowVisibleBounds[iShadow], m_pContext, viewport, lightDirection, shadowmvpmatrix, NULL, m_cShadowBuffers, KRNode::RENDER_PASS_SHADOWMAP, newVisibleBounds); scene.render(this, m_shadowVisibleBounds[iShadow], m_pContext, viewport, lightDirection, shadowmvpmatrix, NULL, m_cShadowBuffers, KRNode::RENDER_PASS_SHADOWMAP, newVisibleBounds);
m_shadowVisibleBounds[iShadow] = newVisibleBounds; m_shadowVisibleBounds[iShadow] = newVisibleBounds;
GLDEBUG(glViewport(0, 0, backingWidth, backingHeight)); GLDEBUG(glViewport(0, 0, backingWidth, backingHeight));

View File

@@ -95,7 +95,7 @@ void KRInstance::render(KRCamera *pCamera, KRContext *pContext, const KRViewport
if(renderPass != KRNode::RENDER_PASS_SHADOWMAP) { if(renderPass != KRNode::RENDER_PASS_SHADOWMAP) {
projectionMatrix = pCamera->getProjectionMatrix(); projectionMatrix = pCamera->getProjectionMatrix();
} }
KRMat4 matMVP = m_modelMatrix * viewport.getViewMatrix() * viewport.getProjectionMatrix(); KRMat4 matMVP = m_modelMatrix * viewport.getViewProjectionMatrix();
float lod_coverage = getBounds().coverage(matMVP, pCamera->getViewportSize()); // This also checks the view frustrum culling float lod_coverage = getBounds().coverage(matMVP, pCamera->getViewportSize()); // This also checks the view frustrum culling
if(lod_coverage > m_min_lod_coverage) { if(lod_coverage > m_min_lod_coverage) {

View File

@@ -57,7 +57,7 @@ KRScene::~KRScene() {
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
void KRScene::render(KRCamera *pCamera, int childOrder[], std::set<KRAABB> &visibleBounds, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds) { void KRScene::render(KRCamera *pCamera, std::set<KRAABB> &visibleBounds, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds) {
updateOctree(); updateOctree();
pCamera->setSkyBox(m_skyBoxName); // This is temporary until the camera is moved into the scene graph pCamera->setSkyBox(m_skyBoxName); // This is temporary until the camera is moved into the scene graph
@@ -118,10 +118,10 @@ void KRScene::render(KRCamera *pCamera, int childOrder[], std::set<KRAABB> &visi
newRemainingOctrees.clear(); newRemainingOctrees.clear();
newRemainingOctreesTestResults.clear(); newRemainingOctreesTestResults.clear();
for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctrees.begin(); octree_itr != remainingOctrees.end(); octree_itr++) { for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctrees.begin(); octree_itr != remainingOctrees.end(); octree_itr++) {
render(childOrder, *octree_itr, visibleBounds, pCamera, pContext, viewport, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false); render(*octree_itr, visibleBounds, pCamera, pContext, viewport, 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++) { for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctreesTestResults.begin(); octree_itr != remainingOctreesTestResults.end(); octree_itr++) {
render(childOrder, *octree_itr, visibleBounds, pCamera, pContext, viewport, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, false); render(*octree_itr, visibleBounds, pCamera, pContext, viewport, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, false);
} }
remainingOctrees = newRemainingOctrees; remainingOctrees = newRemainingOctrees;
remainingOctreesTestResults = newRemainingOctreesTestResults; remainingOctreesTestResults = newRemainingOctreesTestResults;
@@ -130,7 +130,7 @@ void KRScene::render(KRCamera *pCamera, int childOrder[], std::set<KRAABB> &visi
newRemainingOctrees.clear(); newRemainingOctrees.clear();
newRemainingOctreesTestResults.clear(); newRemainingOctreesTestResults.clear();
for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctreesTestResultsOnly.begin(); octree_itr != remainingOctreesTestResultsOnly.end(); octree_itr++) { for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctreesTestResultsOnly.begin(); octree_itr != remainingOctreesTestResultsOnly.end(); octree_itr++) {
render(childOrder, *octree_itr, visibleBounds, pCamera, pContext, viewport, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, true); render(*octree_itr, visibleBounds, pCamera, pContext, viewport, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, true);
} }
std::set<KRNode *> outerNodes = std::set<KRNode *>(m_nodeTree.getOuterSceneNodes()); // HACK - Copying the std::set as it is potentially modified as KRNode's update their bounds during the iteration. This is very expensive and will be eliminated in the future. std::set<KRNode *> outerNodes = std::set<KRNode *>(m_nodeTree.getOuterSceneNodes()); // HACK - Copying the std::set as it is potentially modified as KRNode's update their bounds during the iteration. This is very expensive and will be eliminated in the future.
@@ -139,7 +139,7 @@ void KRScene::render(KRCamera *pCamera, int childOrder[], std::set<KRAABB> &visi
} }
} }
void KRScene::render(int childOrder[], KROctreeNode *pOctreeNode, std::set<KRAABB> &visibleBounds, KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, 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(KROctreeNode *pOctreeNode, std::set<KRAABB> &visibleBounds, KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, 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) { if(pOctreeNode) {
@@ -170,11 +170,10 @@ void KRScene::render(int childOrder[], KROctreeNode *pOctreeNode, std::set<KRAAB
if(renderPass != KRNode::RENDER_PASS_SHADOWMAP) { if(renderPass != KRNode::RENDER_PASS_SHADOWMAP) {
projectionMatrix = pCamera->getProjectionMatrix(); projectionMatrix = pCamera->getProjectionMatrix();
} }
KRMat4 matVP = viewport.getViewMatrix() * viewport.getProjectionMatrix();
float min_coverage = 0.0f; // 1.0f / 1024.0f / 768.0f; // FINDME - HACK - Need to dynamically select the absolute minimum based on the render buffer size float min_coverage = 0.0f; // 1.0f / 1024.0f / 768.0f; // FINDME - HACK - Need to dynamically select the absolute minimum based on the render buffer size
float lod_coverage = pOctreeNode->getBounds().coverage(matVP, pCamera->getViewportSize()); // This also checks the view frustrum culling float lod_coverage = pOctreeNode->getBounds().coverage(viewport.getViewProjectionMatrix(), pCamera->getViewportSize()); // This also checks the view frustrum culling
if(lod_coverage > min_coverage) { if(lod_coverage > min_coverage) {
// ----====---- Rendering and occlusion test pass ----====---- // ----====---- Rendering and occlusion test pass ----====----
@@ -184,10 +183,7 @@ void KRScene::render(int childOrder[], KROctreeNode *pOctreeNode, std::set<KRAAB
if(!bVisible) { if(!bVisible) {
// Assume bounding boxes are visible without occlusion test queries if the camera is inside the box. // Assume bounding boxes are visible without occlusion test queries if the camera is inside the box.
// The near clipping plane of the camera is taken into consideration by expanding the match area // The near clipping plane of the camera is taken into consideration by expanding the match area
KRMat4 invView = viewport.getViewMatrix(); KRAABB cameraExtents = KRAABB(viewport.getCameraPosition() - KRVector3(pCamera->getPerspectiveNearZ()), viewport.getCameraPosition() + KRVector3(pCamera->getPerspectiveNearZ()));
invView.invert();
KRVector3 cameraPos = KRMat4::Dot(invView, KRVector3::Zero());
KRAABB cameraExtents = KRAABB(cameraPos - KRVector3(pCamera->getPerspectiveNearZ()), cameraPos + KRVector3(pCamera->getPerspectiveNearZ()));
bVisible = octreeBounds.intersects(cameraExtents); bVisible = octreeBounds.intersects(cameraExtents);
if(bVisible) { if(bVisible) {
newVisibleBounds.insert(octreeBounds); // Record the actual tests that succeeded during this frame newVisibleBounds.insert(octreeBounds); // Record the actual tests that succeeded during this frame
@@ -233,7 +229,7 @@ void KRScene::render(int childOrder[], KROctreeNode *pOctreeNode, std::set<KRAAB
KRMat4 matModel = KRMat4(); KRMat4 matModel = KRMat4();
matModel.scale(octreeBounds.size() / 2.0f); matModel.scale(octreeBounds.size() / 2.0f);
matModel.translate(octreeBounds.center()); matModel.translate(octreeBounds.center());
KRMat4 mvpmatrix = matModel * viewport.getViewMatrix() * viewport.getProjectionMatrix(); KRMat4 mvpmatrix = matModel * viewport.getViewProjectionMatrix();
// Enable additive blending // Enable additive blending
if(renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT) { if(renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT) {
@@ -289,8 +285,10 @@ void KRScene::render(int childOrder[], KROctreeNode *pOctreeNode, std::set<KRAAB
(*itr)->render(pCamera, pContext, viewport, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass); (*itr)->render(pCamera, pContext, viewport, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
} }
const int *childOctreeOrder = renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT || renderPass == KRNode::RENDER_PASS_FLARES ? viewport.getBackToFrontOrder() : viewport.getFrontToBackOrder();
for(int i=0; i<8; i++) { for(int i=0; i<8; i++) {
render(childOrder, pOctreeNode->getChildren()[childOrder[i]], visibleBounds, pCamera, pContext, viewport, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, remainingOctrees, remainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false); render(pOctreeNode->getChildren()[childOctreeOrder[i]], visibleBounds, pCamera, pContext, viewport, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass, remainingOctrees, remainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false);
} }
} }
} }

View File

@@ -62,9 +62,9 @@ public:
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
void render(KRCamera *pCamera, int childOrder[], std::set<KRAABB> &visibleBounds, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds); void render(KRCamera *pCamera, std::set<KRAABB> &visibleBounds, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds);
void render(int childOrder[], KROctreeNode *pOctreeNode, std::set<KRAABB> &visibleBounds, KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, 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(KROctreeNode *pOctreeNode, std::set<KRAABB> &visibleBounds, KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, 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 #endif

View File

@@ -219,23 +219,18 @@ bool KRShader::bind(const KRViewport &viewport, const KRMat4 &matModel, const KR
if(m_uniforms[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE] != -1) { if(m_uniforms[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE] != -1) {
// Transform location of camera to object space for calculation of specular halfVec // Transform location of camera to object space for calculation of specular halfVec
KRMat4 inverseViewMatrix = viewport.getViewMatrix(); KRVector3 cameraPosObject = KRMat4::Dot(inverseModelMatrix, viewport.getCameraPosition());
inverseViewMatrix.invert();
KRVector3 cameraPosition = KRMat4::Dot(inverseViewMatrix, KRVector3::Zero());
KRVector3 cameraPosObject = KRMat4::Dot(inverseModelMatrix, cameraPosition);
cameraPosObject.setUniform(m_uniforms[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE]); cameraPosObject.setUniform(m_uniforms[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE]);
} }
} }
if(m_uniforms[KRENGINE_UNIFORM_MVP] != -1 || m_uniforms[KRShader::KRENGINE_UNIFORM_INVMVP] != -1) { if(m_uniforms[KRENGINE_UNIFORM_MVP] != -1 || m_uniforms[KRShader::KRENGINE_UNIFORM_INVMVP] != -1) {
// Bind our modelmatrix variable to be a uniform called mvpmatrix in our shaderprogram // Bind our modelmatrix variable to be a uniform called mvpmatrix in our shaderprogram
KRMat4 mvpMatrix = matModel * viewport.getViewMatrix() * viewport.getProjectionMatrix(); KRMat4 mvpMatrix = matModel * viewport.getViewProjectionMatrix();
mvpMatrix.setUniform(m_uniforms[KRENGINE_UNIFORM_MVP]); mvpMatrix.setUniform(m_uniforms[KRENGINE_UNIFORM_MVP]);
if(m_uniforms[KRShader::KRENGINE_UNIFORM_INVMVP] != -1) { if(m_uniforms[KRShader::KRENGINE_UNIFORM_INVMVP] != -1) {
KRMat4 matInvMVP = mvpMatrix; KRMat4::Invert(mvpMatrix).setUniform(m_uniforms[KRShader::KRENGINE_UNIFORM_INVMVP]);
matInvMVP.invert();
matInvMVP.setUniform(m_uniforms[KRShader::KRENGINE_UNIFORM_INVMVP]);
} }
} }
@@ -265,9 +260,7 @@ bool KRShader::bind(const KRViewport &viewport, const KRMat4 &matModel, const KR
} }
if(m_uniforms[KRShader::KRENGINE_UNIFORM_INVP] != -1) { if(m_uniforms[KRShader::KRENGINE_UNIFORM_INVP] != -1) {
KRMat4 matInvProjection = viewport.getProjectionMatrix(); viewport.getInverseProjectionMatrix().setUniform(m_uniforms[KRShader::KRENGINE_UNIFORM_INVP]);
matInvProjection.invert();
matInvProjection.setUniform(m_uniforms[KRShader::KRENGINE_UNIFORM_INVP]);
} }
if(m_uniforms[KRShader::KRENGINE_UNIFORM_INVMVP_NO_TRANSLATE] != -1) { if(m_uniforms[KRShader::KRENGINE_UNIFORM_INVMVP_NO_TRANSLATE] != -1) {

View File

@@ -6,6 +6,8 @@
// Copyright (c) 2012 Kearwood Software. All rights reserved. // Copyright (c) 2012 Kearwood Software. All rights reserved.
// //
#define KRENGINE_SWAP_INT(x,y) {int t;t=x;x=y;y=t;}
#include "KRVector2.h" #include "KRVector2.h"
#include "KRMat4.h" #include "KRMat4.h"
#include "KRViewport.h" #include "KRViewport.h"
@@ -16,6 +18,7 @@ KRViewport::KRViewport()
m_size = KRVector2::One(); m_size = KRVector2::One();
m_matProjection = KRMat4(); m_matProjection = KRMat4();
m_matView = KRMat4(); m_matView = KRMat4();
calculateDerivedValues();
} }
KRViewport::KRViewport(const KRVector2 &size, const KRMat4 &matView, const KRMat4 &matProjection) KRViewport::KRViewport(const KRVector2 &size, const KRMat4 &matView, const KRMat4 &matProjection)
@@ -23,6 +26,7 @@ KRViewport::KRViewport(const KRVector2 &size, const KRMat4 &matView, const KRMat
m_size = size; m_size = size;
m_matView = matView; m_matView = matView;
m_matProjection = matProjection; m_matProjection = matProjection;
calculateDerivedValues();
} }
@@ -31,6 +35,8 @@ KRViewport& KRViewport::operator=(const KRViewport &v) {
m_size = v.m_size; m_size = v.m_size;
m_matProjection = v.m_matProjection; m_matProjection = v.m_matProjection;
m_matView = v.m_matView; m_matView = v.m_matView;
calculateDerivedValues();
} }
return *this; return *this;
} }
@@ -64,9 +70,84 @@ void KRViewport::setSize(const KRVector2 &size)
void KRViewport::setViewMatrix(const KRMat4 &matView) void KRViewport::setViewMatrix(const KRMat4 &matView)
{ {
m_matView = matView; m_matView = matView;
calculateDerivedValues();
} }
void KRViewport::setProjectionMatrix(const KRMat4 &matProjection) void KRViewport::setProjectionMatrix(const KRMat4 &matProjection)
{ {
m_matProjection = matProjection; m_matProjection = matProjection;
calculateDerivedValues();
}
const KRMat4 &KRViewport::KRViewport::getViewProjectionMatrix() const
{
return m_matViewProjection;
}
const KRMat4 &KRViewport::getInverseViewMatrix() const
{
return m_matInverseView;
}
const KRMat4 &KRViewport::getInverseProjectionMatrix() const
{
return m_matInverseProjection;
}
const KRVector3 &KRViewport::getCameraDirection() const
{
return m_cameraDirection;
}
const KRVector3 &KRViewport::getCameraPosition() const
{
return m_cameraPosition;
}
const int *KRViewport::getFrontToBackOrder() const
{
return &m_frontToBackOrder[0];
}
const int *KRViewport::getBackToFrontOrder() const
{
return &m_backToFrontOrder[0];
}
void KRViewport::calculateDerivedValues()
{
m_matViewProjection = m_matView * m_matProjection;
m_matInverseView = KRMat4::Invert(m_matView);
m_matInverseProjection = KRMat4::Invert(m_matProjection);
m_cameraPosition = KRMat4::Dot(m_matInverseView, KRVector3::Zero());
m_cameraDirection = KRMat4::Dot(m_matInverseView, KRVector3(0.0, 0.0, 1.0)) - KRMat4::Dot(m_matInverseView, KRVector3(0.0, 0.0, 0.0));
for(int i=0; i<8; i++) {
m_frontToBackOrder[i] = i;
}
if(m_cameraDirection.x > 0.0) {
KRENGINE_SWAP_INT(m_frontToBackOrder[0], m_frontToBackOrder[1]);
KRENGINE_SWAP_INT(m_frontToBackOrder[2], m_frontToBackOrder[3]);
KRENGINE_SWAP_INT(m_frontToBackOrder[4], m_frontToBackOrder[5]);
KRENGINE_SWAP_INT(m_frontToBackOrder[6], m_frontToBackOrder[7]);
}
if(m_cameraDirection.y > 0.0) {
KRENGINE_SWAP_INT(m_frontToBackOrder[0], m_frontToBackOrder[2]);
KRENGINE_SWAP_INT(m_frontToBackOrder[1], m_frontToBackOrder[3]);
KRENGINE_SWAP_INT(m_frontToBackOrder[4], m_frontToBackOrder[6]);
KRENGINE_SWAP_INT(m_frontToBackOrder[5], m_frontToBackOrder[7]);
}
if(m_cameraDirection.z > 0.0) {
KRENGINE_SWAP_INT(m_frontToBackOrder[0], m_frontToBackOrder[4]);
KRENGINE_SWAP_INT(m_frontToBackOrder[1], m_frontToBackOrder[5]);
KRENGINE_SWAP_INT(m_frontToBackOrder[2], m_frontToBackOrder[6]);
KRENGINE_SWAP_INT(m_frontToBackOrder[3], m_frontToBackOrder[7]);
}
for(int i=0; i<8; i++) {
m_backToFrontOrder[i] = m_frontToBackOrder[7-i];
}
} }

View File

@@ -21,6 +21,13 @@ public:
const KRVector2 &getSize() const; const KRVector2 &getSize() const;
const KRMat4 &getViewMatrix() const; const KRMat4 &getViewMatrix() const;
const KRMat4 &getProjectionMatrix() const; const KRMat4 &getProjectionMatrix() const;
const KRMat4 &getViewProjectionMatrix() const;
const KRMat4 &getInverseViewMatrix() const;
const KRMat4 &getInverseProjectionMatrix() const;
const KRVector3 &getCameraDirection() const;
const KRVector3 &getCameraPosition() const;
const int *getFrontToBackOrder() const;
const int *getBackToFrontOrder() const;
void setSize(const KRVector2 &size); void setSize(const KRVector2 &size);
void setViewMatrix(const KRMat4 &matView); void setViewMatrix(const KRMat4 &matView);
void setProjectionMatrix(const KRMat4 &matProjection); void setProjectionMatrix(const KRMat4 &matProjection);
@@ -32,6 +39,19 @@ private:
KRVector2 m_size; KRVector2 m_size;
KRMat4 m_matView; KRMat4 m_matView;
KRMat4 m_matProjection; KRMat4 m_matProjection;
// Derived values
KRMat4 m_matViewProjection;
KRMat4 m_matInverseView;
KRMat4 m_matInverseProjection;
KRVector3 m_cameraDirection;
KRVector3 m_cameraPosition;
int m_frontToBackOrder[8];
int m_backToFrontOrder[8];
void calculateDerivedValues();
}; };
#endif #endif