Shading still doesn't work
authorSam Moore <[email protected]>
Mon, 25 Aug 2014 14:44:33 +0000 (22:44 +0800)
committerSam Moore <[email protected]>
Mon, 25 Aug 2014 14:44:33 +0000 (22:44 +0800)
Actually it's supposed to be "filling" shading implies the colour changes.
Whatever.

src/Makefile
src/bezier.h
src/document.cpp
src/document.h
src/group.cpp [new file with mode: 0644]
src/group.h [new file with mode: 0644]
src/ipdf.h
src/objectrenderer.cpp
src/objectrenderer.h
src/svg-tests/rectpath.svg [new file with mode: 0644]

index bc07e1e..af72dfa 100644 (file)
@@ -3,7 +3,7 @@ ARCH := $(shell uname -m)
 # TODO: stb_truetype doesn't compile with some of these warnings.
 CXX = g++ -std=gnu++0x -g -Wall -Werror -Wshadow -pedantic -rdynamic
 MAIN = main.o
-OBJ = log.o real.o bezier.o document.o objectrenderer.o view.o screen.o vfpu.o quadtree.o graphicsbuffer.o framebuffer.o shaderprogram.o stb_truetype.o gl_core44.o add_digits_asm.o sub_digits_asm.o mul_digits_asm.o div_digits_asm.o arbint.o moc_controlpanel.o controlpanel.o
+OBJ = log.o real.o bezier.o document.o objectrenderer.o view.o screen.o vfpu.o quadtree.o graphicsbuffer.o framebuffer.o shaderprogram.o stb_truetype.o gl_core44.o add_digits_asm.o sub_digits_asm.o mul_digits_asm.o div_digits_asm.o arbint.o moc_controlpanel.o controlpanel.o group.o
 
 QT_INCLUDE := -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -Itests -I.
 QT_DEF := -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB
index 9273cee..6a134b7 100644 (file)
@@ -62,14 +62,17 @@ namespace IPDF
                Real x1; Real y1;
                Real x2; Real y2;
                Real x3; Real y3;
+               
+               typedef enum {LINE, QUADRATIC, CUSP, LOOP, SERPENTINE} Type;
+               Type type;
+               
                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) 
                {
-                       
+                       //TODO: classify the curve
+                       type = SERPENTINE;
                }
                
-               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) {}
-               
                std::string Str() const
                {
                        std::stringstream s;
@@ -81,7 +84,7 @@ namespace IPDF
                 * 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)
+               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), type(cpy.type)
                {
                        x0 *= t.w;
                        y0 *= t.h;
index 8a5635c..72a12c1 100644 (file)
@@ -284,7 +284,7 @@ void Document::Load(const string & filename)
 #endif
 }
 
-unsigned Document::AddGroup(unsigned start_index, unsigned end_index, const Colour & shading)
+unsigned Document::AddGroup(unsigned start_index, unsigned end_index, const Colour & fill)
 {
        Real xmin = 0; Real ymin = 0; 
        Real xmax = 0; Real ymax = 0;
@@ -306,7 +306,7 @@ unsigned Document::AddGroup(unsigned start_index, unsigned end_index, const Colo
        
        Rect bounds(xmin,ymin, xmax-xmin, ymax-ymin);
        
-       Group group = {start_index, end_index, shading};
+       Group group(start_index, end_index, 0U, fill);
        
        unsigned data_index = AddGroupData(group);
        unsigned result = Add(GROUP, bounds,data_index);
index df818f2..cab7684 100644 (file)
@@ -52,7 +52,7 @@ namespace IPDF
                        bool operator==(const Document & equ) const;
                        bool operator!=(const Document & equ) const {return !(this->operator==(equ));}
 
-                       unsigned AddGroup(unsigned start_index, unsigned end_index, const Colour & shading=Colour(0.1,0.1,0.1,1));
+                       unsigned AddGroup(unsigned start_index, unsigned end_index, const Colour & shading=Colour(0.6,0.6,0.6,1));
                        unsigned AddBezier(const Bezier & bezier);
                        unsigned Add(ObjectType type, const Rect & bounds, unsigned data_index = 0);
                        unsigned AddBezierData(const Bezier & bezier);
diff --git a/src/group.cpp b/src/group.cpp
new file mode 100644 (file)
index 0000000..8407a4b
--- /dev/null
@@ -0,0 +1,8 @@
+#include "group.h"
+using namespace std;
+
+namespace IPDF
+{
+       
+               
+}
diff --git a/src/group.h b/src/group.h
new file mode 100644 (file)
index 0000000..f72369b
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef _GROUP_H
+#define _GROUP_H
+
+#include <vector>
+#include <algorithm>
+
+namespace IPDF
+{
+       
+       struct Colour
+       {
+               float r; float g; float b; float a;
+               Colour() = default;
+               Colour(float _r, float _g, float _b, float _a) : r(_r), g(_g), b(_b), a(_a) {}
+       };
+       
+       class Objects;
+       
+       struct Group
+       {
+               Group(unsigned _start, unsigned _end, unsigned _index, const Colour & _fill = Colour(0.8,0.8,0.8,1))
+                       : m_start(_start), m_end(_end), m_index(_index), m_fill(_fill)
+               {
+                       
+               }
+               unsigned m_start;
+               unsigned m_end;
+               unsigned m_index;
+               Colour m_fill;          
+       };
+
+}
+#endif //_GROUP_H
index 968a3ed..f9d3a96 100644 (file)
@@ -6,10 +6,7 @@
 #include "bezier.h"
 #include "rect.h"
 
-#define C_RED Colour(1,0,0,1)
-#define C_GREEN Colour(0,1,0,1)
-#define C_BLUE Colour(0,0,1,1)
-#define C_BLACK Colour(0,0,0,1);
+#include "group.h"
 
 namespace IPDF
 {
@@ -43,24 +40,6 @@ namespace IPDF
                CT_OBJGROUPS
        };
 
-
-
-       
-       
-       struct Colour
-       {
-               float r; float g; float b; float a;
-               Colour() = default;
-               Colour(float _r, float _g, float _b, float _a) : r(_r), g(_g), b(_b), a(_a) {}
-       };
-       
-       struct Group
-       {
-               unsigned start;
-               unsigned end;
-               Colour shading;
-       };
-
        struct Objects
        {
                /** Used by all objects **/
index 967f7e1..6108f4f 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "objectrenderer.h"
 #include "view.h"
+#include <list>
 
 using namespace std;
 
@@ -331,6 +332,13 @@ void BezierRenderer::RenderUsingGPU(unsigned first_obj_id, unsigned last_obj_id)
        glDrawElements(GL_LINES, (last_index-first_index)*2, GL_UNSIGNED_INT, (GLvoid*)(2*first_index*sizeof(uint32_t)));
 }
 
+inline bool IsBlack(uint8_t * pixels, int64_t index)
+{
+       bool result = (pixels[index+0] == 0 && pixels[index+1] == 0 && pixels[index+2] == 0 && pixels[index+3] == 255);
+       //pixels[index+3] = 254; // hax
+       return result;
+}
+
 /**
  * Render Group (shading)
  */
@@ -349,50 +357,73 @@ void GroupRenderer::RenderUsingCPU(const Objects & objects, const View & view, c
                PixelBounds pix_bounds(bounds);
                
                const Group & group = objects.groups[objects.data_indices[m_indexes[i]]];
-               const Colour & c = group.shading;
-               if (c.a == 0 || !view.PerformingShading())
+               if (group.m_fill.a == 0 || !view.PerformingShading())
                        continue;
 
                // make the bounds just a little bit bigger
-               pix_bounds.x--;
-               pix_bounds.w++;
-               pix_bounds.y--;
-               pix_bounds.h++;
+               pix_bounds.x-=1;
+               pix_bounds.w+=2;
+               pix_bounds.y-=1;
+               pix_bounds.h+=2;
                
                // Attempt to shade the region
                // Assumes the outline has been drawn first...
                //#ifdef SHADING_DUMB
                for (int64_t y = max((int64_t)0, pix_bounds.y); y <= min(pix_bounds.y+pix_bounds.h, target.h-1); ++y)
                {
-                       bool inside = false;
-                       bool online = false;
-                       for (int64_t x = max((int64_t)0, pix_bounds.x); x <= min(pix_bounds.x+pix_bounds.w, target.w-1); ++x)
+                       struct Segment
                        {
-                               int64_t index = (x+target.w*y)*4;
-                               if (target.pixels[index+0] == 0 && target.pixels[index+1] == 0 && target.pixels[index+2] == 0 && target.pixels[index+3] == 255)
+                               int64_t first;
+                               int64_t second;
+                               bool all_black;
+                       };
+                       list<Segment> segments;
+                       int64_t min_x = max((int64_t)0, pix_bounds.x);
+                       int64_t max_x = min(pix_bounds.x+pix_bounds.w, target.w-1);
+                       int64_t yy = y*target.w;
+
+                       int64_t x = min_x;
+                       while (x <= max_x)
+                       {
+                               bool start_black = IsBlack(target.pixels, 4*(x+yy));
+                               bool black = start_black;
+                               segments.push_back({x,x,start_black});
+                               while (black == start_black && ++x <= max_x)
                                {
-                                       online = true;
-                                       continue;
+                                       black = IsBlack(target.pixels, 4*(x+yy));
                                }
-                               else if (online)
+                               segments.back().second = x-1;
+                       }
+                       
+                       // Keep only the interior segments
+                       list<Segment>::iterator j = segments.begin();
+                       //TODO: Magically delete unneeded segments here...
+                       
+                       // Fill in remaining segments
+                       for (j=segments.begin(); j != segments.end(); ++j)
+                       {
+                               Colour c(group.m_fill);
+                               if (j->all_black)
                                {
-                                       inside = !inside;
-                                       online = false;
+                                       c.r = 1;//1; // Change to debug the outline scanning
+                                       c.g = 0;
+                                       c.b = 0;
+                                       c.a = 1;
                                }
-                               
-                               if (inside)
+                               for (x = max(min_x, j->first); x <= min(max_x, j->second); ++x)
                                {
-                                       target.pixels[index+0] = c.r*255;
-                                       target.pixels[index+1] = c.g*255;
-                                       target.pixels[index+2] = c.b*255;
-                                       target.pixels[index+3] = c.a*255;
+                                       int64_t index = 4*(x+yy);
+                                       target.pixels[index+0] = 255*c.r;
+                                       target.pixels[index+1] = 255*c.g;
+                                       target.pixels[index+2] = 255*c.b;
+                                       target.pixels[index+3] = 255*c.a;
                                }
                        }
                }
                //#endif //SHADING_DUMB
                if (view.ShowingObjectBounds())
                {
-                       
+                       const Colour & c = group.m_fill;
                        ObjectRenderer::RenderLineOnCPU(pix_bounds.x, pix_bounds.y, pix_bounds.x+pix_bounds.w, pix_bounds.y, target, c);
                        ObjectRenderer::RenderLineOnCPU(pix_bounds.x, pix_bounds.y+pix_bounds.h, pix_bounds.x+pix_bounds.w, pix_bounds.y+pix_bounds.h, target, c);
                        ObjectRenderer::RenderLineOnCPU(pix_bounds.x, pix_bounds.y, pix_bounds.x, pix_bounds.y+pix_bounds.h, target, c);
index 70339e7..8f52aa0 100644 (file)
@@ -11,6 +11,7 @@
 #include "shaderprogram.h"
 #include "bufferbuilder.h"
 
+
 namespace IPDF
 {
        class View;
diff --git a/src/svg-tests/rectpath.svg b/src/svg-tests/rectpath.svg
new file mode 100644 (file)
index 0000000..61fa957
--- /dev/null
@@ -0,0 +1,17 @@
+<?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="100" height="100"
+
+   >
+       <path 
+               d = "M 0,0 0,100 100,100 100,0 Z M 25,25 25,75 75,75 75,25 25,25"
+               fill="#f0f0f0"
+       />
+       
+       
+ </svg>
+

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