wip procgen
This commit is contained in:
parent
a653eae745
commit
79a678f162
18 changed files with 1317 additions and 127 deletions
126
src/pxl8_bsp.c
126
src/pxl8_bsp.c
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue