kopia lustrzana https://github.com/pimoroni/pimoroni-pico
PicoVector: Faster polygon rendering.
rodzic
12228c4036
commit
d84a1e3470
|
@ -488,45 +488,44 @@ void add_line_segment_to_nodes(const pp_point_t start, const pp_point_t end, pp_
|
|||
x += xinc * xjump;
|
||||
}
|
||||
|
||||
// #ifdef USE_RP2040_INTERP
|
||||
// interp1->base[1] = full_tile_width;
|
||||
// interp1->accum[0] = x;
|
||||
int32_t *pp_scanline_nodes = &pp_nodes[y * _pp_max_nodes_per_scanline * 2];
|
||||
const int32_t nodes_step = _pp_max_nodes_per_scanline * 2;
|
||||
|
||||
// // loop over scanlines
|
||||
// while(count--) {
|
||||
// // consume accumulated error
|
||||
// while(e > dy) {e -= dy; interp1->add_raw[0] = xinc;}
|
||||
const int full_tile_width = (tb->w << _pp_antialias);
|
||||
if (false && _pp_min(x, ex) >= 0 && _pp_max(x, ex) <= full_tile_width) {
|
||||
// loop over scanlines
|
||||
while(count--) {
|
||||
// consume accumulated error
|
||||
while(e > dy) {e -= dy; x += xinc;}
|
||||
|
||||
// // clamp node x value to tile bounds
|
||||
// const int nx = interp1->peek[0];
|
||||
// debug(" + adding node at %d, %d\n", x, y);
|
||||
// // add node to node list
|
||||
// pp_nodes[y][pp_node_counts[y]++] = nx;
|
||||
//debug(" + adding node at %d, %d\n", x, y);
|
||||
// add node to node list
|
||||
pp_scanline_nodes[pp_node_counts[y]++] = x;
|
||||
|
||||
// // step to next scanline and accumulate error
|
||||
// y++;
|
||||
// e += einc;
|
||||
// }
|
||||
// #else
|
||||
// loop over scanlines
|
||||
|
||||
while(count--) {
|
||||
int32_t *pp_scanline_nodes = &pp_nodes[y * _pp_max_nodes_per_scanline * 2];
|
||||
|
||||
// consume accumulated error
|
||||
while(e > dy) {e -= dy; x += xinc;}
|
||||
|
||||
// clamp node x value to tile bounds
|
||||
int nx = _pp_max(_pp_min(x, (tb->w << _pp_antialias)), 0);
|
||||
//debug(" + adding node at %d, %d\n", x, y);
|
||||
// add node to node list
|
||||
pp_scanline_nodes[pp_node_counts[y]++] = nx;
|
||||
|
||||
// step to next scanline and accumulate error
|
||||
y++;
|
||||
e += einc;
|
||||
// step to next scanline and accumulate error
|
||||
y++;
|
||||
e += einc;
|
||||
pp_scanline_nodes += nodes_step;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// loop over scanlines
|
||||
while(count--) {
|
||||
// consume accumulated error
|
||||
while(e > dy) {e -= dy; x += xinc;}
|
||||
|
||||
// clamp node x value to tile bounds
|
||||
int nx = _pp_max(_pp_min(x, full_tile_width), 0);
|
||||
//debug(" + adding node at %d, %d\n", x, y);
|
||||
// add node to node list
|
||||
pp_scanline_nodes[pp_node_counts[y]++] = nx;
|
||||
|
||||
// step to next scanline and accumulate error
|
||||
y++;
|
||||
e += einc;
|
||||
pp_scanline_nodes += nodes_step;
|
||||
}
|
||||
}
|
||||
//#endif
|
||||
}
|
||||
|
||||
void build_nodes(pp_path_t *path, pp_rect_t *tb) {
|
||||
|
@ -555,8 +554,9 @@ int compare_nodes(const void* a, const void* b) {
|
|||
}
|
||||
|
||||
pp_rect_t render_nodes(pp_rect_t *tb) {
|
||||
pp_rect_t rb = {PP_TILE_BUFFER_SIZE << _pp_antialias, PP_TILE_BUFFER_SIZE << _pp_antialias, 0, 0}; // render bounds
|
||||
int maxx = 0, minx = PP_TILE_BUFFER_SIZE << _pp_antialias;
|
||||
pp_rect_t rb = {PP_TILE_BUFFER_SIZE << _pp_antialias, 0, 0, 0}; // render bounds
|
||||
int maxx = 0, maxy = -1;
|
||||
const int antialias_mask = (1 << _pp_antialias) - 1;
|
||||
debug(" + render tile %d, %d - %d, %d\n", tb->x, tb->y, tb->w, tb->h);
|
||||
|
||||
for(int y = 0; y < ((int)PP_TILE_BUFFER_SIZE << _pp_antialias); y++) {
|
||||
|
@ -570,6 +570,9 @@ pp_rect_t render_nodes(pp_rect_t *tb) {
|
|||
|
||||
unsigned char* row_data = &pp_tile_buffer[(y >> _pp_antialias) * PP_TILE_BUFFER_SIZE];
|
||||
|
||||
bool rendered_any = false;
|
||||
|
||||
rb.x = _pp_min(rb.x, *pp_scanline_nodes);
|
||||
for(uint32_t i = 0; i < pp_node_counts[y]; i += 2) {
|
||||
int sx = *pp_scanline_nodes++;
|
||||
int ex = *pp_scanline_nodes++;
|
||||
|
@ -579,22 +582,44 @@ pp_rect_t render_nodes(pp_rect_t *tb) {
|
|||
}
|
||||
|
||||
// update render bounds
|
||||
rb.x = _pp_min(rb.x, sx);
|
||||
rb.y = _pp_min(rb.y, y);
|
||||
minx = _pp_min(_pp_min(sx, ex), minx);
|
||||
maxx = _pp_max(_pp_max(sx, ex), maxx);
|
||||
rb.h = y - rb.y + 1;
|
||||
rendered_any = true;
|
||||
|
||||
//debug(" - render span at %d from %d to %d\n", y, sx, ex);
|
||||
if (_pp_antialias) {
|
||||
int ax = sx >> _pp_antialias;
|
||||
const int aex = ex >> _pp_antialias;
|
||||
|
||||
// rasterise the span into the tile buffer
|
||||
do {
|
||||
row_data[sx >> _pp_antialias]++;
|
||||
} while(++sx < ex);
|
||||
if (ax == aex) {
|
||||
row_data[ax] += ex - sx;
|
||||
continue;
|
||||
}
|
||||
|
||||
row_data[ax] += (1 << _pp_antialias) - (sx & antialias_mask);
|
||||
for(ax++; ax < aex; ax++) {
|
||||
row_data[ax] += (1 << _pp_antialias);
|
||||
}
|
||||
|
||||
// This might add 0 to the byte after the end of the row,
|
||||
// TODO check that's OK
|
||||
row_data[ax] += ex & antialias_mask;
|
||||
}
|
||||
else {
|
||||
for(int x = sx; x < ex; x++) {
|
||||
row_data[x]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
maxx = _pp_max(*(pp_scanline_nodes-1) - 1, maxx);
|
||||
if (rendered_any) {
|
||||
maxy = y;
|
||||
}
|
||||
else if (y == rb.y) {
|
||||
++rb.y;
|
||||
}
|
||||
}
|
||||
|
||||
rb.w = maxx - minx;
|
||||
rb.w = (maxx >= rb.x) ? maxx + 1 - rb.x : 0;
|
||||
rb.h = (maxy >= rb.y) ? maxy + 1 - rb.y : 0;
|
||||
|
||||
// shifting the width and height effectively "floors" the result which can
|
||||
// mean we lose a pixel off the right or bottom edge of the tile. by adding
|
||||
|
|
Ładowanie…
Reference in New Issue