Merge pull request #432 from w23/sprite-improvements

- [x] fixes #297 
- [x] fixes #256 
- [x] Sprite rendering differs from GL, especially with glow(3) and solid/transalpha(4)
This commit is contained in:
Ivan Avdeev 2023-02-25 14:27:20 -08:00 committed by GitHub
commit 26ad10483f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 298 additions and 282 deletions

View File

@ -38,11 +38,9 @@ layout(set = 0, binding = 17, rgba16f) uniform image2D prev_temporal_specular;
const int INDIRECT_SCALE = 2; const int INDIRECT_SCALE = 2;
//layout(set = 0, binding = 2, rgba16f) uniform readonly image2D light_poly_diffuse; //#define DEBUG_TEXTURE normals_gs
/* layout(set = 0, binding = 3, rgba16f) uniform readonly image2D specular; */ //#define DEBUG_TEXTURE emissive
/* layout(set = 0, binding = 4, rgba16f) uniform readonly image2D additive; */ //#define DEBUG_TEXTURE light_point_diffuse
/* layout(set = 0, binding = 5, rgba16f) uniform readonly image2D normals; */
/* layout(set = 0, binding = 6, rgba32f) uniform readonly image2D position_t; */
// Blatantly copypasted from https://www.shadertoy.com/view/XsGfWV // Blatantly copypasted from https://www.shadertoy.com/view/XsGfWV
vec3 aces_tonemap(vec3 color){ vec3 aces_tonemap(vec3 color){
@ -192,26 +190,19 @@ void main() {
/* imageStore(out_dest, pix, vec4(sqrt(float(pix.x) / res.x))); return; */ /* imageStore(out_dest, pix, vec4(sqrt(float(pix.x) / res.x))); return; */
/* } */ /* } */
//const float material_index = imageLoad(light_poly, pix).a; #if defined(DEBUG_TEXTURE)
imageStore(out_dest, pix, vec4(LINEARtoSRGB(imageLoad(DEBUG_TEXTURE, pix).rgb), 0.)); return;
#endif
//imageStore(out_dest, pix, vec4(aces_tonemap(base_color_a.rgb), 0.)); return; //imageStore(out_dest, pix, vec4(fract(imageLoad(position_t, pix).rgb/10.), 0.)); return;
//imageStore(out_dest, pix, vec4((base_color_a.rgb), 0.)); return; //imageStore(out_dest, pix, vec4(fract(imageLoad(geometry_prev_position, pix).rgb/50.), 0.)); return;
//imageStore(out_dest, pix, vec4(fract(imageLoad(position_t, pix).rgb / 10.), 0.)); return;
//imageStore(out_dest, pix, vec4((imageLoad(light_poly, pix).rgb), 0.)); return;
//imageStore(out_dest, pix, vec4((imageLoad(light_poly, pix).rgb * base_color_a.rgb), 0.)); return;
//imageStore(out_dest, pix, vec4(imageLoad(normals, pix)*.5 + .5f)); return;
//imageStore(out_dest, pix, vec4(imageLoad(specular, pix)*.5 + .5f)); return;
//imageStore(out_dest, pix, vec4(imageLoad(indirect_diffuse, pix)*.5 + .5f)); return;
//imageStore(out_dest, pix, vec4(aces_tonemap(imageLoad(light_poly, pix).rgb), 0.)); return;
//imageStore(out_dest, pix, vec4(aces_tonemap(imageLoad(specular, pix).rgb), 0.)); return;
//imageStore(out_dest, pix, vec4(aces_tonemap(imageLoad(indirect_diffuse, pix).rgb), 0.)); return;
/* #if 0
vec3 geometry_normal, shading_normal; vec3 geometry_normal, shading_normal;
readNormals(pix, geometry_normal, shading_normal); readNormals(pix, geometry_normal, shading_normal);
*/
//imageStore(out_dest, pix, vec4(.5 + geometry_normal * .5, 0.)); return; //imageStore(out_dest, pix, vec4(.5 + geometry_normal * .5, 0.)); return;
imageStore(out_dest, pix, vec4(.5 + shading_normal * .5, 0.)); return;
#endif
/* const uint mi = uint(material_index); */ /* const uint mi = uint(material_index); */
/* imageStore(out_dest, pix, vec4(rand3_f01(uvec3(mi,mi+1,mi+2)), 0.)); */ /* imageStore(out_dest, pix, vec4(rand3_f01(uvec3(mi,mi+1,mi+2)), 0.)); */

View File

@ -34,7 +34,7 @@ void primaryRayHit(rayQueryEXT rq, inout RayPayloadPrimary payload) {
payload.emissive.rgb = SRGBtoLINEAR(texture(skybox, rayDirection).rgb); payload.emissive.rgb = SRGBtoLINEAR(texture(skybox, rayDirection).rgb);
return; return;
} else { } else {
payload.base_color_a = sampleTexture(tex_base_color, geom.uv, geom.uv_lods) * kusok.color; payload.base_color_a = sampleTexture(tex_base_color, geom.uv, geom.uv_lods);
payload.material_rmxx.r = (kusok.tex_roughness > 0) ? sampleTexture(kusok.tex_roughness, geom.uv, geom.uv_lods).r : kusok.roughness; payload.material_rmxx.r = (kusok.tex_roughness > 0) ? sampleTexture(kusok.tex_roughness, geom.uv, geom.uv_lods).r : kusok.roughness;
payload.material_rmxx.g = (kusok.tex_metalness > 0) ? sampleTexture(kusok.tex_metalness, geom.uv, geom.uv_lods).r : kusok.metalness; payload.material_rmxx.g = (kusok.tex_metalness > 0) ? sampleTexture(kusok.tex_metalness, geom.uv, geom.uv_lods).r : kusok.metalness;
@ -63,6 +63,8 @@ void primaryRayHit(rayQueryEXT rq, inout RayPayloadPrimary payload) {
if (any(greaterThan(kusok.emissive, vec3(0.)))) if (any(greaterThan(kusok.emissive, vec3(0.))))
payload.emissive.rgb = payload.base_color_a.rgb; payload.emissive.rgb = payload.base_color_a.rgb;
#endif #endif
payload.base_color_a *= kusok.color;
} }
#endif // ifndef RAY_PRIMARY_HIT_GLSL_INCLUDED #endif // ifndef RAY_PRIMARY_HIT_GLSL_INCLUDED

View File

@ -15,8 +15,8 @@ vec3 traceAdditive(vec3 pos, vec3 dir, float L) {
const MiniGeometry geom = readCandidateMiniGeometry(rq); const MiniGeometry geom = readCandidateMiniGeometry(rq);
const uint tex_base_color = getKusok(geom.kusok_index).tex_base_color; const uint tex_base_color = getKusok(geom.kusok_index).tex_base_color;
const vec4 texture_color = texture(textures[nonuniformEXT(tex_base_color)], geom.uv); const vec4 texture_color = texture(textures[nonuniformEXT(tex_base_color)], geom.uv);
const vec3 kusok_emissive = getKusok(geom.kusok_index).emissive; const Kusok kusok = getKusok(geom.kusok_index);
const vec3 color = texture_color.rgb * kusok_emissive * texture_color.a; // * kusok_color.a; const vec3 color = texture_color.rgb * kusok.emissive * texture_color.a * kusok.color.a;
const float hit_t = rayQueryGetIntersectionTEXT(rq, false); const float hit_t = rayQueryGetIntersectionTEXT(rq, false);
const float overshoot = hit_t - L; const float overshoot = hit_t - L;

View File

@ -390,8 +390,8 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f
.emissive = { color[0], color[1], color[2] }, .emissive = { color[0], color[1], color[2] },
}; };
vk_render_type_e render_type = render_mode == kRenderNormal ? kVkRenderTypeSolid : kVkRenderType_A_1_R;
VK_RenderModelDynamicBegin( render_mode, "beam" /* TODO its name */ ); VK_RenderModelDynamicBegin( render_type, color, "beam" /* TODO its name */ );
VK_RenderModelDynamicAddGeometry( &geometry ); VK_RenderModelDynamicAddGeometry( &geometry );
VK_RenderModelDynamicCommit(); VK_RenderModelDynamicCommit();
} }
@ -1108,8 +1108,6 @@ void R_BeamDraw( BEAM *pbeam, float frametime )
VK_RenderStateSetMatrixModel( matrix4x4_identity ); VK_RenderStateSetMatrixModel( matrix4x4_identity );
// TODO gl renderer has per-vertex color that is updated using brightness and whatever // 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" ); VK_RenderDebugLabelBegin( "beam" );
switch( pbeam->type ) switch( pbeam->type )

View File

@ -234,7 +234,21 @@ static void EmitWaterPolys( const cl_entity_t *ent, const msurface_t *warp, qboo
// FIXME VK GL_SetupFogColorForSurfaces(); // FIXME VK GL_SetupFogColorForSurfaces();
} }
void XVK_DrawWaterSurfaces( const cl_entity_t *ent ) static vk_render_type_e brushRenderModeToRenderType( int render_mode ) {
switch (render_mode) {
case kRenderNormal: return kVkRenderTypeSolid;
case kRenderTransColor: return kVkRenderType_A_1mA_RW;
case kRenderTransTexture: return kVkRenderType_A_1mA_R;
case kRenderGlow: return kVkRenderType_A_1mA_R;
case kRenderTransAlpha: return kVkRenderType_AT;
case kRenderTransAdd: return kVkRenderType_A_1_R;
default: ASSERT(!"Unxpected render_mode");
}
return kVkRenderTypeSolid;
}
static void brushDrawWaterSurfaces( const cl_entity_t *ent, const vec4_t color )
{ {
const model_t *model = ent->model; const model_t *model = ent->model;
vec3_t mins, maxs; vec3_t mins, maxs;
@ -258,7 +272,7 @@ void XVK_DrawWaterSurfaces( const cl_entity_t *ent )
// if( R_CullBox( mins, maxs )) // if( R_CullBox( mins, maxs ))
// return; // return;
VK_RenderModelDynamicBegin( ent->curstate.rendermode, "%s water", model->name ); VK_RenderModelDynamicBegin( brushRenderModeToRenderType(ent->curstate.rendermode), color, "%s water", model->name );
// Iterate through all surfaces, find *TURB* // Iterate through all surfaces, find *TURB*
for( int i = 0; i < model->nummodelsurfaces; i++ ) for( int i = 0; i < model->nummodelsurfaces; i++ )
@ -337,8 +351,7 @@ const texture_t *R_TextureAnimation( const cl_entity_t *ent, const msurface_t *s
return base; 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 // Expect all buffers to be bound
const model_t *mod = ent->model; const model_t *mod = ent->model;
vk_brush_model_t *bmodel = mod->cache.data; vk_brush_model_t *bmodel = mod->cache.data;
@ -348,8 +361,23 @@ void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, const matrix4x4
return; 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);
}
// Only Normal and TransAlpha have lightmaps
// TODO: on big maps more than a single lightmap texture is possible
bmodel->render_model.lightmap = (render_mode == kRenderNormal || render_mode == kRenderTransAlpha) ? 1 : 0;
if (bmodel->num_water_surfaces) { if (bmodel->num_water_surfaces) {
XVK_DrawWaterSurfaces(ent); brushDrawWaterSurfaces(ent, bmodel->render_model.color);
} }
if (bmodel->render_model.num_geometries == 0) if (bmodel->render_model.num_geometries == 0)
@ -360,8 +388,11 @@ void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, const matrix4x4
const int surface_index = geom->surf - mod->surfaces; 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; 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 // Patch by constant texture index first, if it exists
if (patch_surface && patch_surface->tex_id >= 0) {
geom->texture = patch_surface->tex_id; geom->texture = patch_surface->tex_id;
} else { } else {
// Optionally patch by texture_s pointer and run animations // Optionally patch by texture_s pointer and run animations
@ -372,7 +403,7 @@ void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, const matrix4x4
} }
} }
bmodel->render_model.render_mode = render_mode; bmodel->render_model.render_type = brushRenderModeToRenderType(render_mode);
VK_RenderModelDraw(ent, &bmodel->render_model); VK_RenderModelDraw(ent, &bmodel->render_model);
} }
@ -672,10 +703,11 @@ qboolean VK_BrushModelLoad( model_t *mod, qboolean map )
vk_brush_model_t *bmodel = Mem_Calloc(vk_core.pool, model_size); vk_brush_model_t *bmodel = Mem_Calloc(vk_core.pool, model_size);
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_mode = kRenderNormal; bmodel->render_model.render_type = kVkRenderTypeSolid;
bmodel->render_model.static_map = map; bmodel->render_model.static_map = map;
bmodel->num_water_surfaces = sizes.water_surfaces; bmodel->num_water_surfaces = sizes.water_surfaces;
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 = (vk_render_geometry_t*)((char*)(bmodel + 1));

View File

@ -14,7 +14,7 @@ void VK_BrushShutdown( void );
qboolean VK_BrushModelLoad(struct model_s *mod, qboolean map); qboolean VK_BrushModelLoad(struct model_s *mod, qboolean map);
void VK_BrushModelDestroy(struct model_s *mod); 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 ); void VK_BrushStatsClear( void );
const texture_t *R_TextureAnimation( const cl_entity_t *ent, const msurface_t *s, const struct texture_s *base_override ); const texture_t *R_TextureAnimation( const cl_entity_t *ent, const msurface_t *s, const struct texture_s *base_override );

View File

@ -7,6 +7,7 @@
#include "crtlib.h" #include "crtlib.h"
#define ASSERT(x) if(!( x )) gEngine.Host_Error( "assert %s failed at %s:%d\n", #x, __FILE__, __LINE__ ) #define ASSERT(x) if(!( x )) gEngine.Host_Error( "assert %s failed at %s:%d\n", #x, __FILE__, __LINE__ )
// TODO ASSERTF(x, fmt, ...)
#define Mem_Malloc( pool, size ) gEngine._Mem_Alloc( pool, size, false, __FILE__, __LINE__ ) #define Mem_Malloc( pool, size ) gEngine._Mem_Alloc( pool, size, false, __FILE__, __LINE__ )
#define Mem_Calloc( pool, size ) gEngine._Mem_Alloc( pool, size, true, __FILE__, __LINE__ ) #define Mem_Calloc( pool, size ) gEngine._Mem_Alloc( pool, size, true, __FILE__, __LINE__ )

View File

@ -195,7 +195,7 @@ static void applyMaterialToKusok(vk_kusok_data_t* kusok, const vk_render_geometr
} }
if (geom->material == kXVkMaterialEmissive) { if (geom->material == kXVkMaterialEmissive) {
VectorCopy( geom->emissive, kusok->emissive ); VectorCopy(geom->emissive, kusok->emissive);
} else { } else {
RT_GetEmissiveForTexture( kusok->emissive, geom->texture ); RT_GetEmissiveForTexture( kusok->emissive, geom->texture );
} }
@ -249,6 +249,20 @@ vk_ray_model_t* VK_RayModelCreate( vk_ray_model_init_t args ) {
/* gEngine.Con_Reportf("Loading model %s, geoms: %d\n", args.model->debug_name, args.model->num_geometries); */ /* gEngine.Con_Reportf("Loading model %s, geoms: %d\n", args.model->debug_name, args.model->num_geometries); */
qboolean HACK_additive_emissive = false;
switch (args.model->render_type) {
case kVkRenderType_A_1mA_RW: // blend: scr*a + dst*(1-a), depth: RW
case kVkRenderType_A_1mA_R: // blend: scr*a + dst*(1-a), depth test
HACK_additive_emissive = true;
break;
case kVkRenderType_A_1: // blend: scr*a + dst, no depth test or write
case kVkRenderType_A_1_R: // blend: scr*a + dst, depth test
case kVkRenderType_1_1_R: // blend: scr + dst, depth test
HACK_additive_emissive = true;
break;
}
for (int i = 0; i < args.model->num_geometries; ++i) { for (int i = 0; i < args.model->num_geometries; ++i) {
vk_render_geometry_t *mg = args.model->geometries + i; vk_render_geometry_t *mg = args.model->geometries + i;
const uint32_t prim_count = mg->element_count / 3; const uint32_t prim_count = mg->element_count / 3;
@ -299,8 +313,12 @@ vk_ray_model_t* VK_RayModelCreate( vk_ray_model_init_t args ) {
kusochki[i].tex_base_color &= (~KUSOK_MATERIAL_FLAG_SKYBOX); kusochki[i].tex_base_color &= (~KUSOK_MATERIAL_FLAG_SKYBOX);
} }
const vec4_t color = {1, 1, 1, 1}; if (HACK_additive_emissive && mg->material != kXVkMaterialEmissive) {
applyMaterialToKusok(kusochki + i, mg, color, false); mg->material = kXVkMaterialEmissive;
VectorCopy(args.model->color, mg->emissive);
}
applyMaterialToKusok(kusochki + i, mg, args.model->color, false);
Matrix4x4_LoadIdentity(kusochki[i].prev_transform); Matrix4x4_LoadIdentity(kusochki[i].prev_transform);
} }
@ -421,8 +439,7 @@ static void computeConveyorSpeed(const color24 rendercolor, int tex_index, vec2_
speed[1] = sy * flRate; speed[1] = sy * flRate;
} }
void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render_model, const matrix3x4 *transform_row, const vec4_t color, color24 entcolor) { void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render_model, const matrix3x4 *transform_row) {
qboolean HACK_reflective = false;
vk_ray_draw_model_t* draw_model = g_ray_model_state.frame.models + g_ray_model_state.frame.num_models; vk_ray_draw_model_t* draw_model = g_ray_model_state.frame.models + g_ray_model_state.frame.num_models;
ASSERT(vk_core.rtx); ASSERT(vk_core.rtx);
@ -443,31 +460,35 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
memcpy(draw_model->transform_row, *transform_row, sizeof(draw_model->transform_row)); memcpy(draw_model->transform_row, *transform_row, sizeof(draw_model->transform_row));
} }
switch (render_model->render_mode) { qboolean HACK_reflective = false;
case kRenderNormal: qboolean HACK_additive_emissive = false;
switch (render_model->render_type) {
case kVkRenderTypeSolid:
draw_model->material_mode = MaterialMode_Opaque; draw_model->material_mode = MaterialMode_Opaque;
break; break;
case kVkRenderType_A_1mA_RW: // blend: scr*a + dst*(1-a), depth: RW
// C = (1 - alpha) * DST + alpha * SRC (TODO is this right?) case kVkRenderType_A_1mA_R: // blend: scr*a + dst*(1-a), depth test
case kRenderTransColor: // FIXME proper trasnlucency
case kRenderTransTexture: //HACK_reflective = true;
HACK_reflective = true; //draw_model->material_mode = MaterialMode_Refractive;
draw_model->material_mode = MaterialMode_Refractive; HACK_additive_emissive = true;
break;
// Additive blending: C = SRC * alpha + DST
case kRenderGlow:
case kRenderTransAdd:
draw_model->material_mode = MaterialMode_Additive; draw_model->material_mode = MaterialMode_Additive;
break; break;
// Alpha test (TODO additive? mixing?) case kVkRenderType_A_1: // blend: scr*a + dst, no depth test or write
case kRenderTransAlpha: case kVkRenderType_A_1_R: // blend: scr*a + dst, depth test
case kVkRenderType_1_1_R: // blend: scr + dst, depth test
HACK_additive_emissive = true;
draw_model->material_mode = MaterialMode_Additive;
break;
case kVkRenderType_AT: // no blend, depth RW, alpha test
draw_model->material_mode = MaterialMode_Opaque_AlphaTest; draw_model->material_mode = MaterialMode_Opaque_AlphaTest;
break; break;
default: default:
gEngine.Host_Error("Unexpected render mode %d\n", render_model->render_mode); gEngine.Host_Error("Unexpected render type %d\n", render_model->render_type);
} }
// TODO optimize: // TODO optimize:
@ -492,9 +513,15 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
vk_kusok_data_t *const kusochki = kusok_staging.ptr; vk_kusok_data_t *const kusochki = kusok_staging.ptr;
for (int i = 0; i < render_model->num_geometries; ++i) { for (int i = 0; i < render_model->num_geometries; ++i) {
const vk_render_geometry_t *geom = render_model->geometries + i; vk_render_geometry_t *geom = render_model->geometries + i;
applyMaterialToKusok(kusochki + i, geom, color, HACK_reflective);
// FIXME an impedance mismatch: render_type is per-model, while materials and emissive color are per-geom
if (HACK_additive_emissive && geom->material != kXVkMaterialEmissive) {
geom->material = kXVkMaterialEmissive;
VectorCopy(render_model->color, geom->emissive);
}
applyMaterialToKusok(kusochki + i, geom, render_model->color, HACK_reflective);
Matrix4x4_Copy((kusochki + i)->prev_transform, render_model->prev_transform); Matrix4x4_Copy((kusochki + i)->prev_transform, render_model->prev_transform);
} }

View File

@ -30,7 +30,7 @@ typedef struct {
static struct { static struct {
VkPipelineLayout pipeline_layout; VkPipelineLayout pipeline_layout;
VkPipeline pipelines[kRenderTransAdd + 1]; VkPipeline pipelines[kVkRenderType_COUNT];
vk_buffer_t uniform_buffer; vk_buffer_t uniform_buffer;
uint32_t ubo_align; uint32_t ubo_align;
@ -121,70 +121,80 @@ static qboolean createPipelines( void )
.cullMode = VK_CULL_MODE_FRONT_BIT, .cullMode = VK_CULL_MODE_FRONT_BIT,
}; };
for (int i = 0; i < ARRAYSIZE(g_render.pipelines); ++i) for (int i = 0; i < kVkRenderType_COUNT; ++i)
{ {
const char *name = "UNDEFINED"; const char *name = "UNDEFINED";
switch (i) switch (i)
{ {
case kRenderNormal: case kVkRenderTypeSolid:
spec_data.alpha_test_threshold = 0.f; spec_data.alpha_test_threshold = 0.f;
ci.blendEnable = VK_FALSE; ci.blendEnable = VK_FALSE;
ci.depthWriteEnable = VK_TRUE; ci.depthWriteEnable = VK_TRUE;
ci.depthTestEnable = VK_TRUE; ci.depthTestEnable = VK_TRUE;
name = "brush kRenderNormal"; name = "kVkRenderTypeSolid";
break; break;
case kRenderTransColor: case kVkRenderType_A_1mA_RW:
spec_data.alpha_test_threshold = 0.f; spec_data.alpha_test_threshold = 0.f;
ci.depthWriteEnable = VK_TRUE; ci.depthWriteEnable = VK_TRUE;
ci.depthTestEnable = VK_TRUE; ci.depthTestEnable = VK_TRUE;
ci.blendEnable = VK_TRUE; ci.blendEnable = VK_TRUE;
ci.colorBlendOp = VK_BLEND_OP_ADD; // TODO check ci.colorBlendOp = VK_BLEND_OP_ADD;
ci.srcAlphaBlendFactor = ci.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; ci.srcAlphaBlendFactor = ci.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
ci.dstAlphaBlendFactor = ci.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; ci.dstAlphaBlendFactor = ci.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
name = "brush kRenderTransColor"; name = "kVkRenderType_A_1mA_RW";
break; break;
case kRenderTransAdd: case kVkRenderType_A_1mA_R:
spec_data.alpha_test_threshold = 0.f; spec_data.alpha_test_threshold = 0.f;
ci.depthWriteEnable = VK_FALSE; ci.depthWriteEnable = VK_FALSE;
ci.depthTestEnable = VK_TRUE; ci.depthTestEnable = VK_TRUE;
ci.blendEnable = VK_TRUE; ci.blendEnable = VK_TRUE;
ci.colorBlendOp = VK_BLEND_OP_ADD; // TODO check ci.colorBlendOp = VK_BLEND_OP_ADD;
ci.srcAlphaBlendFactor = ci.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
// sprites do SRC_ALPHA ci.dstAlphaBlendFactor = ci.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
ci.srcAlphaBlendFactor = ci.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;// TODO ? FACTOR_ONE; name = "kVkRenderType_A_1mA_R";
ci.dstAlphaBlendFactor = ci.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
name = "brush kRenderTransAdd";
break; break;
case kRenderTransAlpha: case kVkRenderType_A_1:
spec_data.alpha_test_threshold = 0.f;
ci.depthWriteEnable = VK_FALSE;
ci.depthTestEnable = VK_FALSE; // Fake bloom, should be over geometry too
ci.blendEnable = VK_TRUE;
ci.colorBlendOp = VK_BLEND_OP_ADD;
ci.srcAlphaBlendFactor = ci.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
ci.dstAlphaBlendFactor = ci.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
name = "kVkRenderType_A_1";
break;
case kVkRenderType_A_1_R:
spec_data.alpha_test_threshold = 0.f;
ci.depthWriteEnable = VK_FALSE;
ci.depthTestEnable = VK_TRUE;
ci.blendEnable = VK_TRUE;
ci.colorBlendOp = VK_BLEND_OP_ADD;
ci.srcAlphaBlendFactor = ci.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
ci.dstAlphaBlendFactor = ci.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
name = "kVkRenderType_A_1_R";
break;
case kVkRenderType_AT:
spec_data.alpha_test_threshold = .25f; spec_data.alpha_test_threshold = .25f;
ci.depthWriteEnable = VK_TRUE; ci.depthWriteEnable = VK_TRUE;
ci.depthTestEnable = VK_TRUE; ci.depthTestEnable = VK_TRUE;
ci.blendEnable = VK_FALSE; ci.blendEnable = VK_FALSE;
name = "brush kRenderTransAlpha(test)"; name = "kVkRenderType_AT";
break; break;
case kRenderGlow: case kVkRenderType_1_1_R:
spec_data.alpha_test_threshold = 0.f; spec_data.alpha_test_threshold = 0.f;
ci.depthWriteEnable = VK_FALSE; ci.depthWriteEnable = VK_FALSE;
ci.depthTestEnable = VK_TRUE; ci.depthTestEnable = VK_TRUE;
ci.blendEnable = VK_TRUE; ci.blendEnable = VK_TRUE;
ci.colorBlendOp = VK_BLEND_OP_ADD; // TODO check ci.colorBlendOp = VK_BLEND_OP_ADD;
ci.srcAlphaBlendFactor = ci.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; ci.srcAlphaBlendFactor = ci.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
ci.dstAlphaBlendFactor = ci.dstColorBlendFactor = VK_BLEND_FACTOR_ONE; ci.dstAlphaBlendFactor = ci.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
break; name = "kVkRenderType_1_1_R";
case kRenderTransTexture:
spec_data.alpha_test_threshold = 0.f;
ci.depthWriteEnable = VK_FALSE;
ci.depthTestEnable = VK_TRUE;
ci.blendEnable = VK_TRUE;
ci.colorBlendOp = VK_BLEND_OP_ADD; // TODO check
ci.srcAlphaBlendFactor = ci.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
ci.dstAlphaBlendFactor = ci.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
name = "brush kRenderTransTexture/Glow";
break; break;
default: default:
@ -228,7 +238,7 @@ typedef struct {
typedef struct render_draw_s { typedef struct render_draw_s {
int lightmap, texture; int lightmap, texture;
int render_mode; int pipeline_index;
uint32_t element_count; uint32_t element_count;
uint32_t index_offset, vertex_offset; uint32_t index_offset, vertex_offset;
/* TODO this should be a separate thing? */ struct { float r, g, b; } emissive; /* TODO this should be a separate thing? */ struct { float r, g, b; } emissive;
@ -328,11 +338,10 @@ void VK_RenderShutdown( void )
enum { enum {
UNIFORM_UNSET = 0, UNIFORM_UNSET = 0,
UNIFORM_SET_COLOR = 1,
UNIFORM_SET_MATRIX_MODEL = 2, UNIFORM_SET_MATRIX_MODEL = 2,
UNIFORM_SET_MATRIX_VIEW = 4, UNIFORM_SET_MATRIX_VIEW = 4,
UNIFORM_SET_MATRIX_PROJECTION = 8, 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, UNIFORM_UPLOADED = 16,
}; };
@ -352,15 +361,6 @@ void VK_RenderBegin( qboolean ray_tracing ) {
VK_RayFrameBegin(); 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) // Vulkan has Y pointing down, and z should end up in (0, 1)
// NOTE this matrix is row-major // NOTE this matrix is row-major
static const matrix4x4 vk_proj_fixup = { static const matrix4x4 vk_proj_fixup = {
@ -453,8 +453,8 @@ static void drawCmdPushDraw( const render_draw_t *draw )
{ {
draw_command_t *draw_command; draw_command_t *draw_command;
ASSERT(draw->render_mode >= 0); ASSERT(draw->pipeline_index >= 0);
ASSERT(draw->render_mode < ARRAYSIZE(g_render.pipelines)); ASSERT(draw->pipeline_index < ARRAYSIZE(g_render.pipelines));
ASSERT(draw->lightmap >= 0); ASSERT(draw->lightmap >= 0);
ASSERT(draw->texture >= 0); ASSERT(draw->texture >= 0);
@ -591,8 +591,8 @@ void VK_RenderEnd( VkCommandBuffer cmdbuf )
vkCmdBindDescriptorSets(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, g_render.pipeline_layout, 0, 1, vk_desc.ubo_sets, 1, &ubo_offset); vkCmdBindDescriptorSets(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, g_render.pipeline_layout, 0, 1, vk_desc.ubo_sets, 1, &ubo_offset);
} }
if (pipeline != draw->draw.draw.render_mode) { if (pipeline != draw->draw.draw.pipeline_index) {
pipeline = draw->draw.draw.render_mode; pipeline = draw->draw.draw.pipeline_index;
vkCmdBindPipeline(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, g_render.pipelines[pipeline]); vkCmdBindPipeline(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, g_render.pipelines[pipeline]);
} }
@ -682,6 +682,11 @@ void VK_RenderModelDraw( const cl_entity_t *ent, vk_render_model_t* model ) {
int index_offset = -1; int index_offset = -1;
int vertex_offset = 0; int vertex_offset = 0;
// TODO get rid of this dirty ubo thing
Vector4Copy(model->color, g_render_state.dirty_uniform_data.color);
ASSERT(model->lightmap <= MAX_LIGHTMAPS);
const int lightmap = model->lightmap > 0 ? tglob.lightmapTextures[model->lightmap - 1] : tglob.whiteTexture;
if (g_render_state.current_frame_is_ray_traced) { if (g_render_state.current_frame_is_ray_traced) {
if (ent != NULL && model != NULL) { if (ent != NULL && model != NULL) {
R_PrevFrame_ModelTransform( ent->index, model->prev_transform ); R_PrevFrame_ModelTransform( ent->index, model->prev_transform );
@ -691,7 +696,7 @@ void VK_RenderModelDraw( const cl_entity_t *ent, vk_render_model_t* model ) {
Matrix4x4_Copy( model->prev_transform, g_render_state.model ); Matrix4x4_Copy( model->prev_transform, g_render_state.model );
} }
VK_RayFrameAddModel(model->ray_model, model, (const matrix3x4*)g_render_state.model, g_render_state.dirty_uniform_data.color, ent ? ent->curstate.rendercolor : (color24){255,255,255}); VK_RayFrameAddModel(model->ray_model, model, (const matrix3x4*)g_render_state.model);
return; return;
} }
@ -713,9 +718,9 @@ void VK_RenderModelDraw( const cl_entity_t *ent, vk_render_model_t* model ) {
if (split) { if (split) {
if (element_count) { if (element_count) {
render_draw_t draw = { render_draw_t draw = {
.lightmap = tglob.lightmapTextures[0], // FIXME there can be more than one lightmap textures .lightmap = lightmap,
.texture = current_texture, .texture = current_texture,
.render_mode = model->render_mode, .pipeline_index = model->render_type,
.element_count = element_count, .element_count = element_count,
.vertex_offset = vertex_offset, .vertex_offset = vertex_offset,
.index_offset = index_offset, .index_offset = index_offset,
@ -737,9 +742,9 @@ void VK_RenderModelDraw( const cl_entity_t *ent, vk_render_model_t* model ) {
if (element_count) { if (element_count) {
const render_draw_t draw = { const render_draw_t draw = {
.lightmap = tglob.lightmapTextures[0], .lightmap = lightmap,
.texture = current_texture, .texture = current_texture,
.render_mode = model->render_mode, .pipeline_index = model->render_type,
.element_count = element_count, .element_count = element_count,
.vertex_offset = vertex_offset, .vertex_offset = vertex_offset,
.index_offset = index_offset, .index_offset = index_offset,
@ -758,7 +763,7 @@ static struct {
vk_render_geometry_t geometries[MAX_DYNAMIC_GEOMETRY]; vk_render_geometry_t geometries[MAX_DYNAMIC_GEOMETRY];
} g_dynamic_model = {0}; } g_dynamic_model = {0};
void VK_RenderModelDynamicBegin( int render_mode, const char *debug_name_fmt, ... ) { void VK_RenderModelDynamicBegin( vk_render_type_e render_type, const vec4_t color, const char *debug_name_fmt, ... ) {
va_list argptr; va_list argptr;
va_start( argptr, debug_name_fmt ); va_start( argptr, debug_name_fmt );
vsnprintf(g_dynamic_model.model.debug_name, sizeof(g_dynamic_model.model.debug_name), debug_name_fmt, argptr ); vsnprintf(g_dynamic_model.model.debug_name, sizeof(g_dynamic_model.model.debug_name), debug_name_fmt, argptr );
@ -767,7 +772,9 @@ void VK_RenderModelDynamicBegin( int render_mode, const char *debug_name_fmt, ..
ASSERT(!g_dynamic_model.model.geometries); ASSERT(!g_dynamic_model.model.geometries);
g_dynamic_model.model.geometries = g_dynamic_model.geometries; g_dynamic_model.model.geometries = g_dynamic_model.geometries;
g_dynamic_model.model.num_geometries = 0; g_dynamic_model.model.num_geometries = 0;
g_dynamic_model.model.render_mode = render_mode; g_dynamic_model.model.render_type = render_type;
g_dynamic_model.model.lightmap = 0;
Vector4Copy(color, g_dynamic_model.model.color);
} }
void VK_RenderModelDynamicAddGeometry( const vk_render_geometry_t *geom ) { void VK_RenderModelDynamicAddGeometry( const vk_render_geometry_t *geom ) {
ASSERT(g_dynamic_model.model.geometries); 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 // 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 // ScheduleDraw itself, so we need to either set up per-submodule global state, or
// centralize this global state in here // 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_RenderStateSetMatrixProjection(const matrix4x4 proj, float fov_angle_y);
void VK_RenderStateSetMatrixView(const matrix4x4 view); void VK_RenderStateSetMatrixView(const matrix4x4 view);
void VK_RenderStateSetMatrixModel(const matrix4x4 model); void VK_RenderStateSetMatrixModel(const matrix4x4 model);
@ -65,10 +62,25 @@ struct vk_ray_model_s;
#define MAX_MODEL_NAME_LENGTH 64 #define MAX_MODEL_NAME_LENGTH 64
typedef enum {
kVkRenderTypeSolid, // no blending, depth RW
kVkRenderType_A_1mA_RW, // blend: src*a + dst*(1-a), depth: RW
kVkRenderType_A_1mA_R, // blend: src*a + dst*(1-a), depth test
kVkRenderType_A_1, // blend: src*a + dst, no depth test or write
kVkRenderType_A_1_R, // blend: src*a + dst, depth test
kVkRenderType_AT, // no blend, depth RW, alpha test
kVkRenderType_1_1_R, // blend: src + dst, depth test
kVkRenderType_COUNT
} vk_render_type_e;
struct rt_light_add_polygon_s; struct rt_light_add_polygon_s;
typedef struct vk_render_model_s { typedef struct vk_render_model_s {
char debug_name[MAX_MODEL_NAME_LENGTH]; char debug_name[MAX_MODEL_NAME_LENGTH];
int render_mode;
// FIXME: brushes, sprites, studio models, etc all treat render_mode differently
vk_render_type_e render_type;
vec4_t color;
int lightmap; // <= 0 if no lightmap
int num_geometries; int num_geometries;
vk_render_geometry_t *geometries; vk_render_geometry_t *geometries;
@ -91,7 +103,7 @@ qboolean VK_RenderModelInit( vk_render_model_t* model );
void VK_RenderModelDestroy( 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_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( vk_render_type_e render_type, const vec4_t color, const char *debug_name_fmt, ... );
void VK_RenderModelDynamicAddGeometry( const vk_render_geometry_t *geom ); void VK_RenderModelDynamicAddGeometry( const vk_render_geometry_t *geom );
void VK_RenderModelDynamicCommit( void ); void VK_RenderModelDynamicCommit( void );

View File

@ -17,6 +17,3 @@ void GL_SetRenderMode( int renderMode );
void TriColor4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ); void TriColor4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a );
void R_AllowFog( qboolean allow ); void R_AllowFog( qboolean allow );
void R_Set2DMode( qboolean enable ); void R_Set2DMode( qboolean enable );
void R_BeginFrame( qboolean clearScene );
void R_RenderScene( void );
void R_EndFrame( void );

View File

@ -499,7 +499,7 @@ static const ref_device_t *pfnGetRenderDevice( unsigned int idx )
return &vk_core.devices[idx]; return &vk_core.devices[idx];
} }
ref_interface_t gReffuncs = static const ref_interface_t gReffuncs =
{ {
.R_Init = R_VkInit, .R_Init = R_VkInit,
.R_Shutdown = R_VkShutdown, .R_Shutdown = R_VkShutdown,

View File

@ -17,7 +17,7 @@ void VK_RayModelDestroy( struct vk_ray_model_s *model );
void VK_RayFrameBegin( void ); void VK_RayFrameBegin( void );
// TODO how to improve this render vs ray model storage/interaction? // TODO how to improve this render vs ray model storage/interaction?
void VK_RayFrameAddModel( struct vk_ray_model_s *model, const struct vk_render_model_s *render_model, const matrix3x4 *transform_row, const vec4_t color, color24 entcolor ); void VK_RayFrameAddModel(struct vk_ray_model_s *model, const struct vk_render_model_s *render_model, const matrix3x4 *transform_row);
typedef struct { typedef struct {
VkBuffer buffer; VkBuffer buffer;

View File

@ -523,61 +523,33 @@ static void drawEntity( cl_entity_t *ent, int render_mode )
{ {
const model_t *mod = ent->model; const model_t *mod = ent->model;
matrix4x4 model; matrix4x4 model;
float alpha;
if (!mod) if (!mod)
return; return;
// handle studiomodels with custom rendermodes on texture // handle studiomodels with custom rendermodes on texture
alpha = render_mode == kRenderNormal ? 1.f : CL_FxBlend( ent ) / 255.0f; const float blend = render_mode == kRenderNormal ? 1.f : CL_FxBlend( ent ) / 255.0f;
// TODO ref_gl does this earlier (when adding entity), can we too? // TODO ref_gl does this earlier (when adding entity), can we too?
if( alpha <= 0.0f ) if( blend <= 0.0f )
return; return;
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( alpha, alpha, alpha, 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, alpha);
}
switch (mod->type) switch (mod->type)
{ {
case mod_brush: case mod_brush:
R_RotateForEntity( model, ent ); R_RotateForEntity( model, ent );
VK_RenderStateSetMatrixModel( model ); VK_RenderStateSetMatrixModel( model );
VK_BrushModelDraw( ent, render_mode, model ); VK_BrushModelDraw( ent, render_mode, blend, model );
break; break;
case mod_studio: case mod_studio:
VK_RenderStateSetMatrixModel( matrix4x4_identity ); VK_RenderStateSetMatrixModel( matrix4x4_identity );
VK_StudioDrawModel( ent, render_mode ); VK_StudioDrawModel( ent, render_mode, blend );
break; break;
case mod_sprite: case mod_sprite:
VK_RenderStateSetMatrixModel( matrix4x4_identity ); VK_RenderStateSetMatrixModel( matrix4x4_identity );
VK_SpriteDrawModel( ent ); R_VkSpriteDrawModel( ent, blend );
break; break;
case mod_alias: case mod_alias:
@ -608,7 +580,6 @@ void VK_SceneRender( const ref_viewpass_t *rvp ) {
// Draw view model // Draw view model
{ {
APROF_SCOPE_BEGIN(draw_viewmodel); APROF_SCOPE_BEGIN(draw_viewmodel);
VK_RenderStateSetColor( 1.f, 1.f, 1.f, 1.f );
R_RunViewmodelEvents(); R_RunViewmodelEvents();
R_DrawViewModel(); R_DrawViewModel();
APROF_SCOPE_END(draw_viewmodel); APROF_SCOPE_END(draw_viewmodel);
@ -620,10 +591,8 @@ void VK_SceneRender( const ref_viewpass_t *rvp ) {
cl_entity_t *world = gEngine.GetEntityByIndex( 0 ); cl_entity_t *world = gEngine.GetEntityByIndex( 0 );
if( world && world->model ) if( world && world->model )
{ {
//VK_LightsBakePVL( 0 /* FIXME frame number */); const float blend = 1.f;
VK_BrushModelDraw( world, kRenderNormal, blend, NULL );
VK_RenderStateSetColor( 1.f, 1.f, 1.f, 1.f);
VK_BrushModelDraw( world, kRenderNormal, NULL );
} }
APROF_SCOPE_END(draw_worldbrush); APROF_SCOPE_END(draw_worldbrush);
} }

View File

@ -400,7 +400,7 @@ NOTE: we using prevblending[0] and [1] for holds interval
between frames where are we lerping between frames where are we lerping
================ ================
*/ */
float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe, mspriteframe_t **curframe ) static float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe, mspriteframe_t **curframe )
{ {
msprite_t *psprite; msprite_t *psprite;
mspritegroup_t *pspritegroup; mspritegroup_t *pspritegroup;
@ -616,11 +616,10 @@ static float R_SpriteGlowBlend( vec3_t origin, int rendermode, int renderfx, flo
} }
// Do occlusion test for glow-sprites // Do occlusion test for glow-sprites
qboolean R_SpriteOccluded( cl_entity_t *e, vec3_t origin, float *pscale ) static qboolean spriteIsOccluded( const cl_entity_t *e, vec3_t origin, float *pscale, float *blend )
{ {
if( e->curstate.rendermode == kRenderGlow ) if( e->curstate.rendermode == kRenderGlow )
{ {
float blend;
vec3_t v; vec3_t v;
TriWorldToScreen( origin, v ); TriWorldToScreen( origin, v );
@ -630,10 +629,9 @@ qboolean R_SpriteOccluded( cl_entity_t *e, vec3_t origin, float *pscale )
if( v[1] < g_camera.viewport[1] || v[1] > g_camera.viewport[1] + g_camera.viewport[3] ) if( v[1] < g_camera.viewport[1] || v[1] > g_camera.viewport[1] + g_camera.viewport[3] )
return true; // do scissor return true; // do scissor
blend = R_SpriteGlowBlend( origin, e->curstate.rendermode, e->curstate.renderfx, pscale ); *blend = R_SpriteGlowBlend( origin, e->curstate.rendermode, e->curstate.renderfx, pscale );
// FIXME VK tr.blend *= blend;
if( blend <= 0.01f ) if( *blend <= 0.01f )
return true; // faded return true; // faded
} }
else else
@ -645,47 +643,72 @@ qboolean R_SpriteOccluded( cl_entity_t *e, vec3_t origin, float *pscale )
return false; 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 vk_render_type_e spriteRenderModeToRenderType( int render_mode ) {
{ switch (render_mode) {
vec3_t point; case kRenderNormal: return kVkRenderTypeSolid;
vk_vertex_t *dst_vtx; case kRenderTransColor: return kVkRenderType_A_1mA_RW;
uint16_t *dst_idx; case kRenderTransTexture: return kVkRenderType_A_1mA_RW;
case kRenderGlow: return kVkRenderType_A_1;
case kRenderTransAlpha: return kVkRenderType_A_1mA_R;
case kRenderTransAdd: return kVkRenderType_A_1_R;
default: ASSERT(!"Unxpected render_mode");
}
// Get buffer region for vertices and indices return kVkRenderTypeSolid;
}
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; r_geometry_buffer_lock_t buffer;
if (!R_GeometryBufferAllocAndLock( &buffer, 4, 6, LifetimeSingleFrame )) { if (!R_GeometryBufferAllocAndLock( &buffer, 4, 6, LifetimeSingleFrame )) {
gEngine.Con_Printf(S_ERROR "Cannot allocate geometry for sprite quad\n"); gEngine.Con_Printf(S_ERROR "Cannot allocate geometry for sprite quad\n");
return; return;
} }
vec3_t point;
vk_vertex_t *dst_vtx;
uint16_t *dst_idx;
dst_vtx = buffer.vertices.ptr; dst_vtx = buffer.vertices.ptr;
dst_idx = buffer.indices.ptr; dst_idx = buffer.indices.ptr;
// FIXME VK r_stats.c_sprite_polys++; vec3_t v_normal;
CrossProduct(v_right, v_up, v_normal);
VectorMA( org, frame->down * scale, v_up, point ); VectorMA( org, frame->down * scale, v_up, point );
VectorMA( point, frame->left * scale, v_right, dst_vtx[0].pos ); VectorMA( point, frame->left * scale, v_right, dst_vtx[0].pos );
dst_vtx[0].gl_tc[0] = 0.f; dst_vtx[0].gl_tc[0] = 0.f;
dst_vtx[0].gl_tc[1] = 1.f; dst_vtx[0].gl_tc[1] = 1.f;
dst_vtx[0].lm_tc[0] = dst_vtx[0].lm_tc[1] = 0.f; dst_vtx[0].lm_tc[0] = dst_vtx[0].lm_tc[1] = 0.f;
dst_vtx[0].flags = 1; // vertex lighting instead of lightmap lighting
Vector4Set(dst_vtx[0].color, 255, 255, 255, 255);
VectorCopy(v_normal, dst_vtx[0].normal);
VectorMA( org, frame->up * scale, v_up, point ); VectorMA( org, frame->up * scale, v_up, point );
VectorMA( point, frame->left * scale, v_right, dst_vtx[1].pos ); VectorMA( point, frame->left * scale, v_right, dst_vtx[1].pos );
dst_vtx[1].gl_tc[0] = 0.f; dst_vtx[1].gl_tc[0] = 0.f;
dst_vtx[1].gl_tc[1] = 0.f; dst_vtx[1].gl_tc[1] = 0.f;
dst_vtx[1].lm_tc[0] = dst_vtx[1].lm_tc[1] = 0.f; dst_vtx[1].lm_tc[0] = dst_vtx[1].lm_tc[1] = 0.f;
dst_vtx[1].flags = 1; // vertex lighting instead of lightmap lighting
Vector4Set(dst_vtx[1].color, 255, 255, 255, 255);
VectorCopy(v_normal, dst_vtx[1].normal);
VectorMA( org, frame->up * scale, v_up, point ); VectorMA( org, frame->up * scale, v_up, point );
VectorMA( point, frame->right * scale, v_right, dst_vtx[2].pos ); VectorMA( point, frame->right * scale, v_right, dst_vtx[2].pos );
dst_vtx[2].gl_tc[0] = 1.f; dst_vtx[2].gl_tc[0] = 1.f;
dst_vtx[2].gl_tc[1] = 0.f; dst_vtx[2].gl_tc[1] = 0.f;
dst_vtx[2].lm_tc[0] = dst_vtx[2].lm_tc[1] = 0.f; dst_vtx[2].lm_tc[0] = dst_vtx[2].lm_tc[1] = 0.f;
dst_vtx[2].flags = 1; // vertex lighting instead of lightmap lighting
Vector4Set(dst_vtx[2].color, 255, 255, 255, 255);
VectorCopy(v_normal, dst_vtx[2].normal);
VectorMA( org, frame->down * scale, v_up, point ); VectorMA( org, frame->down * scale, v_up, point );
VectorMA( point, frame->right * scale, v_right, dst_vtx[3].pos ); VectorMA( point, frame->right * scale, v_right, dst_vtx[3].pos );
dst_vtx[3].gl_tc[0] = 1.f; dst_vtx[3].gl_tc[0] = 1.f;
dst_vtx[3].gl_tc[1] = 1.f; dst_vtx[3].gl_tc[1] = 1.f;
dst_vtx[3].lm_tc[0] = dst_vtx[3].lm_tc[1] = 0.f; dst_vtx[3].lm_tc[0] = dst_vtx[3].lm_tc[1] = 0.f;
dst_vtx[3].flags = 1; // vertex lighting instead of lightmap lighting
Vector4Set(dst_vtx[3].color, 255, 255, 255, 255);
VectorCopy(v_normal, dst_vtx[3].normal);
dst_idx[0] = 0; dst_idx[0] = 0;
dst_idx[1] = 1; dst_idx[1] = 1;
@ -710,7 +733,7 @@ static void R_DrawSpriteQuad( const char *debug_name, mspriteframe_t *frame, vec
.emissive = {color[0], color[1], color[2]}, .emissive = {color[0], color[1], color[2]},
}; };
VK_RenderModelDynamicBegin( render_mode, "%s", debug_name ); VK_RenderModelDynamicBegin( spriteRenderModeToRenderType(render_mode), color, "%s", debug_name );
VK_RenderModelDynamicAddGeometry( &geometry ); VK_RenderModelDynamicAddGeometry( &geometry );
VK_RenderModelDynamicCommit(); VK_RenderModelDynamicCommit();
} }
@ -745,13 +768,17 @@ static qboolean R_SpriteHasLightmap( cl_entity_t *e, int texFormat )
return true; return true;
} }
static qboolean R_SpriteAllowLerping( cl_entity_t *e, msprite_t *psprite ) static qboolean R_SpriteAllowLerping( const cl_entity_t *e, msprite_t *psprite )
{ {
/* FIXME VK /* FIXME VK
if( !r_sprite_lerping->value ) if( !r_sprite_lerping->value )
return false; return false;
*/ */
// FIXME: lerping means drawing 2 coplanar quads blended on top of each other, which is not something ray tracing can do easily
if (vk_core.rtx)
return false;
if( psprite->numframes <= 1 ) if( psprite->numframes <= 1 )
return false; return false;
@ -764,9 +791,9 @@ static qboolean R_SpriteAllowLerping( cl_entity_t *e, msprite_t *psprite )
return true; return true;
} }
void VK_SpriteDrawModel( cl_entity_t *e ) void R_VkSpriteDrawModel( cl_entity_t *e, float blend )
{ {
mspriteframe_t *frame, *oldframe; mspriteframe_t *frame = NULL, *oldframe = NULL;
msprite_t *psprite; msprite_t *psprite;
model_t *model; model_t *model;
int i, type; int i, type;
@ -805,7 +832,7 @@ void VK_SpriteDrawModel( cl_entity_t *e )
scale = e->curstate.scale; scale = e->curstate.scale;
if( !scale ) scale = 1.0f; if( !scale ) scale = 1.0f;
if( R_SpriteOccluded( e, origin, &scale )) if( spriteIsOccluded( e, origin, &scale, &blend))
return; // sprite culled return; // sprite culled
/* FIXME VK /* FIXME VK
@ -820,7 +847,7 @@ void VK_SpriteDrawModel( cl_entity_t *e )
switch( e->curstate.rendermode ) switch( e->curstate.rendermode )
{ {
case kRenderTransAlpha: case kRenderTransAlpha:
pglDepthMask( GL_FALSE ); pglDepthMask( GL_FALSE ); // <-- FIXME this is different. GL render doesn't write depth, VK one does, as it expects it to be solid-like
// fallthrough // fallthrough
case kRenderTransColor: case kRenderTransColor:
case kRenderTransTexture: case kRenderTransTexture:
@ -875,7 +902,8 @@ void VK_SpriteDrawModel( cl_entity_t *e )
if( R_SpriteAllowLerping( e, psprite )) if( R_SpriteAllowLerping( e, psprite ))
lerp = R_GetSpriteFrameInterpolant( e, &oldframe, &frame ); lerp = R_GetSpriteFrameInterpolant( e, &oldframe, &frame );
else frame = oldframe = R_GetSpriteFrame( model, e->curstate.frame, e->angles[YAW] ); else
frame = oldframe = R_GetSpriteFrame( model, e->curstate.frame, e->angles[YAW] );
type = psprite->type; type = psprite->type;
@ -927,15 +955,8 @@ void VK_SpriteDrawModel( cl_entity_t *e )
if( oldframe == frame ) if( oldframe == frame )
{ {
// draw the single non-lerped frame // draw the single non-lerped frame
const vec4_t color4 = {color[0], color[1], color[2], blend};
/* FIXME VK make sure we end up with the same values R_DrawSpriteQuad( model->name, frame, origin, v_right, v_up, scale, frame->gl_texturenum, e->curstate.rendermode, color4 );
ubo->color[0] = color[0];
ubo->color[1] = color[1];
ubo->color[2] = color[2];
ubo->color[3] = tr.blend;
*/
VK_RenderStateSetColor( color[0], color[1], color[2], CL_FxBlend( e ) / 255.f );
R_DrawSpriteQuad( model->name, frame, origin, v_right, v_up, scale, frame->gl_texturenum, e->curstate.rendermode, color );
} }
else else
{ {
@ -945,16 +966,16 @@ void VK_SpriteDrawModel( cl_entity_t *e )
if( ilerp != 0.0f ) if( ilerp != 0.0f )
{ {
// FIXME VK make sure we end up with the same values as gl const vec4_t color4 = {color[0], color[1], color[2], blend * ilerp};
VK_RenderStateSetColor( color[0], color[1], color[2], 1.f * ilerp ); ASSERT(oldframe);
R_DrawSpriteQuad( model->name, oldframe, origin, v_right, v_up, scale, oldframe->gl_texturenum, e->curstate.rendermode, color ); R_DrawSpriteQuad( model->name, oldframe, origin, v_right, v_up, scale, oldframe->gl_texturenum, e->curstate.rendermode, color4 );
} }
if( lerp != 0.0f ) if( lerp != 0.0f )
{ {
// FIXME VK make sure we end up with the same values as gl const vec4_t color4 = {color[0], color[1], color[2], blend * lerp};
VK_RenderStateSetColor( color[0], color[1], color[2], 1.f * lerp ); ASSERT(frame);
R_DrawSpriteQuad( model->name, frame, origin, v_right, v_up, scale, frame->gl_texturenum, e->curstate.rendermode, color ); R_DrawSpriteQuad( model->name, frame, origin, v_right, v_up, scale, frame->gl_texturenum, e->curstate.rendermode, color4 );
} }
} }

View File

@ -7,4 +7,4 @@ int R_GetSpriteTexture( const model_t *m_pSpriteModel, int frame );
void Mod_LoadMapSprite( struct model_s *mod, const void *buffer, size_t size, qboolean *loaded ); void Mod_LoadMapSprite( struct model_s *mod, const void *buffer, size_t size, qboolean *loaded );
void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags ); void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags );
void VK_SpriteDrawModel( cl_entity_t *e ); void R_VkSpriteDrawModel( cl_entity_t *e, float blend );

View File

@ -54,7 +54,7 @@ typedef struct
double frametime; double frametime;
int framecount; // studio framecount int framecount; // studio framecount
qboolean interpolate; qboolean interpolate;
int rendermode; int rendermode, rendermode2;
float blend; // blend value float blend; // blend value
// bones // bones
@ -1110,6 +1110,7 @@ void R_StudioBuildNormalTable( void )
g_studio.chrome_origin[1] = sin( r_glowshellfreq->value * g_studio.time ) * 4000.0f; g_studio.chrome_origin[1] = sin( r_glowshellfreq->value * g_studio.time ) * 4000.0f;
g_studio.chrome_origin[2] = cos( r_glowshellfreq->value * g_studio.time * 0.33f ) * 4000.0f; g_studio.chrome_origin[2] = cos( r_glowshellfreq->value * g_studio.time * 0.33f ) * 4000.0f;
// FIXME VK: pass this to model color
if( e->curstate.rendercolor.r || e->curstate.rendercolor.g || e->curstate.rendercolor.b ) if( e->curstate.rendercolor.r || e->curstate.rendercolor.g || e->curstate.rendercolor.b )
TriColor4ub( e->curstate.rendercolor.r, e->curstate.rendercolor.g, e->curstate.rendercolor.b, 255 ); TriColor4ub( e->curstate.rendercolor.r, e->curstate.rendercolor.g, e->curstate.rendercolor.b, 255 );
else TriColor4ub( 255, 255, 255, 255 ); else TriColor4ub( 255, 255, 255, 255 );
@ -1679,7 +1680,7 @@ void R_LightLambert( vec4_t light[MAX_LOCALLIGHTS], const vec3_t normal, vec3_t
{ {
float r, r2; float r, r2;
/* VK FIXME NOT IMPL if( tr.fFlipViewModel ) /* FIXME VK NOT IMPL if( tr.fFlipViewModel )
r = DotProduct( normal, light[i] ); r = DotProduct( normal, light[i] );
else */ r = -DotProduct( normal, light[i] ); else */ r = -DotProduct( normal, light[i] );
@ -1710,53 +1711,17 @@ void R_LightLambert( vec4_t light[MAX_LOCALLIGHTS], const vec3_t normal, vec3_t
out[2] = finalLight[2] * 255; out[2] = finalLight[2] * 255;
} }
static void R_StudioSetColorBegin(const short *ptricmds, const vec3_t *pstudionorms, rgba_t out_color ) static void R_StudioSetColorArray(const short *ptricmds, const vec3_t *pstudionorms, byte *color )
{ {
float *lv = (float *)g_studio.lightvalues[ptricmds[1]]; float *lv = (float *)g_studio.lightvalues[ptricmds[1]];
if( g_studio.numlocallights ) color[3] = g_studio.blend * 255;
{ R_LightLambert( g_studio.lightpos[ptricmds[0]], pstudionorms[ptricmds[1]], lv, color );
// FIXME VK color[3] = tr.blend * 255;
out_color[3] = 255;
R_LightLambert( g_studio.lightpos[ptricmds[0]], pstudionorms[ptricmds[1]], lv, out_color );
}
else
{
if( RI.currententity->curstate.rendermode == kRenderTransColor )
{
// FIXME VK color[3] = tr.blend * 255;
out_color[3] = 255;
VectorCopy( (byte*)&RI.currententity->curstate.rendercolor, out_color );
}
else
{
out_color[0] = lv[0] * 255.0f;
out_color[1] = lv[1] * 255.0f;
out_color[2] = lv[2] * 255.0f;
out_color[3] = 255; // FIXME VK tr.blend / 255.0f;
}
}
} }
static void R_StudioSetColorArray(short *ptricmds, vec3_t *pstudionorms, byte *color ) static void R_StudioSetColorBegin(const short *ptricmds, const vec3_t *pstudionorms, rgba_t out_color )
{ {
float *lv = (float *)g_studio.lightvalues[ptricmds[1]]; R_StudioSetColorArray( ptricmds, pstudionorms, out_color );
color[3] = 255; // FIXME VK tr.blend * 255;
if( g_studio.numlocallights )
R_LightLambert( g_studio.lightpos[ptricmds[0]], pstudionorms[ptricmds[1]], lv, color );
else
{
if( RI.currententity->curstate.rendermode == kRenderTransColor )
VectorCopy( (byte*)&RI.currententity->curstate.rendercolor, color );
else
{
color[0] = lv[0] * 255;
color[1] = lv[1] * 255;
color[2] = lv[2] * 255;
}
}
} }
void R_LightStrength( int bone, vec3_t localpos, vec4_t light[MAX_LOCALLIGHTS] ) void R_LightStrength( int bone, vec3_t localpos, vec4_t light[MAX_LOCALLIGHTS] )
@ -1827,12 +1792,15 @@ mstudiotexture_t *R_StudioGetTexture( cl_entity_t *e )
return ptexture; return ptexture;
} }
// TODO where does this need to be declared and defined? currently it's in vk_scene.c
extern int CL_FxBlend( cl_entity_t *e );
void R_StudioSetRenderamt( int iRenderamt ) void R_StudioSetRenderamt( int iRenderamt )
{ {
if( !RI.currententity ) return; if( !RI.currententity ) return;
RI.currententity->curstate.renderamt = iRenderamt; RI.currententity->curstate.renderamt = iRenderamt;
// VK FIXME tr.blend = CL_FxBlend( RI.currententity ) / 255.0f; g_studio.blend = CL_FxBlend( RI.currententity ) / 255.0f;
} }
/* /*
@ -2098,6 +2066,20 @@ _inline void R_StudioDrawChromeMesh( short *ptricmds, vec3_t *pstudionorms, floa
} }
*/ */
static vk_render_type_e studioRenderModeToRenderType( int render_mode ) {
switch (render_mode) {
case kRenderNormal: return kVkRenderTypeSolid;
case kRenderTransColor: return kVkRenderType_A_1mA_RW;
case kRenderTransTexture: return kVkRenderType_A_1mA_RW;
case kRenderGlow: return kVkRenderType_A_1mA_RW;
case kRenderTransAlpha: return kVkRenderType_A_1mA_RW;
case kRenderTransAdd: return kVkRenderType_1_1_R;
default: ASSERT(!"Unxpected render_mode");
}
return kVkRenderTypeSolid;
}
static void R_StudioDrawPoints( void ) static void R_StudioDrawPoints( void )
{ {
int i, j, k, m_skinnum; int i, j, k, m_skinnum;
@ -2114,7 +2096,11 @@ static void R_StudioDrawPoints( void )
if( !m_pStudioHeader ) return; if( !m_pStudioHeader ) return;
VK_RenderModelDynamicBegin( RI.currententity->curstate.rendermode, "%s", m_pSubModel->name ); vec4_t color = {1, 1, 1, g_studio.blend};
if (g_studio.rendermode2 == kRenderTransAdd) {
Vector4Set(color, g_studio.blend, g_studio.blend, g_studio.blend, 1.f);
}
VK_RenderModelDynamicBegin( studioRenderModeToRenderType(RI.currententity->curstate.rendermode), color, "%s", m_pSubModel->name );
g_studio.numverts = g_studio.numelems = 0; g_studio.numverts = g_studio.numelems = 0;
@ -2201,7 +2187,7 @@ static void R_StudioDrawPoints( void )
const struct { float blend; } tr = {1.f}; const struct { float blend; } tr = {1.f};
if( FBitSet( g_nFaceFlags, STUDIO_NF_CHROME )) if( FBitSet( g_nFaceFlags, STUDIO_NF_CHROME ))
R_StudioSetupChrome( g_studio.chrome[k], *pnormbone, (float *)pstudionorms ); R_StudioSetupChrome( g_studio.chrome[k], *pnormbone, (float *)pstudionorms );
VectorSet( g_studio.lightvalues[k], tr.blend, tr.blend, tr.blend ); VectorSet( g_studio.lightvalues[k], g_studio.blend, g_studio.blend, g_studio.blend );
} }
} }
else else
@ -2230,9 +2216,7 @@ static void R_StudioDrawPoints( void )
for( j = 0; j < m_pSubModel->nummesh; j++ ) for( j = 0; j < m_pSubModel->nummesh; j++ )
{ {
// FIXME VK float oldblend = g_studio.blend;
const struct { float blend; } tr = {1.f};
float oldblend = tr.blend;
uint startArrayVerts = g_studio.numverts; uint startArrayVerts = g_studio.numverts;
uint startArrayElems = g_studio.numelems; uint startArrayElems = g_studio.numelems;
short *ptricmds; short *ptricmds;
@ -2254,7 +2238,7 @@ static void R_StudioDrawPoints( void )
pglAlphaFunc( GL_GREATER, 0.5f ); pglAlphaFunc( GL_GREATER, 0.5f );
pglDepthMask( GL_TRUE ); pglDepthMask( GL_TRUE );
if( R_ModelOpaque( RI.currententity->curstate.rendermode )) if( R_ModelOpaque( RI.currententity->curstate.rendermode ))
tr.blend = 1.0f; g_studio.blend = 1.0f;
} }
else if( FBitSet( g_nFaceFlags, STUDIO_NF_ADDITIVE )) else if( FBitSet( g_nFaceFlags, STUDIO_NF_ADDITIVE ))
{ {
@ -2291,7 +2275,7 @@ static void R_StudioDrawPoints( void )
} }
r_stats.c_studio_polys += pmesh->numtris; r_stats.c_studio_polys += pmesh->numtris;
tr.blend = oldblend; g_studio.blend = oldblend;
*/ */
} }
@ -2631,34 +2615,7 @@ static void R_StudioDrawPointsShadow( void )
void GL_StudioSetRenderMode( int rendermode ) void GL_StudioSetRenderMode( int rendermode )
{ {
PRINT_NOT_IMPLEMENTED_ARGS("(%d)", rendermode); g_studio.rendermode2 = rendermode;
/* FIXME VK
switch( rendermode )
{
case kRenderNormal:
break;
case kRenderTransColor:
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglEnable( GL_BLEND );
break;
case kRenderTransAdd:
pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglColor4f( tr.blend, tr.blend, tr.blend, 1.0f );
pglBlendFunc( GL_ONE, GL_ONE );
pglDepthMask( GL_FALSE );
pglEnable( GL_BLEND );
break;
default:
pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglColor4f( 1.0f, 1.0f, 1.0f, tr.blend );
pglDepthMask( GL_TRUE );
pglEnable( GL_BLEND );
break;
}
*/
} }
/* /*
@ -2678,7 +2635,7 @@ static void GL_StudioDrawShadow( void )
if( r_shadows.value && g_studio.rendermode != kRenderTransAdd && !FBitSet( RI.currentmodel->flags, STUDIO_AMBIENT_LIGHT )) if( r_shadows.value && g_studio.rendermode != kRenderTransAdd && !FBitSet( RI.currentmodel->flags, STUDIO_AMBIENT_LIGHT ))
{ {
float color = 1.0f; // FIXME VK - (tr.blend * 0.5f); float color = 1.0f - (g_studio.blend * 0.5f);
/* FIXME VK /* FIXME VK
pglDisable( GL_TEXTURE_2D ); pglDisable( GL_TEXTURE_2D );
@ -2713,7 +2670,7 @@ void R_StudioRenderFinal( void )
{ {
R_StudioSetupModel( i, (void**)&m_pBodyPart, (void**)&m_pSubModel ); R_StudioSetupModel( i, (void**)&m_pBodyPart, (void**)&m_pSubModel );
GL_StudioSetRenderMode( rendermode ); // TODO does literally nothing GL_StudioSetRenderMode( rendermode );
R_StudioDrawPoints(); R_StudioDrawPoints();
GL_StudioDrawShadow(); GL_StudioDrawShadow();
} }
@ -3114,7 +3071,7 @@ void R_StudioDrawModelInternal( cl_entity_t *e, int flags )
VK_RenderDebugLabelEnd(); VK_RenderDebugLabelEnd();
} }
void R_DrawStudioModel( cl_entity_t *e ) static void R_DrawStudioModel( cl_entity_t *e )
{ {
/* FIXME VK /* FIXME VK
if( FBitSet( RI.params, RP_ENVVIEW )) if( FBitSet( RI.params, RP_ENVVIEW ))
@ -3209,8 +3166,8 @@ void R_DrawViewModel( void )
if( !RP_NORMALPASS() || ENGINE_GET_PARM( PARM_LOCAL_HEALTH ) <= 0 || !CL_IsViewEntityLocalPlayer()) if( !RP_NORMALPASS() || ENGINE_GET_PARM( PARM_LOCAL_HEALTH ) <= 0 || !CL_IsViewEntityLocalPlayer())
return; return;
tr.blend = CL_FxBlend( view ) / 255.0f; g_studio.blend = CL_FxBlend( view ) / 255.0f;
if( !R_ModelOpaque( view->curstate.rendermode ) && tr.blend <= 0.0f ) if( !R_ModelOpaque( view->curstate.rendermode ) && g_studio.blend <= 0.0f )
return; // invisible ? return; // invisible ?
*/ */
@ -3529,12 +3486,14 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded )
PRINT_NOT_IMPLEMENTED_ARGS("(%s)", mod->name); PRINT_NOT_IMPLEMENTED_ARGS("(%s)", mod->name);
} }
void VK_StudioDrawModel( cl_entity_t *ent, int render_mode ) void VK_StudioDrawModel( cl_entity_t *ent, int render_mode, float blend )
{ {
RI.currententity = ent; RI.currententity = ent;
RI.currentmodel = ent->model; RI.currentmodel = ent->model;
RI.drawWorld = true; RI.drawWorld = true;
g_studio.blend = blend;
R_DrawStudioModel( ent ); R_DrawStudioModel( ent );
RI.currentmodel = NULL; RI.currentmodel = NULL;

View File

@ -12,7 +12,7 @@ void VK_StudioShutdown( void );
void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded ); void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded );
void Mod_StudioLoadTextures( model_t *mod, void *data ); void Mod_StudioLoadTextures( model_t *mod, void *data );
void VK_StudioDrawModel( cl_entity_t *ent, int render_mode ); void VK_StudioDrawModel( cl_entity_t *ent, int render_mode, float blend );
void R_RunViewmodelEvents( void ); void R_RunViewmodelEvents( void );
void R_DrawViewModel( void ); void R_DrawViewModel( void );