X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=blobdiff_plain;f=src%2Fview.cpp;h=4bba59163d21554a57d9c4520ac456a9c390f194;hp=38b2c17a63edfd5fa51f016e5a2ff56d06127b4a;hb=09fc4981be389620d3c269beacf0630de45871bb;hpb=f8ef964f021d1d6da6ea46bbb1fe8f0250a5be8c diff --git a/src/view.cpp b/src/view.cpp index 38b2c17..4bba591 100644 --- a/src/view.cpp +++ b/src/view.cpp @@ -1,6 +1,6 @@ #include "view.h" #include "bufferbuilder.h" - +#include "screen.h" #include "gl_core44.h" using namespace IPDF; @@ -13,18 +13,19 @@ using namespace std; * @param bounds - Initial bounds of the View * @param colour - Colour to use for rendering this view. TODO: Make sure this actually works, or just remove it */ -View::View(Document & document, const Rect & bounds, const Colour & colour) +View::View(Document & document, Screen & screen, const Rect & bounds, const Colour & colour) : m_use_gpu_transform(USE_GPU_TRANSFORM), m_use_gpu_rendering(USE_GPU_RENDERING), m_bounds_dirty(true), m_buffer_dirty(true), - m_render_dirty(true), m_document(document), m_cached_display(), m_bounds(bounds), m_colour(colour), m_bounds_ubo(), - m_objbounds_vbo(), m_object_renderers(NUMBER_OF_OBJECT_TYPES) + m_render_dirty(true), m_document(document), m_screen(screen), m_cached_display(), m_bounds(bounds), m_colour(colour), m_bounds_ubo(), + m_objbounds_vbo(), m_object_renderers(NUMBER_OF_OBJECT_TYPES), m_cpu_rendering_pixels(NULL) { Debug("View Created - Bounds => {%s}", m_bounds.Str().c_str()); // Create ObjectRenderers - new's match delete's in View::~View - // Ok, look, this may seem disgusting, but go look at View::PrepareRender before you murder me + //TODO: Don't forget to put new renderers here or things will be segfaultastic m_object_renderers[RECT_FILLED] = new RectFilledRenderer(); m_object_renderers[RECT_OUTLINE] = new RectOutlineRenderer(); m_object_renderers[CIRCLE_FILLED] = new CircleFilledRenderer(); + m_object_renderers[BEZIER] = new BezierRenderer(); // To add rendering for a new type of object; // 1. Add enum to ObjectType in ipdf.h @@ -41,9 +42,10 @@ View::~View() { for (unsigned i = 0; i < m_object_renderers.size(); ++i) { - //delete m_object_renderers[i]; + delete m_object_renderers[i]; // delete's match new's in constructor } m_object_renderers.clear(); + delete [] m_cpu_rendering_pixels; } /** @@ -118,7 +120,9 @@ Rect View::TransformToViewCoords(const Rect& inp) const void View::Render(int width, int height) { // View dimensions have changed (ie: Window was resized) - if (width != m_cached_display.GetWidth() || height != m_cached_display.GetHeight()) + int prev_width = m_cached_display.GetWidth(); + int prev_height = m_cached_display.GetHeight(); + if (width != prev_width || height != prev_height) { m_cached_display.Create(width, height); m_bounds_dirty = true; @@ -133,8 +137,6 @@ void View::Render(int width, int height) } // Bind FrameBuffer for rendering, and clear it - m_cached_display.Bind(); //NOTE: This is redundant; Clear already calls Bind - m_cached_display.Clear(); if (m_render_dirty) // document has changed @@ -155,6 +157,9 @@ void View::Render(int width, int height) } m_bounds_dirty = false; + m_cached_display.Bind(); //NOTE: This is redundant; Clear already calls Bind + m_cached_display.Clear(); + // Render using GPU if (m_use_gpu_rendering) @@ -182,10 +187,25 @@ void View::Render(int width, int height) } else // Rasterise on CPU then blit texture to GPU { + // Dynamically resize CPU rendering target pixels if needed + if (m_cpu_rendering_pixels == NULL || width*height > prev_width*prev_height) + { + delete [] m_cpu_rendering_pixels; + m_cpu_rendering_pixels = new uint8_t[width*height*4]; + if (m_cpu_rendering_pixels == NULL) + Fatal("Could not allocate %d*%d*4 = %d bytes for cpu rendered pixels", width, height, width*height*4); + } + // Clear CPU rendering pixels + for (int i = 0; i < width*height*4; ++i) + m_cpu_rendering_pixels[i] = 255; + for (unsigned i = 0; i < m_object_renderers.size(); ++i) { - m_object_renderers[i]->RenderUsingCPU(); + m_object_renderers[i]->RenderUsingCPU(m_document.m_objects, *this, {m_cpu_rendering_pixels, width, height}); } + m_screen.RenderPixels(0,0,width, height, m_cpu_rendering_pixels); //TODO: Make this work :( + // Debug for great victory (do something similar for GPU and compare?) + ObjectRenderer::SaveBMP({m_cpu_rendering_pixels, width, height}, "cpu_rendering_last_frame.bmp"); } m_cached_display.UnBind(); // resets render target to the screen m_cached_display.Blit(); // blit FrameBuffer to screen @@ -193,7 +213,6 @@ void View::Render(int width, int height) void View::UpdateObjBoundsVBO() { - Debug("Called"); m_objbounds_vbo.Invalidate(); m_objbounds_vbo.SetType(GraphicsBuffer::BufferTypeVertex); if (m_use_gpu_transform) @@ -238,7 +257,9 @@ void View::UpdateObjBoundsVBO() */ void View::PrepareRender() { + Debug("Recreate buffers with %u objects", m_document.ObjectCount()); // Prepare bounds vbo + m_bounds_ubo.Invalidate(); m_bounds_ubo.SetType(GraphicsBuffer::BufferTypeUniform); m_bounds_ubo.SetUsage(GraphicsBuffer::BufferUsageStreamDraw); @@ -259,12 +280,15 @@ void View::PrepareRender() ObjectType type = m_document.m_objects.types[id]; m_object_renderers.at(type)->AddObjectToBuffers(id); // Use at() in case the document is corrupt TODO: Better error handling? // (Also, Wow I just actually used std::vector::at()) + // (Also, I just managed to make it throw an exception because I'm a moron) + Debug("Object of type %d", type); } // Finish the buffers for (unsigned i = 0; i < m_object_renderers.size(); ++i) { m_object_renderers[i]->FinaliseBuffers(); - } + } + dynamic_cast(m_object_renderers[BEZIER])->PrepareBezierGPUBuffer(m_document.m_objects); m_render_dirty = false; }