per-instance frustum culling
parent
aec753e2c4
commit
9bfb5b47fd
|
@ -1493,6 +1493,7 @@ typedef struct model_t {
|
||||||
vec3 *meshcenters;
|
vec3 *meshcenters;
|
||||||
aabb *meshbounds;
|
aabb *meshbounds;
|
||||||
float *meshradii;
|
float *meshradii;
|
||||||
|
bool *mesh_visible;
|
||||||
int num_tris;
|
int num_tris;
|
||||||
handle vao, ibo, vbo, vao_instanced;
|
handle vao, ibo, vbo, vao_instanced;
|
||||||
int* lod_collapse_map;
|
int* lod_collapse_map;
|
||||||
|
|
|
@ -17783,6 +17783,7 @@ typedef struct model_t {
|
||||||
vec3 *meshcenters;
|
vec3 *meshcenters;
|
||||||
aabb *meshbounds;
|
aabb *meshbounds;
|
||||||
float *meshradii;
|
float *meshradii;
|
||||||
|
bool *mesh_visible;
|
||||||
int num_tris;
|
int num_tris;
|
||||||
handle vao, ibo, vbo, vao_instanced;
|
handle vao, ibo, vbo, vao_instanced;
|
||||||
|
|
||||||
|
@ -386398,6 +386399,7 @@ bool model_load_meshes(iqm_t *q, const struct iqmheader *hdr, model_t *m) {
|
||||||
m->meshcenters = CALLOC(hdr->num_meshes, sizeof(vec3));
|
m->meshcenters = CALLOC(hdr->num_meshes, sizeof(vec3));
|
||||||
m->meshbounds = CALLOC(hdr->num_meshes, sizeof(aabb));
|
m->meshbounds = CALLOC(hdr->num_meshes, sizeof(aabb));
|
||||||
m->meshradii = CALLOC(hdr->num_meshes, sizeof(float));
|
m->meshradii = CALLOC(hdr->num_meshes, sizeof(float));
|
||||||
|
m->mesh_visible = CALLOC(hdr->num_meshes, sizeof(bool));
|
||||||
|
|
||||||
for(int i = 0; i < (int)hdr->num_meshes; i++) {
|
for(int i = 0; i < (int)hdr->num_meshes; i++) {
|
||||||
int invalid = texture_checker().id;
|
int invalid = texture_checker().id;
|
||||||
|
@ -387195,7 +387197,7 @@ bool model_is_visible(model_t m, int mesh, mat44 model_mat, mat44 proj, mat44 vi
|
||||||
mat44 proj_modified;
|
mat44 proj_modified;
|
||||||
copy44(proj_modified, proj);
|
copy44(proj_modified, proj);
|
||||||
|
|
||||||
// Increase FOV by 1.5
|
// Increase FOV by GLOBAL_FRUSTUM_FOV_MULTIPLIER
|
||||||
float fov_scale = 1.0f / GLOBAL_FRUSTUM_FOV_MULTIPLIER;
|
float fov_scale = 1.0f / GLOBAL_FRUSTUM_FOV_MULTIPLIER;
|
||||||
proj_modified[0] *= fov_scale;
|
proj_modified[0] *= fov_scale;
|
||||||
proj_modified[5] *= fov_scale;
|
proj_modified[5] *= fov_scale;
|
||||||
|
@ -387265,14 +387267,14 @@ void model_draw_call(model_t m, int shader, int pass, vec3 cam_pos, mat44 model_
|
||||||
|
|
||||||
if (rs_idx > RENDER_PASS_OVERRIDES_BEGIN) {
|
if (rs_idx > RENDER_PASS_OVERRIDES_BEGIN) {
|
||||||
for(int i = 0; i < q->nummeshes; i++) {
|
for(int i = 0; i < q->nummeshes; i++) {
|
||||||
if (!model_is_visible(m, i, model_mat, proj, view)) continue;
|
if (!m.mesh_visible[i]) continue;
|
||||||
array_push(drawcalls, (drawcall_t){i, -1});
|
array_push(drawcalls, (drawcall_t){i, -1});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(pass == -1 || pass == RENDER_PASS_OPAQUE) {
|
if(pass == -1 || pass == RENDER_PASS_OPAQUE) {
|
||||||
for(int i = 0; i < q->nummeshes; i++) {
|
for(int i = 0; i < q->nummeshes; i++) {
|
||||||
if (!model_is_visible(m, i, model_mat, proj, view)) continue;
|
if (!m.mesh_visible[i]) continue;
|
||||||
|
|
||||||
// collect opaque drawcalls
|
// collect opaque drawcalls
|
||||||
if (required_rs[i] == RENDER_PASS_OPAQUE) {
|
if (required_rs[i] == RENDER_PASS_OPAQUE) {
|
||||||
drawcall_t call;
|
drawcall_t call;
|
||||||
|
@ -387288,8 +387290,8 @@ void model_draw_call(model_t m, int shader, int pass, vec3 cam_pos, mat44 model_
|
||||||
|
|
||||||
if(pass == -1 || pass == RENDER_PASS_TRANSPARENT) {
|
if(pass == -1 || pass == RENDER_PASS_TRANSPARENT) {
|
||||||
for(int i = 0; i < q->nummeshes; i++) {
|
for(int i = 0; i < q->nummeshes; i++) {
|
||||||
if (!model_is_visible(m, i, model_mat, proj, view)) continue;
|
if (!m.mesh_visible[i]) continue;
|
||||||
|
|
||||||
// collect transparent drawcalls
|
// collect transparent drawcalls
|
||||||
if (required_rs[i] == RENDER_PASS_TRANSPARENT) {
|
if (required_rs[i] == RENDER_PASS_TRANSPARENT) {
|
||||||
drawcall_t call;
|
drawcall_t call;
|
||||||
|
@ -387364,28 +387366,52 @@ void model_draw_call(model_t m, int shader, int pass, vec3 cam_pos, mat44 model_
|
||||||
shader_bind(old_shader);
|
shader_bind(old_shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
void model_render_instanced_pass(model_t m, mat44 proj, mat44 view, mat44* models, int shader, unsigned count, int pass) {
|
static mat44 *pass_model_matrices = NULL;
|
||||||
if(!m.iqm) return;
|
|
||||||
iqm_t *q = m.iqm;
|
void model_render_instanced_pass(model_t mdl, mat44 proj, mat44 view, mat44* models, int shader, unsigned count, int pass) {
|
||||||
|
if(!mdl.iqm) return;
|
||||||
|
iqm_t *q = mdl.iqm;
|
||||||
|
|
||||||
if (active_shadowmap && active_shadowmap->skip_render) {
|
if (active_shadowmap && active_shadowmap->skip_render) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mat44 mv; multiply44x2(mv, view, models[0]);
|
pass_model_matrices = array_resize(pass_model_matrices, count); //@leak
|
||||||
|
memcpy(pass_model_matrices, models, count * sizeof(mat44));
|
||||||
|
memset(mdl.mesh_visible, 0, q->nummeshes * sizeof(bool));
|
||||||
|
|
||||||
if( count != m.num_instances ) {
|
for (int i = 0; i < count; i++) {
|
||||||
m.num_instances = count;
|
bool any_visible = false;
|
||||||
m.instanced_matrices = (float*)models;
|
for (int m = 0; m < q->nummeshes; m++) {
|
||||||
model_set_state(m);
|
bool visible = model_is_visible(mdl, m, pass_model_matrices[i], proj, view);
|
||||||
|
mdl.mesh_visible[m] |= visible;
|
||||||
|
any_visible |= visible;
|
||||||
|
}
|
||||||
|
if (!any_visible) {
|
||||||
|
array_erase_fast(pass_model_matrices, i);
|
||||||
|
i--;
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat44 mv; multiply44x2(mv, view, pass_model_matrices[0]);
|
||||||
|
|
||||||
|
if( count != mdl.num_instances ) {
|
||||||
|
mdl.num_instances = count;
|
||||||
|
mdl.instanced_matrices = (float*)pass_model_matrices;
|
||||||
|
model_set_state(mdl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model_getpass() > RENDER_PASS_SHADOW_BEGIN && model_getpass() < RENDER_PASS_SHADOW_END) {
|
if (model_getpass() > RENDER_PASS_SHADOW_BEGIN && model_getpass() < RENDER_PASS_SHADOW_END) {
|
||||||
shader = m.shadow_program;
|
shader = mdl.shadow_program;
|
||||||
}
|
}
|
||||||
|
|
||||||
model_set_uniforms(m, shader > 0 ? shader : m.program, mv, proj, view, models[0]);
|
model_set_uniforms(mdl, shader > 0 ? shader : mdl.program, mv, proj, view, pass_model_matrices[0]);
|
||||||
model_draw_call(m, shader > 0 ? shader : m.program, pass, pos44(view), models[0], proj, view);
|
model_draw_call(mdl, shader > 0 ? shader : mdl.program, pass, pos44(view), pass_model_matrices[0], proj, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void model_render_instanced(model_t m, mat44 proj, mat44 view, mat44* models, int shader, unsigned count) {
|
void model_render_instanced(model_t m, mat44 proj, mat44 view, mat44* models, int shader, unsigned count) {
|
||||||
|
@ -387796,6 +387822,7 @@ void model_destroy(model_t m) {
|
||||||
FREE(m.meshcenters);
|
FREE(m.meshcenters);
|
||||||
FREE(m.meshbounds);
|
FREE(m.meshbounds);
|
||||||
FREE(m.meshradii);
|
FREE(m.meshradii);
|
||||||
|
FREE(m.mesh_visible);
|
||||||
|
|
||||||
iqm_t *q = m.iqm;
|
iqm_t *q = m.iqm;
|
||||||
// if(m.mesh) mesh_destroy(m.mesh);
|
// if(m.mesh) mesh_destroy(m.mesh);
|
||||||
|
|
|
@ -4575,6 +4575,7 @@ bool model_load_meshes(iqm_t *q, const struct iqmheader *hdr, model_t *m) {
|
||||||
m->meshcenters = CALLOC(hdr->num_meshes, sizeof(vec3));
|
m->meshcenters = CALLOC(hdr->num_meshes, sizeof(vec3));
|
||||||
m->meshbounds = CALLOC(hdr->num_meshes, sizeof(aabb));
|
m->meshbounds = CALLOC(hdr->num_meshes, sizeof(aabb));
|
||||||
m->meshradii = CALLOC(hdr->num_meshes, sizeof(float));
|
m->meshradii = CALLOC(hdr->num_meshes, sizeof(float));
|
||||||
|
m->mesh_visible = CALLOC(hdr->num_meshes, sizeof(bool));
|
||||||
|
|
||||||
for(int i = 0; i < (int)hdr->num_meshes; i++) {
|
for(int i = 0; i < (int)hdr->num_meshes; i++) {
|
||||||
int invalid = texture_checker().id;
|
int invalid = texture_checker().id;
|
||||||
|
@ -5372,7 +5373,7 @@ bool model_is_visible(model_t m, int mesh, mat44 model_mat, mat44 proj, mat44 vi
|
||||||
mat44 proj_modified;
|
mat44 proj_modified;
|
||||||
copy44(proj_modified, proj);
|
copy44(proj_modified, proj);
|
||||||
|
|
||||||
// Increase FOV by 1.5
|
// Increase FOV by GLOBAL_FRUSTUM_FOV_MULTIPLIER
|
||||||
float fov_scale = 1.0f / GLOBAL_FRUSTUM_FOV_MULTIPLIER;
|
float fov_scale = 1.0f / GLOBAL_FRUSTUM_FOV_MULTIPLIER;
|
||||||
proj_modified[0] *= fov_scale;
|
proj_modified[0] *= fov_scale;
|
||||||
proj_modified[5] *= fov_scale;
|
proj_modified[5] *= fov_scale;
|
||||||
|
@ -5442,14 +5443,14 @@ void model_draw_call(model_t m, int shader, int pass, vec3 cam_pos, mat44 model_
|
||||||
|
|
||||||
if (rs_idx > RENDER_PASS_OVERRIDES_BEGIN) {
|
if (rs_idx > RENDER_PASS_OVERRIDES_BEGIN) {
|
||||||
for(int i = 0; i < q->nummeshes; i++) {
|
for(int i = 0; i < q->nummeshes; i++) {
|
||||||
if (!model_is_visible(m, i, model_mat, proj, view)) continue;
|
if (!m.mesh_visible[i]) continue;
|
||||||
array_push(drawcalls, (drawcall_t){i, -1});
|
array_push(drawcalls, (drawcall_t){i, -1});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(pass == -1 || pass == RENDER_PASS_OPAQUE) {
|
if(pass == -1 || pass == RENDER_PASS_OPAQUE) {
|
||||||
for(int i = 0; i < q->nummeshes; i++) {
|
for(int i = 0; i < q->nummeshes; i++) {
|
||||||
if (!model_is_visible(m, i, model_mat, proj, view)) continue;
|
if (!m.mesh_visible[i]) continue;
|
||||||
|
|
||||||
// collect opaque drawcalls
|
// collect opaque drawcalls
|
||||||
if (required_rs[i] == RENDER_PASS_OPAQUE) {
|
if (required_rs[i] == RENDER_PASS_OPAQUE) {
|
||||||
drawcall_t call;
|
drawcall_t call;
|
||||||
|
@ -5465,8 +5466,8 @@ void model_draw_call(model_t m, int shader, int pass, vec3 cam_pos, mat44 model_
|
||||||
|
|
||||||
if(pass == -1 || pass == RENDER_PASS_TRANSPARENT) {
|
if(pass == -1 || pass == RENDER_PASS_TRANSPARENT) {
|
||||||
for(int i = 0; i < q->nummeshes; i++) {
|
for(int i = 0; i < q->nummeshes; i++) {
|
||||||
if (!model_is_visible(m, i, model_mat, proj, view)) continue;
|
if (!m.mesh_visible[i]) continue;
|
||||||
|
|
||||||
// collect transparent drawcalls
|
// collect transparent drawcalls
|
||||||
if (required_rs[i] == RENDER_PASS_TRANSPARENT) {
|
if (required_rs[i] == RENDER_PASS_TRANSPARENT) {
|
||||||
drawcall_t call;
|
drawcall_t call;
|
||||||
|
@ -5541,28 +5542,52 @@ void model_draw_call(model_t m, int shader, int pass, vec3 cam_pos, mat44 model_
|
||||||
shader_bind(old_shader);
|
shader_bind(old_shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
void model_render_instanced_pass(model_t m, mat44 proj, mat44 view, mat44* models, int shader, unsigned count, int pass) {
|
static mat44 *pass_model_matrices = NULL;
|
||||||
if(!m.iqm) return;
|
|
||||||
iqm_t *q = m.iqm;
|
void model_render_instanced_pass(model_t mdl, mat44 proj, mat44 view, mat44* models, int shader, unsigned count, int pass) {
|
||||||
|
if(!mdl.iqm) return;
|
||||||
|
iqm_t *q = mdl.iqm;
|
||||||
|
|
||||||
if (active_shadowmap && active_shadowmap->skip_render) {
|
if (active_shadowmap && active_shadowmap->skip_render) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mat44 mv; multiply44x2(mv, view, models[0]);
|
pass_model_matrices = array_resize(pass_model_matrices, count); //@leak
|
||||||
|
memcpy(pass_model_matrices, models, count * sizeof(mat44));
|
||||||
|
memset(mdl.mesh_visible, 0, q->nummeshes * sizeof(bool));
|
||||||
|
|
||||||
if( count != m.num_instances ) {
|
for (int i = 0; i < count; i++) {
|
||||||
m.num_instances = count;
|
bool any_visible = false;
|
||||||
m.instanced_matrices = (float*)models;
|
for (int m = 0; m < q->nummeshes; m++) {
|
||||||
model_set_state(m);
|
bool visible = model_is_visible(mdl, m, pass_model_matrices[i], proj, view);
|
||||||
|
mdl.mesh_visible[m] |= visible;
|
||||||
|
any_visible |= visible;
|
||||||
|
}
|
||||||
|
if (!any_visible) {
|
||||||
|
array_erase_fast(pass_model_matrices, i);
|
||||||
|
i--;
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat44 mv; multiply44x2(mv, view, pass_model_matrices[0]);
|
||||||
|
|
||||||
|
if( count != mdl.num_instances ) {
|
||||||
|
mdl.num_instances = count;
|
||||||
|
mdl.instanced_matrices = (float*)pass_model_matrices;
|
||||||
|
model_set_state(mdl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model_getpass() > RENDER_PASS_SHADOW_BEGIN && model_getpass() < RENDER_PASS_SHADOW_END) {
|
if (model_getpass() > RENDER_PASS_SHADOW_BEGIN && model_getpass() < RENDER_PASS_SHADOW_END) {
|
||||||
shader = m.shadow_program;
|
shader = mdl.shadow_program;
|
||||||
}
|
}
|
||||||
|
|
||||||
model_set_uniforms(m, shader > 0 ? shader : m.program, mv, proj, view, models[0]);
|
model_set_uniforms(mdl, shader > 0 ? shader : mdl.program, mv, proj, view, pass_model_matrices[0]);
|
||||||
model_draw_call(m, shader > 0 ? shader : m.program, pass, pos44(view), models[0], proj, view);
|
model_draw_call(mdl, shader > 0 ? shader : mdl.program, pass, pos44(view), pass_model_matrices[0], proj, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void model_render_instanced(model_t m, mat44 proj, mat44 view, mat44* models, int shader, unsigned count) {
|
void model_render_instanced(model_t m, mat44 proj, mat44 view, mat44* models, int shader, unsigned count) {
|
||||||
|
@ -5973,6 +5998,7 @@ void model_destroy(model_t m) {
|
||||||
FREE(m.meshcenters);
|
FREE(m.meshcenters);
|
||||||
FREE(m.meshbounds);
|
FREE(m.meshbounds);
|
||||||
FREE(m.meshradii);
|
FREE(m.meshradii);
|
||||||
|
FREE(m.mesh_visible);
|
||||||
|
|
||||||
iqm_t *q = m.iqm;
|
iqm_t *q = m.iqm;
|
||||||
// if(m.mesh) mesh_destroy(m.mesh);
|
// if(m.mesh) mesh_destroy(m.mesh);
|
||||||
|
|
|
@ -815,6 +815,7 @@ typedef struct model_t {
|
||||||
vec3 *meshcenters;
|
vec3 *meshcenters;
|
||||||
aabb *meshbounds;
|
aabb *meshbounds;
|
||||||
float *meshradii;
|
float *meshradii;
|
||||||
|
bool *mesh_visible;
|
||||||
int num_tris;
|
int num_tris;
|
||||||
handle vao, ibo, vbo, vao_instanced;
|
handle vao, ibo, vbo, vao_instanced;
|
||||||
|
|
||||||
|
|
60
engine/v4k.c
60
engine/v4k.c
|
@ -21429,6 +21429,7 @@ bool model_load_meshes(iqm_t *q, const struct iqmheader *hdr, model_t *m) {
|
||||||
m->meshcenters = CALLOC(hdr->num_meshes, sizeof(vec3));
|
m->meshcenters = CALLOC(hdr->num_meshes, sizeof(vec3));
|
||||||
m->meshbounds = CALLOC(hdr->num_meshes, sizeof(aabb));
|
m->meshbounds = CALLOC(hdr->num_meshes, sizeof(aabb));
|
||||||
m->meshradii = CALLOC(hdr->num_meshes, sizeof(float));
|
m->meshradii = CALLOC(hdr->num_meshes, sizeof(float));
|
||||||
|
m->mesh_visible = CALLOC(hdr->num_meshes, sizeof(bool));
|
||||||
|
|
||||||
for(int i = 0; i < (int)hdr->num_meshes; i++) {
|
for(int i = 0; i < (int)hdr->num_meshes; i++) {
|
||||||
int invalid = texture_checker().id;
|
int invalid = texture_checker().id;
|
||||||
|
@ -22226,7 +22227,7 @@ bool model_is_visible(model_t m, int mesh, mat44 model_mat, mat44 proj, mat44 vi
|
||||||
mat44 proj_modified;
|
mat44 proj_modified;
|
||||||
copy44(proj_modified, proj);
|
copy44(proj_modified, proj);
|
||||||
|
|
||||||
// Increase FOV by 1.5
|
// Increase FOV by GLOBAL_FRUSTUM_FOV_MULTIPLIER
|
||||||
float fov_scale = 1.0f / GLOBAL_FRUSTUM_FOV_MULTIPLIER;
|
float fov_scale = 1.0f / GLOBAL_FRUSTUM_FOV_MULTIPLIER;
|
||||||
proj_modified[0] *= fov_scale;
|
proj_modified[0] *= fov_scale;
|
||||||
proj_modified[5] *= fov_scale;
|
proj_modified[5] *= fov_scale;
|
||||||
|
@ -22296,14 +22297,14 @@ void model_draw_call(model_t m, int shader, int pass, vec3 cam_pos, mat44 model_
|
||||||
|
|
||||||
if (rs_idx > RENDER_PASS_OVERRIDES_BEGIN) {
|
if (rs_idx > RENDER_PASS_OVERRIDES_BEGIN) {
|
||||||
for(int i = 0; i < q->nummeshes; i++) {
|
for(int i = 0; i < q->nummeshes; i++) {
|
||||||
if (!model_is_visible(m, i, model_mat, proj, view)) continue;
|
if (!m.mesh_visible[i]) continue;
|
||||||
array_push(drawcalls, (drawcall_t){i, -1});
|
array_push(drawcalls, (drawcall_t){i, -1});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(pass == -1 || pass == RENDER_PASS_OPAQUE) {
|
if(pass == -1 || pass == RENDER_PASS_OPAQUE) {
|
||||||
for(int i = 0; i < q->nummeshes; i++) {
|
for(int i = 0; i < q->nummeshes; i++) {
|
||||||
if (!model_is_visible(m, i, model_mat, proj, view)) continue;
|
if (!m.mesh_visible[i]) continue;
|
||||||
|
|
||||||
// collect opaque drawcalls
|
// collect opaque drawcalls
|
||||||
if (required_rs[i] == RENDER_PASS_OPAQUE) {
|
if (required_rs[i] == RENDER_PASS_OPAQUE) {
|
||||||
drawcall_t call;
|
drawcall_t call;
|
||||||
|
@ -22319,8 +22320,8 @@ void model_draw_call(model_t m, int shader, int pass, vec3 cam_pos, mat44 model_
|
||||||
|
|
||||||
if(pass == -1 || pass == RENDER_PASS_TRANSPARENT) {
|
if(pass == -1 || pass == RENDER_PASS_TRANSPARENT) {
|
||||||
for(int i = 0; i < q->nummeshes; i++) {
|
for(int i = 0; i < q->nummeshes; i++) {
|
||||||
if (!model_is_visible(m, i, model_mat, proj, view)) continue;
|
if (!m.mesh_visible[i]) continue;
|
||||||
|
|
||||||
// collect transparent drawcalls
|
// collect transparent drawcalls
|
||||||
if (required_rs[i] == RENDER_PASS_TRANSPARENT) {
|
if (required_rs[i] == RENDER_PASS_TRANSPARENT) {
|
||||||
drawcall_t call;
|
drawcall_t call;
|
||||||
|
@ -22395,28 +22396,52 @@ void model_draw_call(model_t m, int shader, int pass, vec3 cam_pos, mat44 model_
|
||||||
shader_bind(old_shader);
|
shader_bind(old_shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
void model_render_instanced_pass(model_t m, mat44 proj, mat44 view, mat44* models, int shader, unsigned count, int pass) {
|
static mat44 *pass_model_matrices = NULL;
|
||||||
if(!m.iqm) return;
|
|
||||||
iqm_t *q = m.iqm;
|
void model_render_instanced_pass(model_t mdl, mat44 proj, mat44 view, mat44* models, int shader, unsigned count, int pass) {
|
||||||
|
if(!mdl.iqm) return;
|
||||||
|
iqm_t *q = mdl.iqm;
|
||||||
|
|
||||||
if (active_shadowmap && active_shadowmap->skip_render) {
|
if (active_shadowmap && active_shadowmap->skip_render) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mat44 mv; multiply44x2(mv, view, models[0]);
|
pass_model_matrices = array_resize(pass_model_matrices, count); //@leak
|
||||||
|
memcpy(pass_model_matrices, models, count * sizeof(mat44));
|
||||||
|
memset(mdl.mesh_visible, 0, q->nummeshes * sizeof(bool));
|
||||||
|
|
||||||
if( count != m.num_instances ) {
|
for (int i = 0; i < count; i++) {
|
||||||
m.num_instances = count;
|
bool any_visible = false;
|
||||||
m.instanced_matrices = (float*)models;
|
for (int m = 0; m < q->nummeshes; m++) {
|
||||||
model_set_state(m);
|
bool visible = model_is_visible(mdl, m, pass_model_matrices[i], proj, view);
|
||||||
|
mdl.mesh_visible[m] |= visible;
|
||||||
|
any_visible |= visible;
|
||||||
|
}
|
||||||
|
if (!any_visible) {
|
||||||
|
array_erase_fast(pass_model_matrices, i);
|
||||||
|
i--;
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat44 mv; multiply44x2(mv, view, pass_model_matrices[0]);
|
||||||
|
|
||||||
|
if( count != mdl.num_instances ) {
|
||||||
|
mdl.num_instances = count;
|
||||||
|
mdl.instanced_matrices = (float*)pass_model_matrices;
|
||||||
|
model_set_state(mdl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model_getpass() > RENDER_PASS_SHADOW_BEGIN && model_getpass() < RENDER_PASS_SHADOW_END) {
|
if (model_getpass() > RENDER_PASS_SHADOW_BEGIN && model_getpass() < RENDER_PASS_SHADOW_END) {
|
||||||
shader = m.shadow_program;
|
shader = mdl.shadow_program;
|
||||||
}
|
}
|
||||||
|
|
||||||
model_set_uniforms(m, shader > 0 ? shader : m.program, mv, proj, view, models[0]);
|
model_set_uniforms(mdl, shader > 0 ? shader : mdl.program, mv, proj, view, pass_model_matrices[0]);
|
||||||
model_draw_call(m, shader > 0 ? shader : m.program, pass, pos44(view), models[0], proj, view);
|
model_draw_call(mdl, shader > 0 ? shader : mdl.program, pass, pos44(view), pass_model_matrices[0], proj, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void model_render_instanced(model_t m, mat44 proj, mat44 view, mat44* models, int shader, unsigned count) {
|
void model_render_instanced(model_t m, mat44 proj, mat44 view, mat44* models, int shader, unsigned count) {
|
||||||
|
@ -22827,6 +22852,7 @@ void model_destroy(model_t m) {
|
||||||
FREE(m.meshcenters);
|
FREE(m.meshcenters);
|
||||||
FREE(m.meshbounds);
|
FREE(m.meshbounds);
|
||||||
FREE(m.meshradii);
|
FREE(m.meshradii);
|
||||||
|
FREE(m.mesh_visible);
|
||||||
|
|
||||||
iqm_t *q = m.iqm;
|
iqm_t *q = m.iqm;
|
||||||
// if(m.mesh) mesh_destroy(m.mesh);
|
// if(m.mesh) mesh_destroy(m.mesh);
|
||||||
|
|
|
@ -3850,6 +3850,7 @@ typedef struct model_t {
|
||||||
vec3 *meshcenters;
|
vec3 *meshcenters;
|
||||||
aabb *meshbounds;
|
aabb *meshbounds;
|
||||||
float *meshradii;
|
float *meshradii;
|
||||||
|
bool *mesh_visible;
|
||||||
int num_tris;
|
int num_tris;
|
||||||
handle vao, ibo, vbo, vao_instanced;
|
handle vao, ibo, vbo, vao_instanced;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue