My eyes, they burn! Also runs faster, slightly less buggy.
authorDavid Gow <david@ingeniumdigital.com>
Tue, 21 Oct 2014 05:55:52 +0000 (13:55 +0800)
committerDavid Gow <david@ingeniumdigital.com>
Tue, 21 Oct 2014 05:55:52 +0000 (13:55 +0800)
src/bezier.cpp
src/controlpanel.cpp
src/debugscript.cpp
src/document.cpp
src/graphicsbuffer.cpp
src/objectrenderer.cpp
src/profiler.h
src/quadtree.h
src/view.cpp

index 19d89af..1c11235 100644 (file)
@@ -96,12 +96,16 @@ vector<BReal> SolveCubic(const BReal & a, const BReal & b, const BReal & c, cons
        //Debug("%u turning points", turns.size());
        for (unsigned i = 1; i < turns.size(); ++i)
        {
-               tu = turns[i];
+               if (tl > max) break;
+               tu = std::min(turns[i],tu);
                CubicSolveSegment(roots, a, b, c, d, tl, tu,delta);
                tl = turns[i];
        }
-       tu = max;
-       CubicSolveSegment(roots, a, b, c, d, tl, tu,delta);
+       if (tu < max)
+       {
+               tu = max;
+               CubicSolveSegment(roots, a, b, c, d, tl, tu,delta);
+       }
        return roots;
 }
 
index 0a50114..462105f 100644 (file)
@@ -315,6 +315,10 @@ void ControlPanel::InsertTextIntoDocument()
        m_doc.AddText(msg, scale, xx, yy);
 #ifndef QUADTREE_DISABLED
        m_doc.PropagateQuadChanges(m_view.GetCurrentQuadtreeNode());
+       // We may have split the object across up-to four nodes, so try the neighbouring nodes.
+       m_doc.PropagateQuadChanges(m_doc.GetQuadTree().GetNeighbour(m_view.GetCurrentQuadtreeNode(), 0, 1, 0));
+       m_doc.PropagateQuadChanges(m_doc.GetQuadTree().GetNeighbour(m_view.GetCurrentQuadtreeNode(), 1, 0, 0));
+       m_doc.PropagateQuadChanges(m_doc.GetQuadTree().GetNeighbour(m_view.GetCurrentQuadtreeNode(), 1, 1, 0));
 #endif
        m_view.ForceRenderDirty();
        m_view.ForceBufferDirty();
@@ -335,6 +339,10 @@ void ControlPanel::InsertSVGIntoDocument()
        m_doc.ParseSVG(m_text_edit->toPlainText().toStdString(), bounds);
 #ifndef QUADTREE_DISABLED
        m_doc.PropagateQuadChanges(m_view.GetCurrentQuadtreeNode());
+       // We may have split the object across up-to four nodes, so try the neighbouring nodes.
+       m_doc.PropagateQuadChanges(m_doc.GetQuadTree().GetNeighbour(m_view.GetCurrentQuadtreeNode(), 0, 1, 0));
+       m_doc.PropagateQuadChanges(m_doc.GetQuadTree().GetNeighbour(m_view.GetCurrentQuadtreeNode(), 1, 0, 0));
+       m_doc.PropagateQuadChanges(m_doc.GetQuadTree().GetNeighbour(m_view.GetCurrentQuadtreeNode(), 1, 1, 0));
 #endif
        m_view.ForceRenderDirty();
        m_view.ForceBufferDirty();
@@ -365,6 +373,10 @@ void ControlPanel::LoadSVGIntoDocument()
        m_doc.LoadSVG(filename.toStdString(), bounds);
 #ifndef QUADTREE_DISABLED
        m_doc.PropagateQuadChanges(m_view.GetCurrentQuadtreeNode());
+       // We may have split the object across up-to four nodes, so try the neighbouring nodes.
+       m_doc.PropagateQuadChanges(m_doc.GetQuadTree().GetNeighbour(m_view.GetCurrentQuadtreeNode(), 0, 1, 0));
+       m_doc.PropagateQuadChanges(m_doc.GetQuadTree().GetNeighbour(m_view.GetCurrentQuadtreeNode(), 1, 0, 0));
+       m_doc.PropagateQuadChanges(m_doc.GetQuadTree().GetNeighbour(m_view.GetCurrentQuadtreeNode(), 1, 1, 0));
 #endif
        m_view.ForceRenderDirty();
        m_view.ForceBufferDirty();
index 64cbf49..dd6a5df 100644 (file)
@@ -262,6 +262,9 @@ bool DebugScript::Execute(View *view, Screen *scr)
                #endif
 #ifndef QUADTREE_DISABLED
                view->Doc().PropagateQuadChanges(view->GetCurrentQuadtreeNode());
+               view->Doc().PropagateQuadChanges(view->Doc().GetQuadTree().GetNeighbour(view->GetCurrentQuadtreeNode(), 0, 1, 0));
+               view->Doc().PropagateQuadChanges(view->Doc().GetQuadTree().GetNeighbour(view->GetCurrentQuadtreeNode(), 1, 0, 0));
+               view->Doc().PropagateQuadChanges(view->Doc().GetQuadTree().GetNeighbour(view->GetCurrentQuadtreeNode(), 1, 1, 0));
 #endif
                currentAction.type = AT_WaitFrame;
                view->ForceRenderDirty();
index 5b04bd2..4a5214a 100644 (file)
@@ -173,7 +173,7 @@ QuadTreeIndex Document::GenQuadChild(QuadTreeIndex parent, QuadTreeNodeChildren
        PROFILE_SCOPE("Document::GenQuadChild()");
        QuadTreeIndex new_index = m_quadtree.nodes.size();
        Debug("-------------- Generating Quadtree Node %d (parent %d, type %d) ----------------------", new_index, parent, type);
-       m_quadtree.nodes.push_back(QuadTreeNode{QUADTREE_EMPTY, QUADTREE_EMPTY, QUADTREE_EMPTY, QUADTREE_EMPTY, parent, type, 0, 0, -1});
+       m_quadtree.nodes.push_back(QuadTreeNode{QUADTREE_EMPTY, QUADTREE_EMPTY, QUADTREE_EMPTY, QUADTREE_EMPTY, parent, type, 0, 0, -1, true});
 
        m_quadtree.nodes[new_index].object_begin = m_objects.bounds.size();
        for (QuadTreeIndex overlay = parent; overlay != -1; overlay = m_quadtree.nodes[overlay].next_overlay)
@@ -215,7 +215,7 @@ void Document::OverlayQuadChildren(QuadTreeIndex orig_parent, QuadTreeIndex pare
        PROFILE_SCOPE("Document::OverlayQuadChildren()");
        QuadTreeIndex new_index = m_quadtree.nodes.size();
        Debug("-------------- Generating Quadtree Node %d (orig %d parent %d, type %d) ----------------------", new_index, orig_parent, parent, type);
-       m_quadtree.nodes.push_back(QuadTreeNode{QUADTREE_EMPTY, QUADTREE_EMPTY, QUADTREE_EMPTY, QUADTREE_EMPTY, orig_parent, type, 0, 0, -1});
+       m_quadtree.nodes.push_back(QuadTreeNode{QUADTREE_EMPTY, QUADTREE_EMPTY, QUADTREE_EMPTY, QUADTREE_EMPTY, orig_parent, type, 0, 0, -1, true});
 
        m_quadtree.nodes[new_index].object_begin = m_objects.bounds.size();
        for (unsigned i = m_quadtree.nodes[parent].object_dirty; i < m_quadtree.nodes[parent].object_end; ++i)
@@ -272,7 +272,7 @@ void Document::OverlayQuadParent(QuadTreeIndex orig_child, QuadTreeIndex child,
 {
        PROFILE_SCOPE("Document::OverlayQuadParent()");
        QuadTreeIndex new_index = m_quadtree.nodes.size();
-       m_quadtree.nodes.push_back(QuadTreeNode{QUADTREE_EMPTY, QUADTREE_EMPTY, QUADTREE_EMPTY, QUADTREE_EMPTY, -1, QTC_UNKNOWN, 0, 0, -1});
+       m_quadtree.nodes.push_back(QuadTreeNode{QUADTREE_EMPTY, QUADTREE_EMPTY, QUADTREE_EMPTY, QUADTREE_EMPTY, -1, QTC_UNKNOWN, 0, 0, -1, true});
 
        m_quadtree.nodes[new_index].object_begin = m_objects.bounds.size();
        m_quadtree.nodes[new_index].object_dirty = m_objects.bounds.size();
@@ -280,7 +280,10 @@ void Document::OverlayQuadParent(QuadTreeIndex orig_child, QuadTreeIndex child,
        {
                for (unsigned i = m_quadtree.nodes[overlay].object_begin; i < m_quadtree.nodes[overlay].object_end; ++i)
                {
-                       m_objects.bounds.push_back(TransformFromQuadChild(m_objects.bounds[i], type));
+                       Rect new_bounds = TransformFromQuadChild(m_objects.bounds[i], type);
+                       // If the object is too small to be seen, discard it.
+                       if (!new_bounds.w || !new_bounds.h) continue;
+                       m_objects.bounds.push_back(new_bounds);
                        m_objects.types.push_back(m_objects.types[i]);
                        m_objects.data_indices.push_back(m_objects.data_indices[i]);
                        m_count++;
@@ -295,6 +298,7 @@ void Document::OverlayQuadParent(QuadTreeIndex orig_child, QuadTreeIndex child,
        QuadTreeIndex prev_overlay = orig_node;
        while (m_quadtree.nodes[prev_overlay].next_overlay != -1) prev_overlay = m_quadtree.nodes[prev_overlay].next_overlay;
        m_quadtree.nodes[prev_overlay].next_overlay = new_index;
+       Debug("OverlayQuadParent(%d, %d, %d) = %d", orig_child, child, type, new_index);
 
        // Recurse into any extant parent.
        if (m_quadtree.nodes[orig_node].parent != -1)
@@ -313,7 +317,7 @@ void Document::PropagateQuadChanges(QuadTreeIndex node)
                if (m_quadtree.nodes[overlay].object_dirty == m_quadtree.nodes[overlay].object_end) continue;
                // Recurse into our parent, should we have any.
                if (m_quadtree.nodes[node].parent != -1)
-                       OverlayQuadParent(node, overlay, m_quadtree.nodes[overlay].child_type);
+                       OverlayQuadParent(node, overlay, m_quadtree.nodes[node].child_type);
                // Recurse into any extant children.
                if (m_quadtree.nodes[node].top_left != -1)
                        OverlayQuadChildren(node, overlay, QTC_TOP_LEFT);
@@ -332,14 +336,17 @@ void Document::PropagateQuadChanges(QuadTreeIndex node)
 QuadTreeIndex Document::GenQuadParent(QuadTreeIndex child, QuadTreeNodeChildren type)
 {
        QuadTreeIndex new_index = m_quadtree.nodes.size();
-       m_quadtree.nodes.push_back(QuadTreeNode{QUADTREE_EMPTY, QUADTREE_EMPTY, QUADTREE_EMPTY, QUADTREE_EMPTY, -1, QTC_UNKNOWN, 0, 0, -1});
+       m_quadtree.nodes.push_back(QuadTreeNode{QUADTREE_EMPTY, QUADTREE_EMPTY, QUADTREE_EMPTY, QUADTREE_EMPTY, -1, QTC_UNKNOWN, 0, 0, -1, true});
 
        m_quadtree.nodes[new_index].object_begin = m_objects.bounds.size();
        for (QuadTreeIndex overlay = child; overlay != -1; overlay = m_quadtree.nodes[overlay].next_overlay)
        {
                for (unsigned i = m_quadtree.nodes[overlay].object_begin; i < m_quadtree.nodes[overlay].object_end; ++i)
                {
-                       m_objects.bounds.push_back(TransformFromQuadChild(m_objects.bounds[i], type));
+                       Rect new_bounds = TransformFromQuadChild(m_objects.bounds[i], type);
+                       // If the object is too small to be seen, discard it.
+                       if (!new_bounds.w || !new_bounds.h) continue;
+                       m_objects.bounds.push_back(new_bounds);
                        m_objects.types.push_back(m_objects.types[i]);
                        m_objects.data_indices.push_back(m_objects.data_indices[i]);
                        m_count++;
@@ -511,29 +518,24 @@ unsigned Document::Add(ObjectType type, const Rect & bounds, unsigned data_index
 {
        PROFILE_SCOPE("Document::Add");
        Rect new_bounds = bounds;
-       int num_added = 1;
-       bool still_to_add = true;
 #ifndef QUADTREE_DISABLED
+       int num_added = 1;
        if (qti == -1) qti = m_current_insert_node;
        if (qti != -1)
        {
                // Move the object to the quadtree node it should be in.
                m_quadtree.GetCanonicalCoords(qti, new_bounds.x, new_bounds.y, this);
                Rect cliprect = Rect(0,0,1,1);
-               // If an object spans multiple quadtree nodes...
-               if (!cliprect.Contains(new_bounds))
-               {
-                       num_added = AddClip(type, new_bounds, data_index, cliprect);
-                       still_to_add = false;
-               }
+               num_added = AddClip(type, new_bounds, data_index, cliprect);
        }
+       else
 #endif
-       if (still_to_add)
        {
                m_objects.types.push_back(type);
                m_objects.bounds.push_back(new_bounds);
                m_objects.data_indices.push_back(data_index);
        }
+       m_document_dirty = true;
 #ifndef QUADTREE_DISABLED
        if (qti != -1)
        {
@@ -543,25 +545,28 @@ unsigned Document::Add(ObjectType type, const Rect & bounds, unsigned data_index
                        if (m_count == m_quadtree.nodes[new_qti].object_end+1)
                        {
                                m_quadtree.nodes[new_qti].object_end += num_added;
-                               goto done;
+                               m_quadtree.nodes[new_qti].render_dirty = true;
+                               new_qti = -1;
+                               break;
                        }
                        new_qti = m_quadtree.nodes[new_qti].next_overlay;
                }
+               if (new_qti != -1)
                {
                        QuadTreeIndex overlay = m_quadtree.nodes.size();
                        Debug("Adding new overlay, nqti = %d, overlay = %d", new_qti, overlay);
-                       m_quadtree.nodes.push_back(m_quadtree.nodes[qti]);
+                       m_quadtree.nodes.push_back(QuadTreeNode{QUADTREE_EMPTY, QUADTREE_EMPTY, QUADTREE_EMPTY, QUADTREE_EMPTY, -1, QTC_UNKNOWN, 0, 0, -1});
                        m_quadtree.nodes[overlay].object_begin = m_count;
                        // All objects are dirty.
                        m_quadtree.nodes[overlay].object_dirty = m_count;
                        m_quadtree.nodes[overlay].object_end = m_count+num_added;
                        m_quadtree.nodes[overlay].next_overlay = -1;
+                       m_quadtree.nodes[overlay].render_dirty = true;
                        m_quadtree.nodes[new_qti].next_overlay = overlay;
                        new_qti = overlay;
                }
-done: // matches is not amused, but sulix is nice and moved it inside the #ifdef for him.
-               m_count += num_added;
        }
+       m_count += num_added;
        return m_count-num_added;
 #else // words fail me (still not amused)
        return (m_count++);
index c3d9620..02a8f7c 100644 (file)
@@ -190,6 +190,9 @@ void* GraphicsBuffer::MapRange(int offset, int length, bool read, bool write, bo
        // This sometimes makes Intel corrupt memory?
        if (!length) return (m_map_pointer = 0);
 
+       if ((size_t)(length + offset) > m_buffer_size)
+               Fatal("Tried to map outside of range!");
+
 
        RecreateBuffer();
 
@@ -255,19 +258,18 @@ void GraphicsBuffer::Resize(size_t length)
 {
        if (!m_buffer_size)
        {
+               m_invalidated = true;
                m_buffer_size = length;
                return;
        }
-       if (m_invalidated && m_buffer_size >= length)
+       if (m_invalidated)
        {
                m_buffer_size = length;
-       }
-       else if (length <= m_buffer_size)
-       {
-               // Don't need to do anything.
+               m_buffer_shape_dirty = true;
        }
        else
        {
+               size_t oldsize = m_buffer_size;
                glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, -1, "Resizing buffer.");
                glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, NULL, GL_TRUE);
                // Create a new buffer and copy the old data into it.
@@ -277,7 +279,7 @@ void GraphicsBuffer::Resize(size_t length)
                Upload(length, NULL);
                glBindBuffer(GL_COPY_READ_BUFFER, old_buffer);
                glBindBuffer(GL_COPY_WRITE_BUFFER, m_buffer_handle);
-               glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, m_buffer_size);
+               glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, oldsize);
                glDeleteBuffers(1, &old_buffer);
                m_buffer_size = length;
                glPopDebugGroup();
index 3f1bc41..9b84ec2 100644 (file)
@@ -382,7 +382,14 @@ void BezierRenderer::RenderUsingGPU(unsigned first_obj_id, unsigned last_obj_id)
        if (m_indexes.empty()) return;
 
        unsigned first_index = 0;
-       while (m_indexes.size() > first_index && m_indexes[first_index] < first_obj_id) first_index ++;
+       while (m_indexes.size() > first_index && m_indexes[first_index] < first_obj_id)
+       {
+               unsigned new_index = (first_index + first_obj_id) / 2;
+               if (new_index < m_indexes.size() && m_indexes[new_index] < first_obj_id)
+                       first_index = new_index;
+               else
+                       first_index ++;
+       }
        unsigned last_index = first_index;
        while (m_indexes.size() > last_index && m_indexes[last_index] < last_obj_id) last_index ++;
 
index f69f06a..e406536 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _PROFILER_H
 #define _PROFILER_H
 
+#include <stdint.h>
 #include <map>
 #include <string>
 #include <stack>
index 4fd4b2d..9a7b8f9 100644 (file)
@@ -44,6 +44,7 @@ namespace IPDF
                QuadTreeIndex next_overlay;
                // First object which has not yet been propagated to extant children/parent.
                unsigned object_dirty;
+               bool render_dirty;
        };
 
        struct QuadTree
index 1ed36e7..007b9e0 100644 (file)
@@ -233,7 +233,7 @@ void View::Render(int width, int height)
        {
                g_profiler.BeginZone("View::Render -- Quadtree view bounds management");
                // If we're too far zoomed out, become the parent of the current node.
-               if ( m_bounds.w > 1.0 || m_bounds.h > 1.0)
+               while ( m_bounds.w > 1.0 || m_bounds.h > 1.0)
                {
                        // If a parent node exists, we'll become it.
                        //TODO: Generate a new parent node if none exists, and work out when to change child_type
@@ -243,6 +243,7 @@ void View::Render(int width, int height)
                                m_bounds = TransformFromQuadChild(m_bounds, m_document.GetQuadTree().nodes[m_current_quadtree_node].child_type);
                                m_current_quadtree_node = m_document.GetQuadTree().nodes[m_current_quadtree_node].parent;
                        }
+                       else break;
                }
 
                // If we have a parent... (This prevents some crashes, but should disappear.)
@@ -320,7 +321,7 @@ void View::Render(int width, int height)
 
                // Otherwise, we'll arbitrarily select the bottom-right.
                // TODO: Perhaps select based on greatest area?
-               if (m_bounds.w < 0.5 || m_bounds.h < 0.5)
+               while (m_bounds.w < 0.5 || m_bounds.h < 0.5)
                {
                        if (m_document.GetQuadTree().nodes[m_current_quadtree_node].bottom_right == QUADTREE_EMPTY)
                        {
@@ -377,6 +378,12 @@ void View::Render(int width, int height)
 #ifdef QUADTREE_DISABLED
        RenderRange(width, height, 0, m_document.ObjectCount());
 #else
+       // Make sure we update the gpu buffers properly.
+       if (m_document.m_document_dirty)
+       {
+               m_render_dirty = m_buffer_dirty = true;
+               m_document.m_document_dirty = false;
+       }
        RenderQuadtreeNode(width, height, m_current_quadtree_node, m_quadtree_max_depth);
 #endif
        if (!m_use_gpu_rendering)
@@ -404,17 +411,15 @@ void View::RenderQuadtreeNode(int width, int height, QuadTreeIndex node, int rem
        Rect old_bounds = m_bounds;
        if (node == QUADTREE_EMPTY) return;
        if (!remaining_depth) return;
-       //Debug("Rendering QT node %d, (objs: %d -- %d)\n", node, m_document.GetQuadTree().nodes[node].object_begin, m_document.GetQuadTree().nodes[node].object_end);
        m_bounds_dirty = true;
-       if (m_document.m_document_dirty)
-       {
-               m_render_dirty = m_buffer_dirty = true;
-               m_document.m_document_dirty = false;
-       }
        QuadTreeIndex overlay = node;
        while(overlay != -1)
        {
+               //Debug("Rendering QT node %d, (overlay %d, objs: %d -- %d)\n", node, overlay, m_document.GetQuadTree().nodes[overlay].object_begin, m_document.GetQuadTree().nodes[overlay].object_end);
+               if (m_document.GetQuadTree().nodes[overlay].render_dirty)
+                       m_buffer_dirty = m_render_dirty = true;
                RenderRange(width, height, m_document.GetQuadTree().nodes[overlay].object_begin, m_document.GetQuadTree().nodes[overlay].object_end);
+               const_cast<bool&>(m_document.GetQuadTree().nodes[overlay].render_dirty) = false;
                overlay = m_document.GetQuadTree().nodes[overlay].next_overlay;
        }
 
@@ -462,41 +467,46 @@ void View::RenderQuadtreeNode(int width, int height, QuadTreeIndex node, int rem
 
 void View::RenderRange(int width, int height, unsigned first_obj, unsigned last_obj)
 {
+       // We don't want to render an empty range,
+       // so don't waste time setting up everything.
+       if (first_obj == last_obj) return;
        PROFILE_SCOPE("View::RenderRange");
        glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 43, -1, "View::RenderRange()");
        if (m_render_dirty) // document has changed
                PrepareRender();
 
+
        if (m_buffer_dirty || m_bounds_dirty || !m_lazy_rendering) // object bounds have changed
        {
                if (m_use_gpu_rendering)
                        UpdateObjBoundsVBO(first_obj, last_obj);
        }
 
-       if (m_use_gpu_transform)
-       {
-               #ifdef TRANSFORM_OBJECTS_NOT_VIEW
-                       //Debug("Transform objects, not view");
-                               GLfloat glbounds[] = {0.0f, 0.0f, 1.0f, 1.0f,
-                                       0.0f, 0.0f, float(width), float(height)};
-               #else
-               GLfloat glbounds[] = {static_cast<GLfloat>(Float(m_bounds.x)), static_cast<GLfloat>(Float(m_bounds.y)), static_cast<GLfloat>(Float(m_bounds.w)), static_cast<GLfloat>(Float(m_bounds.h)),
-                                       0.0, 0.0, static_cast<GLfloat>(width), static_cast<GLfloat>(height)};
-               #endif
-               m_bounds_ubo.Upload(sizeof(float)*8, glbounds);
-       }
-       else
-       {
-               GLfloat glbounds[] = {0.0f, 0.0f, 1.0f, 1.0f,
-                                       0.0f, 0.0f, float(width), float(height)};
-               m_bounds_ubo.Upload(sizeof(float)*8, glbounds);
-       }
-       m_bounds_dirty = false;
-
 
        // Render using GPU
        if (m_use_gpu_rendering) 
        {
+
+               if (m_use_gpu_transform)
+               {
+                       #ifdef TRANSFORM_OBJECTS_NOT_VIEW
+                               //Debug("Transform objects, not view");
+                                       GLfloat glbounds[] = {0.0f, 0.0f, 1.0f, 1.0f,
+                                               0.0f, 0.0f, float(width), float(height)};
+                       #else
+                       GLfloat glbounds[] = {static_cast<GLfloat>(Float(m_bounds.x)), static_cast<GLfloat>(Float(m_bounds.y)), static_cast<GLfloat>(Float(m_bounds.w)), static_cast<GLfloat>(Float(m_bounds.h)),
+                                               0.0, 0.0, static_cast<GLfloat>(width), static_cast<GLfloat>(height)};
+                       #endif
+                       m_bounds_ubo.Upload(sizeof(float)*8, glbounds);
+               }
+               else
+               {
+                       GLfloat glbounds[] = {0.0f, 0.0f, 1.0f, 1.0f,
+                                               0.0f, 0.0f, float(width), float(height)};
+                       m_bounds_ubo.Upload(sizeof(float)*8, glbounds);
+               }
+               m_bounds_dirty = false;
+
                if (m_colour.a < 1.0f)
                {
                        glEnable(GL_BLEND);

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