]> git.tdb.fi Git - libs/gl.git/blobdiff - source/render/occludedscene.cpp
Check the flat qualifier from the correct member
[libs/gl.git] / source / render / occludedscene.cpp
index 7c043fa691c5ab578fc7da430244db471632bdc0..cb37a60e924eb266624f5762e0a990c0e23c5a2d 100644 (file)
@@ -1,11 +1,10 @@
-#include <algorithm>
-#include <msp/gl/extensions/arb_occlusion_query.h>
-#include <msp/gl/extensions/arb_occlusion_query2.h>
+#include <msp/core/algorithm.h>
 #include "camera.h"
+#include "mesh.h"
 #include "occludedscene.h"
+#include "program.h"
 #include "renderer.h"
 #include "resources.h"
-#include "sphere.h"
 
 using namespace std;
 
@@ -14,33 +13,30 @@ namespace GL {
 
 OccludedScene::OccludedScene():
        bounding_mesh(Resources::get_global().get<Mesh>("_occluder.mesh")),
-       bounding_shader(Resources::get_global().get<Program>("_occluder.glsl.shader")),
-       occluder_min_size(0.25f),
-       cache_dirty(false)
+       bounding_shader(Resources::get_global().get<Program>("occluder.glsl.shader")),
+       queries(OCCLUSION_QUERY, 0)
 {
-       static Require req(ARB_occlusion_query);
-       static Require req2(ARB_occlusion_query2);
-}
-
-OccludedScene::~OccludedScene()
-{
-       vector<unsigned> 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()<renderables.size())
-       {
-               unsigned old_size = occluded_cache.size();
-               occluded_cache.resize(renderables.size());
-               vector<unsigned> new_queries(occluded_cache.size()-old_size);
-               glGenQueries(new_queries.size(), &new_queries[0]);
-               for(unsigned i=0; i<new_queries.size(); ++i)
-                       occluded_cache[old_size+i].query = new_queries[i];
-       }
+       if(queries.get_size()<content.size())
+               queries.resize(content.size());
+       if(occluded_cache.size()<content.size())
+               occluded_cache.resize(content.size());
 
-       OccludedArray::iterator j = occluded_cache.begin();
-       for(RenderableSet::iterator i=renderables.begin(); i!=renderables.end(); ++i, ++j)
-               j->renderable = *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, Tag tag) const
 {
-       if(renderables.empty())
+       if(content.empty())
                return;
 
        populate_cache();
@@ -93,8 +84,8 @@ void OccludedScene::render(Renderer &renderer, 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, 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, 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, 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