X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=blobdiff_plain;f=src%2Fview.cpp;h=2d9d0b39dcfe815488c42f0b89406a555e8f6dec;hp=38b2c17a63edfd5fa51f016e5a2ff56d06127b4a;hb=35e78b378435e37ffdb6e53a97f6fa0998999f67;hpb=f8ef964f021d1d6da6ea46bbb1fe8f0250a5be8c diff --git a/src/view.cpp b/src/view.cpp index 38b2c17..2d9d0b3 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; } /** @@ -86,7 +88,7 @@ void View::ScaleAroundPoint(Real x, Real y, Real scale_amount) m_bounds.y = y - top; m_bounds.w *= scale_amount; m_bounds.h *= scale_amount; - Debug("View Bounds => %s", m_bounds.Str().c_str()); + //Debug("Scale at {%s, %s} by %s View Bounds => %s", x.Str().c_str(), y.Str().c_str(), scale_amount.Str().c_str(), m_bounds.Str().c_str()); if (!m_use_gpu_transform) m_buffer_dirty = true; m_bounds_dirty = true; @@ -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 @@ -145,16 +147,21 @@ void View::Render(int width, int height) if (m_use_gpu_transform) { - GLfloat glbounds[] = {static_cast(Float(m_bounds.x)), static_cast(Float(m_bounds.y)), static_cast(Float(m_bounds.w)), static_cast(Float(m_bounds.h))}; - m_bounds_ubo.Upload(sizeof(float)*4, glbounds); + GLfloat glbounds[] = {static_cast(Float(m_bounds.x)), static_cast(Float(m_bounds.y)), static_cast(Float(m_bounds.w)), static_cast(Float(m_bounds.h)), + 0.0, 0.0, 640.0, 480.0}; + m_bounds_ubo.Upload(sizeof(float)*8, glbounds); } else { - GLfloat glbounds[] = {0.0f, 0.0f, 1.0f, 1.0f}; - m_bounds_ubo.Upload(sizeof(float)*4, glbounds); + GLfloat glbounds[] = {0.0f, 0.0f, 1.0f, 1.0f, + 0.0f, 0.0f, 640.0f, 480.0f}; + m_bounds_ubo.Upload(sizeof(float)*8, glbounds); } 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 +189,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 +215,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 +259,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 +282,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; }