Bezier bounds rectangles are calculated correctly
authorSam Moore <[email protected]>
Thu, 14 Aug 2014 04:21:31 +0000 (12:21 +0800)
committerSam Moore <[email protected]>
Thu, 14 Aug 2014 04:21:31 +0000 (12:21 +0800)
CPU rendering and SVG parsing uses absolute coordinates.
GPU rendering uses relative coordinates (relative to the bounding box).

The Objects struct stores the absolute bounding boxes now.

Previously it was just using {0,0,1,1} (and thus the GPU's relative coordinates were
equivelant to the CPU's absolute coordinates).

I might have fixed some other things but I can't remember.

src/bezier.cpp
src/bezier.h
src/document.cpp
src/document.h
src/ipdf.h
src/main.cpp
src/objectrenderer.cpp
src/objectrenderer.h
src/real.h
src/svg-tests/circlepath.svg [new file with mode: 0644]
src/view.cpp

index f0e1f4d..a30a20a 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <unordered_map>
 #include <cmath>
+#include <algorithm>
 
 using namespace std;
 
@@ -45,4 +46,94 @@ Real Bernstein(int k, int n, const Real & u)
        return Real(BinomialCoeff(n, k)) * Power(u, k) * Power(Real(1.0) - u, n-k);
 }
 
+
+/**
+ * Returns the parametric parameter at the turning point(s)
+ * In one coordinate direction
+ */
+
+static pair<Real, Real> BezierTurningPoints(const Real & p0, const Real & p1, const Real & p2, const Real & p3)
+{
+       // straight line
+       if (p1 == p2 && p2 == p3)
+       {
+               return pair<Real,Real>(0, 1);
+       }
+       Real a = (p1- p0 - 2*(p2-p1) + p3-p2);
+       Real b = (p1-p0 - (p2-p1))*(p1-p0);
+       Real c = (p1-p0);
+       if (a == 0)
+       {
+               if (b == 0)
+                       return pair<Real, Real>(0,1);
+               Real t = -c/b;
+               if (t > 1) t = 1;
+               if (t < 0) t = 0;
+               return pair<Real, Real>(t, t);
+       }
+       Debug("a, b, c are %f, %f, %f", Float(a), Float(b), Float(c));
+       if (b*b - 4*a*c < 0)
+       {
+               return pair<Real, Real>(0,1);
+       }
+       pair<Real, Real> tsols = SolveQuadratic(a, b, c);
+       if (tsols.first > 1) tsols.first = 1;
+       if (tsols.first < 0) tsols.first = 0;
+       if (tsols.second > 1) tsols.second = 1;
+       if (tsols.second < 0) tsols.second = 0;
+       return tsols;
 }
+
+inline bool CompRealByPtr(const Real * a, const Real * b) 
+{
+       return (*a) < (*b);
+}
+
+/**
+ * Get Bounds Rectangle of Bezier
+ */
+Rect Bezier::SolveBounds() const
+{
+       Rect result;
+       pair<Real, Real> tsols = BezierTurningPoints(x0, x1, x2, x3);
+       
+       Real tp0; Real tp1; Real o;
+       Evaluate(tp0, o, tsols.first);
+       Evaluate(tp1, o, tsols.second);
+       
+       Debug("x: tp0 is %f tp1 is %f", Float(tp0), Float(tp1));
+       
+       vector<const Real*> v(4);
+       v[0] = &x0;
+       v[1] = &x3;
+       v[2] = &tp0;
+       v[3] = &tp1;
+       
+       // Not using a lambda to keep this compiling on cabellera
+       sort(v.begin(), v.end(), CompRealByPtr);
+
+       result.x = *(v[0]);
+       result.w = *(v[3]) - result.x;
+
+       // Do the same thing for y component (wow this is a mess)
+       tsols = BezierTurningPoints(y0, y1, y2, y3);
+       Evaluate(o, tp0, tsols.first);
+       Evaluate(o, tp1, tsols.second);
+       
+       
+       Debug("y: tp0 is %f tp1 is %f", Float(tp0), Float(tp1));
+       
+       v[0] = &y0;
+       v[1] = &y3;
+       v[2] = &tp0;
+       v[3] = &tp1;
+       sort(v.begin(), v.end(), CompRealByPtr);
+       
+       result.y = *(v[0]);
+       result.h = *(v[3]) - result.y;
+       
+       Debug("Solved Bezier %s bounds as %s", Str().c_str(), result.Str().c_str());
+       return result;
+}
+
+} // end namespace
index 0e9217f..449d7bd 100644 (file)
@@ -8,6 +8,13 @@ namespace IPDF
        extern int Factorial(int n);
        extern int BinomialCoeff(int n, int k);
        extern Real Bernstein(int k, int n, const Real & u);
+       
+       inline std::pair<Real,Real> SolveQuadratic(const Real & a, const Real & b, const Real & c)
+       {
+               Real x0((b + Sqrt(b*b - Real(4)*a*c))/(Real(2)*a));
+               Real x1((b - Sqrt(b*b - Real(4)*a*c))/(Real(2)*a));
+               return std::pair<Real,Real>(x0,x1);
+       }
 
        /** A _cubic_ bezier. **/
        struct Bezier
@@ -17,7 +24,10 @@ namespace IPDF
                Real x2; Real y2;
                Real x3; Real y3;
                Bezier() = default; // Needed so we can fread/fwrite this struct... for now.
-               Bezier(Real _x0, Real _y0, Real _x1, Real _y1, Real _x2, Real _y2, Real _x3, Real _y3) : x0(_x0), y0(_y0), x1(_x1), y1(_y1), x2(_x2), y2(_y2), x3(_x3), y3(_y3) {}
+               Bezier(Real _x0, Real _y0, Real _x1, Real _y1, Real _x2, Real _y2, Real _x3, Real _y3) : x0(_x0), y0(_y0), x1(_x1), y1(_y1), x2(_x2), y2(_y2), x3(_x3), y3(_y3) 
+               {
+                       
+               }
                
                Bezier(Real _x0, Real _y0, Real _x1, Real _y1, Real _x2, Real _y2) : x0(_x0), y0(_y0), x1(_x1), y1(_y1), x2(_x2), y2(_y2), x3(_x2), y3(_y2) {}
                
@@ -27,6 +37,11 @@ namespace IPDF
                        s << "Bezier{" << Float(x0) << "," << Float(y0) << " -> " << Float(x1) << "," << Float(y1) << " -> " << Float(x2) << "," << Float(y2) << " -> " << Float(x3) << "," << Float(y3) << "}";
                        return s.str();
                }
+               
+               /**
+                * Construct absolute control points using relative control points to a bounding rectangle
+                * ie: If cpy is relative to bounds rectangle, this will be absolute
+                */
                Bezier(const Bezier & cpy, const Rect & t = Rect(0,0,1,1)) : x0(cpy.x0), y0(cpy.y0), x1(cpy.x1), y1(cpy.y1), x2(cpy.x2),y2(cpy.y2), x3(cpy.x3), y3(cpy.y3)
                {
                        x0 *= t.w;
@@ -47,10 +62,54 @@ namespace IPDF
                        y3 += t.y;
                }
 
-               Rect ToRect() {return Rect(x0,y0,x3-x0,y3-y0);}
+               Rect SolveBounds() const;
+               
+               /** Convert absolute control points to control points relative to bounds
+                * (This basically does the opposite of the Copy constructor)
+                * ie: If this is absolute, the returned Bezier will be relative to the bounds rectangle
+                */
+               Bezier CopyInverse(const Rect & bounds) const
+               {
+                       // x' <- (x - x0)/w etc
+                       // special cases when w or h = 0
+                       // (So can't just use the Copy constructor on the inverse of bounds)
+                       // Rect inverse = {-bounds.x/bounds.w, -bounds.y/bounds.h, Real(1)/bounds.w, Real(1)/bounds.h};
+                       Bezier result;
+                       if (bounds.w == 0)
+                       {
+                               result.x0 = 0;
+                               result.x1 = 0;
+                               result.x2 = 0;
+                               result.x3 = 0;
+                       }
+                       else
+                       {
+                               result.x0 = (x0 - bounds.x)/bounds.w;   
+                               result.x1 = (x1 - bounds.x)/bounds.w;
+                               result.x2 = (x2 - bounds.x)/bounds.w;
+                               result.x3 = (x3 - bounds.x)/bounds.w;
+                       }
+
+                       if (bounds.h == 0)
+                       {
+                               result.y0 = 0;
+                               result.y1 = 0;
+                               result.y2 = 0;
+                               result.y3 = 0;
+                       }
+                       else
+                       {
+                               result.y0 = (y0 - bounds.y)/bounds.h;   
+                               result.y1 = (y1 - bounds.y)/bounds.h;
+                               result.y2 = (y2 - bounds.y)/bounds.h;
+                               result.y3 = (y3 - bounds.y)/bounds.h;
+                       }
+                       return result;
+               }
+               
 
                /** Evaluate the Bezier at parametric parameter u, puts resultant point in (x,y) **/
-               void Evaluate(Real & x, Real & y, const Real & u)
+               void Evaluate(Real & x, Real & y, const Real & u) const
                {
                        Real coeff[4];
                        for (unsigned i = 0; i < 4; ++i)
index dab0868..65a07ec 100644 (file)
@@ -254,6 +254,11 @@ void Document::Load(const string & filename)
                        Debug("Bezier data...");
                        LoadStructVector<Bezier>(file, chunk_size/sizeof(Bezier), m_objects.beziers);
                        break;
+                       
+               case CT_OBJGROUPS:
+                       Debug("Group data...");
+                       Warn("Not handled because lazy");
+                       break;
                }
        }
        Debug("Successfully loaded %u objects from \"%s\"", ObjectCount(), filename.c_str());
@@ -265,12 +270,28 @@ void Document::Load(const string & filename)
 #endif
 }
 
-void Document::Add(ObjectType type, const Rect & bounds, unsigned data_index)
+unsigned Document::AddGroup(unsigned start_index, unsigned end_index)
+{
+       //TODO: Set bounds rect?
+       unsigned result = Add(GROUP, Rect(0,0,1,1),0);
+       m_objects.groups[m_count-1].first = start_index;
+       m_objects.groups[m_count-1].second = end_index;
+       return result;
+}
+
+unsigned Document::AddBezier(const Bezier & bezier)
+{
+       unsigned index = AddBezierData(bezier);
+       return Add(BEZIER, bezier.SolveBounds(), index);
+}
+
+unsigned Document::Add(ObjectType type, const Rect & bounds, unsigned data_index)
 {
        m_objects.types.push_back(type);
        m_objects.bounds.push_back(bounds);
        m_objects.data_indices.push_back(data_index);
-       ++m_count; // Why can't we just use the size of types or something?
+       m_objects.groups.push_back(pair<unsigned, unsigned>(data_index, data_index));
+       return (m_count++); // Why can't we just use the size of types or something?
 }
 
 unsigned Document::AddBezierData(const Bezier & bezier)
@@ -440,7 +461,9 @@ void Document::ParseSVGNode(pugi::xml_node & root, SVGMatrix & parent_transform)
                {
                        string d = child.attribute("d").as_string();
                        Debug("Path data attribute is \"%s\"", d.c_str());
-                       ParseSVGPathData(d, transform);
+                       pair<unsigned, unsigned> range = ParseSVGPathData(d, transform);
+                       AddGroup(range.first, range.second);
+                       
                }
                else if (strcmp(child.name(), "line") == 0)
                {
@@ -450,8 +473,7 @@ void Document::ParseSVGNode(pugi::xml_node & root, SVGMatrix & parent_transform)
                        Real y1(child.attribute("y2").as_float());
                        TransformXYPair(x0,y0,transform);
                        TransformXYPair(x1,y1,transform);
-                       unsigned index = AddBezierData(Bezier(x0,y0,x1,y1,x1,y1,x1,y1));
-                       Add(BEZIER, Rect(0,0,1,1), index);
+                       AddBezier(Bezier(x0,y0,x1,y1,x1,y1,x1,y1));
                }
                else if (strcmp(child.name(), "rect") == 0)
                {
@@ -524,7 +546,7 @@ void Document::LoadSVG(const string & filename, const Rect & bounds)
 
 // Fear the wrath of the tokenizing svg data
 // Seriously this isn't really very DOM-like at all is it?
-void Document::ParseSVGPathData(const string & d, const SVGMatrix & transform)
+pair<unsigned, unsigned> Document::ParseSVGPathData(const string & d, const SVGMatrix & transform)
 {
        Real x[4] = {0,0,0,0};
        Real y[4] = {0,0,0,0};
@@ -540,7 +562,10 @@ void Document::ParseSVGPathData(const string & d, const SVGMatrix & transform)
        
        bool start = false;
        
+
        static string delims("()[],{}<>;:=LlHhVvmMqQzZcC");
+
+       pair<unsigned, unsigned> range(m_count, m_count);
        
        while (i < d.size() && GetToken(d, token, i, delims).size() > 0)
        {
@@ -609,9 +634,7 @@ void Document::ParseSVGPathData(const string & d, const SVGMatrix & transform)
                        for (int j = 0; j < 4; ++j)
                                TransformXYPair(x[j],y[j], transform);
 
-                       unsigned index = AddBezierData(Bezier(x[0],y[0],x[1],y[1],x[2],y[2],x[3],y[3]));
-                       Add(BEZIER,Rect(0,0,1,1),index);
-                       
+                       range.second = AddBezier(Bezier(x[0],y[0],x[1],y[1],x[2],y[2],x[3],y[3]));
                        
                        //Debug("[%u] curveto %f,%f %f,%f %f,%f", index, Float(x[1]),Float(y[1]),Float(x[2]),Float(y[2]),Float(x[3]),Float(y[3]));
                        
@@ -654,8 +677,7 @@ void Document::ParseSVGPathData(const string & d, const SVGMatrix & transform)
                        TransformXYPair(x[1],y[1],transform);
 
 
-                       unsigned index = AddBezierData(Bezier(x[0],y[0],x[1],y[1],x[1],y[1],x[1],y[1]));
-                       Add(BEZIER,Rect(0,0,1,1),index);
+                       range.second = AddBezier(Bezier(x[0],y[0],x[1],y[1],x[1],y[1],x[1],y[1]));
                        
                        //Debug("[%u] lineto %f,%f %f,%f", index, Float(x[0]),Float(y[0]),Float(x[1]),Float(y[1]));
                        
@@ -678,9 +700,7 @@ void Document::ParseSVGPathData(const string & d, const SVGMatrix & transform)
                        for (int j = 0; j < 4; ++j)
                                TransformXYPair(x[j],y[j], transform);
 
-                       unsigned index = AddBezierData(Bezier(x[0],y[0],x[1],y[1],x[2],y[2],x[3],y[3]));
-                       Add(BEZIER,Rect(0,0,1,1),index);
-                       
+                       range.second = AddBezier(Bezier(x[0],y[0],x[1],y[1],x[2],y[2],x[3],y[3]));
                        //Debug("[%u] returnto %f,%f %f,%f", index, Float(x[0]),Float(y[0]),Float(x[1]),Float(y[1]));
                        
                        x[0] = x3;
@@ -701,6 +721,7 @@ void Document::ParseSVGPathData(const string & d, const SVGMatrix & transform)
                }
                prev_i = i;
        }
+       return range;
 }
 
 void Document::SetFont(const string & font_filename)
@@ -804,9 +825,8 @@ void Document::AddFontGlyphAtPoint(stbtt_fontinfo *font, int character, Real sca
                        // - Endpoints are the same.
                        // - cubic1 = quad0+(2/3)*(quad1-quad0)
                        // - cubic2 = quad2+(2/3)*(quad1-quad2)
-                       bezier_index = AddBezierData(Bezier(old_x + x, old_y + y, old_x + Real(2)*(inst_cx-old_x)/Real(3) + x, old_y + Real(2)*(inst_cy-old_y)/Real(3) + y,
+                       bezier_index = AddBezier(Bezier(old_x + x, old_y + y, old_x + Real(2)*(inst_cx-old_x)/Real(3) + x, old_y + Real(2)*(inst_cy-old_y)/Real(3) + y,
                                                current_x + Real(2)*(inst_cx-current_x)/Real(3) + x, current_y + Real(2)*(inst_cy-current_y)/Real(3) + y, current_x + x, current_y + y));
-                       Add(BEZIER,Rect(0,0,1,1),bezier_index);
                        break;
                }
        }
index 76e3b7f..6592f4b 100644 (file)
@@ -50,7 +50,9 @@ namespace IPDF
                        bool operator==(const Document & equ) const;
                        bool operator!=(const Document & equ) const {return !(this->operator==(equ));}
 
-                       void Add(ObjectType type, const Rect & bounds, unsigned data_index = 0);
+                       unsigned AddGroup(unsigned start_index, unsigned end_index);
+                       unsigned AddBezier(const Bezier & bezier);
+                       unsigned Add(ObjectType type, const Rect & bounds, unsigned data_index = 0);
                        unsigned AddBezierData(const Bezier & bezier);
                        
 
@@ -67,7 +69,7 @@ namespace IPDF
                        /** Parse an SVG node or SVG-group node, adding children to the document **/
                        void ParseSVGNode(pugi::xml_node & root, SVGMatrix & transform);
                        /** Parse an SVG path with string **/
-                       void ParseSVGPathData(const std::string & d, const SVGMatrix & transform);
+                       std::pair<unsigned, unsigned> ParseSVGPathData(const std::string & d, const SVGMatrix & transform);
                        
                        /** Modify an SVG transformation matrix **/
                        static void ParseSVGTransform(const std::string & s, SVGMatrix & transform);
index cd6ef6f..ff31533 100644 (file)
@@ -29,6 +29,7 @@ namespace IPDF
                RECT_FILLED,
                RECT_OUTLINE,
                BEZIER,
+               GROUP,
                NUMBER_OF_OBJECT_TYPES
        } ObjectType;
 
@@ -38,8 +39,8 @@ namespace IPDF
                CT_OBJTYPES,
                CT_OBJBOUNDS,
                CT_OBJINDICES,
-               CT_OBJBEZIERS
-               //CT_OBJGROUPS
+               CT_OBJBEZIERS,
+               CT_OBJGROUPS
        };
 
 
@@ -52,11 +53,10 @@ namespace IPDF
                Colour() = default;
                Colour(float _r, float _g, float _b, float _a) : r(_r), g(_g), b(_b), a(_a) {}
        };
-
-       struct ObjectData
+       
+       struct Group
        {
-               Colour colour;
-               
+               Colour shading;
        };
 
        struct Objects
@@ -70,6 +70,8 @@ namespace IPDF
 
                /** Used by BEZIER only **/
                std::vector<Bezier> beziers; // bezier curves - look up by data_indices
+               
+               std::vector<std::pair<unsigned, unsigned> > groups;
        };
 
        class View;
index 8942a9c..718361f 100644 (file)
@@ -82,29 +82,8 @@ int main(int argc, char ** argv)
        }
        else 
        {
-/*             doc.AddBezierData(Bezier(0,0,0,1,1,0));
-               doc.AddBezierData(Bezier(0,0,1,0,0,1));
-               doc.AddBezierData(Bezier(0,0,1,1,1,0));
-               doc.AddBezierData(Bezier(0,1,1,0,0,1));*/
-               
-       
-               
-               doc.AddText("abcde", 0.5, Real(0), Real(1));
-
-               for(int x = 0; x < 8; ++x)
-               {
-                       
-                       for (int y = 0; y < 8; ++y)
-                       {
-                               //doc.Add(static_cast<IPDF::ObjectType>((x^y)%3), Rect(0.2+x-4.0,0.2+y-4.0,0.6,0.6));
-                               //doc.Add(BEZIER, Rect(0.2+x-4.0, 0.2+y-4.0, 0.6,0.6), (x^y)%3);
-                       }
-               }
-       /*      doc.Add(BEZIER, Rect(0.1,0.1,0.8,0.8), 0);
-               doc.Add(BEZIER, Rect(0.1,0.1,0.8,0.8), 1);
-               doc.Add(BEZIER, Rect(0.1,0.1,0.8,0.8), 2);
-               doc.Add(BEZIER, Rect(0.1,0.1,0.8,0.8), 3);*/
-               //doc.Add(CIRCLE_FILLED, Rect(0.1,0.1,0.8,0.8), 0);
+               //doc.AddBezier(Bezier(0,0, 1,0.5, 0.5,1, 1,1));
+               doc.AddText("c",1,0,0);
        }
        Debug("Start!");
        Rect bounds(b[0],b[1],b[2],b[3]);
index 76aba52..4b77f00 100644 (file)
@@ -42,7 +42,7 @@ void ObjectRenderer::RenderUsingGPU(unsigned first_obj_id, unsigned last_obj_id)
 
        m_shader_program.Use();
        m_ibo.Bind();
-       glDrawElements(GL_LINES, (last_index-first_index)*2, GL_UNSIGNED_INT, (GLvoid*)(2*first_index*sizeof(uint32_t)));
+       glDrawElements(GL_LINES, (last_index-first_index)*2, GL_UNSIGNED_INT, (GLvoid*)(first_index*sizeof(uint32_t)));
 }
 
 
@@ -72,7 +72,6 @@ void ObjectRenderer::PrepareBuffers(unsigned max_objects)
        m_ibo.Invalidate();
        m_ibo.SetUsage(GraphicsBuffer::BufferUsageStaticDraw);
        m_ibo.SetType(GraphicsBuffer::BufferTypeIndex);
-       m_ibo.SetName("m_ibo: ObjectRenderer GPU indices");
        m_ibo.Resize(max_objects * 2 * sizeof(uint32_t));
        // BufferBuilder is used to construct the ibo
        m_buffer_builder = new BufferBuilder<uint32_t>(m_ibo.Map(false, true, true), m_ibo.GetSize()); // new matches delete in ObjectRenderer::FinaliseBuffers
@@ -225,14 +224,13 @@ void BezierRenderer::RenderUsingCPU(const Objects & objects, const View & view,
                Rect bounds(CPURenderBounds(objects.bounds[m_indexes[i]], view, target));
                PixelBounds pix_bounds(bounds);
 
-
-               Bezier control(objects.beziers[objects.data_indices[m_indexes[i]]], bounds);
+               Bezier control(objects.beziers[objects.data_indices[m_indexes[i]]],CPURenderBounds(Rect(0,0,1,1), view, target));
                //Debug("%s -> %s via %s", objects.beziers[objects.data_indices[m_indexes[i]]].Str().c_str(), control.Str().c_str(), bounds.Str().c_str());
-               // Draw a rectangle around the bezier for debugging the coord transforms
-               //ObjectRenderer::RenderLineOnCPU(pix_bounds.x, pix_bounds.y, pix_bounds.x+pix_bounds.w, pix_bounds.y, target);
-               //ObjectRenderer::RenderLineOnCPU(pix_bounds.x, pix_bounds.y+pix_bounds.h, pix_bounds.x+pix_bounds.w, pix_bounds.y+pix_bounds.h, target);
-               //ObjectRenderer::RenderLineOnCPU(pix_bounds.x, pix_bounds.y, pix_bounds.x, pix_bounds.y+pix_bounds.h, target);
-               //ObjectRenderer::RenderLineOnCPU(pix_bounds.x+pix_bounds.w, pix_bounds.y, pix_bounds.x+pix_bounds.w, pix_bounds.y+pix_bounds.h, target);
+               // Draw a rectangle around the bezier for debugging the bounds rectangle calculations
+               ObjectRenderer::RenderLineOnCPU(pix_bounds.x, pix_bounds.y, pix_bounds.x+pix_bounds.w, pix_bounds.y, target, Colour(1,0,0,1));
+               ObjectRenderer::RenderLineOnCPU(pix_bounds.x, pix_bounds.y+pix_bounds.h, pix_bounds.x+pix_bounds.w, pix_bounds.y+pix_bounds.h, target, Colour(0,1,0,1));
+               ObjectRenderer::RenderLineOnCPU(pix_bounds.x, pix_bounds.y, pix_bounds.x, pix_bounds.y+pix_bounds.h, target, Colour(0,0,1,1));
+               ObjectRenderer::RenderLineOnCPU(pix_bounds.x+pix_bounds.w, pix_bounds.y, pix_bounds.x+pix_bounds.w, pix_bounds.y+pix_bounds.h, target, Colour(1,0,1,1));
        
                // Draw lines between the control points for debugging
                //ObjectRenderer::RenderLineOnCPU((int64_t)control.x0, (int64_t)control.y0, (int64_t)control.x1, (int64_t)control.y1,target);
@@ -278,17 +276,20 @@ void BezierRenderer::PrepareBezierGPUBuffer(const Objects& objects)
 {
        m_bezier_coeffs.SetType(GraphicsBuffer::BufferTypeTexture);
        m_bezier_coeffs.SetUsage(GraphicsBuffer::BufferUsageDynamicDraw);
-       m_bezier_coeffs.SetName("m_bezier_coeffs: Bezier coefficients");
        m_bezier_coeffs.Resize(objects.beziers.size()*sizeof(GPUBezierCoeffs));
        BufferBuilder<GPUBezierCoeffs> builder(m_bezier_coeffs.Map(false, true, true), m_bezier_coeffs.GetSize());
 
-       for (auto bez = objects.beziers.begin(); bez != objects.beziers.end(); ++bez)
+
+       for (unsigned i = 0; i < objects.types.size(); ++i)
        {
+               if (objects.types[i] != BEZIER) continue;
+               Bezier bez = objects.beziers[objects.data_indices[i]].CopyInverse(objects.bounds[i]);
+               
                GPUBezierCoeffs coeffs = {
-                       Float(bez->x0), Float(bez->y0),
-                       Float(bez->x1), Float(bez->y1),
-                       Float(bez->x2), Float(bez->y2),
-                       Float(bez->x3), Float(bez->y3)
+                       Float(bez.x0), Float(bez.y0),
+                       Float(bez.x1), Float(bez.y1),
+                       Float(bez.x2), Float(bez.y2),
+                       Float(bez.x3), Float(bez.y3)
                        };
                builder.Add(coeffs);
        }
@@ -299,7 +300,6 @@ void BezierRenderer::PrepareBezierGPUBuffer(const Objects& objects)
 
        m_bezier_ids.SetType(GraphicsBuffer::BufferTypeTexture);
        m_bezier_ids.SetUsage(GraphicsBuffer::BufferUsageDynamicDraw);
-       m_bezier_ids.SetName("m_bezier_ids: object data_indices");
        m_bezier_ids.Upload(objects.data_indices.size() * sizeof(uint32_t), &objects.data_indices[0]);
        
        glGenTextures(1, &m_bezier_id_buffer_texture);
@@ -328,7 +328,23 @@ void BezierRenderer::RenderUsingGPU(unsigned first_obj_id, unsigned last_obj_id)
        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, (last_index-first_index)*2, GL_UNSIGNED_INT, (GLvoid*)(2*first_index*sizeof(uint32_t)));
+       glDrawElements(GL_LINES, (last_index-first_index)*2, GL_UNSIGNED_INT, (GLvoid*)(first_index*sizeof(uint32_t)));
+}
+
+/**
+ * Render Group (shading)
+ */
+void GroupRenderer::RenderUsingCPU(const Objects & objects, const View & view, const CPURenderTarget & target, unsigned first_obj_id, unsigned last_obj_id)
+{
+       for (unsigned i = 0; i < m_indexes.size(); ++i)
+       {
+               if (m_indexes[i] < first_obj_id) continue;
+               if (m_indexes[i] >= last_obj_id) continue;
+               
+               //pair<unsigned, unsigned> range = objects.groups[m_indexes[i]];
+               
+       
+       }       
 }
 
 /**
index 697cf5b..e3872b0 100644 (file)
@@ -128,6 +128,16 @@ namespace IPDF
                        GLuint m_bezier_id_buffer_texture;
 
        };
+       
+               /** Renderer for filled circles **/
+       class GroupRenderer : public ObjectRenderer
+       {
+               public:
+                       GroupRenderer() : ObjectRenderer(GROUP, "shaders/rect_vert.glsl", "shaders/rect_frag.glsl", "shaders/rect_outline_geom.glsl") {}
+                       virtual ~GroupRenderer() {}
+                       virtual void RenderUsingCPU(const Objects & objects, const View & view, const CPURenderTarget & target, unsigned first_obj_id, unsigned last_obj_id);
+       };
+       
 }
 
 #endif //_OBJECT_RENDERER_H
index 8021ada..406cb8e 100644 (file)
@@ -2,6 +2,7 @@
 #define _REAL_H
 
 #include "common.h"
+#include <cmath>
 
 
 #define REAL_SINGLE 0
@@ -67,6 +68,7 @@ namespace IPDF
        inline double Double(float f) {return (double)f;}
        inline double Double(double f) {return (double)f;}
        inline double Double(long double f) {return (double)(f);}
+       inline double Sqrt(double f) {return sqrt(f);}
        
        inline Real Power(const Real & a, int n)
        {
@@ -80,6 +82,8 @@ namespace IPDF
                return r;
        }
        
+       
+
 }
 
 #endif //_REAL_H
diff --git a/src/svg-tests/circlepath.svg b/src/svg-tests/circlepath.svg
new file mode 100644 (file)
index 0000000..6b483eb
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink"
+     width="800" height="600"
+     transform="translate(400,300)"
+   >
+       <path transform="scale(400,300)"
+               d = "M 0,1 C 0.5522,1 1,0.5522 1,0 M 0,1 C -0.5522,1 -1,0.5522 -1,0 M 0,-1 C 0.5522,-1 1,-0.5522 1,0 M 0,-1 C -0.5522,-1 -1,-0.5522 -1,0"
+               stroke="red"
+               stroke-width="0.001"
+               fill="none"
+       />
+       
+       
+ </svg>
index 8b1857d..e0efce9 100644 (file)
@@ -28,6 +28,7 @@ View::View(Document & document, Screen & screen, const Rect & bounds, const Colo
        m_object_renderers[RECT_OUTLINE] = new RectOutlineRenderer();
        m_object_renderers[CIRCLE_FILLED] = new CircleFilledRenderer();
        m_object_renderers[BEZIER] = new BezierRenderer();
+       m_object_renderers[GROUP] = new GroupRenderer();
 
        // To add rendering for a new type of object;
        // 1. Add enum to ObjectType in ipdf.h

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