implement texture animation and random tiling

This commit is contained in:
Alibek Omarov 2021-02-10 03:42:08 +03:00
parent ad5d515200
commit cbdca0abf9
3 changed files with 90 additions and 9 deletions

View File

@ -30,6 +30,7 @@ typedef struct brush_vertex_s
typedef struct vk_brush_model_surface_s {
int texture_num;
msurface_t *surf;
// Offset into g_brush.index_buffer in vertices
uint32_t index_offset;
@ -59,6 +60,8 @@ static struct {
VkPipelineLayout pipeline_layout;
VkPipeline pipelines[kRenderTransAdd + 1];
int rtable[MOD_FRAMES][MOD_FRAMES];
} g_brush;
/* static brush_vertex_t *allocVertices(int num_vertices) { */
@ -235,6 +238,24 @@ static qboolean createPipelines( void )
return true;
}
void VK_InitRandomTable( void )
{
int tu, tv;
// make random predictable
gEngine.COM_SetRandomSeed( 255 );
for( tu = 0; tu < MOD_FRAMES; tu++ )
{
for( tv = 0; tv < MOD_FRAMES; tv++ )
{
g_brush.rtable[tu][tv] = gEngine.COM_RandomLong( 0, 0x7FFF );
}
}
gEngine.COM_SetRandomSeed( 0 );
}
qboolean VK_BrushInit( void )
{
const uint32_t vertex_buffer_size = MAX_BUFFER_VERTICES * sizeof(brush_vertex_t);
@ -243,6 +264,8 @@ qboolean VK_BrushInit( void )
g_brush.uniform_unit_size = ((sizeof(uniform_data_t) + ubo_align - 1) / ubo_align) * ubo_align;
VK_InitRandomTable ();
// TODO device memory and friends (e.g. handle mobile memory ...)
if (!createBuffer(&g_brush.vertex_buffer, vertex_buffer_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
@ -291,9 +314,63 @@ void VK_BrushShutdown( void )
destroyBuffer( &g_brush.uniform_buffer );
}
void VK_BrushDrawModel( const model_t *mod, int render_mode, int ubo_index )
/*
===============
R_TextureAnimation
Returns the proper texture for a given time and surface
===============
*/
texture_t *R_TextureAnimation( cl_entity_t *ent, msurface_t *s )
{
texture_t *base = s->texinfo->texture;
int count, reletive;
if( ent && ent->curstate.frame )
{
if( base->alternate_anims )
base = base->alternate_anims;
}
if( !base->anim_total )
return base;
if( base->name[0] == '-' )
{
int tx = (int)((s->texturemins[0] + (base->width << 16)) / base->width) % MOD_FRAMES;
int ty = (int)((s->texturemins[1] + (base->height << 16)) / base->height) % MOD_FRAMES;
reletive = g_brush.rtable[tx][ty] % base->anim_total;
}
else
{
int speed;
// Quake1 textures uses 10 frames per second
if( FBitSet( findTexture( base->gl_texturenum )->flags, TF_QUAKEPAL ))
speed = 10;
else speed = 20;
reletive = (int)(gpGlobals->time * speed) % base->anim_total;
}
count = 0;
while( base->anim_min > reletive || base->anim_max <= reletive )
{
base = base->anim_next;
if( !base || ++count > MOD_FRAMES )
return s->texinfo->texture;
}
return base;
}
void VK_BrushDrawModel( const cl_entity_t *ent, int render_mode, int ubo_index )
{
// Expect all buffers to be bound
const model_t *mod = ent->model;
const vk_brush_model_t *bmodel = mod->cache.data;
const uint32_t dynamic_offset[] = { g_brush.uniform_unit_size * ubo_index };
int current_texture = -1;
@ -326,18 +403,20 @@ void VK_BrushDrawModel( const model_t *mod, int render_mode, int ubo_index )
for (int i = 0; i < bmodel->num_surfaces; ++i) {
const vk_brush_model_surface_t *bsurf = bmodel->surfaces + i;
if (bsurf->texture_num < 0)
texture_t *t = R_TextureAnimation(ent, bsurf->surf);
if (t->gl_texturenum < 0)
continue;
if (current_texture != bsurf->texture_num)
if (current_texture != t->gl_texturenum)
{
vk_texture_t *texture = findTexture(bsurf->texture_num);
vk_texture_t *texture = findTexture(t->gl_texturenum);
if (index_count)
vkCmdDrawIndexed(vk_core.cb, index_count, 1, index_offset, bmodel->vertex_offset, 0);
vkCmdBindDescriptorSets(vk_core.cb, VK_PIPELINE_BIND_POINT_GRAPHICS, g_brush.pipeline_layout, 1, 1, &texture->vk.descriptor, 0, NULL);
current_texture = bsurf->texture_num;
current_texture = t->gl_texturenum;
index_count = 0;
index_offset = -1;
}
@ -444,6 +523,7 @@ static int loadBrushSurfaces( const model_t *mod, vk_brush_model_surface_t *out_
return -1;
}
bsurf->surf = surf;
bsurf->texture_num = surf->texinfo->texture->gl_texturenum;
bsurf->index_offset = g_brush.num_indices;
bsurf->index_count = 0;

View File

@ -5,10 +5,11 @@
struct ref_viewpass_s;
struct draw_list_s;
struct model_s;
struct cl_entity_s;
qboolean VK_BrushInit( void );
void VK_BrushShutdown( void );
qboolean VK_LoadBrushModel( struct model_s *mod, const byte *buffer );
qboolean VK_BrushRenderBegin( void );
void VK_BrushDrawModel( const struct model_s *mod, int render_mode, int ubo_index );
void VK_BrushDrawModel( const struct cl_entity_s *ent, int render_mode, int ubo_index );
void VK_BrushClear( void );

View File

@ -539,7 +539,7 @@ static int drawEntity( cl_entity_t *ent, int render_mode, int ubo_index, const m
Matrix4x4_Concat( ent_mvp, mvp, model );
Matrix4x4_ToArrayFloatGL( ent_mvp, (float*)ubo->mvp);
VK_BrushDrawModel( mod, render_mode, ubo_index );
VK_BrushDrawModel( ent, render_mode, ubo_index );
return 1;
}
@ -554,8 +554,8 @@ void VK_SceneRender( void )
prepareMatrix( &fixme_rvp, worldview, projection, mvp );
{
const model_t *world = gEngine.pfnGetModelByIndex( 1 );
if (world)
cl_entity_t *world = gEngine.GetEntityByIndex( 0 );
if( world && world->model )
{
uniform_data_t *ubo = getUniformSlot(ubo_index);
Matrix4x4_ToArrayFloatGL( mvp, (float*)ubo->mvp );