Implemented KRAABB class.
Occlusion culling in progress --HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%4085
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
75
KREngine/KREngine/Classes/KRAABB.cpp
Normal file
75
KREngine/KREngine/Classes/KRAABB.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
37
KREngine/KREngine/Classes/KRAABB.h
Normal file
37
KREngine/KREngine/Classes/KRAABB.h
Normal 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) */
|
||||
@@ -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,11 +350,15 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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, ¶ms);
|
||||
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, ¶ms);
|
||||
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(
|
||||
m_children[iChild] = new KROctreeNode(KRAABB(
|
||||
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),
|
||||
(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_maxPoint.x,
|
||||
(iChild & 2) == 0 ? center.y : m_maxPoint.y,
|
||||
(iChild & 4) == 0 ? center.z : m_maxPoint.z)
|
||||
(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++) {
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user