Fixed inaccurate view frustum culling
Implemented smarter octree visibility query batching algorithm --HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40106
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "KRAABB.h"
|
#include "KRAABB.h"
|
||||||
#include "KRMat4.h"
|
#include "KRMat4.h"
|
||||||
|
#include "assert.h"
|
||||||
|
|
||||||
KRAABB::KRAABB(const KRVector3 &minPoint, const KRVector3 &maxPoint)
|
KRAABB::KRAABB(const KRVector3 &minPoint, const KRVector3 &maxPoint)
|
||||||
{
|
{
|
||||||
@@ -87,6 +88,11 @@ bool KRAABB::contains(const KRAABB &b) const
|
|||||||
return b.min.x >= min.x && b.min.y >= min.y && b.min.z >= min.z && b.max.x <= max.x && b.max.y <= max.y && b.max.z <= max.z;
|
return b.min.x >= min.x && b.min.y >= min.y && b.min.z >= min.z && b.max.x <= max.x && b.max.y <= max.y && b.max.z <= max.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool KRAABB::contains(const KRVector3 &v) const
|
||||||
|
{
|
||||||
|
return v.x >= min.x && v.x <= max.x && v.y >= min.y && v.y <= max.y && v.z >= min.z && v.z <= max.z;
|
||||||
|
}
|
||||||
|
|
||||||
KRAABB KRAABB::Infinite()
|
KRAABB KRAABB::Infinite()
|
||||||
{
|
{
|
||||||
return KRAABB(KRVector3::Min(), KRVector3::Max());
|
return KRAABB(KRVector3::Min(), KRVector3::Max());
|
||||||
@@ -102,13 +108,13 @@ bool KRAABB::visible(const KRMat4 &matViewProjection) const
|
|||||||
int outside_count[6] = {0, 0, 0, 0, 0, 0};
|
int outside_count[6] = {0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
for(int iCorner=0; iCorner<8; iCorner++) {
|
for(int iCorner=0; iCorner<8; iCorner++) {
|
||||||
KRVector3 cornerVertex = KRVector3(
|
KRVector3 sourceCornerVertex = KRVector3(
|
||||||
(iCorner & 1) == 0 ? min.x : max.x,
|
(iCorner & 1) == 0 ? min.x : max.x,
|
||||||
(iCorner & 2) == 0 ? min.y : max.y,
|
(iCorner & 2) == 0 ? min.y : max.y,
|
||||||
(iCorner & 4) == 0 ? min.z : max.z);
|
(iCorner & 4) == 0 ? min.z : max.z);
|
||||||
|
|
||||||
cornerVertex = KRMat4::Dot(matViewProjection, cornerVertex);
|
KRVector3 cornerVertex = KRMat4::Dot(matViewProjection, sourceCornerVertex);
|
||||||
float cornerVertexW = KRMat4::DotW(matViewProjection, cornerVertex);
|
float cornerVertexW = KRMat4::DotW(matViewProjection, sourceCornerVertex);
|
||||||
|
|
||||||
if(cornerVertex.x < -cornerVertexW) {
|
if(cornerVertex.x < -cornerVertexW) {
|
||||||
outside_count[0]++;
|
outside_count[0]++;
|
||||||
@@ -130,6 +136,37 @@ 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) {
|
||||||
@@ -138,9 +175,10 @@ bool KRAABB::visible(const KRMat4 &matViewProjection) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!is_visible) {
|
if(!is_visible) {
|
||||||
fprintf(stderr, "AABB culled: %i%i%i%i%i%i out, (%f, %f, %f) - (%f, %f, %f)\n", outside_count[0], outside_count[1], outside_count[2], outside_count[3], outside_count[4], outside_count[5], min.x, min.y, min.z, max.x, max.y, max.z);
|
//fprintf(stderr, "AABB culled: %i%i%i%i%i%i out, (%f, %f, %f) - (%f, %f, %f)\n", outside_count[0], outside_count[1], outside_count[2], outside_count[3], outside_count[4], outside_count[5], min.x, min.y, min.z, max.x, max.y, max.z);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "AABB visible: %i%i%i%i%i%i out, (%f, %f, %f) - (%f, %f, %f)\n", outside_count[0], outside_count[1], outside_count[2], outside_count[3], outside_count[4], outside_count[5], min.x, min.y, min.z, max.x, max.y, max.z);
|
//fprintf(stderr, "AABB visible: %i%i%i%i%i%i out, (%f, %f, %f) - (%f, %f, %f)\n", outside_count[0], outside_count[1], outside_count[2], outside_count[3], outside_count[4], outside_count[5], min.x, min.y, min.z, max.x, max.y, max.z);
|
||||||
}
|
}
|
||||||
|
//is_visible = true;
|
||||||
return is_visible;
|
return is_visible;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public:
|
|||||||
KRVector3 size() const;
|
KRVector3 size() const;
|
||||||
bool intersects(const KRAABB& b) const;
|
bool intersects(const KRAABB& b) const;
|
||||||
bool contains(const KRAABB &b) const;
|
bool contains(const KRAABB &b) const;
|
||||||
|
bool contains(const KRVector3 &v) const;
|
||||||
bool visible(const KRMat4 &matViewProjection) const;
|
bool visible(const KRMat4 &matViewProjection) const;
|
||||||
|
|
||||||
KRAABB& operator =(const KRAABB& b);
|
KRAABB& operator =(const KRAABB& b);
|
||||||
|
|||||||
@@ -192,6 +192,9 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
|
|||||||
setViewportSize(KRVector2(backingWidth, backingHeight));
|
setViewportSize(KRVector2(backingWidth, backingHeight));
|
||||||
|
|
||||||
KRBoundingVolume frustrumVolume = KRBoundingVolume(viewMatrix, perspective_fov, getViewportSize().x / getViewportSize().y, perspective_nearz, perspective_farz);
|
KRBoundingVolume frustrumVolume = KRBoundingVolume(viewMatrix, perspective_fov, getViewportSize().x / getViewportSize().y, perspective_nearz, perspective_farz);
|
||||||
|
|
||||||
|
std::set<KRAABB> newVisibleBounds;
|
||||||
|
|
||||||
if(bEnableDeferredLighting) {
|
if(bEnableDeferredLighting) {
|
||||||
// ----====---- Opaque Geometry, Deferred rendering Pass 1 ----====----
|
// ----====---- Opaque Geometry, Deferred rendering Pass 1 ----====----
|
||||||
|
|
||||||
@@ -216,7 +219,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
|
|||||||
GLDEBUG(glDisable(GL_BLEND));
|
GLDEBUG(glDisable(GL_BLEND));
|
||||||
|
|
||||||
// Render the geometry
|
// Render the geometry
|
||||||
scene.render(this, m_visibleBounds, 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, newVisibleBounds);
|
||||||
|
|
||||||
// ----====---- Opaque Geometry, Deferred rendering Pass 2 ----====----
|
// ----====---- Opaque Geometry, Deferred rendering Pass 2 ----====----
|
||||||
// Set render target
|
// Set render target
|
||||||
@@ -242,9 +245,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
|
|||||||
|
|
||||||
|
|
||||||
// Render the geometry
|
// Render the geometry
|
||||||
scene.render(this, m_visibleBounds, 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, newVisibleBounds);
|
||||||
|
|
||||||
scene.getOcclusionQueryResults(m_visibleBounds);
|
|
||||||
|
|
||||||
// ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====----
|
// ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====----
|
||||||
// Set render target
|
// Set render target
|
||||||
@@ -275,7 +276,8 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
|
|||||||
GLDEBUG(glDepthMask(GL_TRUE));
|
GLDEBUG(glDepthMask(GL_TRUE));
|
||||||
|
|
||||||
// Render the geometry
|
// Render the geometry
|
||||||
scene.render(this, m_visibleBounds, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_OPAQUE);
|
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);
|
||||||
|
|
||||||
// Deactivate source buffer texture units
|
// Deactivate source buffer texture units
|
||||||
m_pContext->getTextureManager()->selectTexture(6, NULL);
|
m_pContext->getTextureManager()->selectTexture(6, NULL);
|
||||||
@@ -312,9 +314,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
|
|||||||
|
|
||||||
|
|
||||||
// Render the geometry
|
// Render the geometry
|
||||||
scene.render(this, m_visibleBounds, 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, newVisibleBounds);
|
||||||
|
|
||||||
scene.getOcclusionQueryResults(m_visibleBounds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----====---- Transparent Geometry, Forward Rendering ----====----
|
// ----====---- Transparent Geometry, Forward Rendering ----====----
|
||||||
@@ -339,7 +339,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
|
|||||||
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, m_visibleBounds, 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, newVisibleBounds);
|
||||||
|
|
||||||
|
|
||||||
// ----====---- Flares ----====----
|
// ----====---- Flares ----====----
|
||||||
@@ -363,7 +363,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
|
|||||||
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
|
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
|
||||||
|
|
||||||
// Render all flares
|
// Render all flares
|
||||||
scene.render(this, m_visibleBounds, 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, newVisibleBounds);
|
||||||
|
|
||||||
// ----====---- Debug Overlay ----====----
|
// ----====---- Debug Overlay ----====----
|
||||||
|
|
||||||
@@ -395,15 +395,13 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// scene.getOcclusionQueryResults(m_visibleBounds);
|
m_visibleBounds = newVisibleBounds;
|
||||||
|
|
||||||
// fprintf(stderr, "visible bounds: %i\n", (int)m_visibleBounds.size());
|
|
||||||
|
|
||||||
// Re-enable z-buffer write
|
// Re-enable z-buffer write
|
||||||
GLDEBUG(glDepthMask(GL_TRUE));
|
GLDEBUG(glDepthMask(GL_TRUE));
|
||||||
|
|
||||||
|
|
||||||
fprintf(stderr, "VBO Mem: %i Kbyte Texture Mem: %i Kbyte Shader Handles: %i\n", (int)m_pContext->getModelManager()->getMemUsed() / 1024, (int)m_pContext->getTextureManager()->getMemUsed() / 1024, (int)m_pContext->getShaderManager()->getShaderHandlesUsed());
|
fprintf(stderr, "VBO Mem: %i Kbyte Texture Mem: %i Kbyte Shader Handles: %i Visible Bounds: %i\n", (int)m_pContext->getModelManager()->getMemUsed() / 1024, (int)m_pContext->getTextureManager()->getMemUsed() / 1024, (int)m_pContext->getShaderManager()->getShaderHandlesUsed(), (int)m_visibleBounds.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -574,8 +572,10 @@ void KRCamera::renderShadowBuffer(KRScene &scene, int iShadow)
|
|||||||
KRVector3 cameraPosition;
|
KRVector3 cameraPosition;
|
||||||
KRVector3 lightDirection;
|
KRVector3 lightDirection;
|
||||||
KRBoundingVolume shadowVolume = KRBoundingVolume(vertices);
|
KRBoundingVolume shadowVolume = KRBoundingVolume(vertices);
|
||||||
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]);
|
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);
|
||||||
|
m_shadowVisibleBounds[iShadow] = newVisibleBounds;
|
||||||
GLDEBUG(glViewport(0, 0, backingWidth, backingHeight));
|
GLDEBUG(glViewport(0, 0, backingWidth, backingHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,8 +91,8 @@ void KRInstance::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(m_pModel != NULL) {
|
if(m_pModel != NULL) {
|
||||||
if(getExtents(pContext).test_intersect(frustrumVolume) || renderPass == RENDER_PASS_SHADOWMAP) {
|
//if(getExtents(pContext).test_intersect(frustrumVolume) || renderPass == RENDER_PASS_SHADOWMAP) {
|
||||||
//if(m_pModel != NULL && (getBounds().visible(viewMatrix * projectionMatrix) || renderPass == RENDER_PASS_SHADOWMAP)) {
|
if(getBounds().visible(viewMatrix * projectionMatrix)) {
|
||||||
|
|
||||||
if(m_pLightMap == NULL && m_lightMap.size()) {
|
if(m_pLightMap == NULL && m_lightMap.size()) {
|
||||||
m_pLightMap = pContext->getTextureManager()->getTexture(m_lightMap.c_str());
|
m_pLightMap = pContext->getTextureManager()->getTexture(m_lightMap.c_str());
|
||||||
|
|||||||
@@ -91,12 +91,3 @@ std::set<KRNode *> &KROctree::getOuterSceneNodes()
|
|||||||
{
|
{
|
||||||
return m_outerSceneNodes;
|
return m_outerSceneNodes;
|
||||||
}
|
}
|
||||||
#if TARGET_OS_IPHONE
|
|
||||||
void KROctree::getOcclusionQueryResults(std::set<KRAABB> &renderedBounds)
|
|
||||||
{
|
|
||||||
renderedBounds.clear();
|
|
||||||
if(m_pRootNode) {
|
|
||||||
m_pRootNode->getOcclusionQueryResults(renderedBounds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -26,9 +26,7 @@ public:
|
|||||||
|
|
||||||
KROctreeNode *getRootNode();
|
KROctreeNode *getRootNode();
|
||||||
std::set<KRNode *> &getOuterSceneNodes();
|
std::set<KRNode *> &getOuterSceneNodes();
|
||||||
#if TARGET_OS_IPHONE
|
|
||||||
void getOcclusionQueryResults(std::set<KRAABB> &renderedBounds);
|
|
||||||
#endif
|
|
||||||
private:
|
private:
|
||||||
KROctreeNode *m_pRootNode;
|
KROctreeNode *m_pRootNode;
|
||||||
std::set<KRNode *>m_outerSceneNodes;
|
std::set<KRNode *>m_outerSceneNodes;
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ KROctreeNode::KROctreeNode(const KRAABB &bounds) : m_bounds(bounds)
|
|||||||
|
|
||||||
m_occlusionQuery = 0;
|
m_occlusionQuery = 0;
|
||||||
m_occlusionTested = false;
|
m_occlusionTested = false;
|
||||||
m_occlusionQueryTransparent = 0;
|
|
||||||
m_occlusionTestedTransparent = false;
|
|
||||||
m_activeQuery = false;
|
m_activeQuery = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,8 +26,6 @@ KROctreeNode::KROctreeNode(const KRAABB &bounds, int iChild, KROctreeNode *pChil
|
|||||||
|
|
||||||
m_occlusionQuery = 0;
|
m_occlusionQuery = 0;
|
||||||
m_occlusionTested = false;
|
m_occlusionTested = false;
|
||||||
m_occlusionQueryTransparent = 0;
|
|
||||||
m_occlusionTestedTransparent = false;
|
|
||||||
m_activeQuery = false;
|
m_activeQuery = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,21 +40,13 @@ KROctreeNode::~KROctreeNode()
|
|||||||
if(m_occlusionTested) {
|
if(m_occlusionTested) {
|
||||||
GLDEBUG(glDeleteQueriesEXT(1, &m_occlusionQuery));
|
GLDEBUG(glDeleteQueriesEXT(1, &m_occlusionQuery));
|
||||||
}
|
}
|
||||||
if(m_occlusionTestedTransparent) {
|
|
||||||
GLDEBUG(glDeleteQueriesEXT(1, &m_occlusionQueryTransparent));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TARGET_OS_IPHONE
|
#if TARGET_OS_IPHONE
|
||||||
void KROctreeNode::beginOcclusionQuery(bool bTransparentPass)
|
void KROctreeNode::beginOcclusionQuery()
|
||||||
{
|
{
|
||||||
if(bTransparentPass && !m_occlusionTestedTransparent) {
|
if(!m_occlusionTested){
|
||||||
GLDEBUG(glGenQueriesEXT(1, &m_occlusionQueryTransparent));
|
|
||||||
GLDEBUG(glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, m_occlusionQueryTransparent));
|
|
||||||
m_occlusionTestedTransparent = true;
|
|
||||||
m_activeQuery = true;
|
|
||||||
} else if(!bTransparentPass && !m_occlusionTested){
|
|
||||||
GLDEBUG(glGenQueriesEXT(1, &m_occlusionQuery));
|
GLDEBUG(glGenQueriesEXT(1, &m_occlusionQuery));
|
||||||
GLDEBUG(glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, m_occlusionQuery));
|
GLDEBUG(glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, m_occlusionQuery));
|
||||||
m_occlusionTested = true;
|
m_occlusionTested = true;
|
||||||
@@ -74,54 +62,9 @@ void KROctreeNode::endOcclusionQuery()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KROctreeNode::getOcclusionQueryResults(std::set<KRAABB> &renderedBounds)
|
|
||||||
{
|
|
||||||
bool bRendered = false;
|
|
||||||
bool bGoDeeper = false;
|
|
||||||
|
|
||||||
if(m_occlusionTested) {
|
|
||||||
GLuint params = 0;
|
|
||||||
GLDEBUG(glGetQueryObjectuivEXT(m_occlusionQuery, GL_QUERY_RESULT_EXT, ¶ms));
|
|
||||||
if(params) bRendered = true; // At least one opaque fragment processed
|
|
||||||
|
|
||||||
GLDEBUG(glDeleteQueriesEXT(1, &m_occlusionQuery));
|
|
||||||
m_occlusionTested = false;
|
|
||||||
bGoDeeper = true;
|
|
||||||
}
|
|
||||||
if(m_occlusionTestedTransparent) {
|
|
||||||
GLuint params = 0;
|
|
||||||
GLDEBUG(glGetQueryObjectuivEXT(m_occlusionQueryTransparent, GL_QUERY_RESULT_EXT, ¶ms));
|
|
||||||
if(params) bRendered = true; // At least one transparent fragment processed
|
|
||||||
|
|
||||||
GLDEBUG(glDeleteQueriesEXT(1, &m_occlusionQueryTransparent));
|
|
||||||
m_occlusionTestedTransparent = false;
|
|
||||||
|
|
||||||
bGoDeeper = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FINDME - Test Code:
|
|
||||||
//bGoDeeper = true;
|
|
||||||
//bRendered = 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
KRAABB KROctreeNode::getBounds()
|
KRAABB KROctreeNode::getBounds()
|
||||||
{
|
{
|
||||||
return m_bounds;
|
return m_bounds;
|
||||||
@@ -157,55 +100,7 @@ KRAABB KROctreeNode::getChildBounds(int iChild)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int KROctreeNode::getChildIndex(KRNode *pNode)
|
int KROctreeNode::getChildIndex(KRNode *pNode)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
|
|
||||||
KRVector3 min = pNode->getMinPoint();
|
|
||||||
KRVector3 max = pNode->getMaxPoint();
|
|
||||||
|
|
||||||
// 0: max.x < center.x && max.y < center.y && max.z < center.z
|
|
||||||
// 1: min.x > center.x && max.y < center.y && max.z < center.z
|
|
||||||
// 2: max.x < center.x && min.y > center.y && max.z < center.z
|
|
||||||
// 3: min.x > center.x && min.y > center.y && max.z < center.z
|
|
||||||
// 4: max.x < center.x && max.y < center.y && min.z > center.z
|
|
||||||
// 5: min.x > center.x && max.y < center.y && min.z > center.z
|
|
||||||
// 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_bounds.center();
|
|
||||||
int iChild = -1;
|
|
||||||
if(max.z < center.z) {
|
|
||||||
if(max.y < center.y) {
|
|
||||||
if(max.x < center.x) {
|
|
||||||
iChild = 0;
|
|
||||||
} else if(min.x > center.x) {
|
|
||||||
iChild = 1;
|
|
||||||
}
|
|
||||||
} else if(min.y > center.y) {
|
|
||||||
if(max.x < center.x) {
|
|
||||||
iChild = 2;
|
|
||||||
} else if(min.x > center.x) {
|
|
||||||
iChild = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if(min.z > center.z) {
|
|
||||||
if(max.y < center.y) {
|
|
||||||
if(min.x > center.x) {
|
|
||||||
iChild = 4;
|
|
||||||
} else if(min.x > center.x) {
|
|
||||||
iChild = 5;
|
|
||||||
}
|
|
||||||
} else if(min.y > center.y) {
|
|
||||||
if(max.x < center.x) {
|
|
||||||
iChild = 6;
|
|
||||||
} else if(min.x > center.x) {
|
|
||||||
iChild = 7;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return iChild;
|
|
||||||
*/
|
|
||||||
|
|
||||||
for(int iChild=0; iChild < 8; iChild++) {
|
for(int iChild=0; iChild < 8; iChild++) {
|
||||||
if(getChildBounds(iChild).contains(pNode->getBounds())) {
|
if(getChildBounds(iChild).contains(pNode->getBounds())) {
|
||||||
return iChild;
|
return iChild;
|
||||||
|
|||||||
@@ -38,19 +38,14 @@ public:
|
|||||||
bool canShrinkRoot() const;
|
bool canShrinkRoot() const;
|
||||||
KROctreeNode *stripChild();
|
KROctreeNode *stripChild();
|
||||||
|
|
||||||
void beginOcclusionQuery(bool bTransparentPass);
|
void beginOcclusionQuery();
|
||||||
void endOcclusionQuery();
|
void endOcclusionQuery();
|
||||||
bool getOcclusionQueryResults(std::set<KRAABB> &renderedBounds);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
GLuint m_occlusionQuery;
|
GLuint m_occlusionQuery;
|
||||||
bool m_occlusionTested;
|
bool m_occlusionTested;
|
||||||
|
|
||||||
GLuint m_occlusionQueryTransparent;
|
|
||||||
bool m_occlusionTestedTransparent;
|
|
||||||
|
|
||||||
bool m_activeQuery;
|
bool m_activeQuery;
|
||||||
|
private:
|
||||||
|
|
||||||
KRAABB m_bounds;
|
KRAABB m_bounds;
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ KRScene::~KRScene() {
|
|||||||
|
|
||||||
#if TARGET_OS_IPHONE
|
#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) {
|
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) {
|
||||||
|
|
||||||
updateOctree();
|
updateOctree();
|
||||||
|
|
||||||
@@ -103,7 +103,33 @@ void KRScene::render(KRCamera *pCamera, std::set<KRAABB> &visibleBounds, KRConte
|
|||||||
pCamera->dSunB = sun_color.z;
|
pCamera->dSunB = sun_color.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
render(m_nodeTree.getRootNode(), visibleBounds, pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
|
std::vector<KROctreeNode *> remainingOctrees;
|
||||||
|
std::vector<KROctreeNode *> remainingOctreesTestResults;
|
||||||
|
std::vector<KROctreeNode *> remainingOctreesTestResultsOnly;
|
||||||
|
if(m_nodeTree.getRootNode() != NULL) {
|
||||||
|
remainingOctrees.push_back(m_nodeTree.getRootNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<KROctreeNode *> newRemainingOctrees;
|
||||||
|
std::vector<KROctreeNode *> newRemainingOctreesTestResults;
|
||||||
|
while((!remainingOctrees.empty() || !remainingOctreesTestResults.empty())) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
remainingOctrees = newRemainingOctrees;
|
||||||
|
remainingOctreesTestResults = newRemainingOctreesTestResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for(std::set<KRNode *>::iterator itr=m_nodeTree.getOuterSceneNodes().begin(); itr != m_nodeTree.getOuterSceneNodes().end(); itr++) {
|
for(std::set<KRNode *>::iterator itr=m_nodeTree.getOuterSceneNodes().begin(); itr != m_nodeTree.getOuterSceneNodes().end(); itr++) {
|
||||||
@@ -111,61 +137,94 @@ 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)
|
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)
|
||||||
{
|
{
|
||||||
if(pOctreeNode) {
|
if(pOctreeNode) {
|
||||||
KRMat4 projectionMatrix;
|
|
||||||
if(renderPass != KRNode::RENDER_PASS_SHADOWMAP) {
|
|
||||||
projectionMatrix = pCamera->getProjectionMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
KRAABB octreeBounds = pOctreeNode->getBounds();
|
KRAABB octreeBounds = pOctreeNode->getBounds();
|
||||||
|
|
||||||
KRBoundingVolume frustrumVolumeNoNearClip = KRBoundingVolume(viewMatrix, pCamera->perspective_fov, pCamera->m_viewportSize.x / pCamera->m_viewportSize.y, 0.0, pCamera->perspective_farz);
|
if(bOcclusionResultsPass) {
|
||||||
|
// ----====---- Occlusion results pass ----====----
|
||||||
//if(true) {
|
if(pOctreeNode->m_occlusionTested) {
|
||||||
//if(pOctreeNode->getBounds().visible(viewMatrix * projectionMatrix)) { // Only recurse deeper if within the view frustrum
|
GLuint params = 0;
|
||||||
if(frustrumVolumeNoNearClip.test_intersect(pOctreeNode->getBounds())) { // Only recurse deeper if within the view frustrum
|
GLDEBUG(glGetQueryObjectuivEXT(pOctreeNode->m_occlusionQuery, GL_QUERY_RESULT_EXT, ¶ms));
|
||||||
|
if(params) {
|
||||||
|
newVisibleBounds.insert(octreeBounds); // Record the actual tests that succeeded during this frame
|
||||||
|
visibleBounds.insert(octreeBounds); // Update the list of tests that we won't repeat for subsequent passes during this frame
|
||||||
|
if(!bOcclusionTestResultsOnly) {
|
||||||
|
// Schedule a pass to perform the rendering
|
||||||
|
remainingOctrees.push_back(pOctreeNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLDEBUG(glDeleteQueriesEXT(1, &pOctreeNode->m_occlusionQuery));
|
||||||
|
pOctreeNode->m_occlusionTested = false;
|
||||||
|
pOctreeNode->m_occlusionQuery = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
bool can_occlusion_test = renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_DEFERRED_GBUFFER/* || renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT*/;
|
|
||||||
|
// KRBoundingVolume frustrumVolumeNoNearClip = KRBoundingVolume(viewMatrix, pCamera->perspective_fov, pCamera->m_viewportSize.x / pCamera->m_viewportSize.y, 0.0, pCamera->perspective_farz);
|
||||||
|
// if(frustrumVolumeNoNearClip.test_intersect(pOctreeNode->getBounds())) { // Only recurse deeper if within the view frustrum
|
||||||
|
//
|
||||||
|
|
||||||
// can_occlusion_test = false;
|
|
||||||
bool bVisible = true;
|
|
||||||
//bool bVisible = visibleBounds.find(octreeBounds) != visibleBounds.end();
|
|
||||||
|
|
||||||
if(bVisible) {
|
|
||||||
if(can_occlusion_test) {
|
KRMat4 projectionMatrix;
|
||||||
pOctreeNode->beginOcclusionQuery(renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
if(renderPass != KRNode::RENDER_PASS_SHADOWMAP) {
|
||||||
}
|
projectionMatrix = pCamera->getProjectionMatrix();
|
||||||
|
}
|
||||||
// Occlusion test indicates that this bounding box was visible in the last frame
|
if(pOctreeNode->getBounds().visible(viewMatrix * projectionMatrix)) { // Only recurse deeper if within the view frustrum
|
||||||
for(std::set<KRNode *>::iterator itr=pOctreeNode->getSceneNodes().begin(); itr != pOctreeNode->getSceneNodes().end(); itr++) {
|
|
||||||
//assert(pOctreeNode->getBounds().contains((*itr)->getBounds())); // Sanity check
|
// ----====---- Rendering and occlusion test pass ----====----
|
||||||
|
bool bVisible = false;
|
||||||
(*itr)->render(pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
|
bool bNeedOcclusionTest = true;
|
||||||
}
|
|
||||||
|
//bVisible = true; // FINDME - Test Code
|
||||||
if(can_occlusion_test) {
|
|
||||||
pOctreeNode->endOcclusionQuery();
|
if(!bVisible) {
|
||||||
}
|
// 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
|
||||||
|
KRMat4 invView = viewMatrix;
|
||||||
bool bRenderChildren = renderPass != KRNode::RENDER_PASS_DEFERRED_OPAQUE;
|
invView.invert();
|
||||||
if(!bRenderChildren) {
|
KRVector3 cameraPos = KRMat4::Dot(invView, KRVector3::Zero());
|
||||||
bRenderChildren = visibleBounds.find(octreeBounds) != visibleBounds.end();
|
KRAABB cameraExtents = KRAABB(cameraPos - KRVector3(pCamera->perspective_nearz), cameraPos + KRVector3(pCamera->perspective_nearz));
|
||||||
}
|
bVisible = octreeBounds.intersects(cameraExtents);
|
||||||
if(bRenderChildren) {
|
if(bVisible) {
|
||||||
for(int i=0; i<8; i++) {
|
newVisibleBounds.insert(octreeBounds); // Record the actual tests that succeeded during this frame
|
||||||
render(pOctreeNode->getChildren()[i], visibleBounds, pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
|
visibleBounds.insert(octreeBounds); // Update the list of tests that we won't repeat for subsequent passes during this frame
|
||||||
|
bNeedOcclusionTest = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE) {
|
|
||||||
if(pOctreeNode->getSceneNodes().empty()) {
|
if(!bVisible) {
|
||||||
for(int i=0; i<8; i++) {
|
// Check if an occlusion query from the prior pass has returned true
|
||||||
render(pOctreeNode->getChildren()[i], visibleBounds, pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
|
bVisible = newVisibleBounds.find(octreeBounds) != newVisibleBounds.end();
|
||||||
|
if(bVisible) {
|
||||||
|
bNeedOcclusionTest = false;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
pOctreeNode->beginOcclusionQuery(renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
|
||||||
|
if(!bVisible) {
|
||||||
|
// Take advantage of temporal consistency of visible elements from frame to frame
|
||||||
|
// If the previous frame rendered this octree, then attempt to render it in this frame without performing a pre-occlusion test
|
||||||
|
bVisible = visibleBounds.find(octreeBounds) != visibleBounds.end();
|
||||||
|
// We don't set bNeedOcclusionTest to false here, as we need to perform an occlusion test to record if this octree node was visible for the next frame
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!bVisible) {
|
||||||
|
// Optimization: If this is an empty octree node with only a single child node, then immediately try to render the child node without an occlusion test for this higher level, as it would be more expensive than the occlusion test for the child
|
||||||
|
if(pOctreeNode->getSceneNodes().empty()) {
|
||||||
|
int child_count = 0;
|
||||||
|
for(int i=0; i<8; i++) {
|
||||||
|
if(pOctreeNode->getChildren()[i] != NULL) child_count++;
|
||||||
|
}
|
||||||
|
if(child_count == 1) bVisible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bNeedOcclusionTest) {
|
||||||
|
pOctreeNode->beginOcclusionQuery();
|
||||||
|
|
||||||
KRShader *pVisShader = m_pContext->getShaderManager()->getShader("occlusion_test", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
KRShader *pVisShader = m_pContext->getShaderManager()->getShader("occlusion_test", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||||
|
|
||||||
@@ -180,22 +239,60 @@ void KRScene::render(KROctreeNode *pOctreeNode, std::set<KRAABB> &visibleBounds,
|
|||||||
// Enable additive blending
|
// Enable additive blending
|
||||||
GLDEBUG(glEnable(GL_BLEND));
|
GLDEBUG(glEnable(GL_BLEND));
|
||||||
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
|
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
|
||||||
|
|
||||||
|
|
||||||
|
if(renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE ||
|
||||||
|
renderPass == KRNode::RENDER_PASS_DEFERRED_GBUFFER ||
|
||||||
|
renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE ||
|
||||||
|
renderPass == KRNode::RENDER_PASS_SHADOWMAP) {
|
||||||
|
|
||||||
|
// Disable z-buffer write
|
||||||
|
GLDEBUG(glDepthMask(GL_FALSE));
|
||||||
|
}
|
||||||
|
|
||||||
if(pVisShader->bind(pCamera, viewMatrix, mvpmatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
|
if(pVisShader->bind(pCamera, viewMatrix, mvpmatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
|
||||||
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 14));
|
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 14));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE ||
|
||||||
|
renderPass == KRNode::RENDER_PASS_DEFERRED_GBUFFER ||
|
||||||
|
renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE ||
|
||||||
|
renderPass == KRNode::RENDER_PASS_SHADOWMAP) {
|
||||||
|
|
||||||
|
// Re-enable z-buffer write
|
||||||
|
GLDEBUG(glDepthMask(GL_TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
GLDEBUG(glDisable(GL_BLEND));
|
GLDEBUG(glDisable(GL_BLEND));
|
||||||
|
|
||||||
pOctreeNode->endOcclusionQuery();
|
pOctreeNode->endOcclusionQuery();
|
||||||
|
|
||||||
|
|
||||||
|
if(bVisible) {
|
||||||
|
// Schedule a pass to get the result of the occlusion test only for future frames and passes, without rendering the model or recurring further
|
||||||
|
remainingOctreesTestResultsOnly.push_back(pOctreeNode);
|
||||||
|
} else {
|
||||||
|
// Schedule a pass to get the result of the occlusion test and continue recursion and rendering if test is true
|
||||||
|
remainingOctreesTestResults.push_back(pOctreeNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bVisible) {
|
||||||
|
|
||||||
|
for(std::set<KRNode *>::iterator itr=pOctreeNode->getSceneNodes().begin(); itr != pOctreeNode->getSceneNodes().end(); itr++) {
|
||||||
|
//assert(pOctreeNode->getBounds().contains((*itr)->getBounds())); // Sanity check
|
||||||
|
(*itr)->render(pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
//fprintf(stderr, "Octree culled: (%f, %f, %f) - (%f, %f, %f)\n", pOctreeNode->getBounds().min.x, pOctreeNode->getBounds().min.y, pOctreeNode->getBounds().min.z, pOctreeNode->getBounds().max.x, pOctreeNode->getBounds().max.y, pOctreeNode->getBounds().max.z);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// fprintf(stderr, "Octree culled: (%f, %f, %f) - (%f, %f, %f)\n", pOctreeNode->getBounds().min.x, pOctreeNode->getBounds().min.y, pOctreeNode->getBounds().min.z, pOctreeNode->getBounds().max.x, pOctreeNode->getBounds().max.y, pOctreeNode->getBounds().max.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -317,9 +414,4 @@ void KRScene::updateOctree()
|
|||||||
}
|
}
|
||||||
#if TARGET_OS_IPHONE
|
#if TARGET_OS_IPHONE
|
||||||
|
|
||||||
void KRScene::getOcclusionQueryResults(std::set<KRAABB> &renderedBounds)
|
|
||||||
{
|
|
||||||
m_nodeTree.getOcclusionQueryResults(renderedBounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -64,12 +64,9 @@ public:
|
|||||||
|
|
||||||
#if TARGET_OS_IPHONE
|
#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);
|
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(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 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 getOcclusionQueryResults(std::set<KRAABB> &renderedBounds);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#define KRENGINE_MAX_TEXTURE_UNITS 8
|
#define KRENGINE_MAX_TEXTURE_UNITS 8
|
||||||
#define KRENGINE_MAX_TEXTURE_HANDLES 10000
|
#define KRENGINE_MAX_TEXTURE_HANDLES 10000
|
||||||
#define KRENGINE_MAX_TEXTURE_MEM 100000000
|
#define KRENGINE_MAX_TEXTURE_MEM 128000000
|
||||||
|
|
||||||
#ifndef KRTEXTUREMANAGER_H
|
#ifndef KRTEXTUREMANAGER_H
|
||||||
#define KRTEXTUREMANAGER_H
|
#define KRTEXTUREMANAGER_H
|
||||||
|
|||||||
@@ -30,5 +30,6 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
//gl_FragColor = vec4(0.00, 0.00, 0.00, 0.00);
|
||||||
gl_FragColor = vec4(0.00, 0.00, 0.00, 0.00);
|
gl_FragColor = vec4(0.00, 0.00, 0.00, 0.00);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "0440"
|
LastUpgradeVersion = "0450"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
</BuildActionEntries>
|
</BuildActionEntries>
|
||||||
</BuildAction>
|
</BuildAction>
|
||||||
<TestAction
|
<TestAction
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.GDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
buildConfiguration = "Debug">
|
buildConfiguration = "Debug">
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
[self.engine setNearZ: 5.0];
|
[self.engine setNearZ: 5.0];
|
||||||
[self.engine setFarZ: 3000.0];
|
[self.engine setFarZ: 5000.0];
|
||||||
//[renderEngine setNearZ: 1.0];
|
//[renderEngine setNearZ: 1.0];
|
||||||
//[renderEngine setFarZ: 3000.0];
|
//[renderEngine setFarZ: 3000.0];
|
||||||
|
|
||||||
|
|||||||
@@ -252,7 +252,7 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double dScaleFactor = 200.0f * deltaTime;
|
double dScaleFactor = 500.0f * deltaTime;
|
||||||
|
|
||||||
camera_position.z += (-cos(camera_pitch) * cos(camera_yaw) * leftStickDeltaX + -cos(camera_pitch) * cos(camera_yaw - 90.0f * d2r) * -leftStickDeltaY) * dScaleFactor;
|
camera_position.z += (-cos(camera_pitch) * cos(camera_yaw) * leftStickDeltaX + -cos(camera_pitch) * cos(camera_yaw - 90.0f * d2r) * -leftStickDeltaY) * dScaleFactor;
|
||||||
camera_position.x += (cos(camera_pitch) * sin(camera_yaw) * leftStickDeltaX + cos(camera_pitch) * sin(camera_yaw - 90.0f * d2r) * -leftStickDeltaY) * dScaleFactor;
|
camera_position.x += (cos(camera_pitch) * sin(camera_yaw) * leftStickDeltaX + cos(camera_pitch) * sin(camera_yaw - 90.0f * d2r) * -leftStickDeltaY) * dScaleFactor;
|
||||||
|
|||||||
@@ -271,7 +271,7 @@
|
|||||||
29B97313FDCFA39411CA2CEA /* Project object */ = {
|
29B97313FDCFA39411CA2CEA /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastUpgradeCheck = 0440;
|
LastUpgradeCheck = 0450;
|
||||||
};
|
};
|
||||||
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "KRObjView" */;
|
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "KRObjView" */;
|
||||||
compatibilityVersion = "Xcode 3.2";
|
compatibilityVersion = "Xcode 3.2";
|
||||||
|
|||||||
Reference in New Issue
Block a user