Updated realtime occlusion culling algorithm to reduce the number of occlusion tests.

--HG--
extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40160
This commit is contained in:
kearwood
2012-11-17 05:20:26 +00:00
parent a0549b4cfb
commit aae50ff178
6 changed files with 56 additions and 55 deletions

View File

@@ -179,8 +179,6 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
KRVector3 vecCameraDirection = m_viewport.getCameraDirection(); KRVector3 vecCameraDirection = m_viewport.getCameraDirection();
std::set<KRAABB> newVisibleBounds;
// GLuint shadowDepthTexture[KRENGINE_MAX_SHADOW_BUFFERS]; // GLuint shadowDepthTexture[KRENGINE_MAX_SHADOW_BUFFERS];
// KRViewport shadowViewports[KRENGINE_MAX_SHADOW_BUFFERS]; // KRViewport shadowViewports[KRENGINE_MAX_SHADOW_BUFFERS];
// int cShadows = 0; // int cShadows = 0;
@@ -209,10 +207,10 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
GLDEBUG(glDisable(GL_BLEND)); GLDEBUG(glDisable(GL_BLEND));
// Render the geometry // Render the geometry
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_GBUFFER, newVisibleBounds); scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_GBUFFER);
// ----====---- Generate Shadowmaps for Lights ----====---- // ----====---- Generate Shadowmaps for Lights ----====----
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, newVisibleBounds); scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS);
GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y)); GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y));
// ----====---- Opaque Geometry, Deferred rendering Pass 2 ----====---- // ----====---- Opaque Geometry, Deferred rendering Pass 2 ----====----
@@ -239,7 +237,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
// Render the geometry // Render the geometry
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, newVisibleBounds); scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS);
// ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====---- // ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====----
// Set render target // Set render target
@@ -270,8 +268,8 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
GLDEBUG(glDepthMask(GL_TRUE)); GLDEBUG(glDepthMask(GL_TRUE));
// Render the geometry // Render the geometry
std::set<KRAABB> emptyBoundsSet; // At this point, we only render octree nodes that produced fragments during the 1st pass into the GBuffer // TODO: At this point, we only want to render octree nodes that produced fragments during the 1st pass into the GBuffer
scene.render(this, emptyBoundsSet, m_viewport, KRNode::RENDER_PASS_DEFERRED_OPAQUE, newVisibleBounds); scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_OPAQUE);
// Deactivate source buffer texture units // Deactivate source buffer texture units
m_pContext->getTextureManager()->selectTexture(6, NULL); m_pContext->getTextureManager()->selectTexture(6, NULL);
@@ -282,7 +280,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0));
} else { } else {
// ----====---- Generate Shadowmaps for Lights ----====---- // ----====---- Generate Shadowmaps for Lights ----====----
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, newVisibleBounds); scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS);
GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y)); GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y));
// ----====---- Opaque Geometry, Forward Rendering ----====---- // ----====---- Opaque Geometry, Forward Rendering ----====----
@@ -313,7 +311,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
// Render the geometry // Render the geometry
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_OPAQUE, newVisibleBounds); scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_OPAQUE);
} }
// ----====---- Sky Box ----====---- // ----====---- Sky Box ----====----
@@ -372,7 +370,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
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_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, newVisibleBounds); scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
// ----====---- Flares ----====---- // ----====---- Flares ----====----
@@ -396,7 +394,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE)); GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
// Render all flares // Render all flares
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_ADDITIVE_PARTICLES, newVisibleBounds); scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_ADDITIVE_PARTICLES);
// ----====---- Volumetric Lighting ----====---- // ----====---- Volumetric Lighting ----====----
@@ -424,7 +422,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
GLDEBUG(glDepthRangef(0.0, 1.0)); GLDEBUG(glDepthRangef(0.0, 1.0));
} }
scene.render(this, m_viewport.getVisibleBounds(), volumetricLightingViewport, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE, newVisibleBounds); scene.render(this, m_viewport.getVisibleBounds(), volumetricLightingViewport, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE);
if(volumetric_environment_downsample != 0) { if(volumetric_environment_downsample != 0) {
// Set render target // Set render target
@@ -459,10 +457,10 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
KRMat4 projectionMatrix = getProjectionMatrix(); KRMat4 projectionMatrix = getProjectionMatrix();
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, true, false, false, false, false); m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, true, false, false, false, false);
for(std::set<KRAABB>::iterator itr=m_viewport.getVisibleBounds().begin(); itr != m_viewport.getVisibleBounds().end(); itr++) { for(std::map<KRAABB, int>::iterator itr=m_viewport.getVisibleBounds().begin(); itr != m_viewport.getVisibleBounds().end(); itr++) {
KRMat4 matModel = KRMat4(); KRMat4 matModel = KRMat4();
matModel.scale((*itr).size() / 2.0f); matModel.scale((*itr).first.size() / 2.0f);
matModel.translate((*itr).center()); matModel.translate((*itr).first.center());
if(getContext().getShaderManager()->selectShader(pVisShader, m_viewport, matModel, std::vector<KRLight *>(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) { if(getContext().getShaderManager()->selectShader(pVisShader, m_viewport, matModel, std::vector<KRLight *>(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 14)); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 14));
@@ -470,8 +468,6 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
} }
} }
m_viewport.setVisibleBounds(newVisibleBounds);
// Re-enable z-buffer write // Re-enable z-buffer write
GLDEBUG(glDepthMask(GL_TRUE)); GLDEBUG(glDepthMask(GL_TRUE));

View File

@@ -300,9 +300,7 @@ void KRLight::renderShadowBuffers(KRCamera *pCamera)
getContext().getShaderManager()->selectShader(shadowShader, m_shadowViewports[iShadow], KRMat4(), std::vector<KRLight *>(), KRNode::RENDER_PASS_SHADOWMAP); getContext().getShaderManager()->selectShader(shadowShader, m_shadowViewports[iShadow], KRMat4(), std::vector<KRLight *>(), KRNode::RENDER_PASS_SHADOWMAP);
std::set<KRAABB> newVisibleBounds; getScene().render(pCamera, m_shadowViewports[iShadow].getVisibleBounds(), m_shadowViewports[iShadow], KRNode::RENDER_PASS_SHADOWMAP);
getScene().render(pCamera, m_shadowViewports[iShadow].getVisibleBounds(), m_shadowViewports[iShadow], KRNode::RENDER_PASS_SHADOWMAP, newVisibleBounds);
m_shadowViewports[iShadow].setVisibleBounds(newVisibleBounds);
} }
} }

View File

@@ -45,6 +45,8 @@
#import "KRPointLight.h" #import "KRPointLight.h"
#import "KRQuaternion.h" #import "KRQuaternion.h"
const long KRENGINE_OCCLUSION_TEST_EXPIRY = 60;
KRScene::KRScene(KRContext &context, std::string name) : KRResource(context, name) { KRScene::KRScene(KRContext &context, std::string name) : KRResource(context, name) {
m_pFirstLight = NULL; m_pFirstLight = NULL;
m_pRootNode = new KRNode(*this, "scene_root"); m_pRootNode = new KRNode(*this, "scene_root");
@@ -58,7 +60,7 @@ KRScene::~KRScene() {
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
void KRScene::render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds) { void KRScene::render(KRCamera *pCamera, std::map<KRAABB, int> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass) {
std::vector<KRLight *> lights; std::vector<KRLight *> lights;
@@ -96,10 +98,10 @@ void KRScene::render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, c
newRemainingOctrees.clear(); newRemainingOctrees.clear();
newRemainingOctreesTestResults.clear(); newRemainingOctreesTestResults.clear();
for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctrees.begin(); octree_itr != remainingOctrees.end(); octree_itr++) { for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctrees.begin(); octree_itr != remainingOctrees.end(); octree_itr++) {
render(*octree_itr, visibleBounds, pCamera, lights, viewport, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false); render(*octree_itr, visibleBounds, pCamera, lights, viewport, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, false, false);
} }
for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctreesTestResults.begin(); octree_itr != remainingOctreesTestResults.end(); octree_itr++) { for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctreesTestResults.begin(); octree_itr != remainingOctreesTestResults.end(); octree_itr++) {
render(*octree_itr, visibleBounds, pCamera, lights, viewport, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, false); render(*octree_itr, visibleBounds, pCamera, lights, viewport, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, true, false);
} }
remainingOctrees = newRemainingOctrees; remainingOctrees = newRemainingOctrees;
remainingOctreesTestResults = newRemainingOctreesTestResults; remainingOctreesTestResults = newRemainingOctreesTestResults;
@@ -108,11 +110,23 @@ void KRScene::render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, c
newRemainingOctrees.clear(); newRemainingOctrees.clear();
newRemainingOctreesTestResults.clear(); newRemainingOctreesTestResults.clear();
for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctreesTestResultsOnly.begin(); octree_itr != remainingOctreesTestResultsOnly.end(); octree_itr++) { for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctreesTestResultsOnly.begin(); octree_itr != remainingOctreesTestResultsOnly.end(); octree_itr++) {
render(*octree_itr, visibleBounds, pCamera, lights, viewport, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, true); render(*octree_itr, visibleBounds, pCamera, lights, viewport, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, true, true);
}
// Expire cached occlusion test results
std::set<KRAABB> expired_visible_bounds;
for(std::map<KRAABB, int>::iterator visible_bounds_itr = visibleBounds.begin(); visible_bounds_itr != visibleBounds.end(); visible_bounds_itr++) {
if((*visible_bounds_itr).second + KRENGINE_OCCLUSION_TEST_EXPIRY < getContext().getCurrentFrame()) {
expired_visible_bounds.insert((*visible_bounds_itr).first);
}
}
for(std::set<KRAABB>::iterator expired_visible_bounds_itr = expired_visible_bounds.begin(); expired_visible_bounds_itr != expired_visible_bounds.end(); expired_visible_bounds_itr++) {
visibleBounds.erase(*expired_visible_bounds_itr);
} }
} }
void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleBounds, KRCamera *pCamera, std::vector<KRLight *> lights, const KRViewport &viewport, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, std::set<KRAABB> &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly) void KRScene::render(KROctreeNode *pOctreeNode, std::map<KRAABB, int> &visibleBounds, KRCamera *pCamera, std::vector<KRLight *> lights, const KRViewport &viewport, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly)
{ {
if(pOctreeNode) { if(pOctreeNode) {
@@ -124,8 +138,9 @@ void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleB
GLuint params = 0; GLuint params = 0;
GLDEBUG(glGetQueryObjectuivEXT(pOctreeNode->m_occlusionQuery, GL_QUERY_RESULT_EXT, &params)); GLDEBUG(glGetQueryObjectuivEXT(pOctreeNode->m_occlusionQuery, GL_QUERY_RESULT_EXT, &params));
if(params) { if(params) {
newVisibleBounds.insert(octreeBounds); // Record the actual tests that succeeded during this frame // Record the frame number that the test has passed on
// visibleBounds.insert(octreeBounds); // Update the list of tests that we won't repeat for subsequent passes during this frame visibleBounds[octreeBounds] = getContext().getCurrentFrame();
if(!bOcclusionTestResultsOnly) { if(!bOcclusionTestResultsOnly) {
// Schedule a pass to perform the rendering // Schedule a pass to perform the rendering
remainingOctrees.push_back(pOctreeNode); remainingOctrees.push_back(pOctreeNode);
@@ -140,8 +155,8 @@ void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleB
float min_coverage = 0.0f; float min_coverage = 0.0f;
float lod_coverage = pOctreeNode->getBounds().coverage(viewport.getViewProjectionMatrix(), viewport.getSize()); // This also checks the view frustrum culling float lod_coverage = pOctreeNode->getBounds().coverage(viewport.getViewProjectionMatrix(), viewport.getSize()); // Cull against the view frustrum
if(lod_coverage > min_coverage) { if(lod_coverage > min_coverage) {
// ----====---- Rendering and occlusion test pass ----====---- // ----====---- Rendering and occlusion test pass ----====----
bool bVisible = false; bool bVisible = false;
@@ -153,25 +168,24 @@ void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleB
KRAABB cameraExtents = KRAABB(viewport.getCameraPosition() - KRVector3(pCamera->getPerspectiveNearZ()), viewport.getCameraPosition() + KRVector3(pCamera->getPerspectiveNearZ())); KRAABB cameraExtents = KRAABB(viewport.getCameraPosition() - KRVector3(pCamera->getPerspectiveNearZ()), viewport.getCameraPosition() + KRVector3(pCamera->getPerspectiveNearZ()));
bVisible = octreeBounds.intersects(cameraExtents); bVisible = octreeBounds.intersects(cameraExtents);
if(bVisible) { if(bVisible) {
newVisibleBounds.insert(octreeBounds); // Record the actual tests that succeeded during this frame // Record the frame number in which the camera was within the bounds
// visibleBounds.insert(octreeBounds); // Update the list of tests that we won't repeat for subsequent passes during this frame visibleBounds[octreeBounds] = getContext().getCurrentFrame();
bNeedOcclusionTest = false; bNeedOcclusionTest = false;
} }
} }
if(!bVisible) {
// Check if an occlusion query from the prior pass has returned true
bVisible = newVisibleBounds.find(octreeBounds) != newVisibleBounds.end();
if(bVisible) {
bNeedOcclusionTest = false;
}
}
if(!bVisible) { if(!bVisible) {
// Take advantage of temporal consistency of visible elements from frame to frame // Check if a previous occlusion query has returned true, taking 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 // 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(); std::map<KRAABB, int>::iterator match_itr = visibleBounds.find(octreeBounds);
// 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(match_itr != visibleBounds.end()) {
bVisible = true;
// We set bNeedOcclusionTest to false only when the previous occlusion test is old and we need to perform an occlusion test to record if this octree node was visible for the next frame
bNeedOcclusionTest = false;
}
} }
if(!bVisible) { if(!bVisible) {
@@ -270,7 +284,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleB
const int *childOctreeOrder = renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT || renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES || renderPass == KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE ? viewport.getBackToFrontOrder() : viewport.getFrontToBackOrder(); const int *childOctreeOrder = renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT || renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES || renderPass == KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE ? viewport.getBackToFrontOrder() : viewport.getFrontToBackOrder();
for(int i=0; i<8; i++) { for(int i=0; i<8; i++) {
render(pOctreeNode->getChildren()[childOctreeOrder[i]], visibleBounds, pCamera, lights, viewport, renderPass, remainingOctrees, remainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false); render(pOctreeNode->getChildren()[childOctreeOrder[i]], visibleBounds, pCamera, lights, viewport, renderPass, remainingOctrees, remainingOctreesTestResults, remainingOctreesTestResultsOnly, false, false);
} }
// Remove lights added at this octree level from the stack // Remove lights added at this octree level from the stack

View File

@@ -62,9 +62,9 @@ public:
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
void render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds); void render(KRCamera *pCamera, std::map<KRAABB, int> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass);
void render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleBounds, KRCamera *pCamera, std::vector<KRLight *> lights, const KRViewport &viewport, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, std::set<KRAABB> &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly); void render(KROctreeNode *pOctreeNode, std::map<KRAABB, int> &visibleBounds, KRCamera *pCamera, std::vector<KRLight *> lights, const KRViewport &viewport, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly);
#endif #endif

View File

@@ -154,14 +154,7 @@ void KRViewport::calculateDerivedValues()
} }
const std::set<KRAABB> &KRViewport::getVisibleBounds() std::map<KRAABB, int> &KRViewport::getVisibleBounds()
{ {
return m_visibleBounds; return m_visibleBounds;
} }
void KRViewport::setVisibleBounds(const std::set<KRAABB> visibleBounds)
{
m_visibleBounds = visibleBounds;
}

View File

@@ -12,6 +12,7 @@
#include "KRVector2.h" #include "KRVector2.h"
#include "KRMat4.h" #include "KRMat4.h"
#include "KRAABB.h" #include "KRAABB.h"
#include <map.h>
class KRLight; class KRLight;
@@ -38,8 +39,7 @@ public:
// Overload assignment operator // Overload assignment operator
KRViewport& operator=(const KRViewport &v); KRViewport& operator=(const KRViewport &v);
const std::set<KRAABB> &getVisibleBounds(); std::map<KRAABB, int> &getVisibleBounds();
void setVisibleBounds(const std::set<KRAABB> visibleBounds);
const std::set<KRLight *> &getVisibleLights(); const std::set<KRLight *> &getVisibleLights();
void setVisibleLights(const std::set<KRLight *> visibleLights); void setVisibleLights(const std::set<KRLight *> visibleLights);
@@ -62,7 +62,7 @@ private:
void calculateDerivedValues(); void calculateDerivedValues();
std::set<KRAABB> m_visibleBounds; // AABB's that output fragments in the last frame std::map<KRAABB, int> m_visibleBounds; // AABB's that output fragments in the last frame
}; };
#endif #endif