add more checks in triangle raster code
This commit is contained in:
parent
79a678f162
commit
9550d34e65
7 changed files with 357 additions and 260 deletions
363
src/pxl8_gfx.c
363
src/pxl8_gfx.c
|
|
@ -416,7 +416,7 @@ void pxl8_clr(pxl8_gfx* gfx, u32 color) {
|
|||
if (frame_count % 60 == 0) {
|
||||
i32 fb_pixels = gfx->framebuffer_width * gfx->framebuffer_height;
|
||||
f32 overdraw = (f32)gfx->frame_pixel_count / (f32)fb_pixels;
|
||||
pxl8_debug("Frame triangles: %u, pixels: %u, overdraw: %.2fx",
|
||||
pxl8_trace("Frame triangles: %u, pixels: %u, overdraw: %.2fx",
|
||||
gfx->frame_triangle_count, gfx->frame_pixel_count, overdraw);
|
||||
}
|
||||
frame_count++;
|
||||
|
|
@ -1033,7 +1033,7 @@ static inline u32 pxl8_sample_texture(pxl8_gfx* gfx, u32 texture_id, f32 u, f32
|
|||
}
|
||||
}
|
||||
|
||||
static inline void pxl8_fill_scanline_textured(
|
||||
static inline void pxl8_fill_scanline_textured_hicolor(
|
||||
pxl8_gfx* gfx, i32 y, i32 xs, i32 xe,
|
||||
f32 z0, f32 z1,
|
||||
f32 u0, f32 v0, f32 w0,
|
||||
|
|
@ -1062,8 +1062,7 @@ static inline void pxl8_fill_scanline_textured(
|
|||
v /= w0;
|
||||
}
|
||||
u32 color = pxl8_sample_texture(gfx, texture_id, u, v);
|
||||
if ((gfx->color_mode == PXL8_COLOR_MODE_HICOLOR && (color & 0xFF000000)) ||
|
||||
(gfx->color_mode != PXL8_COLOR_MODE_HICOLOR && color != 0)) {
|
||||
if (color & 0xFF000000) {
|
||||
gfx->zbuffer[idx] = z0;
|
||||
pxl8_pixel(gfx, xs, y, color);
|
||||
}
|
||||
|
|
@ -1083,122 +1082,147 @@ static inline void pxl8_fill_scanline_textured(
|
|||
f32 v = v0;
|
||||
f32 w = w0;
|
||||
|
||||
if (gfx->affine_textures) {
|
||||
for (i32 x = xs; x <= xe; x++) {
|
||||
if (x >= 0 && x < gfx->framebuffer_width) {
|
||||
i32 idx = y * gfx->zbuffer_width + x;
|
||||
if (z <= gfx->zbuffer[idx]) {
|
||||
gfx->frame_pixel_count++;
|
||||
u32 color = pxl8_sample_texture(gfx, texture_id, u, v);
|
||||
if ((gfx->color_mode == PXL8_COLOR_MODE_HICOLOR && (color & 0xFF000000)) ||
|
||||
(gfx->color_mode != PXL8_COLOR_MODE_HICOLOR && color != 0)) {
|
||||
gfx->zbuffer[idx] = z;
|
||||
pxl8_pixel(gfx, x, y, color);
|
||||
}
|
||||
for (i32 x = xs; x <= xe; x++) {
|
||||
if (x >= 0 && x < gfx->framebuffer_width) {
|
||||
i32 idx = y * gfx->zbuffer_width + x;
|
||||
if (z <= gfx->zbuffer[idx]) {
|
||||
gfx->frame_pixel_count++;
|
||||
f32 tex_u = u, tex_v = v;
|
||||
if (!gfx->affine_textures && fabsf(w) > 1e-6f) {
|
||||
tex_u /= w;
|
||||
tex_v /= w;
|
||||
}
|
||||
u32 color = pxl8_sample_texture(gfx, texture_id, tex_u, tex_v);
|
||||
if (color & 0xFF000000) {
|
||||
gfx->zbuffer[idx] = z;
|
||||
pxl8_pixel(gfx, x, y, color);
|
||||
}
|
||||
}
|
||||
z += dz;
|
||||
u += du;
|
||||
v += dv;
|
||||
}
|
||||
} else {
|
||||
i32 x = xs;
|
||||
while (x <= xe) {
|
||||
f32 w_inv = (fabsf(w) > 1e-6f) ? (1.0f / w) : 0.0f;
|
||||
f32 u_corrected = u * w_inv;
|
||||
f32 v_corrected = v * w_inv;
|
||||
z += dz;
|
||||
u += du;
|
||||
v += dv;
|
||||
w += dw;
|
||||
}
|
||||
}
|
||||
|
||||
i32 span_end = (x + 16 <= xe) ? (x + 16) : (xe + 1);
|
||||
i32 span_len = span_end - x;
|
||||
static inline void pxl8_fill_scanline_textured_indexed(
|
||||
pxl8_gfx* gfx, i32 y, i32 xs, i32 xe,
|
||||
f32 z0, f32 z1,
|
||||
f32 u0, f32 v0, f32 w0,
|
||||
f32 u1, f32 v1, f32 w1,
|
||||
u32 texture_id
|
||||
) {
|
||||
if (y < 0 || y >= gfx->framebuffer_height) return;
|
||||
if (xs > xe) {
|
||||
i32 tmp = xs; xs = xe; xe = tmp;
|
||||
f32 tmpf;
|
||||
tmpf = z0; z0 = z1; z1 = tmpf;
|
||||
tmpf = u0; u0 = u1; u1 = tmpf;
|
||||
tmpf = v0; v0 = v1; v1 = tmpf;
|
||||
tmpf = w0; w0 = w1; w1 = tmpf;
|
||||
}
|
||||
|
||||
f32 next_u, next_v, affine_du, affine_dv;
|
||||
if (span_len > 1) {
|
||||
f32 next_w = w + span_len * dw;
|
||||
f32 next_w_inv = (fabsf(next_w) > 1e-6f) ? (1.0f / next_w) : 0.0f;
|
||||
next_u = (u + span_len * du) * next_w_inv;
|
||||
next_v = (v + span_len * dv) * next_w_inv;
|
||||
f32 inv_span = 1.0f / (f32)span_len;
|
||||
affine_du = (next_u - u_corrected) * inv_span;
|
||||
affine_dv = (next_v - v_corrected) * inv_span;
|
||||
} else {
|
||||
affine_du = 0;
|
||||
affine_dv = 0;
|
||||
}
|
||||
|
||||
f32 affine_u = u_corrected;
|
||||
f32 affine_v = v_corrected;
|
||||
|
||||
for (; x < span_end; x++) {
|
||||
if (x >= 0 && x < gfx->framebuffer_width) {
|
||||
i32 idx = y * gfx->zbuffer_width + x;
|
||||
if (z <= gfx->zbuffer[idx]) {
|
||||
gfx->frame_pixel_count++;
|
||||
u32 color = pxl8_sample_texture(gfx, texture_id, affine_u, affine_v);
|
||||
if ((gfx->color_mode == PXL8_COLOR_MODE_HICOLOR && (color & 0xFF000000)) ||
|
||||
(gfx->color_mode != PXL8_COLOR_MODE_HICOLOR && color != 0)) {
|
||||
gfx->zbuffer[idx] = z;
|
||||
pxl8_pixel(gfx, x, y, color);
|
||||
}
|
||||
}
|
||||
i32 span = xe - xs;
|
||||
if (span <= 0) {
|
||||
if (xs >= 0 && xs < gfx->framebuffer_width) {
|
||||
i32 idx = y * gfx->zbuffer_width + xs;
|
||||
if (z0 <= gfx->zbuffer[idx]) {
|
||||
gfx->frame_pixel_count++;
|
||||
f32 u = u0, v = v0;
|
||||
if (!gfx->affine_textures && fabsf(w0) > 1e-6f) {
|
||||
u /= w0;
|
||||
v /= w0;
|
||||
}
|
||||
u32 color = pxl8_sample_texture(gfx, texture_id, u, v);
|
||||
if (color != 0) {
|
||||
gfx->zbuffer[idx] = z0;
|
||||
pxl8_pixel(gfx, xs, y, color);
|
||||
}
|
||||
z += dz;
|
||||
u += du;
|
||||
v += dv;
|
||||
w += dw;
|
||||
affine_u += affine_du;
|
||||
affine_v += affine_dv;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
f32 inv_span = 1.0f / (f32)span;
|
||||
f32 dz = (z1 - z0) * inv_span;
|
||||
f32 du = (u1 - u0) * inv_span;
|
||||
f32 dv = (v1 - v0) * inv_span;
|
||||
f32 dw = (w1 - w0) * inv_span;
|
||||
|
||||
f32 z = z0;
|
||||
f32 u = u0;
|
||||
f32 v = v0;
|
||||
f32 w = w0;
|
||||
|
||||
for (i32 x = xs; x <= xe; x++) {
|
||||
if (x >= 0 && x < gfx->framebuffer_width) {
|
||||
i32 idx = y * gfx->zbuffer_width + x;
|
||||
if (z <= gfx->zbuffer[idx]) {
|
||||
gfx->frame_pixel_count++;
|
||||
f32 tex_u = u, tex_v = v;
|
||||
if (!gfx->affine_textures && fabsf(w) > 1e-6f) {
|
||||
tex_u /= w;
|
||||
tex_v /= w;
|
||||
}
|
||||
u32 color = pxl8_sample_texture(gfx, texture_id, tex_u, tex_v);
|
||||
if (color != 0) {
|
||||
gfx->zbuffer[idx] = z;
|
||||
pxl8_pixel(gfx, x, y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
z += dz;
|
||||
u += du;
|
||||
v += dv;
|
||||
w += dw;
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (*pxl8_scanline_func)(pxl8_gfx*, i32, i32, i32, f32, f32, u32);
|
||||
typedef void (*pxl8_scanline_textured_func)(pxl8_gfx*, i32, i32, i32, f32, f32, f32, f32, f32, f32, f32, f32, u32);
|
||||
|
||||
static void pxl8_draw_flat_bottom_triangle(
|
||||
static void pxl8_scan_triangle(
|
||||
pxl8_gfx* gfx,
|
||||
i32 x0, i32 y0, f32 z0,
|
||||
i32 x1, i32 y1, f32 z1,
|
||||
i32 x2, i32 y2, f32 z2,
|
||||
u32 color,
|
||||
pxl8_scanline_func fill_scanline
|
||||
pxl8_scanline_func fill_scanline,
|
||||
bool is_bottom
|
||||
) {
|
||||
(void)z2;
|
||||
if (y1 == y0) return;
|
||||
|
||||
f32 inv_slope_1 = (f32)(x1 - x0) / (f32)(y1 - y0);
|
||||
f32 inv_slope_2 = (f32)(x2 - x0) / (f32)(y2 - y0);
|
||||
i32 y_start, y_end, y_step;
|
||||
f32 x_start1, x_start2, inv_slope_1, inv_slope_2;
|
||||
|
||||
f32 cur_x1 = (f32)x0;
|
||||
f32 cur_x2 = (f32)x0;
|
||||
|
||||
for (i32 y = y0; y <= y1; y++) {
|
||||
fill_scanline(gfx, y, (i32)cur_x1, (i32)cur_x2, z0, z1, color);
|
||||
cur_x1 += inv_slope_1;
|
||||
cur_x2 += inv_slope_2;
|
||||
if (is_bottom) {
|
||||
if (y1 == y0 || y1 < y0 || y1 - y0 > gfx->framebuffer_height) return;
|
||||
y_start = y0;
|
||||
y_end = y1;
|
||||
y_step = 1;
|
||||
x_start1 = x_start2 = (f32)x0;
|
||||
inv_slope_1 = (f32)(x1 - x0) / (f32)(y1 - y0);
|
||||
inv_slope_2 = (f32)(x2 - x0) / (f32)(y2 - y0);
|
||||
} else {
|
||||
if (y2 == y0 || y2 < y0 || y2 - y0 > gfx->framebuffer_height) return;
|
||||
y_start = y2;
|
||||
y_end = y0;
|
||||
y_step = -1;
|
||||
x_start1 = x_start2 = (f32)x2;
|
||||
inv_slope_1 = (f32)(x2 - x0) / (f32)(y2 - y0);
|
||||
inv_slope_2 = (f32)(x2 - x1) / (f32)(y2 - y1);
|
||||
}
|
||||
}
|
||||
|
||||
static void pxl8_draw_flat_top_triangle(
|
||||
pxl8_gfx* gfx,
|
||||
i32 x0, i32 y0, f32 z0,
|
||||
i32 x1, i32 y1, f32 z1,
|
||||
i32 x2, i32 y2, f32 z2,
|
||||
u32 color,
|
||||
pxl8_scanline_func fill_scanline
|
||||
) {
|
||||
(void)z2;
|
||||
if (y2 == y0) return;
|
||||
f32 cur_x1 = x_start1;
|
||||
f32 cur_x2 = x_start2;
|
||||
f32 slope_step1 = inv_slope_1 * y_step;
|
||||
f32 slope_step2 = inv_slope_2 * y_step;
|
||||
|
||||
f32 inv_slope_1 = (f32)(x2 - x0) / (f32)(y2 - y0);
|
||||
f32 inv_slope_2 = (f32)(x2 - x1) / (f32)(y2 - y1);
|
||||
|
||||
f32 cur_x1 = (f32)x2;
|
||||
f32 cur_x2 = (f32)x2;
|
||||
|
||||
for (i32 y = y2; y > y0; y--) {
|
||||
for (i32 y = y_start; y != y_end + y_step; y += y_step) {
|
||||
fill_scanline(gfx, y, (i32)cur_x1, (i32)cur_x2, z0, z1, color);
|
||||
cur_x1 -= inv_slope_1;
|
||||
cur_x2 -= inv_slope_2;
|
||||
cur_x1 += slope_step1;
|
||||
cur_x2 += slope_step2;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1266,16 +1290,16 @@ void pxl8_3d_draw_triangle(pxl8_gfx* gfx, pxl8_triangle tri) {
|
|||
: pxl8_fill_scanline_indexed;
|
||||
|
||||
if (y1 == y2) {
|
||||
pxl8_draw_flat_bottom_triangle(gfx, x0, y0, z0, x1, y1, z1, x2, y2, z2, color, fill_scanline);
|
||||
pxl8_scan_triangle(gfx, x0, y0, z0, x1, y1, z1, x2, y2, z2, color, fill_scanline, true);
|
||||
} else if (y0 == y1) {
|
||||
pxl8_draw_flat_top_triangle(gfx, x0, y0, z0, x1, y1, z1, x2, y2, z2, color, fill_scanline);
|
||||
pxl8_scan_triangle(gfx, x0, y0, z0, x1, y1, z1, x2, y2, z2, color, fill_scanline, false);
|
||||
} else {
|
||||
i32 x3 = x0 + (i32)(((f32)(y1 - y0) / (f32)(y2 - y0)) * (x2 - x0));
|
||||
i32 y3 = y1;
|
||||
f32 z3 = z0 + ((f32)(y1 - y0) / (f32)(y2 - y0)) * (z2 - z0);
|
||||
|
||||
pxl8_draw_flat_bottom_triangle(gfx, x0, y0, z0, x1, y1, z1, x3, y3, z3, color, fill_scanline);
|
||||
pxl8_draw_flat_top_triangle(gfx, x1, y1, z1, x3, y3, z3, x2, y2, z2, color, fill_scanline);
|
||||
pxl8_scan_triangle(gfx, x0, y0, z0, x1, y1, z1, x3, y3, z3, color, fill_scanline, true);
|
||||
pxl8_scan_triangle(gfx, x1, y1, z1, x3, y3, z3, x2, y2, z2, color, fill_scanline, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1284,77 +1308,88 @@ typedef struct pxl8_textured_vertex {
|
|||
f32 z, u, v, w;
|
||||
} pxl8_textured_vertex;
|
||||
|
||||
static void pxl8_draw_flat_bottom_triangle_textured(
|
||||
static void pxl8_scan_triangle_textured(
|
||||
pxl8_gfx* gfx,
|
||||
pxl8_textured_vertex v0,
|
||||
pxl8_textured_vertex v1,
|
||||
pxl8_textured_vertex v2,
|
||||
u32 texture_id
|
||||
u32 texture_id,
|
||||
pxl8_scanline_textured_func fill_scanline,
|
||||
bool is_bottom
|
||||
) {
|
||||
if (v1.y == v0.y) return;
|
||||
i32 y_start, y_end, y_step;
|
||||
f32 x_start1, x_start2;
|
||||
f32 z_start1, z_start2, u_start1, u_start2, v_start1, v_start2, w_start1, w_start2;
|
||||
f32 inv_slope_1, inv_slope_2, inv_slope_z1, inv_slope_z2;
|
||||
f32 inv_slope_u1, inv_slope_u2, inv_slope_v1, inv_slope_v2, inv_slope_w1, inv_slope_w2;
|
||||
|
||||
f32 inv_slope_1 = (f32)(v1.x - v0.x) / (f32)(v1.y - v0.y);
|
||||
f32 inv_slope_2 = (f32)(v2.x - v0.x) / (f32)(v2.y - v0.y);
|
||||
f32 inv_slope_z1 = (v1.z - v0.z) / (f32)(v1.y - v0.y);
|
||||
f32 inv_slope_z2 = (v2.z - v0.z) / (f32)(v2.y - v0.y);
|
||||
f32 inv_slope_u1 = (v1.u - v0.u) / (f32)(v1.y - v0.y);
|
||||
f32 inv_slope_u2 = (v2.u - v0.u) / (f32)(v2.y - v0.y);
|
||||
f32 inv_slope_v1 = (v1.v - v0.v) / (f32)(v1.y - v0.y);
|
||||
f32 inv_slope_v2 = (v2.v - v0.v) / (f32)(v2.y - v0.y);
|
||||
f32 inv_slope_w1 = (v1.w - v0.w) / (f32)(v1.y - v0.y);
|
||||
f32 inv_slope_w2 = (v2.w - v0.w) / (f32)(v2.y - v0.y);
|
||||
|
||||
f32 cur_x1 = (f32)v0.x, cur_x2 = (f32)v0.x;
|
||||
f32 cur_z1 = v0.z, cur_z2 = v0.z;
|
||||
f32 cur_u1 = v0.u, cur_u2 = v0.u;
|
||||
f32 cur_v1 = v0.v, cur_v2 = v0.v;
|
||||
f32 cur_w1 = v0.w, cur_w2 = v0.w;
|
||||
|
||||
for (i32 y = v0.y; y <= v1.y; y++) {
|
||||
pxl8_fill_scanline_textured(gfx, y, (i32)cur_x1, (i32)cur_x2,
|
||||
cur_z1, cur_z2, cur_u1, cur_v1, cur_w1, cur_u2, cur_v2, cur_w2, texture_id);
|
||||
cur_x1 += inv_slope_1; cur_x2 += inv_slope_2;
|
||||
cur_z1 += inv_slope_z1; cur_z2 += inv_slope_z2;
|
||||
cur_u1 += inv_slope_u1; cur_u2 += inv_slope_u2;
|
||||
cur_v1 += inv_slope_v1; cur_v2 += inv_slope_v2;
|
||||
cur_w1 += inv_slope_w1; cur_w2 += inv_slope_w2;
|
||||
if (is_bottom) {
|
||||
if (v1.y == v0.y || v1.y < v0.y || v1.y - v0.y > gfx->framebuffer_height) return;
|
||||
y_start = v0.y;
|
||||
y_end = v1.y;
|
||||
y_step = 1;
|
||||
x_start1 = x_start2 = (f32)v0.x;
|
||||
z_start1 = z_start2 = v0.z;
|
||||
u_start1 = u_start2 = v0.u;
|
||||
v_start1 = v_start2 = v0.v;
|
||||
w_start1 = w_start2 = v0.w;
|
||||
inv_slope_1 = (f32)(v1.x - v0.x) / (f32)(v1.y - v0.y);
|
||||
inv_slope_2 = (f32)(v2.x - v0.x) / (f32)(v2.y - v0.y);
|
||||
inv_slope_z1 = (v1.z - v0.z) / (f32)(v1.y - v0.y);
|
||||
inv_slope_z2 = (v2.z - v0.z) / (f32)(v2.y - v0.y);
|
||||
inv_slope_u1 = (v1.u - v0.u) / (f32)(v1.y - v0.y);
|
||||
inv_slope_u2 = (v2.u - v0.u) / (f32)(v2.y - v0.y);
|
||||
inv_slope_v1 = (v1.v - v0.v) / (f32)(v1.y - v0.y);
|
||||
inv_slope_v2 = (v2.v - v0.v) / (f32)(v2.y - v0.y);
|
||||
inv_slope_w1 = (v1.w - v0.w) / (f32)(v1.y - v0.y);
|
||||
inv_slope_w2 = (v2.w - v0.w) / (f32)(v2.y - v0.y);
|
||||
} else {
|
||||
if (v2.y == v0.y || v2.y < v0.y || v2.y - v0.y > gfx->framebuffer_height) return;
|
||||
y_start = v2.y;
|
||||
y_end = v0.y;
|
||||
y_step = -1;
|
||||
x_start1 = x_start2 = (f32)v2.x;
|
||||
z_start1 = z_start2 = v2.z;
|
||||
u_start1 = u_start2 = v2.u;
|
||||
v_start1 = v_start2 = v2.v;
|
||||
w_start1 = w_start2 = v2.w;
|
||||
inv_slope_1 = (f32)(v2.x - v0.x) / (f32)(v2.y - v0.y);
|
||||
inv_slope_2 = (f32)(v2.x - v1.x) / (f32)(v2.y - v1.y);
|
||||
inv_slope_z1 = (v2.z - v0.z) / (f32)(v2.y - v0.y);
|
||||
inv_slope_z2 = (v2.z - v1.z) / (f32)(v2.y - v1.y);
|
||||
inv_slope_u1 = (v2.u - v0.u) / (f32)(v2.y - v0.y);
|
||||
inv_slope_u2 = (v2.u - v1.u) / (f32)(v2.y - v1.y);
|
||||
inv_slope_v1 = (v2.v - v0.v) / (f32)(v2.y - v0.y);
|
||||
inv_slope_v2 = (v2.v - v1.v) / (f32)(v2.y - v1.y);
|
||||
inv_slope_w1 = (v2.w - v0.w) / (f32)(v2.y - v0.y);
|
||||
inv_slope_w2 = (v2.w - v1.w) / (f32)(v2.y - v1.y);
|
||||
}
|
||||
}
|
||||
|
||||
static void pxl8_draw_flat_top_triangle_textured(
|
||||
pxl8_gfx* gfx,
|
||||
pxl8_textured_vertex v0,
|
||||
pxl8_textured_vertex v1,
|
||||
pxl8_textured_vertex v2,
|
||||
u32 texture_id
|
||||
) {
|
||||
if (v2.y == v0.y) return;
|
||||
f32 cur_x1 = x_start1, cur_x2 = x_start2;
|
||||
f32 cur_z1 = z_start1, cur_z2 = z_start2;
|
||||
f32 cur_u1 = u_start1, cur_u2 = u_start2;
|
||||
f32 cur_v1 = v_start1, cur_v2 = v_start2;
|
||||
f32 cur_w1 = w_start1, cur_w2 = w_start2;
|
||||
|
||||
f32 inv_slope_1 = (f32)(v2.x - v0.x) / (f32)(v2.y - v0.y);
|
||||
f32 inv_slope_2 = (f32)(v2.x - v1.x) / (f32)(v2.y - v1.y);
|
||||
f32 inv_slope_z1 = (v2.z - v0.z) / (f32)(v2.y - v0.y);
|
||||
f32 inv_slope_z2 = (v2.z - v1.z) / (f32)(v2.y - v1.y);
|
||||
f32 inv_slope_u1 = (v2.u - v0.u) / (f32)(v2.y - v0.y);
|
||||
f32 inv_slope_u2 = (v2.u - v1.u) / (f32)(v2.y - v1.y);
|
||||
f32 inv_slope_v1 = (v2.v - v0.v) / (f32)(v2.y - v0.y);
|
||||
f32 inv_slope_v2 = (v2.v - v1.v) / (f32)(v2.y - v1.y);
|
||||
f32 inv_slope_w1 = (v2.w - v0.w) / (f32)(v2.y - v0.y);
|
||||
f32 inv_slope_w2 = (v2.w - v1.w) / (f32)(v2.y - v1.y);
|
||||
f32 slope_step_x1 = inv_slope_1 * y_step;
|
||||
f32 slope_step_x2 = inv_slope_2 * y_step;
|
||||
f32 slope_step_z1 = inv_slope_z1 * y_step;
|
||||
f32 slope_step_z2 = inv_slope_z2 * y_step;
|
||||
f32 slope_step_u1 = inv_slope_u1 * y_step;
|
||||
f32 slope_step_u2 = inv_slope_u2 * y_step;
|
||||
f32 slope_step_v1 = inv_slope_v1 * y_step;
|
||||
f32 slope_step_v2 = inv_slope_v2 * y_step;
|
||||
f32 slope_step_w1 = inv_slope_w1 * y_step;
|
||||
f32 slope_step_w2 = inv_slope_w2 * y_step;
|
||||
|
||||
f32 cur_x1 = (f32)v2.x, cur_x2 = (f32)v2.x;
|
||||
f32 cur_z1 = v2.z, cur_z2 = v2.z;
|
||||
f32 cur_u1 = v2.u, cur_u2 = v2.u;
|
||||
f32 cur_v1 = v2.v, cur_v2 = v2.v;
|
||||
f32 cur_w1 = v2.w, cur_w2 = v2.w;
|
||||
|
||||
for (i32 y = v2.y; y > v0.y; y--) {
|
||||
pxl8_fill_scanline_textured(gfx, y, (i32)cur_x1, (i32)cur_x2,
|
||||
for (i32 y = y_start; y != y_end + y_step; y += y_step) {
|
||||
fill_scanline(gfx, y, (i32)cur_x1, (i32)cur_x2,
|
||||
cur_z1, cur_z2, cur_u1, cur_v1, cur_w1, cur_u2, cur_v2, cur_w2, texture_id);
|
||||
cur_x1 -= inv_slope_1; cur_x2 -= inv_slope_2;
|
||||
cur_z1 -= inv_slope_z1; cur_z2 -= inv_slope_z2;
|
||||
cur_u1 -= inv_slope_u1; cur_u2 -= inv_slope_u2;
|
||||
cur_v1 -= inv_slope_v1; cur_v2 -= inv_slope_v2;
|
||||
cur_w1 -= inv_slope_w1; cur_w2 -= inv_slope_w2;
|
||||
cur_x1 += slope_step_x1; cur_x2 += slope_step_x2;
|
||||
cur_z1 += slope_step_z1; cur_z2 += slope_step_z2;
|
||||
cur_u1 += slope_step_u1; cur_u2 += slope_step_u2;
|
||||
cur_v1 += slope_step_v1; cur_v2 += slope_step_v2;
|
||||
cur_w1 += slope_step_w1; cur_w2 += slope_step_w2;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1415,10 +1450,14 @@ void pxl8_3d_draw_triangle_textured(
|
|||
pxl8_textured_vertex tmp = tv[1]; tv[1] = tv[2]; tv[2] = tmp;
|
||||
}
|
||||
|
||||
pxl8_scanline_textured_func fill_scanline = (gfx->color_mode == PXL8_COLOR_MODE_HICOLOR)
|
||||
? pxl8_fill_scanline_textured_hicolor
|
||||
: pxl8_fill_scanline_textured_indexed;
|
||||
|
||||
if (tv[1].y == tv[2].y) {
|
||||
pxl8_draw_flat_bottom_triangle_textured(gfx, tv[0], tv[1], tv[2], texture_id);
|
||||
pxl8_scan_triangle_textured(gfx, tv[0], tv[1], tv[2], texture_id, fill_scanline, true);
|
||||
} else if (tv[0].y == tv[1].y) {
|
||||
pxl8_draw_flat_top_triangle_textured(gfx, tv[0], tv[1], tv[2], texture_id);
|
||||
pxl8_scan_triangle_textured(gfx, tv[0], tv[1], tv[2], texture_id, fill_scanline, false);
|
||||
} else {
|
||||
f32 t = (f32)(tv[1].y - tv[0].y) / (f32)(tv[2].y - tv[0].y);
|
||||
pxl8_textured_vertex v3;
|
||||
|
|
@ -1429,7 +1468,7 @@ void pxl8_3d_draw_triangle_textured(
|
|||
v3.v = tv[0].v + t * (tv[2].v - tv[0].v);
|
||||
v3.w = tv[0].w + t * (tv[2].w - tv[0].w);
|
||||
|
||||
pxl8_draw_flat_bottom_triangle_textured(gfx, tv[0], tv[1], v3, texture_id);
|
||||
pxl8_draw_flat_top_triangle_textured(gfx, tv[1], v3, tv[2], texture_id);
|
||||
pxl8_scan_triangle_textured(gfx, tv[0], tv[1], v3, texture_id, fill_scanline, true);
|
||||
pxl8_scan_triangle_textured(gfx, tv[1], v3, tv[2], texture_id, fill_scanline, false);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue