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;
//layout(set = 0, binding = 2, rgba16f) uniform readonly image2D light_poly_diffuse;
/* layout(set = 0, binding = 3, rgba16f) uniform readonly image2D specular; */
/* layout(set = 0, binding = 4, rgba16f) uniform readonly image2D additive; */
/* layout(set = 0, binding = 5, rgba16f) uniform readonly image2D normals; */
/* layout(set = 0, binding = 6, rgba32f) uniform readonly image2D position_t; */
//#define DEBUG_TEXTURE normals_gs
//#define DEBUG_TEXTURE emissive
//#define DEBUG_TEXTURE light_point_diffuse
// Blatantly copypasted from https://www.shadertoy.com/view/XsGfWV
vec3 aces_tonemap(vec3 color){
@ -192,26 +190,19 @@ void main() {
/* 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((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((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;
//imageStore(out_dest, pix, vec4(fract(imageLoad(position_t, pix).rgb/10.), 0.)); return;
//imageStore(out_dest, pix, vec4(fract(imageLoad(geometry_prev_position, pix).rgb/50.), 0.)); return;
/*
#if 0
vec3 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 + shading_normal * .5, 0.)); return;
#endif
/* const uint mi = uint(material_index); */
/* 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);
return;
} 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.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.))))
payload.emissive.rgb = payload.base_color_a.rgb;
#endif
payload.base_color_a *= kusok.color;
}
#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 uint tex_base_color = getKusok(geom.kusok_index).tex_base_color;
const vec4 texture_color = texture(textures[nonuniformEXT(tex_base_color)], geom.uv);
const vec3 kusok_emissive = getKusok(geom.kusok_index).emissive;
const vec3 color = texture_color.rgb * kusok_emissive * texture_color.a; // * kusok_color.a;
const Kusok kusok = getKusok(geom.kusok_index);
const vec3 color = texture_color.rgb * kusok.emissive * texture_color.a * kusok.color.a;
const float hit_t = rayQueryGetIntersectionTEXT(rq, false);
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] },
};
VK_RenderModelDynamicBegin( render_mode, "beam" /* TODO its name */ );
vk_render_type_e render_type = render_mode == kRenderNormal ? kVkRenderTypeSolid : kVkRenderType_A_1_R;
VK_RenderModelDynamicBegin( render_type, 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,21 @@ 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 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;
vec3_t mins, maxs;
@ -258,7 +272,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( brushRenderModeToRenderType(ent->curstate.rendermode), color, "%s water", model->name );
// Iterate through all surfaces, find *TURB*
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;
}
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 +361,23 @@ 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);
}
// 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) {
XVK_DrawWaterSurfaces(ent);
brushDrawWaterSurfaces(ent, bmodel->render_model.color);
}
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 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,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);
}
@ -672,10 +703,11 @@ qboolean VK_BrushModelLoad( model_t *mod, qboolean map )
vk_brush_model_t *bmodel = Mem_Calloc(vk_core.pool, model_size);
mod->cache.data = bmodel;
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->num_water_surfaces = sizes.water_surfaces;
Vector4Set(bmodel->render_model.color, 1, 1, 1, 1);
if (sizes.num_surfaces != 0) {
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);
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

@ -7,6 +7,7 @@
#include "crtlib.h"
#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_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) {
VectorCopy( geom->emissive, kusok->emissive );
VectorCopy(geom->emissive, kusok->emissive);
} else {
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); */
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) {
vk_render_geometry_t *mg = args.model->geometries + i;
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);
}
const vec4_t color = {1, 1, 1, 1};
applyMaterialToKusok(kusochki + i, mg, color, false);
if (HACK_additive_emissive && mg->material != kXVkMaterialEmissive) {
mg->material = kXVkMaterialEmissive;
VectorCopy(args.model->color, mg->emissive);
}
applyMaterialToKusok(kusochki + i, mg, args.model->color, false);
Matrix4x4_LoadIdentity(kusochki[i].prev_transform);
}
@ -421,8 +439,7 @@ static void computeConveyorSpeed(const color24 rendercolor, int tex_index, vec2_
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) {
qboolean HACK_reflective = false;
void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render_model, const matrix3x4 *transform_row) {
vk_ray_draw_model_t* draw_model = g_ray_model_state.frame.models + g_ray_model_state.frame.num_models;
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));
}
switch (render_model->render_mode) {
case kRenderNormal:
qboolean HACK_reflective = false;
qboolean HACK_additive_emissive = false;
switch (render_model->render_type) {
case kVkRenderTypeSolid:
draw_model->material_mode = MaterialMode_Opaque;
break;
// C = (1 - alpha) * DST + alpha * SRC (TODO is this right?)
case kRenderTransColor:
case kRenderTransTexture:
HACK_reflective = true;
draw_model->material_mode = MaterialMode_Refractive;
break;
// Additive blending: C = SRC * alpha + DST
case kRenderGlow:
case kRenderTransAdd:
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
// FIXME proper trasnlucency
//HACK_reflective = true;
//draw_model->material_mode = MaterialMode_Refractive;
HACK_additive_emissive = true;
draw_model->material_mode = MaterialMode_Additive;
break;
// Alpha test (TODO additive? mixing?)
case kRenderTransAlpha:
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;
draw_model->material_mode = MaterialMode_Additive;
break;
case kVkRenderType_AT: // no blend, depth RW, alpha test
draw_model->material_mode = MaterialMode_Opaque_AlphaTest;
break;
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:
@ -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;
for (int i = 0; i < render_model->num_geometries; ++i) {
const vk_render_geometry_t *geom = render_model->geometries + i;
applyMaterialToKusok(kusochki + i, geom, color, HACK_reflective);
vk_render_geometry_t *geom = render_model->geometries + i;
// 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);
}

View File

@ -30,7 +30,7 @@ typedef struct {
static struct {
VkPipelineLayout pipeline_layout;
VkPipeline pipelines[kRenderTransAdd + 1];
VkPipeline pipelines[kVkRenderType_COUNT];
vk_buffer_t uniform_buffer;
uint32_t ubo_align;
@ -121,70 +121,80 @@ static qboolean createPipelines( void )
.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";
switch (i)
{
case kRenderNormal:
case kVkRenderTypeSolid:
spec_data.alpha_test_threshold = 0.f;
ci.blendEnable = VK_FALSE;
ci.depthWriteEnable = VK_TRUE;
ci.depthTestEnable = VK_TRUE;
name = "brush kRenderNormal";
name = "kVkRenderTypeSolid";
break;
case kRenderTransColor:
case kVkRenderType_A_1mA_RW:
spec_data.alpha_test_threshold = 0.f;
ci.depthWriteEnable = VK_TRUE;
ci.depthTestEnable = 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.dstAlphaBlendFactor = ci.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
name = "brush kRenderTransColor";
name = "kVkRenderType_A_1mA_RW";
break;
case kRenderTransAdd:
case kVkRenderType_A_1mA_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; // TODO check
// sprites do SRC_ALPHA
ci.srcAlphaBlendFactor = ci.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;// TODO ? FACTOR_ONE;
ci.dstAlphaBlendFactor = ci.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
name = "brush kRenderTransAdd";
ci.colorBlendOp = VK_BLEND_OP_ADD;
ci.srcAlphaBlendFactor = ci.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
ci.dstAlphaBlendFactor = ci.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
name = "kVkRenderType_A_1mA_R";
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;
ci.depthWriteEnable = VK_TRUE;
ci.depthTestEnable = VK_TRUE;
ci.blendEnable = VK_FALSE;
name = "brush kRenderTransAlpha(test)";
name = "kVkRenderType_AT";
break;
case kRenderGlow:
case kVkRenderType_1_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; // TODO check
ci.srcAlphaBlendFactor = ci.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
ci.colorBlendOp = VK_BLEND_OP_ADD;
ci.srcAlphaBlendFactor = ci.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
ci.dstAlphaBlendFactor = ci.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
break;
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";
name = "kVkRenderType_1_1_R";
break;
default:
@ -228,7 +238,7 @@ typedef struct {
typedef struct render_draw_s {
int lightmap, texture;
int render_mode;
int pipeline_index;
uint32_t element_count;
uint32_t index_offset, vertex_offset;
/* TODO this should be a separate thing? */ struct { float r, g, b; } emissive;
@ -328,11 +338,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 +361,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 = {
@ -453,8 +453,8 @@ static void drawCmdPushDraw( const render_draw_t *draw )
{
draw_command_t *draw_command;
ASSERT(draw->render_mode >= 0);
ASSERT(draw->render_mode < ARRAYSIZE(g_render.pipelines));
ASSERT(draw->pipeline_index >= 0);
ASSERT(draw->pipeline_index < ARRAYSIZE(g_render.pipelines));
ASSERT(draw->lightmap >= 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);
}
if (pipeline != draw->draw.draw.render_mode) {
pipeline = draw->draw.draw.render_mode;
if (pipeline != draw->draw.draw.pipeline_index) {
pipeline = draw->draw.draw.pipeline_index;
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 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 (ent != NULL && model != NULL) {
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 );
}
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;
}
@ -713,9 +718,9 @@ void VK_RenderModelDraw( const cl_entity_t *ent, vk_render_model_t* model ) {
if (split) {
if (element_count) {
render_draw_t draw = {
.lightmap = tglob.lightmapTextures[0], // FIXME there can be more than one lightmap textures
.lightmap = lightmap,
.texture = current_texture,
.render_mode = model->render_mode,
.pipeline_index = model->render_type,
.element_count = element_count,
.vertex_offset = vertex_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) {
const render_draw_t draw = {
.lightmap = tglob.lightmapTextures[0],
.lightmap = lightmap,
.texture = current_texture,
.render_mode = model->render_mode,
.pipeline_index = model->render_type,
.element_count = element_count,
.vertex_offset = vertex_offset,
.index_offset = index_offset,
@ -758,7 +763,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( vk_render_type_e render_type, 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 );
@ -767,7 +772,9 @@ void VK_RenderModelDynamicBegin( int render_mode, const char *debug_name_fmt, ..
ASSERT(!g_dynamic_model.model.geometries);
g_dynamic_model.model.geometries = g_dynamic_model.geometries;
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 ) {
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);
@ -65,10 +62,25 @@ struct vk_ray_model_s;
#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;
typedef struct vk_render_model_s {
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;
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_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_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 R_AllowFog( qboolean allow );
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];
}
ref_interface_t gReffuncs =
static const ref_interface_t gReffuncs =
{
.R_Init = R_VkInit,
.R_Shutdown = R_VkShutdown,

View File

@ -17,7 +17,7 @@ void VK_RayModelDestroy( struct vk_ray_model_s *model );
void VK_RayFrameBegin( void );
// 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 {
VkBuffer buffer;

View File

@ -523,61 +523,33 @@ static void drawEntity( cl_entity_t *ent, int render_mode )
{
const model_t *mod = ent->model;
matrix4x4 model;
float alpha;
if (!mod)
return;
// 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?
if( alpha <= 0.0f )
if( blend <= 0.0f )
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)
{
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:
VK_RenderStateSetMatrixModel( matrix4x4_identity );
VK_StudioDrawModel( ent, render_mode );
VK_StudioDrawModel( ent, render_mode, blend );
break;
case mod_sprite:
VK_RenderStateSetMatrixModel( matrix4x4_identity );
VK_SpriteDrawModel( ent );
R_VkSpriteDrawModel( ent, blend );
break;
case mod_alias:
@ -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);
@ -620,10 +591,8 @@ void VK_SceneRender( const ref_viewpass_t *rvp ) {
cl_entity_t *world = gEngine.GetEntityByIndex( 0 );
if( world && world->model )
{
//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

@ -400,7 +400,7 @@ NOTE: we using prevblending[0] and [1] for holds interval
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;
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
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 )
{
float blend;
vec3_t 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] )
return true; // do scissor
blend = R_SpriteGlowBlend( origin, e->curstate.rendermode, e->curstate.renderfx, pscale );
// FIXME VK tr.blend *= blend;
*blend = R_SpriteGlowBlend( origin, e->curstate.rendermode, e->curstate.renderfx, pscale );
if( blend <= 0.01f )
if( *blend <= 0.01f )
return true; // faded
}
else
@ -645,47 +643,72 @@ qboolean R_SpriteOccluded( cl_entity_t *e, vec3_t origin, float *pscale )
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 )
{
vec3_t point;
vk_vertex_t *dst_vtx;
uint16_t *dst_idx;
static vk_render_type_e spriteRenderModeToRenderType( 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_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;
if (!R_GeometryBufferAllocAndLock( &buffer, 4, 6, LifetimeSingleFrame )) {
gEngine.Con_Printf(S_ERROR "Cannot allocate geometry for sprite quad\n");
return;
}
vec3_t point;
vk_vertex_t *dst_vtx;
uint16_t *dst_idx;
dst_vtx = buffer.vertices.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( point, frame->left * scale, v_right, dst_vtx[0].pos );
dst_vtx[0].gl_tc[0] = 0.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].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( point, frame->left * scale, v_right, dst_vtx[1].pos );
dst_vtx[1].gl_tc[0] = 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].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( point, frame->right * scale, v_right, dst_vtx[2].pos );
dst_vtx[2].gl_tc[0] = 1.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].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( point, frame->right * scale, v_right, dst_vtx[3].pos );
dst_vtx[3].gl_tc[0] = 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].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[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]},
};
VK_RenderModelDynamicBegin( render_mode, "%s", debug_name );
VK_RenderModelDynamicBegin( spriteRenderModeToRenderType(render_mode), color, "%s", debug_name );
VK_RenderModelDynamicAddGeometry( &geometry );
VK_RenderModelDynamicCommit();
}
@ -745,13 +768,17 @@ static qboolean R_SpriteHasLightmap( cl_entity_t *e, int texFormat )
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
if( !r_sprite_lerping->value )
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 )
return false;
@ -764,9 +791,9 @@ static qboolean R_SpriteAllowLerping( cl_entity_t *e, msprite_t *psprite )
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;
model_t *model;
int i, type;
@ -805,7 +832,7 @@ void VK_SpriteDrawModel( cl_entity_t *e )
scale = e->curstate.scale;
if( !scale ) scale = 1.0f;
if( R_SpriteOccluded( e, origin, &scale ))
if( spriteIsOccluded( e, origin, &scale, &blend))
return; // sprite culled
/* FIXME VK
@ -820,7 +847,7 @@ void VK_SpriteDrawModel( cl_entity_t *e )
switch( e->curstate.rendermode )
{
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
case kRenderTransColor:
case kRenderTransTexture:
@ -875,7 +902,8 @@ void VK_SpriteDrawModel( cl_entity_t *e )
if( R_SpriteAllowLerping( e, psprite ))
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;
@ -927,15 +955,8 @@ void VK_SpriteDrawModel( cl_entity_t *e )
if( oldframe == frame )
{
// draw the single non-lerped frame
/* FIXME VK make sure we end up with the same values
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 );
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
{
@ -945,16 +966,16 @@ void VK_SpriteDrawModel( cl_entity_t *e )
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], 1.f * 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};
ASSERT(oldframe);
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], 1.f * 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};
ASSERT(frame);
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_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;
int framecount; // studio framecount
qboolean interpolate;
int rendermode;
int rendermode, rendermode2;
float blend; // blend value
// 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[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 )
TriColor4ub( e->curstate.rendercolor.r, e->curstate.rendercolor.g, e->curstate.rendercolor.b, 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;
/* VK FIXME NOT IMPL if( tr.fFlipViewModel )
/* FIXME VK NOT IMPL if( tr.fFlipViewModel )
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;
}
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]];
if( g_studio.numlocallights )
{
// 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;
}
}
color[3] = g_studio.blend * 255;
R_LightLambert( g_studio.lightpos[ptricmds[0]], pstudionorms[ptricmds[1]], lv, color );
}
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]];
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;
}
}
R_StudioSetColorArray( ptricmds, pstudionorms, out_color );
}
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;
}
// 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 )
{
if( !RI.currententity ) return;
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 )
{
int i, j, k, m_skinnum;
@ -2114,7 +2096,11 @@ static void R_StudioDrawPoints( void )
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;
@ -2201,7 +2187,7 @@ static void R_StudioDrawPoints( void )
const struct { float blend; } tr = {1.f};
if( FBitSet( g_nFaceFlags, STUDIO_NF_CHROME ))
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
@ -2230,9 +2216,7 @@ static void R_StudioDrawPoints( void )
for( j = 0; j < m_pSubModel->nummesh; j++ )
{
// FIXME VK
const struct { float blend; } tr = {1.f};
float oldblend = tr.blend;
float oldblend = g_studio.blend;
uint startArrayVerts = g_studio.numverts;
uint startArrayElems = g_studio.numelems;
short *ptricmds;
@ -2254,7 +2238,7 @@ static void R_StudioDrawPoints( void )
pglAlphaFunc( GL_GREATER, 0.5f );
pglDepthMask( GL_TRUE );
if( R_ModelOpaque( RI.currententity->curstate.rendermode ))
tr.blend = 1.0f;
g_studio.blend = 1.0f;
}
else if( FBitSet( g_nFaceFlags, STUDIO_NF_ADDITIVE ))
{
@ -2291,7 +2275,7 @@ static void R_StudioDrawPoints( void )
}
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 )
{
PRINT_NOT_IMPLEMENTED_ARGS("(%d)", 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;
}
*/
g_studio.rendermode2 = rendermode;
}
/*
@ -2678,7 +2635,7 @@ static void GL_StudioDrawShadow( void )
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
pglDisable( GL_TEXTURE_2D );
@ -2713,7 +2670,7 @@ void R_StudioRenderFinal( void )
{
R_StudioSetupModel( i, (void**)&m_pBodyPart, (void**)&m_pSubModel );
GL_StudioSetRenderMode( rendermode );
// TODO does literally nothing GL_StudioSetRenderMode( rendermode );
R_StudioDrawPoints();
GL_StudioDrawShadow();
}
@ -3114,7 +3071,7 @@ void R_StudioDrawModelInternal( cl_entity_t *e, int flags )
VK_RenderDebugLabelEnd();
}
void R_DrawStudioModel( cl_entity_t *e )
static void R_DrawStudioModel( cl_entity_t *e )
{
/* FIXME VK
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())
return;
tr.blend = CL_FxBlend( view ) / 255.0f;
if( !R_ModelOpaque( view->curstate.rendermode ) && tr.blend <= 0.0f )
g_studio.blend = CL_FxBlend( view ) / 255.0f;
if( !R_ModelOpaque( view->curstate.rendermode ) && g_studio.blend <= 0.0f )
return; // invisible ?
*/
@ -3529,12 +3486,14 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded )
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.currentmodel = ent->model;
RI.drawWorld = true;
g_studio.blend = blend;
R_DrawStudioModel( ent );
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_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_DrawViewModel( void );