doin' some cleanup...
This commit is contained in:
parent
40f5cdcaa5
commit
f6d6efea95
16 changed files with 136 additions and 182 deletions
|
|
@ -53,25 +53,6 @@ static bool validate_chunk(const demo3d_bsp_chunk* chunk, u32 element_size, usiz
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline bool demo3d_bsp_get_edge_vertex(const demo3d_bsp* bsp, i32 surfedge_idx, u32* out_vert_idx) {
|
||||
if (surfedge_idx >= (i32)bsp->num_surfedges) return false;
|
||||
|
||||
i32 edge_idx = bsp->surfedges[surfedge_idx];
|
||||
u32 vertex_index;
|
||||
|
||||
if (edge_idx >= 0) {
|
||||
if ((u32)edge_idx >= bsp->num_edges) return false;
|
||||
vertex_index = 0;
|
||||
} else {
|
||||
edge_idx = -edge_idx;
|
||||
if ((u32)edge_idx >= bsp->num_edges) return false;
|
||||
vertex_index = 1;
|
||||
}
|
||||
|
||||
*out_vert_idx = bsp->edges[edge_idx].vertex[vertex_index];
|
||||
return *out_vert_idx < bsp->num_vertices;
|
||||
}
|
||||
|
||||
pxl8_result demo3d_bsp_load(const char* path, demo3d_bsp* bsp) {
|
||||
if (!path || !bsp) return PXL8_ERROR_INVALID_ARGUMENT;
|
||||
|
||||
|
|
|
|||
|
|
@ -138,6 +138,25 @@ typedef struct demo3d_bsp {
|
|||
f32 bounds_max_z;
|
||||
} demo3d_bsp;
|
||||
|
||||
static inline bool demo3d_bsp_get_edge_vertex(const demo3d_bsp* bsp, i32 surfedge_idx, u32* out_vert_idx) {
|
||||
if (surfedge_idx >= (i32)bsp->num_surfedges) return false;
|
||||
|
||||
i32 edge_idx = bsp->surfedges[surfedge_idx];
|
||||
u32 vertex_index;
|
||||
|
||||
if (edge_idx >= 0) {
|
||||
if ((u32)edge_idx >= bsp->num_edges) return false;
|
||||
vertex_index = 0;
|
||||
} else {
|
||||
edge_idx = -edge_idx;
|
||||
if ((u32)edge_idx >= bsp->num_edges) return false;
|
||||
vertex_index = 1;
|
||||
}
|
||||
|
||||
*out_vert_idx = bsp->edges[edge_idx].vertex[vertex_index];
|
||||
return *out_vert_idx < bsp->num_vertices;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -7,25 +7,6 @@
|
|||
#include "pxl8_mem.h"
|
||||
#include "pxl8_mesh.h"
|
||||
|
||||
static inline bool demo3d_bsp_get_edge_vertex(const demo3d_bsp* bsp, i32 surfedge_idx, u32* out_vert_idx) {
|
||||
if (surfedge_idx >= (i32)bsp->num_surfedges) return false;
|
||||
|
||||
i32 edge_idx = bsp->surfedges[surfedge_idx];
|
||||
u32 vertex_index;
|
||||
|
||||
if (edge_idx >= 0) {
|
||||
if ((u32)edge_idx >= bsp->num_edges) return false;
|
||||
vertex_index = 0;
|
||||
} else {
|
||||
edge_idx = -edge_idx;
|
||||
if ((u32)edge_idx >= bsp->num_edges) return false;
|
||||
vertex_index = 1;
|
||||
}
|
||||
|
||||
*out_vert_idx = bsp->edges[edge_idx].vertex[vertex_index];
|
||||
return *out_vert_idx < bsp->num_vertices;
|
||||
}
|
||||
|
||||
static inline bool face_in_frustum(const demo3d_bsp* bsp, u32 face_id, const pxl8_frustum* frustum) {
|
||||
const demo3d_bsp_face* face = &bsp->faces[face_id];
|
||||
return pxl8_frustum_test_aabb(frustum, face->aabb_min, face->aabb_max);
|
||||
|
|
@ -132,12 +113,20 @@ demo3d_bsp_render_state* demo3d_bsp_render_state_create(u32 num_faces) {
|
|||
}
|
||||
}
|
||||
|
||||
state->mesh = pxl8_mesh_create(8192, 16384);
|
||||
if (!state->mesh) {
|
||||
pxl8_free(state->render_face_flags);
|
||||
pxl8_free(state);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void demo3d_bsp_render_state_destroy(demo3d_bsp_render_state* state) {
|
||||
if (!state) return;
|
||||
pxl8_free(state->materials);
|
||||
pxl8_mesh_destroy(state->mesh);
|
||||
pxl8_free(state->render_face_flags);
|
||||
pxl8_free(state);
|
||||
}
|
||||
|
|
@ -152,17 +141,24 @@ void demo3d_bsp_render(pxl8_gfx* gfx, const demo3d_bsp* bsp,
|
|||
const pxl8_frustum* frustum = pxl8_3d_get_frustum(gfx);
|
||||
if (!frustum) return;
|
||||
|
||||
pxl8_mesh* mesh = pxl8_mesh_create(8192, 16384);
|
||||
pxl8_mesh* mesh = state->mesh;
|
||||
if (!mesh) return;
|
||||
|
||||
u8 ambient = pxl8_gfx_get_ambient(gfx);
|
||||
pxl8_mat4 identity = pxl8_mat4_identity();
|
||||
|
||||
u8 mat_has_faces[256] = {0};
|
||||
for (u32 face_id = 0; face_id < bsp->num_faces; face_id++) {
|
||||
if (!state->render_face_flags[face_id]) continue;
|
||||
u16 mid = bsp->faces[face_id].material_id;
|
||||
if (mid < state->num_materials) mat_has_faces[mid] = 1;
|
||||
}
|
||||
|
||||
for (u32 mat = 0; mat < state->num_materials; mat++) {
|
||||
if (!mat_has_faces[mat]) continue;
|
||||
for (u32 face_id = 0; face_id < bsp->num_faces; face_id++) {
|
||||
if (!state->render_face_flags[face_id]) continue;
|
||||
const demo3d_bsp_face* face = &bsp->faces[face_id];
|
||||
if (face->material_id != mat) continue;
|
||||
if (bsp->faces[face_id].material_id != mat) continue;
|
||||
if (!face_in_frustum(bsp, face_id, frustum)) continue;
|
||||
collect_face_to_mesh(bsp, state, face_id, mesh, ambient);
|
||||
}
|
||||
|
|
@ -173,8 +169,6 @@ void demo3d_bsp_render(pxl8_gfx* gfx, const demo3d_bsp* bsp,
|
|||
pxl8_mesh_clear(mesh);
|
||||
}
|
||||
}
|
||||
|
||||
pxl8_mesh_destroy(mesh);
|
||||
}
|
||||
|
||||
void demo3d_bsp_set_material(demo3d_bsp_render_state* state, u16 material_id, const pxl8_gfx_material* material) {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,11 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "pxl8_mesh.h"
|
||||
|
||||
typedef struct demo3d_bsp_render_state {
|
||||
pxl8_gfx_material* materials;
|
||||
pxl8_mesh* mesh;
|
||||
u8* render_face_flags;
|
||||
u32 num_materials;
|
||||
u32 num_faces;
|
||||
|
|
|
|||
|
|
@ -11,20 +11,6 @@ typedef struct {
|
|||
bool start_solid;
|
||||
} trace_result;
|
||||
|
||||
static i32 bsp_find_leaf(const demo3d_bsp* bsp, pxl8_vec3 pos) {
|
||||
if (!bsp || bsp->num_nodes == 0) return -1;
|
||||
|
||||
i32 node_id = 0;
|
||||
while (node_id >= 0) {
|
||||
const demo3d_bsp_node* node = &bsp->nodes[node_id];
|
||||
const demo3d_bsp_plane* plane = &bsp->planes[node->plane_id];
|
||||
f32 dist = pxl8_vec3_dot(pos, plane->normal) - plane->dist;
|
||||
node_id = node->children[dist < 0 ? 1 : 0];
|
||||
}
|
||||
|
||||
return -(node_id + 1);
|
||||
}
|
||||
|
||||
static i32 bsp_contents_from(const demo3d_bsp* bsp, i32 node_id, pxl8_vec3 pos) {
|
||||
while (node_id >= 0) {
|
||||
const demo3d_bsp_node* node = &bsp->nodes[node_id];
|
||||
|
|
@ -124,7 +110,7 @@ bool demo3d_bsp_point_solid(const demo3d_bsp* bsp, pxl8_vec3 pos) {
|
|||
(pos.x < bsp->bounds_min_x || pos.x >= bsp->bounds_max_x ||
|
||||
pos.z < bsp->bounds_min_z || pos.z >= bsp->bounds_max_z))
|
||||
return false;
|
||||
i32 leaf = bsp_find_leaf(bsp, pos);
|
||||
i32 leaf = demo3d_bsp_find_leaf(bsp, pos);
|
||||
if (leaf < 0 || (u32)leaf >= bsp->num_leafs) return true;
|
||||
return bsp->leafs[leaf].contents == -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ typedef struct pxl8_game {
|
|||
bool running;
|
||||
pxl8_script* script;
|
||||
bool script_loaded;
|
||||
char script_path[256];
|
||||
char script_path[PXL8_MAX_PATH];
|
||||
f32 time;
|
||||
void* userdata;
|
||||
} pxl8_game;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
#include "pxl8_blit3d.h"
|
||||
#include "pxl8_atlas.h"
|
||||
#include "pxl8_color.h"
|
||||
#include "pxl8_colormap.h"
|
||||
#include "pxl8_dither.h"
|
||||
#include "pxl8_palette.h"
|
||||
#include "pxl8_platform.h"
|
||||
#include "pxl8_log.h"
|
||||
#include "pxl8_mem.h"
|
||||
|
|
@ -62,27 +64,6 @@ static inline f32 blend_factor_value(pxl8_gfx_blend_factor factor, f32 src_a, f3
|
|||
return 1.0f;
|
||||
}
|
||||
|
||||
static u8 palette_find_closest(const u32* palette, u8 r, u8 g, u8 b) {
|
||||
if (!palette) return 0;
|
||||
u8 best_idx = 1;
|
||||
u32 best_dist = 0xFFFFFFFF;
|
||||
for (u32 i = 1; i < 256; i++) {
|
||||
u8 pr = palette[i] & 0xFF;
|
||||
u8 pg = (palette[i] >> 8) & 0xFF;
|
||||
u8 pb = (palette[i] >> 16) & 0xFF;
|
||||
i32 dr = (i32)r - (i32)pr;
|
||||
i32 dg = (i32)g - (i32)pg;
|
||||
i32 db = (i32)b - (i32)pb;
|
||||
u32 dist = (u32)(dr * dr + dg * dg + db * db);
|
||||
if (dist < best_dist) {
|
||||
best_dist = dist;
|
||||
best_idx = (u8)i;
|
||||
if (dist == 0) break;
|
||||
}
|
||||
}
|
||||
return best_idx;
|
||||
}
|
||||
|
||||
static u8 blend_colors(
|
||||
const pxl8_gfx_pipeline_desc* pipeline,
|
||||
u8 src,
|
||||
|
|
@ -92,12 +73,12 @@ static u8 blend_colors(
|
|||
if (!pipeline || !pipeline->blend.enabled) return src;
|
||||
if (src == 0) return dst;
|
||||
if (!palette) return src;
|
||||
if (pipeline->blend.src == PXL8_GFX_BLEND_ONE && pipeline->blend.dst == PXL8_GFX_BLEND_ZERO) return src;
|
||||
|
||||
f32 dst_a = dst == 0 ? 0.0f : 1.0f;
|
||||
f32 sf = blend_factor_value(pipeline->blend.src, 1.0f, dst_a);
|
||||
f32 df = blend_factor_value(pipeline->blend.dst, 1.0f, dst_a);
|
||||
|
||||
if (sf == 1.0f && df == 0.0f) return src;
|
||||
if (sf == 0.0f && df == 1.0f) return dst;
|
||||
|
||||
u8 sr = palette[src] & 0xFF;
|
||||
|
|
@ -112,7 +93,7 @@ static u8 blend_colors(
|
|||
u8 out_g = (u8)pxl8_clamp_byte((i32)(sg * sf + dg * df));
|
||||
u8 out_b = (u8)pxl8_clamp_byte((i32)(sb * sf + db * df));
|
||||
|
||||
return palette_find_closest(palette, out_r, out_g, out_b);
|
||||
return pxl8_color_find_nearest(palette, PXL8_PALETTE_SIZE, out_r, out_g, out_b);
|
||||
}
|
||||
|
||||
static inline pxl8_vec4 vec4_lerp(pxl8_vec4 a, pxl8_vec4 b, f32 t) {
|
||||
|
|
@ -418,8 +399,8 @@ static void rasterize_triangle(
|
|||
if (span_end > x_end) span_end = x_end;
|
||||
i32 span_len = span_end - x + 1;
|
||||
|
||||
f32 pw_start = 1.0f / wr;
|
||||
f32 pw_end = 1.0f / (wr + dwr * (f32)span_len);
|
||||
f32 pw_start = pxl8_fast_rcp(wr);
|
||||
f32 pw_end = pxl8_fast_rcp(wr + dwr * (f32)span_len);
|
||||
|
||||
f32 u_start = uw * pw_start;
|
||||
f32 v_start = vw * pw_start;
|
||||
|
|
@ -1297,6 +1278,13 @@ static void execute_draw(
|
|||
pxl8_gfx_cull_mode cull_mode = pip->desc.rasterizer.cull;
|
||||
bool is_wireframe = pip->desc.rasterizer.fill == PXL8_GFX_FILL_WIREFRAME;
|
||||
|
||||
pxl8_mat4 model = r->current_draw_params.model;
|
||||
bool model_is_identity = (model.m[0] == 1.0f && model.m[5] == 1.0f && model.m[10] == 1.0f && model.m[15] == 1.0f &&
|
||||
model.m[1] == 0.0f && model.m[2] == 0.0f && model.m[3] == 0.0f &&
|
||||
model.m[4] == 0.0f && model.m[6] == 0.0f && model.m[7] == 0.0f &&
|
||||
model.m[8] == 0.0f && model.m[9] == 0.0f && model.m[11] == 0.0f &&
|
||||
model.m[12] == 0.0f && model.m[13] == 0.0f && model.m[14] == 0.0f);
|
||||
|
||||
for (u32 i = cmd->first_index; i < cmd->first_index + cmd->index_count; i += 3) {
|
||||
r->stats.triangles++;
|
||||
u16 i0, i1, i2;
|
||||
|
|
@ -1331,16 +1319,22 @@ static void execute_draw(
|
|||
rv2.clip_pos = pxl8_mat4_multiply_vec4(mvp, p2);
|
||||
|
||||
if (!is_wireframe) {
|
||||
pxl8_vec4 w0 = pxl8_mat4_multiply_vec4(r->current_draw_params.model, p0);
|
||||
pxl8_vec4 w1 = pxl8_mat4_multiply_vec4(r->current_draw_params.model, p1);
|
||||
pxl8_vec4 w2 = pxl8_mat4_multiply_vec4(r->current_draw_params.model, p2);
|
||||
rv0.world_pos = (pxl8_vec3){w0.x, w0.y, w0.z};
|
||||
rv1.world_pos = (pxl8_vec3){w1.x, w1.y, w1.z};
|
||||
rv2.world_pos = (pxl8_vec3){w2.x, w2.y, w2.z};
|
||||
|
||||
rv0.normal = pxl8_vec3_normalize(pxl8_mat4_multiply_vec3(r->current_draw_params.model, v0->normal));
|
||||
rv1.normal = pxl8_vec3_normalize(pxl8_mat4_multiply_vec3(r->current_draw_params.model, v1->normal));
|
||||
rv2.normal = pxl8_vec3_normalize(pxl8_mat4_multiply_vec3(r->current_draw_params.model, v2->normal));
|
||||
if (model_is_identity) {
|
||||
rv0.world_pos = v0->position;
|
||||
rv1.world_pos = v1->position;
|
||||
rv2.world_pos = v2->position;
|
||||
rv0.normal = v0->normal;
|
||||
} else {
|
||||
pxl8_vec4 w0 = pxl8_mat4_multiply_vec4(model, p0);
|
||||
pxl8_vec4 w1 = pxl8_mat4_multiply_vec4(model, p1);
|
||||
pxl8_vec4 w2 = pxl8_mat4_multiply_vec4(model, p2);
|
||||
rv0.world_pos = (pxl8_vec3){w0.x, w0.y, w0.z};
|
||||
rv1.world_pos = (pxl8_vec3){w1.x, w1.y, w1.z};
|
||||
rv2.world_pos = (pxl8_vec3){w2.x, w2.y, w2.z};
|
||||
rv0.normal = pxl8_vec3_normalize(pxl8_mat4_multiply_vec3(model, v0->normal));
|
||||
}
|
||||
rv1.normal = rv0.normal;
|
||||
rv2.normal = rv0.normal;
|
||||
|
||||
rv0.u = v0->u; rv0.v = v0->v;
|
||||
rv1.u = v1->u; rv1.v = v1->v;
|
||||
|
|
|
|||
|
|
@ -96,6 +96,10 @@ void pxl8_camera3d_set_rotation(pxl8_camera3d* cam, f32 pitch, f32 yaw, f32 roll
|
|||
cam->roll = roll;
|
||||
}
|
||||
|
||||
f32 pxl8_camera3d_get_far(const pxl8_camera3d* cam) {
|
||||
return cam ? cam->far : 1000.0f;
|
||||
}
|
||||
|
||||
pxl8_vec3 pxl8_camera3d_get_forward(const pxl8_camera3d* cam) {
|
||||
if (!cam) return (pxl8_vec3){0, 0, -1};
|
||||
|
||||
|
|
@ -111,6 +115,10 @@ pxl8_vec3 pxl8_camera3d_get_forward(const pxl8_camera3d* cam) {
|
|||
};
|
||||
}
|
||||
|
||||
f32 pxl8_camera3d_get_near(const pxl8_camera3d* cam) {
|
||||
return cam ? cam->near : 1.0f;
|
||||
}
|
||||
|
||||
pxl8_vec3 pxl8_camera3d_get_position(const pxl8_camera3d* cam) {
|
||||
if (!cam) return (pxl8_vec3){0, 0, 0};
|
||||
return pxl8_vec3_add(cam->position, cam->shake_offset);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,9 @@ void pxl8_camera3d_set_perspective(pxl8_camera3d* cam, f32 fov, f32 aspect, f32
|
|||
void pxl8_camera3d_set_position(pxl8_camera3d* cam, pxl8_vec3 pos);
|
||||
void pxl8_camera3d_set_rotation(pxl8_camera3d* cam, f32 pitch, f32 yaw, f32 roll);
|
||||
|
||||
f32 pxl8_camera3d_get_far(const pxl8_camera3d* cam);
|
||||
pxl8_vec3 pxl8_camera3d_get_forward(const pxl8_camera3d* cam);
|
||||
f32 pxl8_camera3d_get_near(const pxl8_camera3d* cam);
|
||||
pxl8_vec3 pxl8_camera3d_get_position(const pxl8_camera3d* cam);
|
||||
pxl8_mat4 pxl8_camera3d_get_projection(const pxl8_camera3d* cam);
|
||||
pxl8_vec3 pxl8_camera3d_get_right(const pxl8_camera3d* cam);
|
||||
|
|
|
|||
|
|
@ -82,3 +82,24 @@ static inline void pxl8_rgba32_unpack(u32 color, u8* r, u8* g, u8* b, u8* a) {
|
|||
*b = (color >> 16) & 0xFF;
|
||||
*a = (color >> 24) & 0xFF;
|
||||
}
|
||||
|
||||
static inline u8 pxl8_color_find_nearest(const u32* palette, u32 count, u8 r, u8 g, u8 b) {
|
||||
if (!palette || count < 2) return 1;
|
||||
u8 best_idx = 1;
|
||||
u32 best_dist = 0xFFFFFFFF;
|
||||
for (u32 i = 1; i < count; i++) {
|
||||
u8 pr = palette[i] & 0xFF;
|
||||
u8 pg = (palette[i] >> 8) & 0xFF;
|
||||
u8 pb = (palette[i] >> 16) & 0xFF;
|
||||
i32 dr = (i32)r - (i32)pr;
|
||||
i32 dg = (i32)g - (i32)pg;
|
||||
i32 db = (i32)b - (i32)pb;
|
||||
u32 dist = (u32)(dr * dr + dg * dg + db * db);
|
||||
if (dist < best_dist) {
|
||||
best_dist = dist;
|
||||
best_idx = (u8)i;
|
||||
if (dist == 0) break;
|
||||
}
|
||||
}
|
||||
return best_idx;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ u8 pxl8_gfx_find_color(pxl8_gfx* gfx, u32 color) {
|
|||
u8 r = (color >> 24) & 0xFF;
|
||||
u8 g = (color >> 16) & 0xFF;
|
||||
u8 b = (color >> 8) & 0xFF;
|
||||
return pxl8_palette_find_closest(gfx->palette, r, g, b);
|
||||
return pxl8_palette_find_nearest(gfx->palette, r, g, b);
|
||||
}
|
||||
|
||||
void pxl8_gfx_set_palette_colors(pxl8_gfx* gfx, const u32* colors, u16 count) {
|
||||
|
|
@ -592,9 +592,9 @@ void pxl8_2d_sprite(pxl8_gfx* gfx, u32 sprite_id, i32 x, i32 y, i32 w, i32 h, bo
|
|||
pxl8_blit(framebuffer, fb_width, sprite_data, atlas_width, x, y, w, h);
|
||||
} else {
|
||||
for (i32 py = 0; py < draw_height; py++) {
|
||||
i32 local_y = (py + clip_top) * entry->h / h;
|
||||
for (i32 px = 0; px < draw_width; px++) {
|
||||
i32 local_x = (px + clip_left) * entry->w / w;
|
||||
i32 local_y = (py + clip_top) * entry->h / h;
|
||||
|
||||
i32 src_x = flip_x ? entry->x + entry->w - 1 - local_x : entry->x + local_x;
|
||||
i32 src_y = flip_y ? entry->y + entry->h - 1 - local_y : entry->y + local_y;
|
||||
|
|
@ -625,8 +625,8 @@ static pxl8_3d_frame pxl8_3d_frame_from_camera(const pxl8_camera3d* camera, cons
|
|||
frame.projection = pxl8_camera3d_get_projection(camera);
|
||||
frame.camera_pos = pxl8_camera3d_get_position(camera);
|
||||
frame.camera_dir = pxl8_camera3d_get_forward(camera);
|
||||
frame.near_clip = 1.0f;
|
||||
frame.far_clip = 4096.0f;
|
||||
frame.near_clip = pxl8_camera3d_get_near(camera);
|
||||
frame.far_clip = pxl8_camera3d_get_far(camera);
|
||||
|
||||
if (uniforms) {
|
||||
frame.uniforms = *uniforms;
|
||||
|
|
@ -978,7 +978,7 @@ void pxl8_gfx_colormap_update(pxl8_gfx* gfx) {
|
|||
|
||||
u8 pxl8_gfx_find_closest_color(pxl8_gfx* gfx, u8 r, u8 g, u8 b) {
|
||||
if (!gfx || !gfx->palette) return 0;
|
||||
return pxl8_palette_find_closest(gfx->palette, r, g, b);
|
||||
return pxl8_palette_find_nearest(gfx->palette, r, g, b);
|
||||
}
|
||||
|
||||
void pxl8_gfx_set_wireframe(pxl8_gfx* gfx, bool enabled) {
|
||||
|
|
|
|||
|
|
@ -55,21 +55,6 @@ static void pxl8_palette_rebuild_hash(pxl8_palette* pal) {
|
|||
}
|
||||
}
|
||||
|
||||
static inline u32 pack_rgb(u8 r, u8 g, u8 b) {
|
||||
return 0xFF000000 | ((u32)b << 16) | ((u32)g << 8) | r;
|
||||
}
|
||||
|
||||
static inline u32 pack_rgba(u8 r, u8 g, u8 b, u8 a) {
|
||||
return ((u32)a << 24) | ((u32)b << 16) | ((u32)g << 8) | r;
|
||||
}
|
||||
|
||||
static inline void unpack_rgba(u32 c, u8* r, u8* g, u8* b, u8* a) {
|
||||
*r = c & 0xFF;
|
||||
*g = (c >> 8) & 0xFF;
|
||||
*b = (c >> 16) & 0xFF;
|
||||
*a = (c >> 24) & 0xFF;
|
||||
}
|
||||
|
||||
static f32 apply_easing(pxl8_easing easing, f32 t) {
|
||||
switch (easing) {
|
||||
case PXL8_EASE_IN:
|
||||
|
|
@ -152,7 +137,7 @@ static void pxl8_palette_sort_colors(pxl8_palette* pal) {
|
|||
palette_sort_entry entries[PXL8_PALETTE_SIZE - 1];
|
||||
for (u32 i = 1; i < count; i++) {
|
||||
u8 r, g, b, a;
|
||||
unpack_rgba(pal->colors[i], &r, &g, &b, &a);
|
||||
pxl8_rgba32_unpack(pal->colors[i], &r, &g, &b, &a);
|
||||
|
||||
entries[i - 1].index = (u8)i;
|
||||
rgb_to_hsl(r, g, b, &entries[i - 1].hue, &entries[i - 1].sat, &entries[i - 1].lum);
|
||||
|
|
@ -167,15 +152,15 @@ static void pxl8_palette_sort_colors(pxl8_palette* pal) {
|
|||
|
||||
static u32 lerp_color(u32 c0, u32 c1, f32 t) {
|
||||
u8 r0, g0, b0, a0, r1, g1, b1, a1;
|
||||
unpack_rgba(c0, &r0, &g0, &b0, &a0);
|
||||
unpack_rgba(c1, &r1, &g1, &b1, &a1);
|
||||
pxl8_rgba32_unpack(c0, &r0, &g0, &b0, &a0);
|
||||
pxl8_rgba32_unpack(c1, &r1, &g1, &b1, &a1);
|
||||
|
||||
u8 r = (u8)(r0 + (r1 - r0) * t);
|
||||
u8 g = (u8)(g0 + (g1 - g0) * t);
|
||||
u8 b = (u8)(b0 + (b1 - b0) * t);
|
||||
u8 a = (u8)(a0 + (a1 - a0) * t);
|
||||
|
||||
return pack_rgba(r, g, b, a);
|
||||
return pxl8_rgba32_pack(r, g, b, a);
|
||||
}
|
||||
|
||||
static void update_cycle_colors(pxl8_palette* pal, u8 slot) {
|
||||
|
|
@ -212,8 +197,8 @@ pxl8_palette* pxl8_palette_create(void) {
|
|||
if (!pal) return NULL;
|
||||
|
||||
pal->colors[0] = 0x00000000;
|
||||
pal->colors[1] = pack_rgb(0x00, 0x00, 0x00);
|
||||
pal->colors[2] = pack_rgb(0xFF, 0xFF, 0xFF);
|
||||
pal->colors[1] = pxl8_rgba32_pack(0x00, 0x00, 0x00, 0xFF);
|
||||
pal->colors[2] = pxl8_rgba32_pack(0xFF, 0xFF, 0xFF, 0xFF);
|
||||
pal->color_count = 3;
|
||||
pal->color_ramp[0] = 0;
|
||||
pal->color_ramp[1] = 1;
|
||||
|
|
@ -286,29 +271,9 @@ u8 pxl8_palette_ramp_position(const pxl8_palette* pal, u8 index) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
u8 pxl8_palette_find_closest(const pxl8_palette* pal, u8 r, u8 g, u8 b) {
|
||||
u8 pxl8_palette_find_nearest(const pxl8_palette* pal, u8 r, u8 g, u8 b) {
|
||||
if (!pal || pal->color_count < 2) return 1;
|
||||
|
||||
u8 best_idx = 1;
|
||||
u32 best_dist = 0xFFFFFFFF;
|
||||
|
||||
for (u32 i = 1; i < pal->color_count; i++) {
|
||||
u8 pr, pg, pb, pa;
|
||||
unpack_rgba(pal->colors[i], &pr, &pg, &pb, &pa);
|
||||
|
||||
i32 dr = (i32)r - (i32)pr;
|
||||
i32 dg = (i32)g - (i32)pg;
|
||||
i32 db = (i32)b - (i32)pb;
|
||||
u32 dist = (u32)(dr * dr + dg * dg + db * db);
|
||||
|
||||
if (dist < best_dist) {
|
||||
best_dist = dist;
|
||||
best_idx = (u8)i;
|
||||
if (dist == 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
return best_idx;
|
||||
return pxl8_color_find_nearest(pal->colors, pal->color_count, r, g, b);
|
||||
}
|
||||
|
||||
u32 pxl8_palette_color(const pxl8_palette* pal, u8 idx) {
|
||||
|
|
@ -332,20 +297,20 @@ i32 pxl8_palette_index(const pxl8_palette* pal, u32 rgba) {
|
|||
void pxl8_palette_get_rgb(const pxl8_palette* pal, u8 idx, u8* r, u8* g, u8* b) {
|
||||
if (!pal || !r || !g || !b) return;
|
||||
u8 a;
|
||||
unpack_rgba(pal->colors[idx], r, g, b, &a);
|
||||
pxl8_rgba32_unpack(pal->colors[idx], r, g, b, &a);
|
||||
}
|
||||
|
||||
void pxl8_palette_get_rgba(const pxl8_palette* pal, u8 idx, u8* r, u8* g, u8* b, u8* a) {
|
||||
if (!pal || !r || !g || !b || !a) return;
|
||||
unpack_rgba(pal->colors[idx], r, g, b, a);
|
||||
pxl8_rgba32_unpack(pal->colors[idx], r, g, b, a);
|
||||
}
|
||||
|
||||
void pxl8_palette_set_rgb(pxl8_palette* pal, u8 idx, u8 r, u8 g, u8 b) {
|
||||
if (pal) pal->colors[idx] = pack_rgb(r, g, b);
|
||||
if (pal) pal->colors[idx] = pxl8_rgba32_pack(r, g, b, 0xFF);
|
||||
}
|
||||
|
||||
void pxl8_palette_set_rgba(pxl8_palette* pal, u8 idx, u8 r, u8 g, u8 b, u8 a) {
|
||||
if (pal) pal->colors[idx] = pack_rgba(r, g, b, a);
|
||||
if (pal) pal->colors[idx] = pxl8_rgba32_pack(r, g, b, a);
|
||||
}
|
||||
|
||||
void pxl8_set_palette(pxl8_palette* pal, const u32* colors, u16 count) {
|
||||
|
|
@ -355,7 +320,7 @@ void pxl8_set_palette(pxl8_palette* pal, const u32* colors, u16 count) {
|
|||
u8 r = (rgb >> 16) & 0xFF;
|
||||
u8 g = (rgb >> 8) & 0xFF;
|
||||
u8 b = rgb & 0xFF;
|
||||
pal->colors[i] = pack_rgb(r, g, b);
|
||||
pal->colors[i] = pxl8_rgba32_pack(r, g, b, 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -363,8 +328,8 @@ void pxl8_palette_fill_gradient(pxl8_palette* pal, u8 start, u8 count, u32 from,
|
|||
if (!pal || count == 0) return;
|
||||
|
||||
u8 r0, g0, b0, a0, r1, g1, b1, a1;
|
||||
unpack_rgba(from, &r0, &g0, &b0, &a0);
|
||||
unpack_rgba(to, &r1, &g1, &b1, &a1);
|
||||
pxl8_rgba32_unpack(from, &r0, &g0, &b0, &a0);
|
||||
pxl8_rgba32_unpack(to, &r1, &g1, &b1, &a1);
|
||||
|
||||
for (u8 i = 0; i < count; i++) {
|
||||
f32 t = (count > 1) ? (f32)i / (f32)(count - 1) : 0.0f;
|
||||
|
|
@ -372,12 +337,12 @@ void pxl8_palette_fill_gradient(pxl8_palette* pal, u8 start, u8 count, u32 from,
|
|||
u8 g = (u8)(g0 + (g1 - g0) * t);
|
||||
u8 b = (u8)(b0 + (b1 - b0) * t);
|
||||
u8 a = (u8)(a0 + (a1 - a0) * t);
|
||||
pal->colors[start + i] = pack_rgba(r, g, b, a);
|
||||
pal->colors[start + i] = pxl8_rgba32_pack(r, g, b, a);
|
||||
}
|
||||
}
|
||||
|
||||
void pxl8_palette_fill_gradient_rgb(pxl8_palette* pal, u8 start, u8 count, u8 r0, u8 g0, u8 b0, u8 r1, u8 g1, u8 b1) {
|
||||
pxl8_palette_fill_gradient(pal, start, count, pack_rgb(r0, g0, b0), pack_rgb(r1, g1, b1));
|
||||
pxl8_palette_fill_gradient(pal, start, count, pxl8_rgba32_pack(r0, g0, b0, 0xFF), pxl8_rgba32_pack(r1, g1, b1, 0xFF));
|
||||
}
|
||||
|
||||
void pxl8_palette_reset_cycle(pxl8_palette* pal, u8 slot) {
|
||||
|
|
@ -491,16 +456,14 @@ pxl8_cycle_range pxl8_cycle_range_disabled(void) {
|
|||
static u8 find_closest_stable(const pxl8_palette* pal, u8 r, u8 g, u8 b) {
|
||||
u8 best_idx = 1;
|
||||
u32 best_dist = 0xFFFFFFFF;
|
||||
|
||||
u8 dynamic_end = PXL8_DYNAMIC_RANGE_START + PXL8_DYNAMIC_RANGE_COUNT;
|
||||
|
||||
for (u32 i = 1; i < PXL8_FULLBRIGHT_START; i++) {
|
||||
if (i >= PXL8_DYNAMIC_RANGE_START && i < dynamic_end) {
|
||||
continue;
|
||||
}
|
||||
if (i >= PXL8_DYNAMIC_RANGE_START && i < dynamic_end) continue;
|
||||
|
||||
u8 pr, pg, pb;
|
||||
pxl8_palette_get_rgb(pal, (u8)i, &pr, &pg, &pb);
|
||||
u8 pr = pal->colors[i] & 0xFF;
|
||||
u8 pg = (pal->colors[i] >> 8) & 0xFF;
|
||||
u8 pb = (pal->colors[i] >> 16) & 0xFF;
|
||||
|
||||
i32 dr = (i32)r - (i32)pr;
|
||||
i32 dg = (i32)g - (i32)pg;
|
||||
|
|
@ -547,7 +510,7 @@ void pxl8_palette_cube_rebuild(pxl8_palette_cube* cube, const pxl8_palette* pal)
|
|||
u8 g8 = (u8)((gi * 255) / (PXL8_CUBE_SIZE - 1));
|
||||
u8 b8 = (u8)((bi * 255) / (PXL8_CUBE_SIZE - 1));
|
||||
|
||||
cube->table[idx] = pxl8_palette_find_closest(pal, r8, g8, b8);
|
||||
cube->table[idx] = pxl8_palette_find_nearest(pal, r8, g8, b8);
|
||||
cube->stable[idx] = find_closest_stable(pal, r8, g8, b8);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ u8* pxl8_palette_color_ramp(pxl8_palette* pal);
|
|||
u32* pxl8_palette_colors(pxl8_palette* pal);
|
||||
u8 pxl8_palette_ramp_index(const pxl8_palette* pal, u8 position);
|
||||
u8 pxl8_palette_ramp_position(const pxl8_palette* pal, u8 index);
|
||||
u8 pxl8_palette_find_closest(const pxl8_palette* pal, u8 r, u8 g, u8 b);
|
||||
u8 pxl8_palette_find_nearest(const pxl8_palette* pal, u8 r, u8 g, u8 b);
|
||||
u32 pxl8_palette_color(const pxl8_palette* pal, u8 idx);
|
||||
i32 pxl8_palette_index(const pxl8_palette* pal, u32 color);
|
||||
void pxl8_palette_get_rgb(const pxl8_palette* pal, u8 idx, u8* r, u8* g, u8* b);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ struct pxl8_net {
|
|||
socket_t sock;
|
||||
|
||||
u8 recv_buf[4096];
|
||||
u8 send_buf[4096];
|
||||
|
||||
#ifdef PXL8_ASYNC_THREADS
|
||||
pxl8_thread* recv_thread;
|
||||
|
|
@ -220,11 +219,4 @@ void pxl8_net_packet_free(pxl8_packet* pkt) {
|
|||
pxl8_free(pkt);
|
||||
}
|
||||
|
||||
bool pxl8_net_process_packet(pxl8_net* net, const pxl8_packet* pkt) {
|
||||
if (!net || !pkt) return false;
|
||||
(void)net;
|
||||
(void)pkt;
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ void pxl8_net_start_thread(pxl8_net* net);
|
|||
void pxl8_net_stop_thread(pxl8_net* net);
|
||||
pxl8_packet* pxl8_net_pop_packet(pxl8_net* net);
|
||||
void pxl8_net_packet_free(pxl8_packet* pkt);
|
||||
bool pxl8_net_process_packet(pxl8_net* net, const pxl8_packet* pkt);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -23,14 +23,6 @@ static f32 gradient2d(i32 ix, i32 iy, f32 fx, f32 fy, u32 seed) {
|
|||
return gx * fx + gy * fy;
|
||||
}
|
||||
|
||||
static inline f32 smoothstep(f32 t) {
|
||||
return t * t * (3.0f - 2.0f * t);
|
||||
}
|
||||
|
||||
static inline f32 lerp(f32 a, f32 b, f32 t) {
|
||||
return a + t * (b - a);
|
||||
}
|
||||
|
||||
static f32 noise_value(f32 x, f32 y, f32 scale, u32 seed) {
|
||||
f32 sx = x * scale;
|
||||
f32 sy = y * scale;
|
||||
|
|
@ -38,15 +30,15 @@ static f32 noise_value(f32 x, f32 y, f32 scale, u32 seed) {
|
|||
i32 iy = (i32)floorf(sy);
|
||||
f32 fx = sx - (f32)ix;
|
||||
f32 fy = sy - (f32)iy;
|
||||
f32 u = smoothstep(fx);
|
||||
f32 v = smoothstep(fy);
|
||||
f32 u = pxl8_smoothstep(fx);
|
||||
f32 v = pxl8_smoothstep(fy);
|
||||
|
||||
f32 n00 = hash2d_f(ix, iy, seed);
|
||||
f32 n10 = hash2d_f(ix + 1, iy, seed);
|
||||
f32 n01 = hash2d_f(ix, iy + 1, seed);
|
||||
f32 n11 = hash2d_f(ix + 1, iy + 1, seed);
|
||||
|
||||
return lerp(lerp(n00, n10, u), lerp(n01, n11, u), v);
|
||||
return pxl8_lerp(pxl8_lerp(n00, n10, u), pxl8_lerp(n01, n11, u), v);
|
||||
}
|
||||
|
||||
static f32 noise_perlin(f32 x, f32 y, f32 scale, u32 seed) {
|
||||
|
|
@ -56,15 +48,15 @@ static f32 noise_perlin(f32 x, f32 y, f32 scale, u32 seed) {
|
|||
i32 iy = (i32)floorf(sy);
|
||||
f32 fx = sx - (f32)ix;
|
||||
f32 fy = sy - (f32)iy;
|
||||
f32 u = smoothstep(fx);
|
||||
f32 v = smoothstep(fy);
|
||||
f32 u = pxl8_smoothstep(fx);
|
||||
f32 v = pxl8_smoothstep(fy);
|
||||
|
||||
f32 n00 = gradient2d(ix, iy, fx, fy, seed);
|
||||
f32 n10 = gradient2d(ix + 1, iy, fx - 1.0f, fy, seed);
|
||||
f32 n01 = gradient2d(ix, iy + 1, fx, fy - 1.0f, seed);
|
||||
f32 n11 = gradient2d(ix + 1, iy + 1, fx - 1.0f, fy - 1.0f, seed);
|
||||
|
||||
f32 result = lerp(lerp(n00, n10, u), lerp(n01, n11, u), v);
|
||||
f32 result = pxl8_lerp(pxl8_lerp(n00, n10, u), pxl8_lerp(n01, n11, u), v);
|
||||
return result * 0.5f + 0.5f;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue