+ for (unsigned id = path.m_start; id <= path.m_end; ++id)
+ {
+ if (id < first_obj || id >= last_obj)
+ continue;
+
+ Rect obj_bounds = m_document.m_objects.bounds[id];
+ obj_bounds.x *= pbounds.w;
+ obj_bounds.x += pbounds.x;
+ obj_bounds.y *= pbounds.h;
+ obj_bounds.y += pbounds.y;
+ obj_bounds.w *= pbounds.w;
+ obj_bounds.h *= pbounds.h;
+
+ if (!m_use_gpu_transform)
+ obj_bounds = TransformToViewCoords(obj_bounds);
+ GPUObjBounds gpu_bounds = {
+ ClampFloat(obj_bounds.x),
+ ClampFloat(obj_bounds.y),
+ ClampFloat(obj_bounds.x + obj_bounds.w),
+ ClampFloat(obj_bounds.y + obj_bounds.h)
+ };
+ obj_bounds_builder.Add(gpu_bounds);
+ //Debug("Path %d %s -> %s via %s", id, m_document.m_objects.bounds[id].Str().c_str(), obj_bounds.Str().c_str(), pbounds.Str().c_str());
+
+ if (m_query_gpu_bounds_on_next_frame != NULL)
+ {
+ fprintf(m_query_gpu_bounds_on_next_frame,"%d\t%f\t%f\t%f\t%f\n", id, ClampFloat(obj_bounds.x), ClampFloat(obj_bounds.y), ClampFloat(obj_bounds.w), ClampFloat(obj_bounds.h));
+ }
+ }
+ GPUObjBounds p_gpu_bounds = {
+ ClampFloat(pbounds.x),
+ ClampFloat(pbounds.y),
+ ClampFloat(pbounds.x + pbounds.w),
+ ClampFloat(pbounds.y + pbounds.h)
+ };
+ obj_bounds_builder.Add(p_gpu_bounds);
+ }
+ #endif
+ if (m_query_gpu_bounds_on_next_frame != NULL)
+ {
+ if (m_query_gpu_bounds_on_next_frame != stdout && m_query_gpu_bounds_on_next_frame != stderr)
+ fclose(m_query_gpu_bounds_on_next_frame);
+ m_query_gpu_bounds_on_next_frame = NULL;
+ }
+ m_objbounds_vbo.UnMap();
+}
+/**
+ * Prepare the document for rendering
+ * Will be called on View::Render if m_render_dirty is set
+ * (Called at least once, on the first Render)
+ */
+void View::PrepareRender()
+{
+ PROFILE_SCOPE("View::PrepareRender()");
+ Debug("Recreate buffers with %u objects", m_document.ObjectCount());
+ // Prepare bounds vbo
+ if (UsingGPURendering())
+ {
+ m_bounds_ubo.Invalidate();
+ m_bounds_ubo.SetType(GraphicsBuffer::BufferTypeUniform);
+ m_bounds_ubo.SetUsage(GraphicsBuffer::BufferUsageStreamDraw);
+ m_bounds_ubo.SetName("m_bounds_ubo: Screen bounds.");
+ }
+
+ // Instead of having each ObjectRenderer go through the whole document
+ // we initialise them, go through the document once adding to the appropriate Renderers
+ // and then finalise them
+ // This will totally be efficient if we have like, a lot of distinct ObjectTypes. Which could totally happen. You never know.
+
+ // Prepare the buffers
+ for (unsigned i = 0; i < m_object_renderers.size(); ++i)
+ {
+ m_object_renderers[i]->PrepareBuffers(m_document.ObjectCount());
+ }
+
+ // Add objects from Document to buffers
+ for (unsigned id = 0; id < m_document.ObjectCount(); ++id)
+ {
+ 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);
+ }