vk: pass model color explicitly

Instead of passing model color around as an implicit global state, pass it per-model.
This makes it (a) easier to track, (b) easy to fix blending issues. E.g. this fixes incorrect coloring of brush and studio models, which is also different.
This commit is contained in:
Ivan 'provod' Avdeev 2023-02-24 22:48:26 -08:00
parent 92b1e78d85
commit 005b7c84eb
8 changed files with 58 additions and 70 deletions

View File

@ -391,7 +391,7 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f
};
VK_RenderModelDynamicBegin( render_mode, "beam" /* TODO its name */ );
VK_RenderModelDynamicBegin( render_mode, color, "beam" /* TODO its name */ );
VK_RenderModelDynamicAddGeometry( &geometry );
VK_RenderModelDynamicCommit();
}
@ -1108,8 +1108,6 @@ void R_BeamDraw( BEAM *pbeam, float frametime )
VK_RenderStateSetMatrixModel( matrix4x4_identity );
// TODO gl renderer has per-vertex color that is updated using brightness and whatever
VK_RenderStateSetColor( color[0], color[1], color[2], color[3] );
VK_RenderDebugLabelBegin( "beam" );
switch( pbeam->type )

View File

@ -234,7 +234,7 @@ static void EmitWaterPolys( const cl_entity_t *ent, const msurface_t *warp, qboo
// FIXME VK GL_SetupFogColorForSurfaces();
}
void XVK_DrawWaterSurfaces( const cl_entity_t *ent )
static void brushDrawWaterSurfaces( const cl_entity_t *ent, const vec4_t color )
{
const model_t *model = ent->model;
vec3_t mins, maxs;
@ -258,7 +258,7 @@ void XVK_DrawWaterSurfaces( const cl_entity_t *ent )
// if( R_CullBox( mins, maxs ))
// return;
VK_RenderModelDynamicBegin( ent->curstate.rendermode, "%s water", model->name );
VK_RenderModelDynamicBegin( ent->curstate.rendermode, color, "%s water", model->name );
// Iterate through all surfaces, find *TURB*
for( int i = 0; i < model->nummodelsurfaces; i++ )
@ -337,8 +337,7 @@ const texture_t *R_TextureAnimation( const cl_entity_t *ent, const msurface_t *s
return base;
}
void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, 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
const model_t *mod = ent->model;
vk_brush_model_t *bmodel = mod->cache.data;
@ -348,8 +347,19 @@ void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, const matrix4x4
return;
}
if (render_mode == kRenderTransColor) {
Vector4Set(bmodel->render_model.color,
ent->curstate.rendercolor.r / 255.f,
ent->curstate.rendercolor.g / 255.f,
ent->curstate.rendercolor.b / 255.f,
blend);
} else {
// Other render modes are not affected by entity current state color
Vector4Set(bmodel->render_model.color, 1, 1, 1, blend);
}
if (bmodel->num_water_surfaces) {
XVK_DrawWaterSurfaces(ent);
brushDrawWaterSurfaces(ent, bmodel->render_model.color);
}
if (bmodel->render_model.num_geometries == 0)
@ -360,8 +370,11 @@ void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, const matrix4x4
const int surface_index = geom->surf - mod->surfaces;
const xvk_patch_surface_t *patch_surface = g_map_entities.patch.surfaces ? g_map_entities.patch.surfaces+surface_index : NULL;
if (render_mode == kRenderTransColor) {
// TransColor mode means no texture color is used
geom->texture = tglob.whiteTexture;
} else if (patch_surface && patch_surface->tex_id >= 0) {
// Patch by constant texture index first, if it exists
if (patch_surface && patch_surface->tex_id >= 0) {
geom->texture = patch_surface->tex_id;
} else {
// Optionally patch by texture_s pointer and run animations
@ -372,6 +385,17 @@ void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, const matrix4x4
}
}
if (render_mode == kRenderTransColor) {
Vector4Set(bmodel->render_model.color,
ent->curstate.rendercolor.r / 255.f,
ent->curstate.rendercolor.g / 255.f,
ent->curstate.rendercolor.b / 255.f,
blend);
} else {
// Other render modes are not affected by entity current state color
Vector4Set(bmodel->render_model.color, 1, 1, 1, blend);
}
bmodel->render_model.render_mode = render_mode;
VK_RenderModelDraw(ent, &bmodel->render_model);
}

View File

@ -14,7 +14,7 @@ void VK_BrushShutdown( void );
qboolean VK_BrushModelLoad(struct model_s *mod, qboolean map);
void VK_BrushModelDestroy(struct model_s *mod);
void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, const matrix4x4 model );
void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, float blend, const matrix4x4 model );
void VK_BrushStatsClear( void );
const texture_t *R_TextureAnimation( const cl_entity_t *ent, const msurface_t *s, const struct texture_s *base_override );

View File

@ -328,11 +328,10 @@ void VK_RenderShutdown( void )
enum {
UNIFORM_UNSET = 0,
UNIFORM_SET_COLOR = 1,
UNIFORM_SET_MATRIX_MODEL = 2,
UNIFORM_SET_MATRIX_VIEW = 4,
UNIFORM_SET_MATRIX_PROJECTION = 8,
UNIFORM_SET_ALL = UNIFORM_SET_COLOR | UNIFORM_SET_MATRIX_MODEL | UNIFORM_SET_MATRIX_VIEW | UNIFORM_SET_MATRIX_PROJECTION,
UNIFORM_SET_ALL = UNIFORM_SET_MATRIX_MODEL | UNIFORM_SET_MATRIX_VIEW | UNIFORM_SET_MATRIX_PROJECTION,
UNIFORM_UPLOADED = 16,
};
@ -352,15 +351,6 @@ void VK_RenderBegin( qboolean ray_tracing ) {
VK_RayFrameBegin();
}
void VK_RenderStateSetColor( float r, float g, float b, float a )
{
g_render_state.uniform_data_set_mask |= UNIFORM_SET_COLOR;
g_render_state.dirty_uniform_data.color[0] = r;
g_render_state.dirty_uniform_data.color[1] = g;
g_render_state.dirty_uniform_data.color[2] = b;
g_render_state.dirty_uniform_data.color[3] = a;
}
// Vulkan has Y pointing down, and z should end up in (0, 1)
// NOTE this matrix is row-major
static const matrix4x4 vk_proj_fixup = {
@ -682,6 +672,9 @@ void VK_RenderModelDraw( const cl_entity_t *ent, vk_render_model_t* model ) {
int index_offset = -1;
int vertex_offset = 0;
// TODO get rid of this dirty ubo thing
Vector4Copy(model->color, g_render_state.dirty_uniform_data.color);
if (g_render_state.current_frame_is_ray_traced) {
if (ent != NULL && model != NULL) {
R_PrevFrame_ModelTransform( ent->index, model->prev_transform );
@ -758,7 +751,7 @@ static struct {
vk_render_geometry_t geometries[MAX_DYNAMIC_GEOMETRY];
} g_dynamic_model = {0};
void VK_RenderModelDynamicBegin( int render_mode, const char *debug_name_fmt, ... ) {
void VK_RenderModelDynamicBegin( int render_mode, const vec4_t color, const char *debug_name_fmt, ... ) {
va_list argptr;
va_start( argptr, debug_name_fmt );
vsnprintf(g_dynamic_model.model.debug_name, sizeof(g_dynamic_model.model.debug_name), debug_name_fmt, argptr );
@ -768,6 +761,7 @@ void VK_RenderModelDynamicBegin( int render_mode, const char *debug_name_fmt, ..
g_dynamic_model.model.geometries = g_dynamic_model.geometries;
g_dynamic_model.model.num_geometries = 0;
g_dynamic_model.model.render_mode = render_mode;
Vector4Copy(color, g_dynamic_model.model.color);
}
void VK_RenderModelDynamicAddGeometry( const vk_render_geometry_t *geom ) {
ASSERT(g_dynamic_model.model.geometries);

View File

@ -10,9 +10,6 @@ void VK_RenderShutdown( void );
// Why? Xash Ref code is organized in a way where we can't reliably pass this info with
// ScheduleDraw itself, so we need to either set up per-submodule global state, or
// centralize this global state in here
void VK_RenderStateSetColor( float r, float g, float b, float a );
// TODO void VK_RenderStateGetColor( vec4_t color );
void VK_RenderStateSetMatrixProjection(const matrix4x4 proj, float fov_angle_y);
void VK_RenderStateSetMatrixView(const matrix4x4 view);
void VK_RenderStateSetMatrixModel(const matrix4x4 model);
@ -68,7 +65,11 @@ struct vk_ray_model_s;
struct rt_light_add_polygon_s;
typedef struct vk_render_model_s {
char debug_name[MAX_MODEL_NAME_LENGTH];
// FIXME: brushes, sprites, studio models, etc all treat render_mode differently
int render_mode;
vec4_t color;
int num_geometries;
vk_render_geometry_t *geometries;
@ -91,7 +92,7 @@ qboolean VK_RenderModelInit( vk_render_model_t* model );
void VK_RenderModelDestroy( vk_render_model_t* model );
void VK_RenderModelDraw( const cl_entity_t *ent, vk_render_model_t* model );
void VK_RenderModelDynamicBegin( int render_mode, const char *debug_name_fmt, ... );
void VK_RenderModelDynamicBegin( int render_mode, const vec4_t color, const char *debug_name_fmt, ... );
void VK_RenderModelDynamicAddGeometry( const vk_render_geometry_t *geom );
void VK_RenderModelDynamicCommit( void );

View File

@ -534,40 +534,12 @@ static void drawEntity( cl_entity_t *ent, int render_mode )
if( blend <= 0.0f )
return;
// FIXME these are not common! all ent types have different things for here
switch (render_mode) {
case kRenderNormal:
VK_RenderStateSetColor( 1.f, 1.f, 1.f, 1.f);
break;
case kRenderTransColor:
// FIXME also zero out texture? use white texture
VK_RenderStateSetColor(
ent->curstate.rendercolor.r / 255.f,
ent->curstate.rendercolor.g / 255.f,
ent->curstate.rendercolor.b / 255.f,
ent->curstate.renderamt / 255.f);
break;
case kRenderTransAdd:
VK_RenderStateSetColor( blend, blend, blend, 1.f);
break;
case kRenderTransAlpha:
VK_RenderStateSetColor( 1.f, 1.f, 1.f, 1.f);
// TODO Q1compat Vector4Set(e_ubo->color, 1.f, 1.f, 1.f, alpha);
break;
default:
VK_RenderStateSetColor( 1.f, 1.f, 1.f, blend);
}
switch (mod->type)
{
case mod_brush:
R_RotateForEntity( model, ent );
VK_RenderStateSetMatrixModel( model );
VK_BrushModelDraw( ent, render_mode, model );
VK_BrushModelDraw( ent, render_mode, blend, model );
break;
case mod_studio:
@ -608,7 +580,6 @@ void VK_SceneRender( const ref_viewpass_t *rvp ) {
// Draw view model
{
APROF_SCOPE_BEGIN(draw_viewmodel);
VK_RenderStateSetColor( 1.f, 1.f, 1.f, 1.f );
R_RunViewmodelEvents();
R_DrawViewModel();
APROF_SCOPE_END(draw_viewmodel);
@ -622,8 +593,8 @@ void VK_SceneRender( const ref_viewpass_t *rvp ) {
{
//VK_LightsBakePVL( 0 /* FIXME frame number */);
VK_RenderStateSetColor( 1.f, 1.f, 1.f, 1.f);
VK_BrushModelDraw( world, kRenderNormal, NULL );
const float blend = 1.f;
VK_BrushModelDraw( world, kRenderNormal, blend, NULL );
}
APROF_SCOPE_END(draw_worldbrush);
}

View File

@ -643,14 +643,14 @@ static qboolean spriteIsOccluded( const cl_entity_t *e, vec3_t origin, float *ps
return false;
}
static void R_DrawSpriteQuad( const char *debug_name, mspriteframe_t *frame, vec3_t org, vec3_t v_right, vec3_t v_up, float scale, int texture, int render_mode, vec3_t color ) {
static void R_DrawSpriteQuad( const char *debug_name, mspriteframe_t *frame, vec3_t org, vec3_t v_right, vec3_t v_up, float scale, int texture, int render_mode, const vec4_t color ) {
r_geometry_buffer_lock_t buffer;
if (!R_GeometryBufferAllocAndLock( &buffer, 4, 6, LifetimeSingleFrame )) {
gEngine.Con_Printf(S_ERROR "Cannot allocate geometry for sprite quad\n");
return;
}
vec3_t point;
vec3_t point;
vk_vertex_t *dst_vtx;
uint16_t *dst_idx;
@ -719,7 +719,7 @@ static void R_DrawSpriteQuad( const char *debug_name, mspriteframe_t *frame, vec
.emissive = {color[0], color[1], color[2]},
};
VK_RenderModelDynamicBegin( render_mode, "%s", debug_name );
VK_RenderModelDynamicBegin( render_mode, color, "%s", debug_name );
VK_RenderModelDynamicAddGeometry( &geometry );
VK_RenderModelDynamicCommit();
}
@ -936,8 +936,8 @@ void R_VkSpriteDrawModel( cl_entity_t *e, float blend )
if( oldframe == frame )
{
// draw the single non-lerped frame
VK_RenderStateSetColor( color[0], color[1], color[2], blend );
R_DrawSpriteQuad( model->name, frame, origin, v_right, v_up, scale, frame->gl_texturenum, e->curstate.rendermode, color );
const vec4_t color4 = {color[0], color[1], color[2], blend};
R_DrawSpriteQuad( model->name, frame, origin, v_right, v_up, scale, frame->gl_texturenum, e->curstate.rendermode, color4 );
}
else
{
@ -947,16 +947,14 @@ void R_VkSpriteDrawModel( cl_entity_t *e, float blend )
if( ilerp != 0.0f )
{
// FIXME VK make sure we end up with the same values as gl
VK_RenderStateSetColor( color[0], color[1], color[2], blend * ilerp );
R_DrawSpriteQuad( model->name, oldframe, origin, v_right, v_up, scale, oldframe->gl_texturenum, e->curstate.rendermode, color );
const vec4_t color4 = {color[0], color[1], color[2], blend * ilerp};
R_DrawSpriteQuad( model->name, oldframe, origin, v_right, v_up, scale, oldframe->gl_texturenum, e->curstate.rendermode, color4 );
}
if( lerp != 0.0f )
{
// FIXME VK make sure we end up with the same values as gl
VK_RenderStateSetColor( color[0], color[1], color[2], blend * lerp );
R_DrawSpriteQuad( model->name, frame, origin, v_right, v_up, scale, frame->gl_texturenum, e->curstate.rendermode, color );
const vec4_t color4 = {color[0], color[1], color[2], blend * lerp};
R_DrawSpriteQuad( model->name, frame, origin, v_right, v_up, scale, frame->gl_texturenum, e->curstate.rendermode, color4 );
}
}

View File

@ -2114,7 +2114,9 @@ static void R_StudioDrawPoints( void )
if( !m_pStudioHeader ) return;
VK_RenderModelDynamicBegin( RI.currententity->curstate.rendermode, "%s", m_pSubModel->name );
// FIXME: pass blend to studio model
const vec4_t color = {1, 1, 1, 1};
VK_RenderModelDynamicBegin( RI.currententity->curstate.rendermode, color, "%s", m_pSubModel->name );
g_studio.numverts = g_studio.numelems = 0;