Implemented KRAABB class.

Occlusion culling in progress

--HG--
extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%4085
This commit is contained in:
kearwood
2012-08-30 22:37:44 +00:00
parent cee504408a
commit 04e7a7e83c
13 changed files with 334 additions and 56 deletions

View File

@@ -9,6 +9,10 @@
/* Begin PBXBuildFile section */
1000469D15E6EF550053B072 /* KRSkyBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1000469B15E6EF550053B072 /* KRSkyBox.cpp */; };
1000469E15E6EF550053B072 /* KRSkyBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 1000469C15E6EF550053B072 /* KRSkyBox.h */; };
E40BA45415EFF79500D7C3DD /* KRAABB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E40BA45215EFF79500D7C3DD /* KRAABB.cpp */; };
E40BA45515EFF79500D7C3DD /* KRAABB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E40BA45215EFF79500D7C3DD /* KRAABB.cpp */; };
E40BA45615EFF79500D7C3DD /* KRAABB.h in Headers */ = {isa = PBXBuildFile; fileRef = E40BA45315EFF79500D7C3DD /* KRAABB.h */; };
E40BA45715EFF79500D7C3DD /* KRAABB.h in Headers */ = {isa = PBXBuildFile; fileRef = E40BA45315EFF79500D7C3DD /* KRAABB.h */; };
E414BAE21435557300A668C4 /* KRInstance.h in Headers */ = {isa = PBXBuildFile; fileRef = E414BAE11435557300A668C4 /* KRInstance.h */; };
E414BAE51435558900A668C4 /* KRInstance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E414BAE41435558800A668C4 /* KRInstance.cpp */; };
E414BAE7143557D200A668C4 /* KRScene.h in Headers */ = {isa = PBXBuildFile; fileRef = E414BAE6143557D200A668C4 /* KRScene.h */; };
@@ -167,6 +171,8 @@
/* Begin PBXFileReference section */
1000469B15E6EF550053B072 /* KRSkyBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KRSkyBox.cpp; path = Classes/KRSkyBox.cpp; sourceTree = "<group>"; };
1000469C15E6EF550053B072 /* KRSkyBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KRSkyBox.h; path = Classes/KRSkyBox.h; sourceTree = "<group>"; };
E40BA45215EFF79500D7C3DD /* KRAABB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KRAABB.cpp; path = Classes/KRAABB.cpp; sourceTree = "<group>"; };
E40BA45315EFF79500D7C3DD /* KRAABB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KRAABB.h; path = Classes/KRAABB.h; sourceTree = "<group>"; };
E414BAE11435557300A668C4 /* KRInstance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = KRInstance.h; path = Classes/KRInstance.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
E414BAE41435558800A668C4 /* KRInstance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = KRInstance.cpp; path = Classes/KRInstance.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
E414BAE6143557D200A668C4 /* KRScene.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = KRScene.h; path = Classes/KRScene.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
@@ -371,6 +377,8 @@
E497B945151BA99400D3DC67 /* KRVector2.cpp */,
E42CB1EB158446940066E0D8 /* KRQuaternion.h */,
E42CB1EF158446AB0066E0D8 /* KRQuaternion.cpp */,
E40BA45215EFF79500D7C3DD /* KRAABB.cpp */,
E40BA45315EFF79500D7C3DD /* KRAABB.h */,
);
name = Math;
sourceTree = "<group>";
@@ -583,6 +591,7 @@
E4924C2715EE95E800B965C6 /* KROctree.h in Headers */,
E4924C2C15EE96AB00B965C6 /* KROctreeNode.h in Headers */,
1000469E15E6EF550053B072 /* KRSkyBox.h in Headers */,
E40BA45615EFF79500D7C3DD /* KRAABB.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -624,6 +633,7 @@
E42CB1ED158446940066E0D8 /* KRQuaternion.h in Headers */,
E43B0ACC15DDBB8500A5CB9F /* KRNotified.h in Headers */,
E43B0AD915DDCA0F00A5CB9F /* KRContextObject.h in Headers */,
E40BA45715EFF79500D7C3DD /* KRAABB.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -744,6 +754,7 @@
E4924C2615EE95E800B965C6 /* KROctree.cpp in Sources */,
E4924C2B15EE96AB00B965C6 /* KROctreeNode.cpp in Sources */,
1000469D15E6EF550053B072 /* KRSkyBox.cpp in Sources */,
E40BA45415EFF79500D7C3DD /* KRAABB.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -784,6 +795,7 @@
E42CB1F1158446AB0066E0D8 /* KRQuaternion.cpp in Sources */,
E43B0ACA15DDBB8500A5CB9F /* KRNotified.cpp in Sources */,
E43B0AD715DDCA0F00A5CB9F /* KRContextObject.cpp in Sources */,
E40BA45515EFF79500D7C3DD /* KRAABB.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@@ -0,0 +1,75 @@
//
// KRAABB.cpp
// KREngine
//
// Created by Kearwood Gilbert on 2012-08-30.
// Copyright (c) 2012 Kearwood Software. All rights reserved.
//
#include "KRAABB.h"
KRAABB::KRAABB(const KRVector3 &minPoint, const KRVector3 &maxPoint)
{
min = minPoint;
max = maxPoint;
}
KRAABB::~KRAABB()
{
}
KRAABB& KRAABB::operator =(const KRAABB& b)
{
min = b.min;
max = b.max;
return *this;
}
bool KRAABB::operator ==(const KRAABB& b) const
{
return min == b.min && max == b.max;
}
bool KRAABB::operator !=(const KRAABB& b) const
{
return min != b.min || max != b.max;
}
KRVector3 KRAABB::center()
{
return (min + max) / 2.0f;
}
KRVector3 KRAABB::size()
{
return max - min;
}
bool KRAABB::operator >(const KRAABB& b) const
{
// Comparison operators are implemented to allow insertion into sorted containers such as std::set
if(min > b.min) {
return true;
} else if(min < b.min) {
return false;
} else if(max > b.max) {
return true;
} else {
return false;
}
}
bool KRAABB::operator <(const KRAABB& b) const
{
// Comparison operators are implemented to allow insertion into sorted containers such as std::set
if(min < b.min) {
return true;
} else if(min > b.min) {
return false;
} else if(max < b.max) {
return true;
} else {
return false;
}
}

View File

@@ -0,0 +1,37 @@
//
// KRAABB.h
// KREngine
//
// Created by Kearwood Gilbert on 2012-08-30.
// Copyright (c) 2012 Kearwood Software. All rights reserved.
//
// Axis aligned bounding box
#ifndef KRAABB_H
#define KRAABB_H
#include "KRVector3.h"
class KRAABB {
public:
KRAABB(const KRVector3 &minPoint, const KRVector3 &maxPoint);
~KRAABB();
KRVector3 center();
KRVector3 size();
KRAABB& operator =(const KRAABB& b);
bool operator ==(const KRAABB& b) const;
bool operator !=(const KRAABB& b) const;
// Comparison operators are implemented to allow insertion into sorted containers such as std::set
bool operator >(const KRAABB& b) const;
bool operator <(const KRAABB& b) const;
KRVector3 min;
KRVector3 max;
};
#endif /* defined(KRAABB_H) */

View File

@@ -213,7 +213,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
glDisable(GL_BLEND);
// Render the geometry
scene.render(this, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_GBUFFER);
scene.render(this, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_GBUFFER);
// ----====---- Opaque Geometry, Deferred rendering Pass 2 ----====----
// Set render target
@@ -237,7 +237,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
// Render the geometry
scene.render(this, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, 0, KRNode::RENDER_PASS_DEFERRED_LIGHTS);
scene.render(this, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, 0, KRNode::RENDER_PASS_DEFERRED_LIGHTS);
// ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====----
// Set render target
@@ -267,7 +267,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
glDepthMask(GL_TRUE);
// Render the geometry
scene.render(this, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_OPAQUE);
scene.render(this, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_OPAQUE);
// Deactivate source buffer texture units
glActiveTexture(GL_TEXTURE6);
@@ -302,7 +302,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
// Render the geometry
scene.render(this, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_OPAQUE);
scene.render(this, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_OPAQUE);
}
// ----====---- Transparent Geometry, Forward Rendering ----====----
@@ -327,7 +327,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Render all transparent geometry
scene.render(this, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
scene.render(this, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
// ----====---- Flares ----====----
@@ -350,10 +350,14 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
glBlendFunc(GL_ONE, GL_ONE);
// Render all flares
scene.render(this, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FLARES);
scene.render(this, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FLARES);
// Re-enable z-buffer write
glDepthMask(GL_TRUE);
scene.getOcclusionQueryResults(m_visibleBounds);
fprintf(stderr, "visible bounds: %i\n", (int)m_visibleBounds.size());
}
@@ -539,7 +543,8 @@ void KRCamera::renderShadowBuffer(KRScene &scene, int iShadow)
KRVector3 cameraPosition;
KRVector3 lightDirection;
KRBoundingVolume shadowVolume = KRBoundingVolume(vertices);
scene.render(this, m_pContext, shadowVolume, shadowmvpmatrix[iShadow], cameraPosition, lightDirection, shadowmvpmatrix, NULL, m_cShadowBuffers, KRNode::RENDER_PASS_SHADOWMAP);
scene.render(this, m_shadowVisibleBounds[iShadow], m_pContext, shadowVolume, shadowmvpmatrix[iShadow], cameraPosition, lightDirection, shadowmvpmatrix, NULL, m_cShadowBuffers, KRNode::RENDER_PASS_SHADOWMAP);
scene.getOcclusionQueryResults(m_shadowVisibleBounds[iShadow]);
glViewport(0, 0, backingWidth, backingHeight);
}

View File

@@ -37,6 +37,7 @@
#import "KRMat4.h"
#import "KRVector2.h"
#import "KRNotified.h"
#import "KRAABB.h"
#define KRENGINE_MAX_SHADOW_BUFFERS 3
@@ -196,6 +197,9 @@ private:
std::list<KRInstanceDistance> m_transparentInstances;
std::set<KRAABB> m_visibleBounds; // AABB's that output fragments in the last frame
std::set<KRAABB> m_shadowVisibleBounds[KRENGINE_MAX_SHADOW_BUFFERS]; // AABB's that output fragments in the last frame for each shadow map
};
#endif

View File

@@ -31,19 +31,18 @@ void KROctree::add(KRNode *pNode)
} else {
if(m_pRootNode == NULL) {
// First item inserted, create a node large enough to fit it
m_pRootNode = new KROctreeNode(pNode->getMinPoint(), pNode->getMaxPoint());
m_pRootNode = new KROctreeNode(KRAABB(pNode->getMinPoint(), pNode->getMaxPoint()));
m_pRootNode->add(pNode);
} else {
// Keep encapsulating the root node until the new root contains the inserted node
bool bInsideRoot = false;
while(!bInsideRoot) {
KRVector3 rootMinPoint = m_pRootNode->getMinPoint();
KRVector3 rootMaxPoint = m_pRootNode->getMaxPoint();
KRVector3 rootSize = rootMaxPoint - rootMinPoint;
if(minPoint.x < rootMinPoint.x || minPoint.y < rootMinPoint.y || minPoint.z < rootMinPoint.z) {
m_pRootNode = new KROctreeNode(rootMinPoint - rootSize, rootMaxPoint, 7, m_pRootNode);
} else if(maxPoint.x > rootMaxPoint.x || maxPoint.y > rootMaxPoint.y || maxPoint.z > rootMaxPoint.z) {
m_pRootNode = new KROctreeNode(rootMaxPoint, rootMaxPoint + rootSize, 0, m_pRootNode);
KRAABB rootBounds = m_pRootNode->getBounds();
KRVector3 rootSize = rootBounds.size();
if(minPoint.x < rootBounds.min.x || minPoint.y < rootBounds.min.y || minPoint.z < rootBounds.min.z) {
m_pRootNode = new KROctreeNode(KRAABB(rootBounds.min - rootSize, rootBounds.max), 7, m_pRootNode);
} else if(maxPoint.x > rootBounds.max.x || maxPoint.y > rootBounds.max.y || maxPoint.z > rootBounds.max.z) {
m_pRootNode = new KROctreeNode(KRAABB(rootBounds.max, rootBounds.max + rootSize), 0, m_pRootNode);
} else {
bInsideRoot = true;
}
@@ -93,3 +92,11 @@ std::set<KRNode *> &KROctree::getOuterSceneNodes()
return m_outerSceneNodes;
}
void KROctree::getOcclusionQueryResults(std::set<KRAABB> &renderedBounds)
{
renderedBounds.clear();
if(m_pRootNode) {
m_pRootNode->getOcclusionQueryResults(renderedBounds);
}
}

View File

@@ -27,6 +27,8 @@ public:
KROctreeNode *getRootNode();
std::set<KRNode *> &getOuterSceneNodes();
void getOcclusionQueryResults(std::set<KRAABB> &renderedBounds);
private:
KROctreeNode *m_pRootNode;
std::set<KRNode *>m_outerSceneNodes;

View File

@@ -9,20 +9,28 @@
#include "KROctreeNode.h"
#include "KRNode.h"
KROctreeNode::KROctreeNode(const KRVector3 &minPoint, const KRVector3 &maxPoint)
KROctreeNode::KROctreeNode(const KRAABB &bounds) : m_bounds(bounds)
{
m_minPoint = minPoint;
m_maxPoint = maxPoint;
for(int i=0; i<8; i++) m_children[i] = NULL;
m_occlusionQuery = 0;
m_occlusionTested = false;
m_occlusionQueryTransparent = 0;
m_occlusionTestedTransparent = false;
m_activeQuery = false;
}
KROctreeNode::KROctreeNode(const KRVector3 &minPoint, const KRVector3 &maxPoint, int iChild, KROctreeNode *pChild)
KROctreeNode::KROctreeNode(const KRAABB &bounds, int iChild, KROctreeNode *pChild) : m_bounds(bounds)
{
// This constructor is used when expanding the octree and replacing the root node with a new root that encapsulates it
m_minPoint = minPoint;
m_maxPoint = maxPoint;
for(int i=0; i<8; i++) m_children[i] = NULL;
m_children[iChild] = pChild;
m_occlusionQuery = 0;
m_occlusionTested = false;
m_occlusionQueryTransparent = 0;
m_occlusionTestedTransparent = false;
m_activeQuery = false;
}
KROctreeNode::~KROctreeNode()
@@ -32,28 +40,105 @@ KROctreeNode::~KROctreeNode()
delete m_children[i];
}
}
if(m_occlusionTested) {
glDeleteQueriesEXT(1, &m_occlusionQuery);
}
if(m_occlusionTestedTransparent) {
glDeleteQueriesEXT(1, &m_occlusionQueryTransparent);
}
}
void KROctreeNode::beginOcclusionQuery(bool bTransparentPass)
{
if(bTransparentPass && !m_occlusionTestedTransparent) {
glGenQueriesEXT(1, &m_occlusionQueryTransparent);
glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, m_occlusionQueryTransparent);
m_occlusionTestedTransparent = true;
m_activeQuery = true;
} else if(!bTransparentPass && !m_occlusionTested){
glGenQueriesEXT(1, &m_occlusionQuery);
glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, m_occlusionQuery);
m_occlusionTested = true;
m_activeQuery = true;
}
}
void KROctreeNode::endOcclusionQuery()
{
if(m_activeQuery) {
// Only end a query if we started one
glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
}
}
bool KROctreeNode::getOcclusionQueryResults(std::set<KRAABB> &renderedBounds)
{
bool bRendered = false;
bool bGoDeeper = false;
if(m_occlusionTested) {
GLuint params = 0;
glGetQueryObjectuivEXT(m_occlusionQuery, GL_QUERY_RESULT_EXT, &params);
if(params) bRendered = true; // At least one opaque fragment processed
glDeleteQueriesEXT(1, &m_occlusionQuery);
m_occlusionTested = false;
bGoDeeper = true;
}
if(m_occlusionTestedTransparent) {
GLuint params = 0;
glGetQueryObjectuivEXT(m_occlusionQueryTransparent, GL_QUERY_RESULT_EXT, &params);
if(params) bRendered = true; // At least one transparent fragment processed
glDeleteQueriesEXT(1, &m_occlusionQueryTransparent);
m_occlusionTestedTransparent = false;
bGoDeeper = true;
}
if(bGoDeeper) { // Only recurse deeper if we reached this level in the previous pass
for(int i=0; i<8; i++) {
if(m_children[i]) {
if(m_children[i]->getOcclusionQueryResults(renderedBounds)) {
bRendered = true; // We must always include the parent, even if the parent's local scene graph nodes are fully occluded
}
}
}
}
if(bRendered) {
renderedBounds.insert(m_bounds);
}
return bRendered;
}
KRAABB KROctreeNode::getBounds()
{
return m_bounds;
}
void KROctreeNode::add(KRNode *pNode)
{
KRVector3 center = (m_minPoint + m_maxPoint) / 2.0f;
KRVector3 center = m_bounds.center();
int iChild = getChildIndex(pNode);
if(iChild == -1) {
m_sceneNodes.insert(pNode);
} else {
if(m_children[iChild] == NULL) {
m_children[iChild] = new KROctreeNode(
KRVector3(
(iChild & 1) == 0 ? m_minPoint.x : center.x,
(iChild & 2) == 0 ? m_minPoint.y : center.y,
(iChild & 4) == 0 ? m_minPoint.z : center.z),
KRVector3(
(iChild & 1) == 0 ? center.x : m_maxPoint.x,
(iChild & 2) == 0 ? center.y : m_maxPoint.y,
(iChild & 4) == 0 ? center.z : m_maxPoint.z)
m_children[iChild] = new KROctreeNode(KRAABB(
KRVector3(
(iChild & 1) == 0 ? m_bounds.min.x : center.x,
(iChild & 2) == 0 ? m_bounds.min.y : center.y,
(iChild & 4) == 0 ? m_bounds.min.z : center.z),
KRVector3(
(iChild & 1) == 0 ? center.x : m_bounds.max.x,
(iChild & 2) == 0 ? center.y : m_bounds.max.y,
(iChild & 4) == 0 ? center.z : m_bounds.max.z)
)
);
}
m_children[iChild]->add(pNode);
@@ -73,7 +158,7 @@ int KROctreeNode::getChildIndex(KRNode *pNode)
// 6: max.x < center.x && min.y > center.y && min.z > center.z
// 7: min.x > center.x && min.y > center.y && min.z > center.z
KRVector3 center = (m_minPoint + m_maxPoint) / 2.0f;
KRVector3 center = m_bounds.center();
int iChild = -1;
if(max.z < center.z) {
if(max.y < center.y) {
@@ -126,16 +211,6 @@ void KROctreeNode::update(KRNode *pNode)
}
KRVector3 KROctreeNode::getMinPoint()
{
return m_minPoint;
}
KRVector3 KROctreeNode::getMaxPoint()
{
return m_maxPoint;
}
bool KROctreeNode::isEmpty() const
{
for(int i=0; i<8; i++) {

View File

@@ -11,13 +11,14 @@
#import "KREngine-common.h"
#include "KRVector3.h"
#include "KRAABB.h"
class KRNode;
class KROctreeNode {
public:
KROctreeNode(const KRVector3 &minPoint, const KRVector3 &maxPoint);
KROctreeNode(const KRVector3 &minPoint, const KRVector3 &maxPoint, int iChild, KROctreeNode *pChild);
KROctreeNode(const KRAABB &bounds);
KROctreeNode(const KRAABB &bounds, int iChild, KROctreeNode *pChild);
~KROctreeNode();
KROctreeNode **getChildren();
@@ -27,8 +28,7 @@ public:
void remove(KRNode *pNode);
void update(KRNode *pNode);
KRVector3 getMinPoint();
KRVector3 getMaxPoint();
KRAABB getBounds();
void setChildNode(int iChild, KROctreeNode *pChild);
int getChildIndex(KRNode *pNode);
@@ -37,9 +37,21 @@ public:
bool canShrinkRoot() const;
KROctreeNode *stripChild();
void beginOcclusionQuery(bool bTransparentPass);
void endOcclusionQuery();
bool getOcclusionQueryResults(std::set<KRAABB> &renderedBounds);
private:
KRVector3 m_minPoint;
KRVector3 m_maxPoint;
GLuint m_occlusionQuery;
bool m_occlusionTested;
GLuint m_occlusionQueryTransparent;
bool m_occlusionTestedTransparent;
bool m_activeQuery;
KRAABB m_bounds;
KROctreeNode *m_children[8];

View File

@@ -54,7 +54,7 @@ KRScene::~KRScene() {
#if TARGET_OS_IPHONE
void KRScene::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) {
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) {
updateOctree();
@@ -124,7 +124,7 @@ void KRScene::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &f
*/
//m_pRootNode->render(pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
render(m_nodeTree.getRootNode(), pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
render(m_nodeTree.getRootNode(), visibleBounds, pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
for(std::set<KRNode *>::iterator itr=m_nodeTree.getOuterSceneNodes().begin(); itr != m_nodeTree.getOuterSceneNodes().end(); itr++) {
@@ -132,14 +132,16 @@ void KRScene::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &f
}
}
void KRScene::render(KROctreeNode *pOctreeNode, KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass)
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)
{
if(pOctreeNode) {
pOctreeNode->beginOcclusionQuery(renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
for(std::set<KRNode *>::iterator itr=pOctreeNode->getSceneNodes().begin(); itr != pOctreeNode->getSceneNodes().end(); itr++) {
(*itr)->render(pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
}
pOctreeNode->endOcclusionQuery();
for(int i=0; i<8; i++) {
render(pOctreeNode->getChildren()[i], pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
render(pOctreeNode->getChildren()[i], visibleBounds, pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
}
}
}
@@ -258,3 +260,8 @@ void KRScene::updateOctree()
m_newNodes.clear();
m_modifiedNodes.clear();
}
void KRScene::getOcclusionQueryResults(std::set<KRAABB> &renderedBounds)
{
m_nodeTree.getOcclusionQueryResults(renderedBounds);
}

View File

@@ -64,9 +64,12 @@ public:
#if TARGET_OS_IPHONE
void render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
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);
void render(KROctreeNode *pOctreeNode, KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
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);
void getOcclusionQueryResults(std::set<KRAABB> &renderedBounds);
#endif

View File

@@ -255,3 +255,38 @@ float KRVector3::Dot(const KRVector3 &v1, const KRVector3 &v2) {
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
bool KRVector3::operator >(const KRVector3& b) const
{
// Comparison operators are implemented to allow insertion into sorted containers such as std::set
if(x > b.x) {
return true;
} else if(x < b.x) {
return false;
} else if(y > b.y) {
return true;
} else if(y < b.y) {
return false;
} else if(z > b.z) {
return true;
} else {
return false;
}
}
bool KRVector3::operator <(const KRVector3& b) const
{
// Comparison operators are implemented to allow insertion into sorted containers such as std::set
if(x < b.x) {
return true;
} else if(x > b.x) {
return false;
} else if(y < b.y) {
return true;
} else if(y > b.y) {
return false;
} else if(z < b.z) {
return true;
} else {
return false;
}
}

View File

@@ -62,6 +62,10 @@ public:
bool operator ==(const KRVector3& b) const;
bool operator !=(const KRVector3& b) const;
// Comparison operators are implemented to allow insertion into sorted containers such as std::set
bool operator >(const KRVector3& b) const;
bool operator <(const KRVector3& b) const;
float& operator[](unsigned i);
float operator[](unsigned i) const;