#include "objectrenderer.h"
#include "view.h"
+#include <vector>
+#include <queue>
using namespace std;
if (m_indexes[i] < first_obj_id) continue;
if (m_indexes[i] >= last_obj_id) continue;
PixelBounds bounds(CPURenderBounds(objects.bounds[m_indexes[i]], view, target));
+ FloodFillOnCPU(bounds.x+1, bounds.y+1, bounds, target, Colour(0,0,0,1));
+ /*
for (int64_t x = max((int64_t)0, bounds.x); x <= min(bounds.x+bounds.w, target.w-1); ++x)
{
for (int64_t y = max((int64_t)0, bounds.y); y <= min(bounds.y+bounds.h, target.h-1); ++y)
target.pixels[index+3] = 255;
}
}
+ */
}
}
result.h *= Real(target.h);
return result;
}
+
+ObjectRenderer::PixelPoint ObjectRenderer::CPUPointLocation(const Vec2 & point, const View & view, const CPURenderTarget & target)
+{
+ // hack...
+ Rect result = view.TransformToViewCoords(Rect(point.x, point.y,1,1));
+ int64_t x = result.x*target.w;
+ int64_t y = result.y*target.h;
+ return PixelPoint(x,y);
+}
/**
for (int64_t j = 1; j <= blen; ++j)
{
control.Evaluate(x[j % 2],y[j % 2], invblen*j);
- ObjectRenderer::RenderLineOnCPU((int64_t)Double(x[0]),(int64_t)Double(y[0]), (int64_t)Double(x[1]),(int64_t)Double(y[1]), target);
+ ObjectRenderer::RenderLineOnCPU((int64_t)Double(x[0]),(int64_t)Double(y[0]), (int64_t)Double(x[1]),(int64_t)Double(y[1]), target, Colour(0,0,0,!view.PerformingShading()));
}
/*
glDrawElements(GL_LINES, (last_index-first_index)*2, GL_UNSIGNED_INT, (GLvoid*)(2*first_index*sizeof(uint32_t)));
}
+
+
/**
- * Render Group (shading)
+ * Render Path (shading)
*/
-void GroupRenderer::RenderUsingCPU(const Objects & objects, const View & view, const CPURenderTarget & target, unsigned first_obj_id, unsigned last_obj_id)
+void PathRenderer::RenderUsingCPU(const Objects & objects, const View & view, const CPURenderTarget & target, unsigned first_obj_id, unsigned last_obj_id)
{
if (!view.ShowingObjectBounds() && !view.PerformingShading())
return;
Rect bounds(CPURenderBounds(objects.bounds[m_indexes[i]], view, target));
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())
+ const Path & path = objects.paths[objects.data_indices[m_indexes[i]]];
+ if (path.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++;
- // 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)
+ for (unsigned f = 0; f < path.m_fill_points.size(); ++f)
{
- 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)
- {
- 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)
- {
- online = true;
- continue;
- }
- else if (online)
- {
- inside = !inside;
- online = false;
- }
-
- if (inside)
- {
- 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;
- }
- }
+ PixelPoint fill_point(CPUPointLocation(path.m_fill_points[f], view, target));
+ FloodFillOnCPU(fill_point.first, fill_point.second, pix_bounds, target, path.m_fill);
}
- //#endif //SHADING_DUMB
- if (view.ShowingObjectBounds())
+
+ /*if (true)//(view.ShowingObjectBounds())
{
- 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);
- ObjectRenderer::RenderLineOnCPU(pix_bounds.x+pix_bounds.w, pix_bounds.y, pix_bounds.x+pix_bounds.w, pix_bounds.y+pix_bounds.h, target, c);
+ PixelPoint start(CPUPointLocation((path.m_top+path.m_left+path.m_right+path.m_bottom)/4, view, target));
+ for (unsigned f = 0; f < path.m_fill_points.size(); ++f)
+ {
+ PixelPoint end(CPUPointLocation(path.m_fill_points[f], view, target));
+ RenderLineOnCPU(start.first, start.second, end.first, end.second, target, Colour(0,0,1,1));
+ }
}
-
+ */
}
}
} while (++x <= x_end);
}
+void ObjectRenderer::FloodFillOnCPU(int64_t x, int64_t y, const PixelBounds & bounds, const CPURenderTarget & target, const Colour & fill)
+{
+ if (fill == Colour(1,1,1,1))
+ return;
+ queue<PixelPoint > traverse;
+ traverse.push(PixelPoint(x,y));
+ // now with 100% less stack overflows!
+ while (traverse.size() > 0)
+ {
+ PixelPoint cur(traverse.front());
+ traverse.pop();
+ if (cur.first < 0 || cur.first < bounds.x || cur.first >= bounds.x+bounds.w || cur.first >= target.w ||
+ cur.second < 0 || cur.second < bounds.y || cur.second >= bounds.y+bounds.h || cur.second >= target.h)
+ continue;
+ if (GetColour(target, cur.first, cur.second) != Colour(1,1,1,1))
+ continue;
+ SetColour(target, cur.first, cur.second, fill);
+
+
+ traverse.push(PixelPoint(cur.first+1, cur.second));
+ traverse.push(PixelPoint(cur.first-1, cur.second));
+ traverse.push(PixelPoint(cur.first, cur.second-1));
+ traverse.push(PixelPoint(cur.first, cur.second+1));
+ }
+}
+
}