X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Foccludedscene.cpp;h=b3219123e8a2ed777d1a3a75d3691864e943712b;hp=8a3b74262430fcc134884b04c8d17c17bd8fd5a3;hb=HEAD;hpb=d31b672d002c685d15f01a59c17c99a8d164d13e diff --git a/source/occludedscene.cpp b/source/occludedscene.cpp deleted file mode 100644 index 8a3b7426..00000000 --- a/source/occludedscene.cpp +++ /dev/null @@ -1,191 +0,0 @@ -#include -#include -#include -#include "camera.h" -#include "occludedscene.h" -#include "programbuilder.h" -#include "renderer.h" -#include "sphere.h" - -using namespace std; - -namespace Msp { -namespace GL { - -OccludedScene::OccludedScene(): - bounding_mesh((VERTEX3, NORMAL3)), - bounding_shader("occluder.glsl"), - occluder_min_size(0.25f), - cache_dirty(false) -{ - static Require req(ARB_occlusion_query); - static Require req2(ARB_occlusion_query2); - - /* Use a slightly larger radius to ensure that all parts of the renderable - fit inside the icosahedron */ - IcoSphereBuilder(1.26f, 1).build(bounding_mesh); - bounding_mesh.set_winding(&WindingTest::counterclockwise()); -} - -OccludedScene::~OccludedScene() -{ - vector queries; - queries.reserve(occluded_cache.size()); - for(OccludedArray::iterator i=occluded_cache.begin(); i!=occluded_cache.end(); ++i) - queries.push_back(i->query); - glDeleteQueries(queries.size(), &queries[0]); -} - -void OccludedScene::add(Renderable &r) -{ - renderables.insert(&r); - cache_dirty = true; -} - -void OccludedScene::remove(Renderable &r) -{ - renderables.erase(&r); - cache_dirty = true; -} - -void OccludedScene::populate_cache() const -{ - if(!cache_dirty) - return; - - if(occluded_cache.size() new_queries(occluded_cache.size()-old_size); - glGenQueries(new_queries.size(), &new_queries[0]); - for(unsigned i=0; irenderable = *i; - for(; j!=occluded_cache.end(); ++j) - { - j->renderable = 0; - j->in_frustum = false; - } - - cache_dirty = false; -} - -void OccludedScene::setup_frame(Renderer &renderer) -{ - populate_cache(); - for(OccludedArray::const_iterator i=occluded_cache.begin(); i!=occluded_cache.end(); ++i) - i->renderable->setup_frame(renderer); -} - -void OccludedScene::finish_frame() -{ - for(OccludedArray::const_iterator i=occluded_cache.begin(); i!=occluded_cache.end(); ++i) - i->renderable->finish_frame(); -} - -void OccludedScene::render(Renderer &renderer, const Tag &tag) const -{ - if(renderables.empty()) - return; - - populate_cache(); - - const Camera *camera = renderer.get_camera(); - if(!camera) - { - for(OccludedArray::const_iterator i=occluded_cache.begin(); i!=occluded_cache.end(); ++i) - renderer.render(*i->renderable, tag); - return; - } - - const Vector3 &camera_pos = camera->get_position(); - const Vector3 &look_dir = camera->get_look_direction(); - float near_clip = camera->get_near_clip(); - float frustum_h = tan(camera->get_field_of_view()/2.0f)*2.0f; - - // Perform frustum culling and render any major occluders - bool use_frustum = setup_frustum(renderer); - for(OccludedArray::iterator i=occluded_cache.begin(); (i!=occluded_cache.end() && i->renderable); ++i) - { - i->in_frustum = (!use_frustum || !frustum_cull(*i->renderable)); - if(!i->in_frustum) - continue; - - const Matrix *matrix = i->renderable->get_matrix(); - i->bounding_sphere = i->renderable->get_bounding_sphere(); - if(matrix && i->bounding_sphere) - { - float depth = dot(*matrix*i->bounding_sphere->get_center()-camera_pos, look_dir); - float size = i->bounding_sphere->get_radius()*2/max(depth, near_clip); - i->occluder = (size>frustum_h*occluder_min_size); - } - else - // If the size can't be calculated, treat it as occluder - i->occluder = true; - - if(i->occluder) - renderer.render(*i->renderable, tag); - } - - // Move all objects within the frustum to the beginning of the array - for(OccludedArray::iterator i=occluded_cache.begin(), j=i+renderables.size()-1; i!=j; ) - { - if(i->in_frustum) - ++i; - else if(j->in_frustum) - swap(*i, *j); - else - --j; - } - - { - Renderer::Push push(renderer); - renderer.set_shader_program(&bounding_shader); - - glColorMask(false, false, false, false); - glDepthMask(false); - - // Fire off the occlusion queries - for(OccludedArray::const_iterator i=occluded_cache.begin(); (i!=occluded_cache.end() && i->in_frustum); ++i) - if(!i->occluder) - { - glBeginQuery(GL_ANY_SAMPLES_PASSED, i->query); - Renderer::Push push2(renderer); - renderer.transform(Matrix(*i->renderable->get_matrix()) - .translate(i->bounding_sphere->get_center()) - .scale(i->bounding_sphere->get_radius())); - bounding_mesh.draw(renderer); - glEndQuery(GL_ANY_SAMPLES_PASSED); - } - - glColorMask(true, true, true, true); - glDepthMask(true); - } - - // Render anything that has a chance of being visible - for(OccludedArray::const_iterator i=occluded_cache.begin(); (i!=occluded_cache.end() && i->in_frustum); ++i) - if(!i->occluder) - { - unsigned any_passed = 0; - glGetQueryObjectuiv(i->query, GL_QUERY_RESULT, &any_passed); - if(any_passed) - renderer.render(*i->renderable, tag); - } -} - - -OccludedScene::OccludedRenderable::OccludedRenderable(): - renderable(0), - bounding_sphere(0), - in_frustum(false), - occluder(false), - query(0) -{ } - -} // namespace GL -} // namespace Msp