Render part of a document (incorrectly) on the GPU
authorDavid Gow <david@ingeniumdigital.com>
Sun, 6 Jul 2014 05:41:16 +0000 (13:41 +0800)
committerDavid Gow <david@ingeniumdigital.com>
Sun, 6 Jul 2014 05:41:16 +0000 (13:41 +0800)
In order to get QuadTrees working, we're going to need to
render small "parts" of a document individually. The way this works
is that, when calling RenderObjectsOnGPU, we now pass a range of
object IDs. The ObjectRenderer will then find (in O(N) time, sadly)
the range of indices needed for that object type and then render those.

B├ęziers, and other objects which rely on the ObjectID on the GPU being
correct might be broken by this (in some cases), though if so it shouldn't
be too hard to fix by passing an offset in as a uniform.

src/objectrenderer.cpp
src/objectrenderer.h
src/view.cpp

index ac25c4a..86b6430 100644 (file)
@@ -29,13 +29,16 @@ ObjectRenderer::ObjectRenderer(const ObjectType & type,
 /**
  * Render using GPU
  */
-void ObjectRenderer::RenderUsingGPU()
+void ObjectRenderer::RenderUsingGPU(unsigned first_obj_id, unsigned last_obj_id)
 {
-       if (!m_shader_program.Valid())
-               Warn("Shader is invalid (objects are of type %d)", m_type);
+       unsigned first_index = 0;
+       while (m_indexes[first_index] < first_obj_id*2) first_index += 2;
+       unsigned last_index = first_index;
+       while (m_indexes[last_index] < last_obj_id*2) last_index += 2;
+
        m_shader_program.Use();
        m_ibo.Bind();
-       glDrawElements(GL_LINES, m_indexes.size()*2, GL_UNSIGNED_INT, 0);
+       glDrawElements(GL_LINES, (last_index-first_index)*2, GL_UNSIGNED_INT, (GLvoid*)(first_index*sizeof(uint32_t)));
 }
 
 
@@ -288,15 +291,21 @@ void BezierRenderer::PrepareBezierGPUBuffer(const Objects& objects)
        glActiveTexture(GL_TEXTURE0);
 }
 
-void BezierRenderer::RenderUsingGPU()
+void BezierRenderer::RenderUsingGPU(unsigned first_obj_id, unsigned last_obj_id)
 {
        if (!m_shader_program.Valid())
                Warn("Shader is invalid (objects are of type %d)", m_type);
+
+       unsigned first_index = 0;
+       while (m_indexes[first_index] < first_obj_id*2) first_index += 2;
+       unsigned last_index = first_index;
+       while (m_indexes[last_index] < last_obj_id*2) last_index += 2;
+
        m_shader_program.Use();
        glUniform1i(m_shader_program.GetUniformLocation("bezier_buffer_texture"), 0);
        glUniform1i(m_shader_program.GetUniformLocation("bezier_id_buffer_texture"), 1);
        m_ibo.Bind();
-       glDrawElements(GL_LINES, m_indexes.size()*2, GL_UNSIGNED_INT, 0);
+       glDrawElements(GL_LINES, (last_index-first_index)*2, GL_UNSIGNED_INT, (GLvoid*)(first_index*sizeof(uint32_t)));
 }
 
 /**
index 6f29add..60cba6c 100644 (file)
@@ -34,7 +34,7 @@ namespace IPDF
                         * Use the GPU to render the objects - GLSL shader approach
                         * This way is definitely faster, but subject to the GPU's limitations on precision
                         */
-                       virtual void RenderUsingGPU();
+                       virtual void RenderUsingGPU(unsigned first_obj_id, unsigned last_obj_id);
 
                        /** 
                         * Use the CPU to render the objects - "make a bitmap and convert it to a texture" approach
@@ -110,7 +110,7 @@ namespace IPDF
                public:
                        BezierRenderer() : ObjectRenderer(BEZIER, "shaders/rect_vert.glsl", "shaders/rect_frag.glsl", "shaders/bezier_texbuf_geom.glsl") {}
                        virtual ~BezierRenderer() {}
-                       virtual void RenderUsingGPU(); 
+                       virtual void RenderUsingGPU(unsigned first_obj_id, unsigned last_obj_id); 
                        virtual void RenderUsingCPU(const Objects & objects, const View & view, const CPURenderTarget & target);
                        void PrepareBezierGPUBuffer(const Objects & objects);
                private:
index 2d9d0b3..4dbe5df 100644 (file)
@@ -162,6 +162,9 @@ void View::Render(int width, int height)
        m_cached_display.Bind(); //NOTE: This is redundant; Clear already calls Bind
        m_cached_display.Clear();
 
+       // When we QuadTree, this will be magic.
+       int first_obj = 0;
+       int last_obj = m_document.ObjectCount();
 
        // Render using GPU
        if (m_use_gpu_rendering) 
@@ -178,7 +181,7 @@ void View::Render(int width, int height)
        
                for (unsigned i = 0; i < m_object_renderers.size(); ++i)
                {
-                       m_object_renderers[i]->RenderUsingGPU();
+                       m_object_renderers[i]->RenderUsingGPU(first_obj, last_obj);
                }
                
                glDisableVertexAttribArray(0);

UCC git Repository :: git.ucc.asn.au