mirror of
https://github.com/w23/xash3d-fwgs
synced 2024-12-15 21:50:59 +01:00
vk: split geometries into static and animated
Load geometries only once, and then update only those which have animated textures. Fixes #523
This commit is contained in:
parent
f722f38617
commit
e1d250e8da
@ -26,6 +26,9 @@ typedef struct vk_brush_model_s {
|
|||||||
vk_render_model_t render_model;
|
vk_render_model_t render_model;
|
||||||
int num_water_surfaces;
|
int num_water_surfaces;
|
||||||
int *surface_to_geometry_index;
|
int *surface_to_geometry_index;
|
||||||
|
|
||||||
|
int *animated_indexes;
|
||||||
|
int animated_indexes_count;
|
||||||
} vk_brush_model_t;
|
} vk_brush_model_t;
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
@ -371,6 +374,25 @@ const texture_t *R_TextureAnimation( const cl_entity_t *ent, const msurface_t *s
|
|||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static qboolean isSurfaceAnimated( const msurface_t *s, const struct texture_s *base_override ) {
|
||||||
|
const texture_t *base = base_override ? base_override : s->texinfo->texture;
|
||||||
|
|
||||||
|
/* FIXME don't have ent here, need to check both explicitly
|
||||||
|
if( ent && ent->curstate.frame ) {
|
||||||
|
if( base->alternate_anims )
|
||||||
|
base = base->alternate_anims;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if( !base->anim_total )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( base->name[0] == '-' )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, float blend, const matrix4x4 model ) {
|
void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, float blend, const matrix4x4 model ) {
|
||||||
// Expect all buffers to be bound
|
// Expect all buffers to be bound
|
||||||
const model_t *mod = ent->model;
|
const model_t *mod = ent->model;
|
||||||
@ -405,18 +427,21 @@ void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, float blend, co
|
|||||||
|
|
||||||
++g_brush.stat.models_drawn;
|
++g_brush.stat.models_drawn;
|
||||||
|
|
||||||
for (int i = 0; i < bmodel->render_model.num_geometries; ++i) {
|
// TransColor means ignore textures and draw just color
|
||||||
vk_render_geometry_t *geom = bmodel->render_model.geometries + i;
|
if (render_mode == kRenderTransColor) {
|
||||||
const int surface_index = geom->surf_deprecate - mod->surfaces;
|
// TODO cache previous render_mode.
|
||||||
const xvk_patch_surface_t *const patch_surface = R_VkPatchGetSurface(surface_index);
|
// TODO also it will break switching render type from TransColor to anyting else -- textures will be stuck at white
|
||||||
|
for (int i = 0; i < bmodel->render_model.num_geometries; ++i) {
|
||||||
if (render_mode == kRenderTransColor) {
|
vk_render_geometry_t *geom = bmodel->render_model.geometries + i;
|
||||||
// TransColor mode means no texture color is used
|
|
||||||
geom->texture = tglob.whiteTexture;
|
geom->texture = tglob.whiteTexture;
|
||||||
} else if (patch_surface && patch_surface->tex_id >= 0) {
|
}
|
||||||
// Patch by constant texture index first, if it exists
|
} else {
|
||||||
geom->texture = patch_surface->tex_id;
|
// Update animated textures
|
||||||
} else {
|
for (int i = 0; i < bmodel->animated_indexes_count; ++i) {
|
||||||
|
vk_render_geometry_t *geom = bmodel->render_model.geometries + bmodel->animated_indexes[i];
|
||||||
|
const int surface_index = geom->surf_deprecate - mod->surfaces;
|
||||||
|
const xvk_patch_surface_t *const patch_surface = R_VkPatchGetSurface(surface_index);
|
||||||
|
|
||||||
// Optionally patch by texture_s pointer and run animations
|
// Optionally patch by texture_s pointer and run animations
|
||||||
const struct texture_s *texture_override = patch_surface ? patch_surface->tex : NULL;
|
const struct texture_s *texture_override = patch_surface ? patch_surface->tex : NULL;
|
||||||
const texture_t *t = R_TextureAnimation(ent, geom->surf_deprecate, texture_override);
|
const texture_t *t = R_TextureAnimation(ent, geom->surf_deprecate, texture_override);
|
||||||
@ -429,7 +454,15 @@ void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, float blend, co
|
|||||||
VK_RenderModelDraw(ent, &bmodel->render_model);
|
VK_RenderModelDraw(ent, &bmodel->render_model);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qboolean renderableSurface( const msurface_t *surf, int i ) {
|
typedef enum {
|
||||||
|
BrushSurface_Hidden = 0,
|
||||||
|
BrushSurface_Regular,
|
||||||
|
BrushSurface_Animated,
|
||||||
|
BrushSurface_Water,
|
||||||
|
BrushSurface_Sky,
|
||||||
|
} brush_surface_type_e;
|
||||||
|
|
||||||
|
static brush_surface_type_e getSurfaceType( const msurface_t *surf, int i ) {
|
||||||
// if ( i >= 0 && (surf->flags & ~(SURF_PLANEBACK | SURF_UNDERWATER | SURF_TRANSPARENT)) != 0)
|
// if ( i >= 0 && (surf->flags & ~(SURF_PLANEBACK | SURF_UNDERWATER | SURF_TRANSPARENT)) != 0)
|
||||||
// {
|
// {
|
||||||
// gEngine.Con_Reportf("\t%d flags: ", i);
|
// gEngine.Con_Reportf("\t%d flags: ", i);
|
||||||
@ -447,38 +480,43 @@ static qboolean renderableSurface( const msurface_t *surf, int i ) {
|
|||||||
// PRINTFLAGS(PRINTFLAG)
|
// PRINTFLAGS(PRINTFLAG)
|
||||||
// gEngine.Con_Reportf("\n");
|
// gEngine.Con_Reportf("\n");
|
||||||
// }
|
// }
|
||||||
|
const xvk_patch_surface_t *patch_surface = R_VkPatchGetSurface(i);
|
||||||
|
if (patch_surface && patch_surface->flags & Patch_Surface_Delete)
|
||||||
|
return BrushSurface_Hidden;
|
||||||
|
|
||||||
{
|
if (surf->flags & (SURF_DRAWTURB | SURF_DRAWTURB_QUADS))
|
||||||
const xvk_patch_surface_t *patch_surface = R_VkPatchGetSurface(i);
|
return BrushSurface_Water;
|
||||||
if (patch_surface && patch_surface->flags & Patch_Surface_Delete)
|
|
||||||
return false;
|
// Explicitly enable SURF_SKY, otherwise they will be skipped by SURF_DRAWTILED
|
||||||
}
|
if( FBitSet( surf->flags, SURF_DRAWSKY ))
|
||||||
|
return BrushSurface_Sky;
|
||||||
|
|
||||||
//if( surf->flags & ( SURF_DRAWSKY | SURF_DRAWTURB | SURF_CONVEYOR | SURF_DRAWTURB_QUADS ) ) {
|
//if( surf->flags & ( SURF_DRAWSKY | SURF_DRAWTURB | SURF_CONVEYOR | SURF_DRAWTURB_QUADS ) ) {
|
||||||
if( surf->flags & ( SURF_DRAWTURB | SURF_DRAWTURB_QUADS ) ) {
|
if( surf->flags & ( SURF_DRAWTURB | SURF_DRAWTURB_QUADS ) ) {
|
||||||
//if( surf->flags & ( SURF_DRAWSKY | SURF_CONVEYOR ) ) {
|
//if( surf->flags & ( SURF_DRAWSKY | SURF_CONVEYOR ) ) {
|
||||||
// FIXME don't print this on second sort-by-texture pass
|
// FIXME don't print this on second sort-by-texture pass
|
||||||
//gEngine.Con_Reportf("Skipping surface %d because of flags %08x\n", i, surf->flags);
|
//gEngine.Con_Reportf("Skipping surface %d because of flags %08x\n", i, surf->flags);
|
||||||
return false;
|
return BrushSurface_Hidden;
|
||||||
}
|
|
||||||
|
|
||||||
// Explicitly enable SURF_SKY, otherwise they will be skipped by SURF_DRAWTILED
|
|
||||||
if( FBitSet( surf->flags, SURF_DRAWSKY )) {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( FBitSet( surf->flags, SURF_DRAWTILED )) {
|
if( FBitSet( surf->flags, SURF_DRAWTILED )) {
|
||||||
//gEngine.Con_Reportf("Skipping surface %d because of tiled flag\n", i);
|
//gEngine.Con_Reportf("Skipping surface %d because of tiled flag\n", i);
|
||||||
return false;
|
return BrushSurface_Hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
const struct texture_s *texture_override = patch_surface ? patch_surface->tex : NULL;
|
||||||
|
if (isSurfaceAnimated(surf, texture_override)) {
|
||||||
|
return BrushSurface_Animated;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BrushSurface_Regular;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int num_surfaces, num_vertices, num_indices;
|
int num_surfaces, num_vertices, num_indices;
|
||||||
int max_texture_id;
|
int max_texture_id;
|
||||||
int water_surfaces;
|
int water_surfaces;
|
||||||
|
int animated_count;
|
||||||
} model_sizes_t;
|
} model_sizes_t;
|
||||||
|
|
||||||
static model_sizes_t computeSizes( const model_t *mod ) {
|
static model_sizes_t computeSizes( const model_t *mod ) {
|
||||||
@ -490,16 +528,25 @@ static model_sizes_t computeSizes( const model_t *mod ) {
|
|||||||
const msurface_t *surf = mod->surfaces + surface_index;
|
const msurface_t *surf = mod->surfaces + surface_index;
|
||||||
const int tex_id = surf->texinfo->texture->gl_texturenum;
|
const int tex_id = surf->texinfo->texture->gl_texturenum;
|
||||||
|
|
||||||
sizes.water_surfaces += !!(surf->flags & (SURF_DRAWTURB | SURF_DRAWTURB_QUADS));
|
if (tex_id > sizes.max_texture_id)
|
||||||
|
sizes.max_texture_id = tex_id;
|
||||||
|
|
||||||
if (!renderableSurface(surf, surface_index))
|
switch (getSurfaceType(surf, surface_index)) {
|
||||||
|
case BrushSurface_Water:
|
||||||
|
sizes.water_surfaces++;
|
||||||
|
case BrushSurface_Hidden:
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
case BrushSurface_Animated:
|
||||||
|
sizes.animated_count++;
|
||||||
|
case BrushSurface_Regular:
|
||||||
|
case BrushSurface_Sky:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
++sizes.num_surfaces;
|
++sizes.num_surfaces;
|
||||||
sizes.num_vertices += surf->numedges;
|
sizes.num_vertices += surf->numedges;
|
||||||
sizes.num_indices += 3 * (surf->numedges - 1);
|
sizes.num_indices += 3 * (surf->numedges - 1);
|
||||||
if (tex_id > sizes.max_texture_id)
|
|
||||||
sizes.max_texture_id = tex_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sizes;
|
return sizes;
|
||||||
@ -513,6 +560,7 @@ static qboolean loadBrushSurfaces( model_sizes_t sizes, const model_t *mod ) {
|
|||||||
uint16_t *bind = NULL;
|
uint16_t *bind = NULL;
|
||||||
uint32_t index_offset = 0;
|
uint32_t index_offset = 0;
|
||||||
r_geometry_buffer_lock_t buffer;
|
r_geometry_buffer_lock_t buffer;
|
||||||
|
int animated_count = 0;
|
||||||
|
|
||||||
if (!R_GeometryBufferAllocAndLock( &buffer, sizes.num_vertices, sizes.num_indices, LifetimeLong )) {
|
if (!R_GeometryBufferAllocAndLock( &buffer, sizes.num_vertices, sizes.num_indices, LifetimeLong )) {
|
||||||
gEngine.Con_Printf(S_ERROR "Cannot allocate geometry for %s\n", mod->name );
|
gEngine.Con_Printf(S_ERROR "Cannot allocate geometry for %s\n", mod->name );
|
||||||
@ -540,12 +588,24 @@ static qboolean loadBrushSurfaces( model_sizes_t sizes, const model_t *mod ) {
|
|||||||
int tex_id = surf->texinfo->texture->gl_texturenum;
|
int tex_id = surf->texinfo->texture->gl_texturenum;
|
||||||
const xvk_patch_surface_t *const psurf = R_VkPatchGetSurface(surface_index);
|
const xvk_patch_surface_t *const psurf = R_VkPatchGetSurface(surface_index);
|
||||||
|
|
||||||
if (!renderableSurface(surf, surface_index))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (t != tex_id)
|
if (t != tex_id)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (psurf && psurf->tex_id >= 0)
|
||||||
|
tex_id = psurf->tex_id;
|
||||||
|
|
||||||
|
const brush_surface_type_e type = getSurfaceType(surf, surface_index);
|
||||||
|
switch (type) {
|
||||||
|
case BrushSurface_Water:
|
||||||
|
case BrushSurface_Hidden:
|
||||||
|
continue;
|
||||||
|
case BrushSurface_Animated:
|
||||||
|
bmodel->animated_indexes[animated_count++] = num_geometries;
|
||||||
|
case BrushSurface_Regular:
|
||||||
|
case BrushSurface_Sky:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
bmodel->surface_to_geometry_index[i] = num_geometries;
|
bmodel->surface_to_geometry_index[i] = num_geometries;
|
||||||
|
|
||||||
++num_geometries;
|
++num_geometries;
|
||||||
@ -569,14 +629,12 @@ static qboolean loadBrushSurfaces( model_sizes_t sizes, const model_t *mod ) {
|
|||||||
|
|
||||||
model_geometry->index_offset = index_offset;
|
model_geometry->index_offset = index_offset;
|
||||||
|
|
||||||
if( FBitSet( surf->flags, SURF_DRAWSKY )) {
|
if(type == BrushSurface_Sky) {
|
||||||
//gEngine.Con_Printf("SURF_SKY: tex_id=%d\n", tex_id);
|
|
||||||
model_geometry->material = kXVkMaterialSky;
|
model_geometry->material = kXVkMaterialSky;
|
||||||
} else {
|
} else {
|
||||||
model_geometry->material = kXVkMaterialRegular;
|
model_geometry->material = kXVkMaterialRegular;
|
||||||
if (!FBitSet( surf->flags, SURF_DRAWTILED )) {
|
ASSERT(!FBitSet( surf->flags, SURF_DRAWTILED ));
|
||||||
VK_CreateSurfaceLightmap( surf, mod );
|
VK_CreateSurfaceLightmap( surf, mod );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FBitSet( surf->flags, SURF_CONVEYOR )) {
|
if (FBitSet( surf->flags, SURF_CONVEYOR )) {
|
||||||
@ -678,6 +736,7 @@ static qboolean loadBrushSurfaces( model_sizes_t sizes, const model_t *mod ) {
|
|||||||
bmodel->render_model.dynamic_polylights_count = 0;
|
bmodel->render_model.dynamic_polylights_count = 0;
|
||||||
|
|
||||||
ASSERT(sizes.num_surfaces == num_geometries);
|
ASSERT(sizes.num_surfaces == num_geometries);
|
||||||
|
ASSERT(sizes.animated_count == animated_count);
|
||||||
bmodel->render_model.num_geometries = num_geometries;
|
bmodel->render_model.num_geometries = num_geometries;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -704,12 +763,9 @@ qboolean VK_BrushModelLoad( model_t *mod ) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
const model_sizes_t sizes = computeSizes( mod );
|
const model_sizes_t sizes = computeSizes( mod );
|
||||||
const size_t model_size =
|
const size_t model_size = sizeof(vk_brush_model_t);
|
||||||
sizeof(vk_brush_model_t) +
|
|
||||||
sizeof(vk_render_geometry_t) * sizes.num_surfaces +
|
|
||||||
sizeof(int) * mod->nummodelsurfaces;
|
|
||||||
|
|
||||||
vk_brush_model_t *bmodel = Mem_Calloc(vk_core.pool, model_size);
|
vk_brush_model_t *bmodel = Mem_Calloc(vk_core.pool, sizeof(*bmodel));
|
||||||
mod->cache.data = bmodel;
|
mod->cache.data = bmodel;
|
||||||
Q_strncpy(bmodel->render_model.debug_name, mod->name, sizeof(bmodel->render_model.debug_name));
|
Q_strncpy(bmodel->render_model.debug_name, mod->name, sizeof(bmodel->render_model.debug_name));
|
||||||
bmodel->render_model.render_type = kVkRenderTypeSolid;
|
bmodel->render_model.render_type = kVkRenderTypeSolid;
|
||||||
@ -718,8 +774,13 @@ qboolean VK_BrushModelLoad( model_t *mod ) {
|
|||||||
Vector4Set(bmodel->render_model.color, 1, 1, 1, 1);
|
Vector4Set(bmodel->render_model.color, 1, 1, 1, 1);
|
||||||
|
|
||||||
if (sizes.num_surfaces != 0) {
|
if (sizes.num_surfaces != 0) {
|
||||||
bmodel->render_model.geometries = (vk_render_geometry_t*)((char*)(bmodel + 1));
|
bmodel->render_model.geometries = Mem_Malloc(vk_core.pool, sizeof(vk_render_geometry_t) * sizes.num_surfaces);
|
||||||
bmodel->surface_to_geometry_index = (int*)((char*)(bmodel->render_model.geometries + sizes.num_surfaces));
|
bmodel->surface_to_geometry_index = Mem_Malloc(vk_core.pool, sizeof(int) * mod->nummodelsurfaces);
|
||||||
|
bmodel->animated_indexes = Mem_Malloc(vk_core.pool, sizeof(int) * sizes.animated_count);
|
||||||
|
bmodel->animated_indexes_count = sizes.animated_count;
|
||||||
|
|
||||||
|
bmodel->render_model.geometries_changed = bmodel->animated_indexes;
|
||||||
|
bmodel->render_model.geometries_changed_count = bmodel->animated_indexes_count;
|
||||||
|
|
||||||
if (!loadBrushSurfaces(sizes, mod) || !VK_RenderModelInit(&bmodel->render_model)) {
|
if (!loadBrushSurfaces(sizes, mod) || !VK_RenderModelInit(&bmodel->render_model)) {
|
||||||
gEngine.Con_Printf(S_ERROR "Could not load model %s\n", mod->name);
|
gEngine.Con_Printf(S_ERROR "Could not load model %s\n", mod->name);
|
||||||
@ -744,6 +805,9 @@ void VK_BrushModelDestroy( model_t *mod ) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
VK_RenderModelDestroy(&bmodel->render_model);
|
VK_RenderModelDestroy(&bmodel->render_model);
|
||||||
|
Mem_Free(bmodel->animated_indexes);
|
||||||
|
Mem_Free(bmodel->surface_to_geometry_index);
|
||||||
|
Mem_Free(bmodel->render_model.geometries);
|
||||||
Mem_Free(bmodel);
|
Mem_Free(bmodel);
|
||||||
mod->cache.data = NULL;
|
mod->cache.data = NULL;
|
||||||
}
|
}
|
||||||
@ -797,8 +861,13 @@ void R_VkBrushModelCollectEmissiveSurfaces( const struct model_s *mod, qboolean
|
|||||||
const int surface_index = mod->firstmodelsurface + i;
|
const int surface_index = mod->firstmodelsurface + i;
|
||||||
const msurface_t *surf = mod->surfaces + surface_index;
|
const msurface_t *surf = mod->surfaces + surface_index;
|
||||||
|
|
||||||
if (!renderableSurface(surf, surface_index))
|
switch (getSurfaceType(surf, surface_index)) {
|
||||||
|
case BrushSurface_Regular:
|
||||||
|
case BrushSurface_Animated:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const int tex_id = surf->texinfo->texture->gl_texturenum; // TODO animation?
|
const int tex_id = surf->texinfo->texture->gl_texturenum; // TODO animation?
|
||||||
|
|
||||||
|
@ -358,6 +358,43 @@ static void computeConveyorSpeed(const color24 rendercolor, int tex_index, vec2_
|
|||||||
speed[1] = sy * flRate;
|
speed[1] = sy * flRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static qboolean uploadKusochkiSubset(const vk_ray_model_t *const model, const vk_render_model_t *const render_model, uint32_t material_mode, const int *geom_indexes, int geom_indexes_count) {
|
||||||
|
// TODO can we sort all animated geometries (in brush) to have only a single range here?
|
||||||
|
for (int i = 0; i < geom_indexes_count; ++i) {
|
||||||
|
const int index = geom_indexes[i];
|
||||||
|
|
||||||
|
const vk_staging_buffer_args_t staging_args = {
|
||||||
|
.buffer = g_ray_model_state.kusochki_buffer.buffer,
|
||||||
|
.offset = (model->kusochki_offset + index) * sizeof(vk_kusok_data_t),
|
||||||
|
.size = sizeof(vk_kusok_data_t),
|
||||||
|
.alignment = 16,
|
||||||
|
};
|
||||||
|
const vk_staging_region_t kusok_staging = R_VkStagingLockForBuffer(staging_args);
|
||||||
|
|
||||||
|
if (!kusok_staging.ptr) {
|
||||||
|
gEngine.Con_Printf(S_ERROR "Couldn't allocate staging for %d kusochek for model %s\n", 1, render_model->debug_name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vk_kusok_data_t *const kusochki = kusok_staging.ptr;
|
||||||
|
|
||||||
|
vk_render_geometry_t *geom = render_model->geometries + index;
|
||||||
|
applyMaterialToKusok(kusochki + 0, geom, render_model->color, material_mode);
|
||||||
|
Matrix4x4_ToArrayFloatGL(render_model->prev_transform, (float*)(kusochki + 0)->model.prev_transform);
|
||||||
|
|
||||||
|
/* gEngine.Con_Reportf("model %s: geom=%d kuoffs=%d kustoff=%d kustsz=%d sthndl=%d\n", */
|
||||||
|
/* render_model->debug_name, */
|
||||||
|
/* render_model->num_geometries, */
|
||||||
|
/* model->kusochki_offset, */
|
||||||
|
/* staging_args.offset, staging_args.size, */
|
||||||
|
/* kusok_staging.handle */
|
||||||
|
/* ); */
|
||||||
|
|
||||||
|
R_VkStagingUnlock(kusok_staging.handle);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static qboolean uploadKusochki(const vk_ray_model_t *const model, const vk_render_model_t *const render_model, uint32_t material_mode) {
|
static qboolean uploadKusochki(const vk_ray_model_t *const model, const vk_render_model_t *const render_model, uint32_t material_mode) {
|
||||||
const vk_staging_buffer_args_t staging_args = {
|
const vk_staging_buffer_args_t staging_args = {
|
||||||
.buffer = g_ray_model_state.kusochki_buffer.buffer,
|
.buffer = g_ray_model_state.kusochki_buffer.buffer,
|
||||||
@ -450,6 +487,9 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
|
|||||||
if (!uploadKusochki(model, render_model, material_mode)) {
|
if (!uploadKusochki(model, render_model, material_mode)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (!uploadKusochkiSubset(model, render_model, material_mode, render_model->geometries_changed, render_model->geometries_changed_count))
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < render_model->dynamic_polylights_count; ++i) {
|
for (int i = 0; i < render_model->dynamic_polylights_count; ++i) {
|
||||||
|
@ -116,6 +116,9 @@ typedef struct vk_render_model_s {
|
|||||||
int num_geometries;
|
int num_geometries;
|
||||||
vk_render_geometry_t *geometries;
|
vk_render_geometry_t *geometries;
|
||||||
|
|
||||||
|
int geometries_changed_count;
|
||||||
|
int *geometries_changed;
|
||||||
|
|
||||||
// This model will be one-frame only, its buffers are not preserved between frames
|
// This model will be one-frame only, its buffers are not preserved between frames
|
||||||
qboolean dynamic;
|
qboolean dynamic;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user