From 47c305b00cc92169d826b0ca5268c92b1d019e28 Mon Sep 17 00:00:00 2001 From: David Gow Date: Sun, 6 Jul 2014 13:41:16 +0800 Subject: [PATCH] Render part of a document (incorrectly) on the GPU MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 | 21 +++++++++++++++------ src/objectrenderer.h | 4 ++-- src/view.cpp | 5 ++++- 3 files changed, 21 insertions(+), 9 deletions(-) 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); -- 2.20.1