vk: begin refactoring rendermodel api, instantiate sprites, crash gpu

This commit is contained in:
Ivan Avdeev 2023-05-31 09:39:27 -07:00
parent c157c9acfc
commit e9ea962bc0
7 changed files with 260 additions and 147 deletions

View File

@ -33,6 +33,8 @@ typedef struct vk_brush_model_s {
int *animated_indexes; int *animated_indexes;
int animated_indexes_count; int animated_indexes_count;
matrix4x4 prev_transform;
} vk_brush_model_t; } vk_brush_model_t;
static struct { static struct {
@ -402,7 +404,7 @@ static qboolean isSurfaceAnimated( const msurface_t *s, const struct texture_s *
return true; return true;
} }
void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, float blend, const matrix4x4 transform ) { void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, float blend, const matrix4x4 in_transform ) {
// 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;
@ -412,46 +414,47 @@ void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, float blend, co
return; return;
} }
if (transform) matrix4x4 transform;
Matrix4x4_Copy(bmodel->render_model.transform, transform); if (in_transform)
Matrix4x4_Copy(transform, in_transform);
else else
Matrix4x4_LoadIdentity(bmodel->render_model.transform); Matrix4x4_LoadIdentity(transform);
Vector4Set(bmodel->render_model.color, 1.f, 1.f, 1.f, 1.f); vec4_t color = {1, 1, 1, 1};
vk_render_type_e render_type = kVkRenderTypeSolid; vk_render_type_e render_type = kVkRenderTypeSolid;
switch (render_mode) { switch (render_mode) {
case kRenderNormal: case kRenderNormal:
Vector4Set(bmodel->render_model.color, 1.f, 1.f, 1.f, 1.f); Vector4Set(color, 1.f, 1.f, 1.f, 1.f);
render_type = kVkRenderTypeSolid; render_type = kVkRenderTypeSolid;
break; break;
case kRenderTransColor: case kRenderTransColor:
render_type = kVkRenderType_A_1mA_RW; render_type = kVkRenderType_A_1mA_RW;
Vector4Set(bmodel->render_model.color, Vector4Set(color,
ent->curstate.rendercolor.r / 255.f, ent->curstate.rendercolor.r / 255.f,
ent->curstate.rendercolor.g / 255.f, ent->curstate.rendercolor.g / 255.f,
ent->curstate.rendercolor.b / 255.f, ent->curstate.rendercolor.b / 255.f,
blend); blend);
break; break;
case kRenderTransAdd: case kRenderTransAdd:
Vector4Set(bmodel->render_model.color, blend, blend, blend, 1.f); Vector4Set(color, blend, blend, blend, 1.f);
render_type = kVkRenderType_A_1_R; render_type = kVkRenderType_A_1_R;
break; break;
case kRenderTransAlpha: case kRenderTransAlpha:
if( gEngine.EngineGetParm( PARM_QUAKE_COMPATIBLE, 0 )) if( gEngine.EngineGetParm( PARM_QUAKE_COMPATIBLE, 0 ))
{ {
render_type = kVkRenderType_A_1mA_RW; render_type = kVkRenderType_A_1mA_RW;
Vector4Set(bmodel->render_model.color, 1.f, 1.f, 1.f, blend); Vector4Set(color, 1.f, 1.f, 1.f, blend);
} }
else else
{ {
Vector4Set(bmodel->render_model.color, 1.f, 1.f, 1.f, 1.f); Vector4Set(color, 1.f, 1.f, 1.f, 1.f);
render_type = kVkRenderType_AT; render_type = kVkRenderType_AT;
} }
break; break;
case kRenderTransTexture: case kRenderTransTexture:
case kRenderGlow: case kRenderGlow:
render_type = kVkRenderType_A_1mA_R; render_type = kVkRenderType_A_1mA_R;
Vector4Set(bmodel->render_model.color, 1.f, 1.f, 1.f, blend); Vector4Set(color, 1.f, 1.f, 1.f, blend);
break; break;
} }
@ -460,7 +463,7 @@ void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, float blend, co
bmodel->render_model.lightmap = (render_mode == kRenderNormal || render_mode == kRenderTransAlpha) ? 1 : 0; bmodel->render_model.lightmap = (render_mode == kRenderNormal || render_mode == kRenderTransAlpha) ? 1 : 0;
if (bmodel->num_water_surfaces) { if (bmodel->num_water_surfaces) {
brushDrawWaterSurfaces(ent, bmodel->render_model.color, bmodel->render_model.transform); brushDrawWaterSurfaces(ent, color, transform);
} }
if (bmodel->render_model.num_geometries == 0) if (bmodel->render_model.num_geometries == 0)
@ -491,8 +494,17 @@ void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, float blend, co
} }
} }
bmodel->render_model.render_type = render_type; R_RenderModelDraw(&bmodel->render_model, (r_model_draw_t){
VK_RenderModelDraw(&bmodel->render_model, ent->index); .render_type = render_type,
.color = &color,
.transform = &transform,
.prev_transform = &bmodel->prev_transform,
.geometries_changed = bmodel->animated_indexes,
.geometries_changed_count = bmodel->animated_indexes_count,
});
Matrix4x4_Copy(bmodel->prev_transform, transform);
} }
typedef enum { typedef enum {
@ -857,9 +869,6 @@ qboolean VK_BrushModelLoad( model_t *mod ) {
// Cannot deallocate bmodel as we might still have staging references to its memory // Cannot deallocate bmodel as we might still have staging references to its memory
return false; return false;
} }
bmodel->render_model.geometries_changed = bmodel->animated_indexes;
bmodel->render_model.geometries_changed_count = bmodel->animated_indexes_count;
} }
g_brush.stat.total_vertices += sizes.num_indices; g_brush.stat.total_vertices += sizes.num_indices;

View File

@ -810,6 +810,8 @@ qboolean R_VkInit( void )
void R_VkShutdown( void ) { void R_VkShutdown( void ) {
XVK_CHECK(vkDeviceWaitIdle(vk_core.device)); XVK_CHECK(vkDeviceWaitIdle(vk_core.device));
R_SpriteShutdown();
if (vk_core.rtx) if (vk_core.rtx)
{ {
VK_LightsShutdown(); VK_LightsShutdown();

View File

@ -406,15 +406,15 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
if (!uploadKusochki(model, render_model)) if (!uploadKusochki(model, render_model))
return; return;
} else { } else {
if (!uploadKusochkiSubset(model, render_model, render_model->geometries_changed, render_model->geometries_changed_count)) /* FIXME move to RT_FrameAddModel if (!uploadKusochkiSubset(model, render_model, render_model->geometries_changed, render_model->geometries_changed_count)) */
return; /* return; */
} }
// TODO needed for brush models only // TODO needed for brush models only
// (? TODO studio models?) // (? TODO studio models?)
for (int i = 0; i < render_model->dynamic_polylights_count; ++i) { for (int i = 0; i < render_model->dynamic_polylights_count; ++i) {
rt_light_add_polygon_t *const polylight = render_model->dynamic_polylights + i; rt_light_add_polygon_t *const polylight = render_model->dynamic_polylights + i;
polylight->transform_row = (const matrix3x4*)render_model->transform; polylight->transform_row = (const matrix3x4*)render_model->deprecate.transform;
polylight->dynamic = true; polylight->dynamic = true;
RT_LightAddPolygon(polylight); RT_LightAddPolygon(polylight);
} }
@ -422,10 +422,10 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
draw_instance->model_toremove = model; draw_instance->model_toremove = model;
draw_instance->blas_addr = model->blas_addr; draw_instance->blas_addr = model->blas_addr;
draw_instance->kusochki_offset = model->kusochki_offset; draw_instance->kusochki_offset = model->kusochki_offset;
draw_instance->material_mode = materialModeFromRenderType(render_model->render_type); draw_instance->material_mode = materialModeFromRenderType(render_model->deprecate.render_type);
Vector4Copy(render_model->color, draw_instance->color); Vector4Copy(render_model->deprecate.color, draw_instance->color);
Matrix3x4_Copy(draw_instance->transform_row, render_model->transform); Matrix3x4_Copy(draw_instance->transform_row, render_model->deprecate.transform);
Matrix4x4_Copy(draw_instance->prev_transform_row, render_model->prev_transform); Matrix4x4_Copy(draw_instance->prev_transform_row, render_model->deprecate.prev_transform);
g_ray_model_state.frame.instances_count++; g_ray_model_state.frame.instances_count++;
} }

View File

@ -650,7 +650,8 @@ qboolean VK_RenderModelInit_old( vk_render_model_t *model ) {
model->ray_model = VK_RayModelCreate(args); model->ray_model = VK_RayModelCreate(args);
model->dynamic_polylights = NULL; model->dynamic_polylights = NULL;
model->dynamic_polylights_count = 0; model->dynamic_polylights_count = 0;
Matrix4x4_LoadIdentity(model->transform); Matrix4x4_LoadIdentity(model->deprecate.transform);
Matrix4x4_LoadIdentity(model->deprecate.prev_transform);
return !!model->ray_model; return !!model->ray_model;
} }
@ -662,12 +663,11 @@ qboolean VK_RenderModelCreate( vk_render_model_t *model, vk_render_model_init_t
memset(model, 0, sizeof(*model)); memset(model, 0, sizeof(*model));
Q_strncpy(model->debug_name, args.name, sizeof(model->debug_name)); Q_strncpy(model->debug_name, args.name, sizeof(model->debug_name));
Matrix4x4_LoadIdentity(model->transform); // TODO these are dynamic and should be removed
Matrix4x4_LoadIdentity(model->prev_transform); Matrix4x4_LoadIdentity(model->deprecate.transform);
Matrix4x4_LoadIdentity(model->deprecate.prev_transform);
// TODO this is dynamic and should be removed model->deprecate.render_type = kVkRenderTypeSolid;
model->render_type = kVkRenderTypeSolid; Vector4Set(model->deprecate.color, 1, 1, 1, 1);
Vector4Set(model->color, 1, 1, 1, 1);
model->geometries = args.geometries; model->geometries = args.geometries;
model->num_geometries = args.geometries_count; model->num_geometries = args.geometries_count;
@ -701,44 +701,19 @@ static void uboComputeAndSetMVPFromModel( const matrix4x4 model ) {
Matrix4x4_ToArrayFloatGL(mvp, (float*)g_render_state.dirty_uniform_data.mvp); Matrix4x4_ToArrayFloatGL(mvp, (float*)g_render_state.dirty_uniform_data.mvp);
} }
void VK_RenderModelDraw( vk_render_model_t* model, int ent_index_prev_frame__toremove ) { static void submitToTraditionalRender( const vk_render_model_t *model, const matrix4x4 transform, const vec4_t color, int render_type ) {
int current_texture = -1; int current_texture = -1;
int element_count = 0; int element_count = 0;
int index_offset = -1; int index_offset = -1;
int vertex_offset = 0; int vertex_offset = 0;
uboComputeAndSetMVPFromModel( model->transform ); uboComputeAndSetMVPFromModel( transform );
// TODO get rid of this dirty ubo thing // TODO get rid of this dirty ubo thing
Vector4Copy(model->color, g_render_state.dirty_uniform_data.color); Vector4Copy(color, g_render_state.dirty_uniform_data.color);
ASSERT(model->lightmap <= MAX_LIGHTMAPS); ASSERT(model->lightmap <= MAX_LIGHTMAPS);
const int lightmap = model->lightmap > 0 ? tglob.lightmapTextures[model->lightmap - 1] : tglob.whiteTexture; const int lightmap = model->lightmap > 0 ? tglob.lightmapTextures[model->lightmap - 1] : tglob.whiteTexture;
++g_render.stats.models_count;
// TODO track prev transform directly as a member in vk_render_model_t
if (g_render_state.current_frame_is_ray_traced) {
if (ent_index_prev_frame__toremove >= 0 && model != NULL) {
R_PrevFrame_SaveCurrentState( ent_index_prev_frame__toremove, model->transform );
R_PrevFrame_ModelTransform( ent_index_prev_frame__toremove, model->prev_transform );
}
else {
Matrix4x4_Copy( model->prev_transform, model->transform );
}
if (model->rt_model) {
RT_FrameAddModel(model->rt_model, (rt_frame_add_model_t){
.render_type = model->render_type,
.transform = (const matrix3x4*)&model->transform,
.prev_transform = (const matrix3x4*)&model->prev_transform,
.color = &model->color,
});
} else
VK_RayFrameAddModel(model->ray_model, model);
return;
}
drawCmdPushDebugLabelBegin( model->debug_name ); drawCmdPushDebugLabelBegin( model->debug_name );
for (int i = 0; i < model->num_geometries; ++i) { for (int i = 0; i < model->num_geometries; ++i) {
@ -758,7 +733,7 @@ void VK_RenderModelDraw( vk_render_model_t* model, int ent_index_prev_frame__tor
render_draw_t draw = { render_draw_t draw = {
.lightmap = lightmap, .lightmap = lightmap,
.texture = current_texture, .texture = current_texture,
.pipeline_index = model->render_type, .pipeline_index = 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,
@ -782,7 +757,7 @@ void VK_RenderModelDraw( vk_render_model_t* model, int ent_index_prev_frame__tor
const render_draw_t draw = { const render_draw_t draw = {
.lightmap = lightmap, .lightmap = lightmap,
.texture = current_texture, .texture = current_texture,
.pipeline_index = model->render_type, .pipeline_index = 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,
@ -794,6 +769,51 @@ void VK_RenderModelDraw( vk_render_model_t* model, int ent_index_prev_frame__tor
drawCmdPushDebugLabelEnd(); drawCmdPushDebugLabelEnd();
} }
void VK_RenderModelDraw_old( vk_render_model_t* model, int ent_index_prev_frame__toremove ) {
++g_render.stats.models_count;
// TODO track prev transform directly as a member in vk_render_model_t
if (g_render_state.current_frame_is_ray_traced) {
if (ent_index_prev_frame__toremove >= 0 && model != NULL) {
R_PrevFrame_SaveCurrentState( ent_index_prev_frame__toremove, model->deprecate.transform );
R_PrevFrame_ModelTransform( ent_index_prev_frame__toremove, model->deprecate.prev_transform );
}
else {
Matrix4x4_Copy( model->deprecate.prev_transform, model->deprecate.transform );
}
if (model->rt_model) {
RT_FrameAddModel(model->rt_model, (rt_frame_add_model_t){
.render_type = model->deprecate.render_type,
.transform = (const matrix3x4*)&model->deprecate.transform,
.prev_transform = (const matrix3x4*)&model->deprecate.prev_transform,
.color = &model->deprecate.color,
});
} else
VK_RayFrameAddModel(model->ray_model, model);
return;
}
submitToTraditionalRender( model, model->deprecate.transform, model->deprecate.color, model->deprecate.render_type );
}
void R_RenderModelDraw(const vk_render_model_t *model, r_model_draw_t args) {
++g_render.stats.models_count;
if (g_render_state.current_frame_is_ray_traced) {
ASSERT(model->rt_model);
RT_FrameAddModel(model->rt_model, (rt_frame_add_model_t){
.render_type = args.render_type,
.transform = (const matrix3x4*)args.transform,
.prev_transform = (const matrix3x4*)args.prev_transform,
.color = args.color,
});
} else {
submitToTraditionalRender(model, *args.transform, *args.color, args.render_type);
}
}
#define MAX_DYNAMIC_GEOMETRY 256 #define MAX_DYNAMIC_GEOMETRY 256
static struct { static struct {
@ -811,9 +831,9 @@ void VK_RenderModelDynamicBegin( vk_render_type_e render_type, const vec4_t colo
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_type = render_type; g_dynamic_model.model.deprecate.render_type = render_type;
g_dynamic_model.model.lightmap = 0; g_dynamic_model.model.lightmap = 0;
Vector4Copy(color, g_dynamic_model.model.color); Vector4Copy(color, g_dynamic_model.model.deprecate.color);
Matrix4x4_LoadIdentity(g_dynamic_model.transform); Matrix4x4_LoadIdentity(g_dynamic_model.transform);
if (transform) if (transform)
Matrix3x4_Copy(g_dynamic_model.transform, transform); Matrix3x4_Copy(g_dynamic_model.transform, transform);
@ -834,8 +854,8 @@ void VK_RenderModelDynamicCommit( void ) {
g_render.stats.dynamic_model_count++; g_render.stats.dynamic_model_count++;
g_dynamic_model.model.dynamic = true; g_dynamic_model.model.dynamic = true;
VK_RenderModelInit_old( &g_dynamic_model.model ); VK_RenderModelInit_old( &g_dynamic_model.model );
Matrix4x4_Copy(g_dynamic_model.model.transform, g_dynamic_model.transform); Matrix4x4_Copy(g_dynamic_model.model.deprecate.transform, g_dynamic_model.transform);
VK_RenderModelDraw( &g_dynamic_model.model, -1 ); VK_RenderModelDraw_old( &g_dynamic_model.model, -1 );
} }
g_dynamic_model.model.debug_name[0] = '\0'; g_dynamic_model.model.debug_name[0] = '\0';

View File

@ -104,19 +104,13 @@ typedef struct vk_render_model_s {
#define MAX_MODEL_NAME_LENGTH 64 #define MAX_MODEL_NAME_LENGTH 64
char debug_name[MAX_MODEL_NAME_LENGTH]; char debug_name[MAX_MODEL_NAME_LENGTH];
// TODO these two are dynamic, extract them to draw args?
vk_render_type_e render_type;
vec4_t color;
// TODO per-geometry? // TODO per-geometry?
int lightmap; // <= 0 if no lightmap int lightmap; // <= 0 if no lightmap
int num_geometries; int num_geometries;
vk_render_geometry_t *geometries; vk_render_geometry_t *geometries;
// TODO potentially dynamic. extract to draw args? struct rt_model_s *rt_model;
int geometries_changed_count;
int *geometries_changed;
// This model will be one-frame only, its buffers are not preserved between frames // This model will be one-frame only, its buffers are not preserved between frames
// TODO deprecate // TODO deprecate
@ -132,12 +126,16 @@ typedef struct vk_render_model_s {
struct rt_light_add_polygon_s *dynamic_polylights; struct rt_light_add_polygon_s *dynamic_polylights;
int dynamic_polylights_count; int dynamic_polylights_count;
matrix4x4 transform; struct {
// TODO these two are dynamic, extract them to draw args?
vk_render_type_e render_type;
vec4_t color;
matrix4x4 transform;
// previous frame ObjectToWorld (model) matrix
matrix4x4 prev_transform;
// previous frame ObjectToWorld (model) matrix // TODO potentially dynamic. extract to draw args?
matrix4x4 prev_transform; } deprecate;
struct rt_model_s *rt_model;
} vk_render_model_t; } vk_render_model_t;
qboolean VK_RenderModelInit_old( vk_render_model_t* model ); qboolean VK_RenderModelInit_old( vk_render_model_t* model );
@ -151,7 +149,21 @@ typedef struct {
qboolean VK_RenderModelCreate( vk_render_model_t *model, vk_render_model_init_t args ); qboolean VK_RenderModelCreate( vk_render_model_t *model, vk_render_model_init_t args );
void VK_RenderModelDestroy( vk_render_model_t* model ); void VK_RenderModelDestroy( vk_render_model_t* model );
void VK_RenderModelDraw( vk_render_model_t* model, int ent_index_prev_frame__toremove ); void VK_RenderModelDraw_old( vk_render_model_t* model, int ent_index_prev_frame__toremove );
typedef struct {
vk_render_type_e render_type;
// These are "consumed": copied into internal storage and can be pointers to stack vars
const vec4_t *color;
const matrix4x4 *transform, *prev_transform;
// These are expected to be alive and valid until frame end at least
int geometries_changed_count;
int *geometries_changed;
} r_model_draw_t;
void R_RenderModelDraw(const vk_render_model_t *model, r_model_draw_t args);
// TODO Begin and commit should be removed // TODO Begin and commit should be removed
void VK_RenderModelDynamicBegin( vk_render_type_e render_type, const vec4_t color, const matrix3x4 transform, const char *debug_name_fmt, ... ); void VK_RenderModelDynamicBegin( vk_render_type_e render_type, const vec4_t color, const matrix3x4 transform, const char *debug_name_fmt, ... );

View File

@ -5,6 +5,7 @@
#include "vk_geometry.h" #include "vk_geometry.h"
#include "vk_scene.h" #include "vk_scene.h"
#include "r_speeds.h" #include "r_speeds.h"
#include "vk_math.h"
#include "sprite.h" #include "sprite.h"
#include "xash3d_mathlib.h" #include "xash3d_mathlib.h"
@ -22,11 +23,108 @@ static struct {
struct { struct {
int sprites; int sprites;
} stats; } stats;
struct {
r_geometry_range_t geom;
vk_render_geometry_t geometry;
vk_render_model_t model;
} quad;
} g_sprite; } g_sprite;
static qboolean createQuadModel(void) {
g_sprite.quad.geom = R_GeometryRangeAlloc(4, 6);
if (g_sprite.quad.geom.block_handle.size == 0) {
gEngine.Con_Printf(S_ERROR "Cannot allocate geometry for sprite quad\n");
return false;
}
const r_geometry_range_lock_t lock = R_GeometryRangeLock(&g_sprite.quad.geom);
vec3_t point;
vk_vertex_t *dst_vtx;
uint16_t *dst_idx;
dst_vtx = lock.vertices;
dst_idx = lock.indices;
const vec3_t org = {0, 0, 0};
const vec3_t v_right = {1, 0, 0};
const vec3_t v_up = {0, 1, 0};
vec3_t v_normal;
CrossProduct(v_right, v_up, v_normal);
VectorMA( org, -1.f, v_up, point );
VectorMA( point, -1.f, 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;
Vector4Set(dst_vtx[0].color, 255, 255, 255, 255);
VectorCopy(v_normal, dst_vtx[0].normal);
VectorMA( org, 1.f, v_up, point );
VectorMA( point, -1.f, 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;
Vector4Set(dst_vtx[1].color, 255, 255, 255, 255);
VectorCopy(v_normal, dst_vtx[1].normal);
VectorMA( org, 1.f, v_up, point );
VectorMA( point, 1.f, 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;
Vector4Set(dst_vtx[2].color, 255, 255, 255, 255);
VectorCopy(v_normal, dst_vtx[2].normal);
VectorMA( org, -1.f, v_up, point );
VectorMA( point, 1.f, 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;
Vector4Set(dst_vtx[3].color, 255, 255, 255, 255);
VectorCopy(v_normal, dst_vtx[3].normal);
dst_idx[0] = 0;
dst_idx[1] = 1;
dst_idx[2] = 2;
dst_idx[3] = 0;
dst_idx[4] = 2;
dst_idx[5] = 3;
R_GeometryRangeUnlock( &lock );
g_sprite.quad.geometry = (vk_render_geometry_t){
.max_vertex = 4,
.vertex_offset = g_sprite.quad.geom.vertices.unit_offset,
.element_count = 6,
.index_offset = g_sprite.quad.geom.indices.unit_offset,
.material = kXVkMaterialRegular,
.texture = tglob.defaultTexture,
.emissive = {1,1,1},
};
return VK_RenderModelCreate(&g_sprite.quad.model, (vk_render_model_init_t){
.name = "sprite",
.geometries = &g_sprite.quad.geometry,
.geometries_count = 1,
});
}
qboolean R_SpriteInit(void) { qboolean R_SpriteInit(void) {
R_SpeedsRegisterMetric(&g_sprite.stats.sprites, "sprites_count", kSpeedsMetricCount); R_SpeedsRegisterMetric(&g_sprite.stats.sprites, "sprites_count", kSpeedsMetricCount);
return true;
return createQuadModel();
}
void R_SpriteShutdown(void) {
if (g_sprite.quad.model.num_geometries)
VK_RenderModelDestroy(&g_sprite.quad.model);
if (g_sprite.quad.geom.block_handle.size)
R_GeometryRangeFree(&g_sprite.quad.geom);
} }
static mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw ) static mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw )
@ -672,81 +770,52 @@ static vk_render_type_e spriteRenderModeToRenderType( int render_mode ) {
} }
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 ) { 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_GeometryBufferAllocOnceAndLock( &buffer, 4, 6)) {
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;
vec3_t v_normal; vec3_t v_normal;
CrossProduct(v_right, v_up, v_normal); vec3_t point;
//CrossProduct(v_right, v_up, v_normal);
VectorMA( org, frame->down * scale, v_up, point ); matrix4x4 transform;
VectorMA( point, frame->left * scale, v_right, dst_vtx[0].pos ); // FIXME orient sprites
dst_vtx[0].gl_tc[0] = 0.f; //VectorMA( org, frame->down * scale, v_up, point );
dst_vtx[0].gl_tc[1] = 1.f; //VectorMA( point, frame->left * scale, v_right, dst_vtx[0].pos );
dst_vtx[0].lm_tc[0] = dst_vtx[0].lm_tc[1] = 0.f; //vtx[0] = org + down * scale + v_up + left * scale * v_right;
Vector4Set(dst_vtx[0].color, 255, 255, 255, 255); Matrix4x4_CreateScale(transform, scale);
VectorCopy(v_normal, dst_vtx[0].normal); Matrix4x4_SetOrigin(transform, org[0], org[1], org[2]);
const vk_render_type_e render_type = spriteRenderModeToRenderType(render_mode);
VectorMA( org, frame->up * scale, v_up, point ); R_RenderModelDraw(&g_sprite.quad.model, (r_model_draw_t){
VectorMA( point, frame->left * scale, v_right, dst_vtx[1].pos ); .render_type = render_type,
dst_vtx[1].gl_tc[0] = 0.f; .color = (const vec4_t*)&color,
dst_vtx[1].gl_tc[1] = 0.f; //.color = (const vec4_t*)color,
dst_vtx[1].lm_tc[0] = dst_vtx[1].lm_tc[1] = 0.f; .transform = &transform,
Vector4Set(dst_vtx[1].color, 255, 255, 255, 255); .prev_transform = &transform,
VectorCopy(v_normal, dst_vtx[1].normal);
VectorMA( org, frame->up * scale, v_up, point ); .geometries_changed = NULL,
VectorMA( point, frame->right * scale, v_right, dst_vtx[2].pos ); .geometries_changed_count = 0,
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;
Vector4Set(dst_vtx[2].color, 255, 255, 255, 255);
VectorCopy(v_normal, dst_vtx[2].normal);
VectorMA( org, frame->down * scale, v_up, point ); #if 0
VectorMA( point, frame->right * scale, v_right, dst_vtx[3].pos ); typedef struct {
dst_vtx[3].gl_tc[0] = 1.f; const char *debug_name;
dst_vtx[3].gl_tc[1] = 1.f; const vk_render_model_t *model;
dst_vtx[3].lm_tc[0] = dst_vtx[3].lm_tc[1] = 0.f; const matrix4x4 *transform;
Vector4Set(dst_vtx[3].color, 255, 255, 255, 255); const vec4_t *color;
VectorCopy(v_normal, dst_vtx[3].normal); vk_render_type_e render_type;
//TODO int material_mode;
int texture;
} vk_render_model_draw_instance_t;
dst_idx[0] = 0; const vk_render_model_draw_instance_t args = {
dst_idx[1] = 1; .debug_name = debug_name,
dst_idx[2] = 2; .model = g_sprite.quad_model,
dst_idx[3] = 0; .transform = &transform,
dst_idx[4] = 2; .color = &color,
dst_idx[5] = 3; .render_type = render_type,
.texture = texture,
};
R_GeometryBufferUnlock( &buffer ); VK_RenderModelInstanced(&args);
#endif
{
const vk_render_geometry_t geometry = {
.texture = texture,
.material = kXVkMaterialRegular,
.max_vertex = 4,
.vertex_offset = buffer.vertices.unit_offset,
.element_count = 6,
.index_offset = buffer.indices.unit_offset,
.emissive = {1,1,1},
};
VK_RenderModelDynamicBegin( spriteRenderModeToRenderType(render_mode), color, m_matrix4x4_identity, "%s", debug_name );
VK_RenderModelDynamicAddGeometry( &geometry );
VK_RenderModelDynamicCommit();
}
} }
static qboolean R_SpriteHasLightmap( cl_entity_t *e, int texFormat ) static qboolean R_SpriteHasLightmap( cl_entity_t *e, int texFormat )

View File

@ -10,3 +10,4 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
void R_VkSpriteDrawModel( cl_entity_t *e, float blend ); void R_VkSpriteDrawModel( cl_entity_t *e, float blend );
qboolean R_SpriteInit(void); qboolean R_SpriteInit(void);
void R_SpriteShutdown(void);