Closed RobLoach closed 3 weeks ago
PNTR_NUKLEAR_API void pntr_nuklear_draw_polygon_fill(pntr_image* dst, const struct nk_vec2i *pnts, int count, pntr_color col) {
int i = 0;
#define MAX_POINTS 64
int left = 10000, top = 10000, bottom = 0, right = 0;
int nodes, nodeX[MAX_POINTS], pixelX, pixelY, j, swap ;
if (count == 0) return;
if (count > MAX_POINTS)
count = MAX_POINTS;
/* Get polygon dimensions */
for (i = 0; i < count; i++) {
if (left > pnts[i].x)
left = pnts[i].x;
if (right < pnts[i].x)
right = pnts[i].x;
if (top > pnts[i].y)
top = pnts[i].y;
if (bottom < pnts[i].y)
bottom = pnts[i].y;
} bottom++; right++;
/* Polygon scanline algorithm released under public-domain by Darel Rex Finley, 2007 */
/* Loop through the rows of the image. */
for (pixelY = top; pixelY < bottom; pixelY ++) {
nodes = 0; /* Build a list of nodes. */
j = count - 1;
for (i = 0; i < count; i++) {
if (((pnts[i].y < pixelY) && (pnts[j].y >= pixelY)) ||
((pnts[j].y < pixelY) && (pnts[i].y >= pixelY))) {
nodeX[nodes++]= (int)((float)pnts[i].x
+ ((float)pixelY - (float)pnts[i].y) / ((float)pnts[j].y - (float)pnts[i].y)
* ((float)pnts[j].x - (float)pnts[i].x));
} j = i;
}
/* Sort the nodes, via a simple “Bubble” sort. */
i = 0;
while (i < nodes - 1) {
if (nodeX[i] > nodeX[i+1]) {
swap = nodeX[i];
nodeX[i] = nodeX[i+1];
nodeX[i+1] = swap;
if (i) i--;
} else i++;
}
/* Fill the pixels between node pairs. */
for (i = 0; i < nodes; i += 2) {
if (nodeX[i+0] >= right) break;
if (nodeX[i+1] > left) {
if (nodeX[i+0] < left) nodeX[i+0] = left ;
if (nodeX[i+1] > right) nodeX[i+1] = right;
for (pixelX = nodeX[i]; pixelX < nodeX[i + 1]; pixelX++)
//nk_rawfb_ctx_setpixel(rawfb, pixelX, pixelY, col);
pntr_draw_point(dst, pixelX, pixelY, col);
}
}
}
#undef MAX_POINTS
}
/**
* @internal
*/
PNTR_NUKLEAR_API void pntr_nuklear_draw_stroke_curve(pntr_image* rawfb,
const struct nk_vec2i p1, const struct nk_vec2i p2,
const struct nk_vec2i p3, const struct nk_vec2i p4,
const unsigned int num_segments, const unsigned short line_thickness,
pntr_color col)
{
unsigned int i_step, segments;
float t_step;
struct nk_vec2i last = p1;
segments = PNTR_MAX(num_segments, 1);
t_step = 1.0f/(float)segments;
for (i_step = 1; i_step <= segments; ++i_step) {
float t = t_step * (float)i_step;
float u = 1.0f - t;
float w1 = u*u*u;
float w2 = 3*u*u*t;
float w3 = 3*u*t*t;
float w4 = t * t *t;
float x = w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x;
float y = w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y;
// TODO: Add line_thickness to pntr_nuklear_draw_stroke_curve
pntr_draw_line(rawfb, last.x, last.y, (int)x, (int)y, col);
last.x = (short)x; last.y = (short)y;
}
}
Anything we can learn from nuklear_rawfb? https://github.com/Immediate-Mode-UI/Nuklear/blob/master/demo/rawfb/nuklear_rawfb.h