]> git.tdb.fi Git - libs/gl.git/blobdiff - source/occludedscene.cpp
Do not attempt to legacy-bind texture targets which do not support it
[libs/gl.git] / source / occludedscene.cpp
index 8d05f7c18161d8af7833fd1f62cae4f9effc21ad..b3219123e8a2ed777d1a3a75d3691864e943712b 100644 (file)
@@ -1,38 +1,25 @@
 #include <algorithm>
 #include <msp/gl/extensions/arb_occlusion_query.h>
+#include <msp/gl/extensions/arb_occlusion_query2.h>
 #include "camera.h"
 #include "occludedscene.h"
+#include "programbuilder.h"
 #include "renderer.h"
 #include "sphere.h"
 
 using namespace std;
 
-namespace {
-
-const char vshader[] =
-       "void main()\n"
-       "{\n"
-       "       gl_Position = gl_ProjectionMatrix*gl_ModelViewMatrix*gl_Vertex;\n"
-       "}";
-
-const char fshader[] =
-       "void main()\n"
-       "{\n"
-       "       gl_FragColor = vec4(1.0);\n"
-       "}";
-
-}
-
 namespace Msp {
 namespace GL {
 
 OccludedScene::OccludedScene():
        bounding_mesh((VERTEX3, NORMAL3)),
-       bounding_shader(vshader, fshader),
+       bounding_shader(ProgramBuilder::StandardFeatures()),
        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 */
@@ -49,53 +36,71 @@ OccludedScene::~OccludedScene()
        glDeleteQueries(queries.size(), &queries[0]);
 }
 
-void OccludedScene::add(const Renderable &r)
+void OccludedScene::add(Renderable &r)
 {
        renderables.insert(&r);
        cache_dirty = true;
 }
 
-void OccludedScene::remove(const Renderable &r)
+void OccludedScene::remove(Renderable &r)
 {
        renderables.erase(&r);
        cache_dirty = true;
 }
 
-void OccludedScene::render(Renderer &renderer, const Tag &tag) const
+void OccludedScene::populate_cache() const
 {
-       if(renderables.empty())
+       if(!cache_dirty)
                return;
 
-       const Camera *camera = renderer.get_camera();
-       if(!camera)
+       if(occluded_cache.size()<renderables.size())
        {
-               for(RenderableSet::const_iterator i=renderables.begin(); i!=renderables.end(); ++i)
-                       renderer.render(**i, tag);
-               return;
+               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(cache_dirty)
+       OccludedArray::iterator j = occluded_cache.begin();
+       for(RenderableSet::iterator i=renderables.begin(); i!=renderables.end(); ++i, ++j)
+               j->renderable = *i;
+       for(; j!=occluded_cache.end(); ++j)
        {
-               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];
-               }
+               j->renderable = 0;
+               j->in_frustum = false;
+       }
 
-               OccludedArray::iterator j = occluded_cache.begin();
-               for(RenderableSet::iterator i=renderables.begin(); i!=renderables.end(); ++i, ++j)
-                       j->renderable = *i;
-               for(; j!=occluded_cache.end(); ++j)
-               {
-                       j->renderable = 0;
-                       j->in_frustum = false;
-               }
+       cache_dirty = 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();
@@ -149,13 +154,13 @@ void OccludedScene::render(Renderer &renderer, const Tag &tag) const
                for(OccludedArray::const_iterator i=occluded_cache.begin(); (i!=occluded_cache.end() && i->in_frustum); ++i)
                        if(!i->occluder)
                        {
-                               glBeginQuery(GL_SAMPLES_PASSED, i->query);
+                               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_SAMPLES_PASSED);
+                               glEndQuery(GL_ANY_SAMPLES_PASSED);
                        }
 
                glColorMask(true, true, true, true);
@@ -166,9 +171,9 @@ void OccludedScene::render(Renderer &renderer, const Tag &tag) const
        for(OccludedArray::const_iterator i=occluded_cache.begin(); (i!=occluded_cache.end() && i->in_frustum); ++i)
                if(!i->occluder)
                {
-                       int samples_passed;
-                       glGetQueryObjectiv(i->query, GL_QUERY_RESULT, &samples_passed);
-                       if(samples_passed>0)
+                       unsigned any_passed = 0;
+                       glGetQueryObjectuiv(i->query, GL_QUERY_RESULT, &any_passed);
+                       if(any_passed)
                                renderer.render(*i->renderable, tag);
                }
 }