clean up gfx a bit... more to come
This commit is contained in:
parent
c662c550df
commit
7f56e0bfe8
2 changed files with 195 additions and 61 deletions
|
|
@ -45,9 +45,7 @@
|
|||
(when (pxl8.key_pressed "9")
|
||||
(set use-nes-palette (not use-nes-palette))
|
||||
(local palette-path (if use-nes-palette "palettes/nes.ase" "sprites/pxl8_logo.ase"))
|
||||
(print (.. "Switching to palette: " palette-path))
|
||||
(pxl8.load_palette palette-path)
|
||||
(print "Palette loaded"))
|
||||
(pxl8.load_palette palette-path))
|
||||
|
||||
(case current-effect
|
||||
1 (do
|
||||
|
|
|
|||
244
src/pxl8_gfx.c
244
src/pxl8_gfx.c
|
|
@ -82,7 +82,13 @@ struct pxl8_gfx {
|
|||
bool affine_textures;
|
||||
};
|
||||
|
||||
static pxl8_skyline_fit pxl8_skyline_find_position(const pxl8_skyline* skyline, u32 atlas_w, u32 atlas_h, u32 rect_w, u32 rect_h) {
|
||||
static pxl8_skyline_fit pxl8_skyline_find_position(
|
||||
const pxl8_skyline* skyline,
|
||||
u32 atlas_w,
|
||||
u32 atlas_h,
|
||||
u32 rect_w,
|
||||
u32 rect_h
|
||||
) {
|
||||
pxl8_skyline_fit result = {.found = false};
|
||||
i32 best_y = INT32_MAX;
|
||||
i32 best_x = 0;
|
||||
|
|
@ -129,8 +135,6 @@ static void pxl8_skyline_add_rect(pxl8_skyline* skyline, pxl8_point pos, u32 w,
|
|||
}
|
||||
}
|
||||
|
||||
pxl8_skyline_node new_node = {pos.x, pos.y + (i32)h, (i32)w};
|
||||
|
||||
u32 nodes_to_remove = 0;
|
||||
for (u32 i = node_idx; i < skyline->count; i++) {
|
||||
if (skyline->nodes[i].x < pos.x + (i32)w) {
|
||||
|
|
@ -142,15 +146,21 @@ static void pxl8_skyline_add_rect(pxl8_skyline* skyline, pxl8_point pos, u32 w,
|
|||
|
||||
if (skyline->count - nodes_to_remove + 1 > skyline->capacity) {
|
||||
skyline->capacity = (skyline->count - nodes_to_remove + 1) * 2;
|
||||
skyline->nodes = (pxl8_skyline_node*)SDL_realloc(skyline->nodes, skyline->capacity * sizeof(pxl8_skyline_node));
|
||||
skyline->nodes = (pxl8_skyline_node*)SDL_realloc(
|
||||
skyline->nodes,
|
||||
skyline->capacity * sizeof(pxl8_skyline_node)
|
||||
);
|
||||
}
|
||||
|
||||
if (nodes_to_remove > 0) {
|
||||
SDL_memmove(&skyline->nodes[node_idx + 1], &skyline->nodes[node_idx + nodes_to_remove],
|
||||
(skyline->count - node_idx - nodes_to_remove) * sizeof(pxl8_skyline_node));
|
||||
SDL_memmove(
|
||||
&skyline->nodes[node_idx + 1],
|
||||
&skyline->nodes[node_idx + nodes_to_remove],
|
||||
(skyline->count - node_idx - nodes_to_remove) * sizeof(pxl8_skyline_node)
|
||||
);
|
||||
}
|
||||
|
||||
skyline->nodes[node_idx] = new_node;
|
||||
skyline->nodes[node_idx] = (pxl8_skyline_node){pos.x, pos.y + (i32)h, (i32)w};
|
||||
skyline->count = skyline->count - nodes_to_remove + 1;
|
||||
}
|
||||
|
||||
|
|
@ -158,8 +168,11 @@ static void pxl8_skyline_compact(pxl8_skyline* skyline) {
|
|||
for (u32 i = 0; i < skyline->count - 1; ) {
|
||||
if (skyline->nodes[i].y == skyline->nodes[i + 1].y) {
|
||||
skyline->nodes[i].width += skyline->nodes[i + 1].width;
|
||||
SDL_memmove(&skyline->nodes[i + 1], &skyline->nodes[i + 2],
|
||||
(skyline->count - i - 2) * sizeof(pxl8_skyline_node));
|
||||
SDL_memmove(
|
||||
&skyline->nodes[i + 1],
|
||||
&skyline->nodes[i + 2],
|
||||
(skyline->count - i - 2) * sizeof(pxl8_skyline_node)
|
||||
);
|
||||
skyline->count--;
|
||||
} else {
|
||||
i++;
|
||||
|
|
@ -167,7 +180,12 @@ static void pxl8_skyline_compact(pxl8_skyline* skyline) {
|
|||
}
|
||||
}
|
||||
|
||||
static pxl8_atlas* pxl8_atlas_create(SDL_Renderer* renderer, u32 width, u32 height, pxl8_color_mode color_mode) {
|
||||
static pxl8_atlas* pxl8_atlas_create(
|
||||
SDL_Renderer* renderer,
|
||||
u32 width,
|
||||
u32 height,
|
||||
pxl8_color_mode color_mode
|
||||
) {
|
||||
pxl8_atlas* atlas = (pxl8_atlas*)SDL_calloc(1, sizeof(pxl8_atlas));
|
||||
if (!atlas) return NULL;
|
||||
|
||||
|
|
@ -181,8 +199,14 @@ static pxl8_atlas* pxl8_atlas_create(SDL_Renderer* renderer, u32 width, u32 heig
|
|||
return NULL;
|
||||
}
|
||||
|
||||
atlas->texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32,
|
||||
SDL_TEXTUREACCESS_STREAMING, width, height);
|
||||
atlas->texture = SDL_CreateTexture(
|
||||
renderer,
|
||||
SDL_PIXELFORMAT_RGBA32,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
width,
|
||||
height
|
||||
);
|
||||
|
||||
if (!atlas->texture) {
|
||||
SDL_free(atlas->pixels);
|
||||
SDL_free(atlas);
|
||||
|
|
@ -209,7 +233,8 @@ static pxl8_atlas* pxl8_atlas_create(SDL_Renderer* renderer, u32 width, u32 heig
|
|||
}
|
||||
|
||||
atlas->skyline.capacity = 16;
|
||||
atlas->skyline.nodes = (pxl8_skyline_node*)SDL_calloc(atlas->skyline.capacity, sizeof(pxl8_skyline_node));
|
||||
atlas->skyline.nodes =
|
||||
(pxl8_skyline_node*)SDL_calloc(atlas->skyline.capacity, sizeof(pxl8_skyline_node));
|
||||
if (!atlas->skyline.nodes) {
|
||||
SDL_free(atlas->free_list);
|
||||
SDL_free(atlas->entries);
|
||||
|
|
@ -228,15 +253,19 @@ static pxl8_atlas* pxl8_atlas_create(SDL_Renderer* renderer, u32 width, u32 heig
|
|||
static void pxl8_atlas_destroy(pxl8_atlas* atlas) {
|
||||
if (!atlas) return;
|
||||
|
||||
SDL_free(atlas->free_list);
|
||||
SDL_free(atlas->entries);
|
||||
SDL_free(atlas->free_list);
|
||||
SDL_free(atlas->pixels);
|
||||
SDL_free(atlas->skyline.nodes);
|
||||
if (atlas->texture) SDL_DestroyTexture(atlas->texture);
|
||||
SDL_free(atlas->pixels);
|
||||
SDL_free(atlas);
|
||||
}
|
||||
|
||||
static bool pxl8_atlas_expand(pxl8_atlas* atlas, SDL_Renderer* renderer, pxl8_color_mode color_mode) {
|
||||
static bool pxl8_atlas_expand(
|
||||
pxl8_atlas* atlas,
|
||||
SDL_Renderer* renderer,
|
||||
pxl8_color_mode color_mode
|
||||
) {
|
||||
if (!atlas || atlas->width >= 4096) return false;
|
||||
|
||||
u32 new_size = atlas->width * 2;
|
||||
|
|
@ -246,8 +275,14 @@ static bool pxl8_atlas_expand(pxl8_atlas* atlas, SDL_Renderer* renderer, pxl8_co
|
|||
u8* new_pixels = (u8*)SDL_calloc(new_size * new_size, bytes_per_pixel);
|
||||
if (!new_pixels) return false;
|
||||
|
||||
SDL_Texture* new_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32,
|
||||
SDL_TEXTUREACCESS_STREAMING, new_size, new_size);
|
||||
SDL_Texture* new_texture = SDL_CreateTexture(
|
||||
renderer,
|
||||
SDL_PIXELFORMAT_RGBA32,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
new_size,
|
||||
new_size
|
||||
);
|
||||
|
||||
if (!new_texture) {
|
||||
SDL_free(new_pixels);
|
||||
return false;
|
||||
|
|
@ -268,8 +303,14 @@ static bool pxl8_atlas_expand(pxl8_atlas* atlas, SDL_Renderer* renderer, pxl8_co
|
|||
for (u32 i = 0; i < atlas->entry_count; i++) {
|
||||
if (!atlas->entries[i].active) continue;
|
||||
|
||||
pxl8_skyline_fit fit = pxl8_skyline_find_position(&new_skyline, new_size, new_size,
|
||||
atlas->entries[i].w, atlas->entries[i].h);
|
||||
pxl8_skyline_fit fit = pxl8_skyline_find_position(
|
||||
&new_skyline,
|
||||
new_size,
|
||||
new_size,
|
||||
atlas->entries[i].w,
|
||||
atlas->entries[i].h
|
||||
);
|
||||
|
||||
if (!fit.found) {
|
||||
SDL_free(new_skyline.nodes);
|
||||
SDL_DestroyTexture(new_texture);
|
||||
|
|
@ -311,15 +352,27 @@ static bool pxl8_atlas_expand(pxl8_atlas* atlas, SDL_Renderer* renderer, pxl8_co
|
|||
return true;
|
||||
}
|
||||
|
||||
static u32 pxl8_atlas_add_texture(pxl8_atlas* atlas, const u8* pixels, u32 w, u32 h, const char* path, pxl8_color_mode color_mode) {
|
||||
static u32 pxl8_atlas_add_texture(
|
||||
pxl8_atlas* atlas,
|
||||
const u8* pixels,
|
||||
u32 w,
|
||||
u32 h,
|
||||
const char* path,
|
||||
pxl8_color_mode color_mode
|
||||
) {
|
||||
if (!atlas || !pixels) return UINT32_MAX;
|
||||
|
||||
pxl8_skyline_fit fit = pxl8_skyline_find_position(&atlas->skyline, atlas->width, atlas->height, w, h);
|
||||
pxl8_skyline_fit fit =
|
||||
pxl8_skyline_find_position(&atlas->skyline, atlas->width, atlas->height, w, h);
|
||||
if (!fit.found) {
|
||||
if (!pxl8_atlas_expand(atlas, atlas->texture ? SDL_GetRendererFromTexture(atlas->texture) : NULL, color_mode)) {
|
||||
SDL_Renderer* renderer = atlas->texture ? SDL_GetRendererFromTexture(atlas->texture) : NULL;
|
||||
|
||||
if (!pxl8_atlas_expand(atlas, renderer, color_mode)) {
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
fit = pxl8_skyline_find_position(&atlas->skyline, atlas->width, atlas->height, w, h);
|
||||
|
||||
if (!fit.found) return UINT32_MAX;
|
||||
}
|
||||
|
||||
|
|
@ -329,8 +382,10 @@ static u32 pxl8_atlas_add_texture(pxl8_atlas* atlas, const u8* pixels, u32 w, u3
|
|||
} else {
|
||||
if (atlas->entry_count >= atlas->entry_capacity) {
|
||||
atlas->entry_capacity *= 2;
|
||||
atlas->entries = (pxl8_atlas_entry*)SDL_realloc(atlas->entries,
|
||||
atlas->entry_capacity * sizeof(pxl8_atlas_entry));
|
||||
atlas->entries = (pxl8_atlas_entry*)SDL_realloc(
|
||||
atlas->entries,
|
||||
atlas->entry_capacity * sizeof(pxl8_atlas_entry)
|
||||
);
|
||||
}
|
||||
texture_id = atlas->entry_count++;
|
||||
}
|
||||
|
|
@ -449,7 +504,13 @@ u32 pxl8_gfx_get_palette_size(const pxl8_gfx* gfx) {
|
|||
return gfx ? gfx->palette_size : 0;
|
||||
}
|
||||
|
||||
pxl8_gfx* pxl8_gfx_create(pxl8_color_mode mode, pxl8_resolution resolution, const char* title, i32 window_width, i32 window_height) {
|
||||
pxl8_gfx* pxl8_gfx_create(
|
||||
pxl8_color_mode mode,
|
||||
pxl8_resolution resolution,
|
||||
const char* title,
|
||||
i32 window_width,
|
||||
i32 window_height
|
||||
) {
|
||||
pxl8_gfx* gfx = (pxl8_gfx*)SDL_calloc(1, sizeof(*gfx));
|
||||
if (!gfx) {
|
||||
pxl8_error("Failed to allocate graphics context");
|
||||
|
|
@ -457,7 +518,11 @@ pxl8_gfx* pxl8_gfx_create(pxl8_color_mode mode, pxl8_resolution resolution, cons
|
|||
}
|
||||
|
||||
gfx->color_mode = mode;
|
||||
pxl8_gfx_get_resolution_dimensions(resolution, &gfx->framebuffer_width, &gfx->framebuffer_height);
|
||||
pxl8_gfx_get_resolution_dimensions(
|
||||
resolution,
|
||||
&gfx->framebuffer_width,
|
||||
&gfx->framebuffer_height
|
||||
);
|
||||
|
||||
gfx->window = SDL_CreateWindow(
|
||||
title,
|
||||
|
|
@ -478,10 +543,12 @@ pxl8_gfx* pxl8_gfx_create(pxl8_color_mode mode, pxl8_resolution resolution, cons
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SDL_SetRenderLogicalPresentation(gfx->renderer,
|
||||
SDL_SetRenderLogicalPresentation(
|
||||
gfx->renderer,
|
||||
gfx->framebuffer_width,
|
||||
gfx->framebuffer_height,
|
||||
SDL_LOGICAL_PRESENTATION_INTEGER_SCALE);
|
||||
SDL_LOGICAL_PRESENTATION_INTEGER_SCALE
|
||||
);
|
||||
|
||||
i32 bytes_per_pixel = (gfx->color_mode == PXL8_COLOR_MODE_HICOLOR) ? 4 : 1;
|
||||
i32 fb_size = gfx->framebuffer_width * gfx->framebuffer_height * bytes_per_pixel;
|
||||
|
|
@ -579,16 +646,19 @@ pxl8_result pxl8_gfx_create_texture(pxl8_gfx* gfx, const u8* pixels, u32 width,
|
|||
if (!gfx->atlas) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
u32 texture_id = pxl8_atlas_add_texture(gfx->atlas, pixels, width, height, NULL, gfx->color_mode);
|
||||
u32 texture_id =
|
||||
pxl8_atlas_add_texture(gfx->atlas, pixels, width, height, NULL, gfx->color_mode);
|
||||
if (texture_id == UINT32_MAX) {
|
||||
pxl8_error("Texture doesn't fit in atlas");
|
||||
return PXL8_ERROR_INVALID_SIZE;
|
||||
}
|
||||
|
||||
pxl8_debug("Created texture %u: %ux%u at (%d,%d)",
|
||||
pxl8_debug(
|
||||
"Created texture %u: %ux%u at (%d,%d)",
|
||||
texture_id, width, height,
|
||||
gfx->atlas->entries[texture_id].x,
|
||||
gfx->atlas->entries[texture_id].y);
|
||||
gfx->atlas->entries[texture_id].y
|
||||
);
|
||||
|
||||
return texture_id;
|
||||
}
|
||||
|
|
@ -623,7 +693,14 @@ pxl8_result pxl8_gfx_load_sprite(pxl8_gfx* gfx, const char* path) {
|
|||
u32 sprite_w = ase_file.header.width;
|
||||
u32 sprite_h = ase_file.header.height;
|
||||
|
||||
u32 texture_id = pxl8_atlas_add_texture(gfx->atlas, ase_file.frames[0].pixels, sprite_w, sprite_h, path, gfx->color_mode);
|
||||
u32 texture_id = pxl8_atlas_add_texture(
|
||||
gfx->atlas,
|
||||
ase_file.frames[0].pixels,
|
||||
sprite_w,
|
||||
sprite_h,
|
||||
path,
|
||||
gfx->color_mode
|
||||
);
|
||||
|
||||
pxl8_ase_destroy(&ase_file);
|
||||
|
||||
|
|
@ -659,7 +736,10 @@ pxl8_result pxl8_gfx_load_palette(pxl8_gfx* gfx, const char* path) {
|
|||
return PXL8_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
u32 copy_size = (ase_file.palette.entry_count < gfx->palette_size) ? ase_file.palette.entry_count : gfx->palette_size;
|
||||
u32 copy_size = ase_file.palette.entry_count < gfx->palette_size
|
||||
? ase_file.palette.entry_count
|
||||
: gfx->palette_size;
|
||||
|
||||
memcpy(gfx->palette, ase_file.palette.colors, copy_size * sizeof(u32));
|
||||
|
||||
u32 last_color = (copy_size > 0) ? gfx->palette[copy_size - 1] : 0xFF000000;
|
||||
|
|
@ -678,7 +758,15 @@ pxl8_result pxl8_gfx_load_font_atlas(pxl8_gfx* gfx) {
|
|||
return PXL8_OK;
|
||||
}
|
||||
|
||||
static void pxl8_upload_indexed_texture(SDL_Texture* texture, const u8* indexed, const u32* palette, u32 palette_size, i32 width, i32 height, u32 default_color) {
|
||||
static void pxl8_upload_indexed_texture(
|
||||
SDL_Texture* texture,
|
||||
const u8* indexed,
|
||||
const u32* palette,
|
||||
u32 palette_size,
|
||||
i32 width,
|
||||
i32 height,
|
||||
u32 default_color
|
||||
) {
|
||||
static u32* rgba_buffer = NULL;
|
||||
static size_t buffer_size = 0;
|
||||
size_t needed_size = width * height;
|
||||
|
|
@ -702,13 +790,22 @@ void pxl8_gfx_upload_framebuffer(pxl8_gfx* gfx) {
|
|||
if (!gfx || !gfx->initialized || !gfx->framebuffer_texture) return;
|
||||
|
||||
if (gfx->color_mode == PXL8_COLOR_MODE_HICOLOR) {
|
||||
SDL_UpdateTexture(gfx->framebuffer_texture, NULL, gfx->framebuffer,
|
||||
gfx->framebuffer_width * 4);
|
||||
SDL_UpdateTexture(
|
||||
gfx->framebuffer_texture,
|
||||
NULL,
|
||||
gfx->framebuffer,
|
||||
gfx->framebuffer_width * 4
|
||||
);
|
||||
} else {
|
||||
pxl8_upload_indexed_texture(gfx->framebuffer_texture, gfx->framebuffer,
|
||||
gfx->palette, gfx->palette_size,
|
||||
gfx->framebuffer_width, gfx->framebuffer_height,
|
||||
0xFF000000);
|
||||
pxl8_upload_indexed_texture(
|
||||
gfx->framebuffer_texture,
|
||||
gfx->framebuffer,
|
||||
gfx->palette,
|
||||
gfx->palette_size,
|
||||
gfx->framebuffer_width,
|
||||
gfx->framebuffer_height,
|
||||
0xFF000000
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -716,13 +813,22 @@ void pxl8_gfx_upload_atlas(pxl8_gfx* gfx) {
|
|||
if (!gfx || !gfx->initialized || !gfx->atlas || !gfx->atlas->texture || !gfx->atlas->dirty) return;
|
||||
|
||||
if (gfx->color_mode == PXL8_COLOR_MODE_HICOLOR) {
|
||||
SDL_UpdateTexture(gfx->atlas->texture, NULL, gfx->atlas->pixels,
|
||||
gfx->atlas->width * 4);
|
||||
SDL_UpdateTexture(
|
||||
gfx->atlas->texture,
|
||||
NULL,
|
||||
gfx->atlas->pixels,
|
||||
gfx->atlas->width * 4
|
||||
);
|
||||
} else {
|
||||
pxl8_upload_indexed_texture(gfx->atlas->texture, gfx->atlas->pixels,
|
||||
gfx->palette, gfx->palette_size,
|
||||
gfx->atlas->width, gfx->atlas->height,
|
||||
0x00000000);
|
||||
pxl8_upload_indexed_texture(
|
||||
gfx->atlas->texture,
|
||||
gfx->atlas->pixels,
|
||||
gfx->palette,
|
||||
gfx->palette_size,
|
||||
gfx->atlas->width,
|
||||
gfx->atlas->height,
|
||||
0x00000000
|
||||
);
|
||||
}
|
||||
|
||||
gfx->atlas->dirty = false;
|
||||
|
|
@ -976,11 +1082,21 @@ void pxl8_sprite(pxl8_gfx* gfx, u32 sprite_id, i32 x, i32 y, i32 w, i32 h) {
|
|||
const u8* sprite_data = gfx->atlas->pixels + entry->y * gfx->atlas->width + entry->x;
|
||||
|
||||
if (gfx->color_mode == PXL8_COLOR_MODE_HICOLOR) {
|
||||
pxl8_blit_simd_hicolor((u32*)gfx->framebuffer, gfx->framebuffer_width,
|
||||
(const u32*)sprite_data, gfx->atlas->width, x, y, w, h);
|
||||
pxl8_blit_simd_hicolor(
|
||||
(u32*)gfx->framebuffer,
|
||||
gfx->framebuffer_width,
|
||||
(const u32*)sprite_data,
|
||||
gfx->atlas->width,
|
||||
x, y, w, h
|
||||
);
|
||||
} else {
|
||||
pxl8_blit_simd_indexed(gfx->framebuffer, gfx->framebuffer_width,
|
||||
sprite_data, gfx->atlas->width, x, y, w, h);
|
||||
pxl8_blit_simd_indexed(
|
||||
gfx->framebuffer,
|
||||
gfx->framebuffer_width,
|
||||
sprite_data,
|
||||
gfx->atlas->width,
|
||||
x, y, w, h
|
||||
);
|
||||
}
|
||||
} else {
|
||||
for (i32 py = 0; py < draw_height; py++) {
|
||||
|
|
@ -1051,7 +1167,14 @@ void pxl8_gfx_fade_palette(pxl8_gfx* gfx, u8 start, u8 count, f32 amount, u32 ta
|
|||
}
|
||||
}
|
||||
|
||||
void pxl8_gfx_interpolate_palettes(pxl8_gfx* gfx, u32* palette1, u32* palette2, u8 start, u8 count, f32 t) {
|
||||
void pxl8_gfx_interpolate_palettes(
|
||||
pxl8_gfx* gfx,
|
||||
u32* palette1,
|
||||
u32* palette2,
|
||||
u8 start,
|
||||
u8 count,
|
||||
f32 t
|
||||
) {
|
||||
if (!gfx || !gfx->palette || !palette1 || !palette2 || count == 0) return;
|
||||
|
||||
if (t < 0.0f) t = 0.0f;
|
||||
|
|
@ -1496,7 +1619,19 @@ static void pxl8_draw_flat_top_triangle_textured(
|
|||
}
|
||||
}
|
||||
|
||||
void pxl8_3d_draw_triangle_textured(pxl8_gfx* gfx, pxl8_vec3 v0, pxl8_vec3 v1, pxl8_vec3 v2, f32 u0, f32 v0f, f32 u1, f32 v1f, f32 u2, f32 v2f, u32 texture_id) {
|
||||
void pxl8_3d_draw_triangle_textured(
|
||||
pxl8_gfx* gfx,
|
||||
pxl8_vec3 v0,
|
||||
pxl8_vec3 v1,
|
||||
pxl8_vec3 v2,
|
||||
f32 u0,
|
||||
f32 v0f,
|
||||
f32 u1,
|
||||
f32 v1f,
|
||||
f32 u2,
|
||||
f32 v2f,
|
||||
u32 texture_id
|
||||
) {
|
||||
if (!gfx || !pxl8_3d_init_zbuffer(gfx)) return;
|
||||
|
||||
pxl8_vec4 cv0 = pxl8_transform_vertex(gfx, v0);
|
||||
|
|
@ -1526,7 +1661,8 @@ void pxl8_3d_draw_triangle_textured(pxl8_gfx* gfx, pxl8_vec3 v0, pxl8_vec3 v1, p
|
|||
tv[2].w = cv2.w;
|
||||
|
||||
if (gfx->backface_culling) {
|
||||
i32 cross = (tv[1].x - tv[0].x) * (tv[2].y - tv[0].y) - (tv[1].y - tv[0].y) * (tv[2].x - tv[0].x);
|
||||
i32 cross =
|
||||
(tv[1].x - tv[0].x) * (tv[2].y - tv[0].y) - (tv[1].y - tv[0].y) * (tv[2].x - tv[0].x);
|
||||
if (cross >= 0) return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue