optimize demo3d bsp render by sorting faces based on material
This commit is contained in:
parent
cf43538518
commit
728b393a8e
3 changed files with 109 additions and 78 deletions
|
|
@ -104,10 +104,18 @@ demo3d_bsp_render_state* demo3d_bsp_render_state_create(u32 num_faces) {
|
|||
pxl8_free(state);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
state->visible_faces = pxl8_malloc(num_faces * sizeof(u32));
|
||||
if (!state->visible_faces) {
|
||||
pxl8_free(state->render_face_flags);
|
||||
pxl8_free(state);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
state->mesh = pxl8_mesh_create(8192, 16384);
|
||||
if (!state->mesh) {
|
||||
pxl8_free(state->visible_faces);
|
||||
pxl8_free(state->render_face_flags);
|
||||
pxl8_free(state);
|
||||
return NULL;
|
||||
|
|
@ -120,6 +128,9 @@ 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->mat_write_pos);
|
||||
pxl8_free(state->mat_offsets);
|
||||
pxl8_free(state->visible_faces);
|
||||
pxl8_free(state->render_face_flags);
|
||||
pxl8_free(state);
|
||||
}
|
||||
|
|
@ -140,18 +151,38 @@ void demo3d_bsp_render(pxl8_gfx* gfx, const demo3d_bsp* bsp,
|
|||
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++) {
|
||||
u32 mat_count = state->num_materials;
|
||||
if (!state->mat_offsets || !state->mat_write_pos) return;
|
||||
|
||||
memset(state->mat_offsets, 0, (mat_count + 1) * sizeof(u32));
|
||||
|
||||
for (u32 face_id = 0; face_id < bsp->num_faces && face_id < state->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;
|
||||
if (mid < mat_count) state->mat_offsets[mid]++;
|
||||
}
|
||||
|
||||
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;
|
||||
if (bsp->faces[face_id].material_id != mat) continue;
|
||||
u32 running = 0;
|
||||
for (u32 i = 0; i < mat_count; i++) {
|
||||
u32 c = state->mat_offsets[i];
|
||||
state->mat_offsets[i] = running;
|
||||
running += c;
|
||||
}
|
||||
state->mat_offsets[mat_count] = running;
|
||||
|
||||
memcpy(state->mat_write_pos, state->mat_offsets, mat_count * sizeof(u32));
|
||||
|
||||
for (u32 face_id = 0; face_id < bsp->num_faces && face_id < state->num_faces; face_id++) {
|
||||
if (!state->render_face_flags[face_id]) continue;
|
||||
u16 mid = bsp->faces[face_id].material_id;
|
||||
if (mid < mat_count) {
|
||||
state->visible_faces[state->mat_write_pos[mid]++] = face_id;
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 mat = 0; mat < mat_count; mat++) {
|
||||
for (u32 i = state->mat_offsets[mat]; i < state->mat_offsets[mat + 1]; i++) {
|
||||
u32 face_id = state->visible_faces[i];
|
||||
if (!face_in_frustum(bsp, face_id, frustum)) continue;
|
||||
collect_face_to_mesh(bsp, state, face_id, mesh, ambient);
|
||||
}
|
||||
|
|
@ -184,6 +215,9 @@ void demo3d_bsp_set_material(demo3d_bsp_render_state* state, u16 material_id, co
|
|||
|
||||
state->materials = new_materials;
|
||||
state->num_materials = new_count;
|
||||
|
||||
state->mat_offsets = pxl8_realloc(state->mat_offsets, (new_count + 1) * sizeof(u32));
|
||||
state->mat_write_pos = pxl8_realloc(state->mat_write_pos, new_count * sizeof(u32));
|
||||
}
|
||||
|
||||
pxl8_vec3 u_axis = state->materials[material_id].u_axis;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue