wip procgen

This commit is contained in:
asrael 2025-11-09 06:30:17 -06:00
parent a653eae745
commit 79a678f162
No known key found for this signature in database
GPG key ID: 2786557804DFAE24
18 changed files with 1317 additions and 127 deletions

View file

@ -1,3 +1,4 @@
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -331,7 +332,47 @@ bool pxl8_bsp_is_leaf_visible(const pxl8_bsp* bsp, i32 leaf_from, i32 leaf_to) {
return (bsp->visdata[visofs + byte_idx] & (1 << bit_idx)) != 0;
}
void pxl8_bsp_render_face(pxl8_gfx* gfx, const pxl8_bsp* bsp, u32 face_id, u32 color) {
static inline bool face_in_frustum(const pxl8_bsp* bsp, u32 face_id, const pxl8_frustum* frustum) {
const pxl8_bsp_face* face = &bsp->faces[face_id];
f32 min_x = 1e30f, min_y = 1e30f, min_z = 1e30f;
f32 max_x = -1e30f, max_y = -1e30f, max_z = -1e30f;
for (u32 i = 0; i < face->num_edges; i++) {
i32 surfedge_idx = face->first_edge + i;
if (surfedge_idx >= (i32)bsp->num_surfedges) continue;
i32 edge_idx = bsp->surfedges[surfedge_idx];
u32 vert_idx;
if (edge_idx >= 0) {
if ((u32)edge_idx >= bsp->num_edges) continue;
vert_idx = bsp->edges[edge_idx].vertex[0];
} else {
edge_idx = -edge_idx;
if ((u32)edge_idx >= bsp->num_edges) continue;
vert_idx = bsp->edges[edge_idx].vertex[1];
}
if (vert_idx >= bsp->num_vertices) continue;
pxl8_vec3 v = bsp->vertices[vert_idx].position;
if (v.x < min_x) min_x = v.x;
if (v.x > max_x) max_x = v.x;
if (v.y < min_y) min_y = v.y;
if (v.y > max_y) max_y = v.y;
if (v.z < min_z) min_z = v.z;
if (v.z > max_z) max_z = v.z;
}
pxl8_vec3 aabb_min = {min_x, min_y, min_z};
pxl8_vec3 aabb_max = {max_x, max_y, max_z};
return pxl8_frustum_test_aabb(frustum, aabb_min, aabb_max);
}
void pxl8_bsp_render_face(pxl8_gfx* gfx, const pxl8_bsp* bsp, u32 face_id, u32 texture_id) {
if (!gfx || !bsp || face_id >= bsp->num_faces) return;
const pxl8_bsp_face* face = &bsp->faces[face_id];
@ -340,6 +381,19 @@ void pxl8_bsp_render_face(pxl8_gfx* gfx, const pxl8_bsp* bsp, u32 face_id, u32 c
pxl8_vec3 verts[64];
u32 num_verts = 0;
const pxl8_bsp_plane* plane = &bsp->planes[face->plane_id];
u32 color;
bool use_texture = false;
if (fabsf(plane->normal.y) > 0.7f) {
color = (plane->normal.y > 0) ? 4 : 3;
} else {
color = 15;
use_texture = (texture_id > 0);
}
for (u32 i = 0; i < face->num_edges && num_verts < 64; i++) {
i32 surfedge_idx = face->first_edge + i;
if (surfedge_idx >= (i32)bsp->num_surfedges) continue;
@ -362,11 +416,77 @@ void pxl8_bsp_render_face(pxl8_gfx* gfx, const pxl8_bsp* bsp, u32 face_id, u32 c
if (num_verts < 3) return;
for (u32 i = 1; i < num_verts - 1; i++) {
pxl8_3d_draw_triangle_raw(gfx, verts[0], verts[i], verts[i + 1], color);
if (use_texture && face->texinfo_id < bsp->num_texinfo) {
const pxl8_bsp_texinfo* texinfo = &bsp->texinfo[face->texinfo_id];
f32 tex_scale = 64.0f;
for (u32 tri_idx = 1; tri_idx < num_verts - 1; tri_idx++) {
pxl8_vec3 v0 = verts[0];
pxl8_vec3 v1 = verts[tri_idx];
pxl8_vec3 v2 = verts[tri_idx + 1];
f32 u0 = (pxl8_vec3_dot(v0, texinfo->u_axis) + texinfo->u_offset) / tex_scale;
f32 v0_uv = (pxl8_vec3_dot(v0, texinfo->v_axis) + texinfo->v_offset) / tex_scale;
f32 u1 = (pxl8_vec3_dot(v1, texinfo->u_axis) + texinfo->u_offset) / tex_scale;
f32 v1_uv = (pxl8_vec3_dot(v1, texinfo->v_axis) + texinfo->v_offset) / tex_scale;
f32 u2 = (pxl8_vec3_dot(v2, texinfo->u_axis) + texinfo->u_offset) / tex_scale;
f32 v2_uv = (pxl8_vec3_dot(v2, texinfo->v_axis) + texinfo->v_offset) / tex_scale;
pxl8_3d_draw_triangle_textured(gfx, v0, v1, v2, u0, v0_uv, u1, v1_uv, u2, v2_uv, texture_id);
}
} else{
for (u32 i = 1; i < num_verts - 1; i++) {
pxl8_3d_draw_triangle_raw(gfx, verts[0], verts[i], verts[i + 1], color);
}
}
}
void pxl8_bsp_render_solid(
pxl8_gfx* gfx,
const pxl8_bsp* bsp,
pxl8_vec3 camera_pos,
u32 texture_id
) {
if (!gfx || !bsp || bsp->num_faces == 0) return;
const pxl8_frustum* frustum = pxl8_3d_get_frustum(gfx);
if (!frustum) return;
i32 camera_leaf = pxl8_bsp_find_leaf(bsp, camera_pos);
static u8* rendered_faces = NULL;
static u32 rendered_faces_capacity = 0;
if (rendered_faces_capacity < bsp->num_faces) {
rendered_faces = realloc(rendered_faces, bsp->num_faces);
if (!rendered_faces) return;
rendered_faces_capacity = bsp->num_faces;
pxl8_debug("Allocated face tracking buffer: %u bytes", bsp->num_faces);
}
memset(rendered_faces, 0, bsp->num_faces);
for (u32 leaf_id = 0; leaf_id < bsp->num_leafs; leaf_id++) {
if (camera_leaf >= 0 && !pxl8_bsp_is_leaf_visible(bsp, camera_leaf, leaf_id)) continue;
const pxl8_bsp_leaf* leaf = &bsp->leafs[leaf_id];
for (u32 i = 0; i < leaf->num_marksurfaces; i++) {
u32 surf_idx = leaf->first_marksurface + i;
if (surf_idx >= bsp->num_marksurfaces) continue;
u32 face_id = bsp->marksurfaces[surf_idx];
if (face_id >= bsp->num_faces) continue;
if (rendered_faces[face_id]) continue;
rendered_faces[face_id] = 1;
pxl8_bsp_render_face(gfx, bsp, face_id, texture_id);
}
}
}
void pxl8_bsp_render_wireframe(
pxl8_gfx* gfx,
const pxl8_bsp* bsp,