X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Frender%2Foccludedscene.cpp;h=644e380d15ab10a25917571fd29d61522040a99f;hp=b3346385a3a9525765fd8c727ec5cb140d541e45;hb=HEAD;hpb=dccad64b2ec82249d850b9745614042171499972 diff --git a/source/render/occludedscene.cpp b/source/render/occludedscene.cpp index b3346385..cb37a60e 100644 --- a/source/render/occludedscene.cpp +++ b/source/render/occludedscene.cpp @@ -1,46 +1,42 @@ -#include -#include -#include +#include #include "camera.h" +#include "mesh.h" #include "occludedscene.h" +#include "program.h" #include "renderer.h" #include "resources.h" -#include "sphere.h" using namespace std; namespace Msp { namespace GL { -OccludedScene::OccludedScene(Resources &resources): - bounding_mesh(resources.get("_occluder.mesh")), - bounding_shader(resources.get("_occluder.glsl.shader")), - occluder_min_size(0.25f), - cache_dirty(false) +OccludedScene::OccludedScene(): + bounding_mesh(Resources::get_global().get("_occluder.mesh")), + bounding_shader(Resources::get_global().get("occluder.glsl.shader")), + queries(OCCLUSION_QUERY, 0) { - static Require req(ARB_occlusion_query); - static Require req2(ARB_occlusion_query2); -} - -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]); + no_color_write.write_mask = WRITE_NONE; } void OccludedScene::add(Renderable &r) { - renderables.insert(&r); - cache_dirty = true; + auto i = lower_bound(content, &r); + if(i==content.end() || *i!=&r) + { + content.insert(i, &r); + cache_dirty = true; + } } void OccludedScene::remove(Renderable &r) { - renderables.erase(&r); - cache_dirty = true; + auto i = lower_bound(content, &r); + if(i!=content.end() && *i==&r) + { + content.erase(i); + cache_dirty = true; + } } void OccludedScene::populate_cache() const @@ -48,19 +44,14 @@ 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; + auto j = occluded_cache.begin(); + for(Renderable *r: content) + j++->renderable = r; for(; j!=occluded_cache.end(); ++j) { j->renderable = 0; @@ -73,19 +64,19 @@ void OccludedScene::populate_cache() const 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); + for(const OccludedRenderable &o: occluded_cache) + o.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(); + for(const OccludedRenderable &o: occluded_cache) + o.renderable->finish_frame(); } -void OccludedScene::render(Renderer &renderer, const Tag &tag) const +void OccludedScene::render(Renderer &renderer, Tag tag) const { - if(renderables.empty()) + if(content.empty()) return; populate_cache(); @@ -93,8 +84,8 @@ void OccludedScene::render(Renderer &renderer, const Tag &tag) const 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); + for(const OccludedRenderable &o: occluded_cache) + o.renderable->render(renderer, tag); return; } @@ -104,10 +95,9 @@ void OccludedScene::render(Renderer &renderer, const Tag &tag) const 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) + for(auto i=occluded_cache.begin(); (i!=occluded_cache.end() && i->renderable); ++i) { - i->in_frustum = (!use_frustum || !frustum_cull(*i->renderable)); + i->in_frustum = camera->is_in_frustum(*i->renderable); if(!i->in_frustum) continue; @@ -124,11 +114,11 @@ void OccludedScene::render(Renderer &renderer, const Tag &tag) const i->occluder = true; if(i->occluder) - renderer.render(*i->renderable, tag); + i->renderable->render(renderer, 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; ) + for(auto i=occluded_cache.begin(), j=i+content.size()-1; i!=j; ) { if(i->in_frustum) ++i; @@ -142,45 +132,28 @@ void OccludedScene::render(Renderer &renderer, const Tag &tag) const Renderer::Push push(renderer); renderer.set_shader_program(&bounding_shader); - glColorMask(false, false, false, false); - glDepthMask(false); + renderer.set_blend(&no_color_write); + // XXX Preserve existing depth test predicate + renderer.set_depth_test(&no_depth_write); // Fire off the occlusion queries - for(OccludedArray::const_iterator i=occluded_cache.begin(); (i!=occluded_cache.end() && i->in_frustum); ++i) + for(auto i=occluded_cache.begin(); (i!=occluded_cache.end() && i->in_frustum); ++i) if(!i->occluder) { - glBeginQuery(GL_ANY_SAMPLES_PASSED, i->query); + QueryPool::Activate activate_query(renderer, queries, i-occluded_cache.begin()); Renderer::Push push2(renderer); - renderer.transform(Matrix(*i->renderable->get_matrix()) + renderer.set_matrix(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); - } + for(auto i=occluded_cache.begin(); (i!=occluded_cache.end() && i->in_frustum); ++i) + if(!i->occluder && queries.get_result(i-occluded_cache.begin())) + i->renderable->render(renderer, tag); } - -OccludedScene::OccludedRenderable::OccludedRenderable(): - renderable(0), - bounding_sphere(0), - in_frustum(false), - occluder(false), - query(0) -{ } - } // namespace GL } // namespace Msp