From: David Gow Date: Sun, 6 Jul 2014 05:41:16 +0000 (+0800) Subject: Render part of a document (incorrectly) on the GPU X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=47c305b00cc92169d826b0ca5268c92b1d019e28;p=ipdf%2Fcode.git Render part of a document (incorrectly) on the GPU 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. --- diff --git a/src/objectrenderer.cpp b/src/objectrenderer.cpp index ac25c4a..86b6430 100644 --- a/src/objectrenderer.cpp +++ b/src/objectrenderer.cpp @@ -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))); } /** diff --git a/src/objectrenderer.h b/src/objectrenderer.h index 6f29add..60cba6c 100644 --- a/src/objectrenderer.h +++ b/src/objectrenderer.h @@ -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: diff --git a/src/view.cpp b/src/view.cpp index 2d9d0b3..4dbe5df 100644 --- a/src/view.cpp +++ b/src/view.cpp @@ -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);