parent
e522acf8b3
commit
9e8ca13dcc
|
@ -1,5 +1,11 @@
|
|||
## 2021-04-24, E86
|
||||
- [x] rtx: restore studio models
|
||||
|
||||
# Next
|
||||
- [ ] rtx: restore studio models
|
||||
- [ ] rtx: dynamic models AS caching
|
||||
- [ ] rtx: better memory handling
|
||||
- [ ] robust tracking of memory hierarchies: global/static, map, frame
|
||||
- or just do a generic allocator with compaction?
|
||||
- [ ] rtx: dynamic surface lights / dynamic light clusters
|
||||
- [ ] rtx: better light culling: normal, bsp visibility, light volumes and intensity, ...
|
||||
- [ ] rtx: live rad file reloading (or other solution for tuning lights)
|
||||
|
@ -18,6 +24,8 @@
|
|||
struct LightCluster { uint16 offset, length; }
|
||||
uint8_t data[];
|
||||
- [ ] rtx: alpha test/blending
|
||||
- [ ] make a wrapper for descriptor sets/layouts
|
||||
- [ ] rtx: coalesce all these buffers
|
||||
|
||||
# Planned
|
||||
- [ ] rtx: denoise
|
||||
|
@ -26,7 +34,7 @@
|
|||
- [ ] SVG+
|
||||
- [ ] ...
|
||||
- [ ] rtx: add fps: rasterize into G-buffer, and only then compute lighting with rtx
|
||||
- [ ] bake light visibility in compute shader
|
||||
- [ ] rtx: bake light visibility in compute shader
|
||||
- [ ] rtx: cull light sources (dlights and light textures) using bsp
|
||||
- [ ] enable entity-parsed lights by lightstyles
|
||||
- [ ] dlight for flashlight seems to be broken
|
||||
|
|
|
@ -28,8 +28,8 @@ typedef struct vertex_2d_s {
|
|||
} vertex_2d_t;
|
||||
|
||||
// TODO should these be dynamic?
|
||||
#define MAX_PICS 8192
|
||||
#define MAX_BATCHES 128
|
||||
#define MAX_PICS 16384
|
||||
#define MAX_BATCHES 256
|
||||
|
||||
static struct {
|
||||
VkPipelineLayout pipeline_layout;
|
||||
|
|
|
@ -384,19 +384,20 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f
|
|||
VK_RenderBufferUnlock( vertex_buffer );
|
||||
|
||||
{
|
||||
const render_draw_t draw = {
|
||||
.lightmap = tglob.whiteTexture,
|
||||
.texture = texture,
|
||||
.render_mode = render_mode,
|
||||
.element_count = total_indices,
|
||||
.vertex_offset = 0,
|
||||
.index_offset = 0,
|
||||
.vertex_buffer = vertex_buffer,
|
||||
.index_buffer = index_buffer,
|
||||
.emissive = { color[0], color[1], color[2] },
|
||||
};
|
||||
// TODO
|
||||
// const render_draw_t draw = {
|
||||
// .lightmap = tglob.whiteTexture,
|
||||
// .texture = texture,
|
||||
// .render_mode = render_mode,
|
||||
// .element_count = total_indices,
|
||||
// .vertex_offset = 0,
|
||||
// .index_offset = 0,
|
||||
// .vertex_buffer = vertex_buffer,
|
||||
// .index_buffer = index_buffer,
|
||||
// .emissive = { color[0], color[1], color[2] },
|
||||
// };
|
||||
|
||||
VK_RenderScheduleDraw( &draw );
|
||||
// VK_RenderScheduleDraw( &draw );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -248,6 +248,8 @@ static qboolean loadBrushSurfaces( model_sizes_t sizes, const model_t *mod ) {
|
|||
model_geometry->texture = t;
|
||||
model_geometry->vertex_count = surf->numedges;
|
||||
model_geometry->surface_index = i;
|
||||
model_geometry->vertex_buffer = vertex_buffer;
|
||||
model_geometry->index_buffer = index_buffer;
|
||||
|
||||
VK_CreateSurfaceLightmap( surf, mod );
|
||||
|
||||
|
@ -311,8 +313,6 @@ static qboolean loadBrushSurfaces( model_sizes_t sizes, const model_t *mod ) {
|
|||
|
||||
ASSERT(sizes.num_surfaces == num_surfaces);
|
||||
bmodel->render_model.num_geometries = num_surfaces;
|
||||
bmodel->render_model.index_buffer = index_buffer;
|
||||
bmodel->render_model.vertex_buffer = vertex_buffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
|
||||
#define PRINT_NOT_IMPLEMENTED_ARGS(msg, ...) do { \
|
||||
static int called = 0; \
|
||||
gEngine.Con_Printf( S_ERROR "VK NOT_IMPLEMENTED(x%d): %s " msg "\n", called, __FUNCTION__, __VA_ARGS__ ); \
|
||||
if ((called&1023) == 0) { \
|
||||
gEngine.Con_Printf( S_ERROR "VK NOT_IMPLEMENTED(x%d): %s " msg "\n", called, __FUNCTION__, __VA_ARGS__ ); \
|
||||
} \
|
||||
++called; \
|
||||
} while(0)
|
||||
|
||||
|
|
|
@ -399,6 +399,12 @@ void VK_RenderBufferUnlock( vk_buffer_handle_t handle )
|
|||
// TODO upload from staging to gpumem
|
||||
}
|
||||
|
||||
uint32_t VK_RenderBufferGetOffsetInUnits( vk_buffer_handle_t handle )
|
||||
{
|
||||
const vk_buffer_alloc_t *alloc = getBufferFromHandle( handle );
|
||||
return alloc->buffer_offset_in_units;
|
||||
}
|
||||
|
||||
// Free all LifetimeSingleFrame resources
|
||||
void VK_RenderBufferClearFrame( void )
|
||||
{
|
||||
|
@ -439,6 +445,15 @@ void VK_RenderBufferPrintStats( void )
|
|||
#define MAX_DRAW_COMMANDS 8192 // TODO estimate
|
||||
#define MAX_DEBUG_NAME_LENGTH 32
|
||||
|
||||
typedef struct render_draw_s {
|
||||
int lightmap, texture;
|
||||
int render_mode;
|
||||
uint32_t element_count;
|
||||
uint32_t index_offset, vertex_offset;
|
||||
vk_buffer_handle_t index_buffer, vertex_buffer;
|
||||
/* TODO this should be a separate thing? */ struct { float r, g, b; } emissive;
|
||||
} render_draw_t;
|
||||
|
||||
typedef struct {
|
||||
render_draw_t draw;
|
||||
uint32_t ubo_offset;
|
||||
|
@ -543,7 +558,7 @@ static uint32_t allocUniform( uint32_t size, uint32_t alignment ) {
|
|||
return offset;
|
||||
}
|
||||
|
||||
void VK_RenderScheduleDraw( const render_draw_t *draw )
|
||||
static void VK_RenderScheduleDraw( const render_draw_t *draw )
|
||||
{
|
||||
const vk_buffer_alloc_t *vertex_buffer = NULL, *index_buffer = NULL;
|
||||
draw_command_t *draw_command;
|
||||
|
@ -831,15 +846,11 @@ void VK_RenderEndRTX( VkCommandBuffer cmdbuf, VkImageView img_dst_view, VkImage
|
|||
}
|
||||
}
|
||||
|
||||
qboolean VK_RenderModelInit( vk_render_model_t *model) {
|
||||
qboolean VK_RenderModelInit( vk_render_model_t *model ) {
|
||||
if (vk_core.rtx) {
|
||||
// TODO runtime rtx switch: ???
|
||||
const vk_buffer_alloc_t *vertex_buffer = getBufferFromHandle( model->vertex_buffer );
|
||||
const vk_buffer_alloc_t *index_buffer = model->index_buffer != InvalidHandle ? getBufferFromHandle( model->index_buffer ) : NULL;
|
||||
const vk_ray_model_init_t args = {
|
||||
.buffer = g_render.buffer.buffer,
|
||||
.index_offset = index_buffer ? index_buffer->buffer_offset_in_units : UINT32_MAX,
|
||||
.vertex_offset = vertex_buffer->buffer_offset_in_units,
|
||||
.model = model,
|
||||
};
|
||||
model->rtx.blas = VK_NULL_HANDLE;
|
||||
|
@ -865,13 +876,15 @@ void VK_RenderModelDraw( vk_render_model_t* model ) {
|
|||
int current_texture = -1;
|
||||
int index_count = 0;
|
||||
int index_offset = -1;
|
||||
vk_buffer_handle_t vertex_buffer = InvalidHandle;
|
||||
vk_buffer_handle_t index_buffer = InvalidHandle;
|
||||
|
||||
for (int i = 0; i < model->num_geometries; ++i) {
|
||||
const vk_render_geometry_t *geom = model->geometries + i;
|
||||
if (geom->texture < 0)
|
||||
continue;
|
||||
|
||||
if (current_texture != geom->texture)
|
||||
if (current_texture != geom->texture || vertex_buffer != geom->vertex_buffer || index_buffer != geom->index_buffer)
|
||||
{
|
||||
if (index_count) {
|
||||
const render_draw_t draw = {
|
||||
|
@ -879,8 +892,8 @@ void VK_RenderModelDraw( vk_render_model_t* model ) {
|
|||
.texture = current_texture,
|
||||
.render_mode = model->render_mode,
|
||||
.element_count = index_count,
|
||||
.vertex_buffer = model->vertex_buffer,
|
||||
.index_buffer = model->index_buffer,
|
||||
.vertex_buffer = vertex_buffer,
|
||||
.index_buffer = index_buffer,
|
||||
.vertex_offset = 0,
|
||||
.index_offset = index_offset,
|
||||
};
|
||||
|
@ -889,6 +902,8 @@ void VK_RenderModelDraw( vk_render_model_t* model ) {
|
|||
}
|
||||
|
||||
current_texture = geom->texture;
|
||||
vertex_buffer = geom->vertex_buffer;
|
||||
index_buffer = geom->index_buffer;
|
||||
index_count = 0;
|
||||
index_offset = -1;
|
||||
}
|
||||
|
@ -906,8 +921,8 @@ void VK_RenderModelDraw( vk_render_model_t* model ) {
|
|||
.texture = current_texture,
|
||||
.render_mode = model->render_mode,
|
||||
.element_count = index_count,
|
||||
.vertex_buffer = model->vertex_buffer,
|
||||
.index_buffer = model->index_buffer,
|
||||
.vertex_buffer = vertex_buffer,
|
||||
.index_buffer = index_buffer,
|
||||
.vertex_offset = 0,
|
||||
.index_offset = index_offset,
|
||||
};
|
||||
|
@ -915,3 +930,40 @@ void VK_RenderModelDraw( vk_render_model_t* model ) {
|
|||
VK_RenderScheduleDraw( &draw );
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_DYNAMIC_GEOMETRY 256
|
||||
|
||||
static struct {
|
||||
vk_render_model_t model;
|
||||
vk_render_geometry_t geometries[MAX_DYNAMIC_GEOMETRY];
|
||||
} g_dynamic_model = {0};
|
||||
|
||||
void VK_RenderModelDynamicBegin( const char *debug_name, int render_mode ) {
|
||||
ASSERT(!g_dynamic_model.model.geometries);
|
||||
g_dynamic_model.model.debug_name = debug_name;
|
||||
g_dynamic_model.model.geometries = g_dynamic_model.geometries;
|
||||
g_dynamic_model.model.num_geometries = 0;
|
||||
g_dynamic_model.model.render_mode = render_mode;
|
||||
memset(&g_dynamic_model.model.rtx, 0, sizeof(g_dynamic_model.model.rtx));
|
||||
}
|
||||
void VK_RenderModelDynamicAddGeometry( const vk_render_geometry_t *geom ) {
|
||||
ASSERT(g_dynamic_model.model.geometries);
|
||||
if (g_dynamic_model.model.num_geometries == MAX_DYNAMIC_GEOMETRY) {
|
||||
gEngine.Con_Printf(S_ERROR "Ran out of dynamic model geometry slots for model %s\n", g_dynamic_model.model.debug_name);
|
||||
return;
|
||||
}
|
||||
|
||||
g_dynamic_model.geometries[g_dynamic_model.model.num_geometries++] = *geom;
|
||||
}
|
||||
void VK_RenderModelDynamicCommit( void ) {
|
||||
ASSERT(g_dynamic_model.model.geometries);
|
||||
|
||||
if (g_dynamic_model.model.num_geometries > 0) {
|
||||
g_dynamic_model.model.dynamic = true;
|
||||
VK_RenderModelInit( &g_dynamic_model.model );
|
||||
VK_RenderModelDraw( &g_dynamic_model );
|
||||
}
|
||||
|
||||
g_dynamic_model.model.debug_name = NULL;
|
||||
g_dynamic_model.model.geometries = NULL;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ typedef enum {
|
|||
vk_buffer_handle_t VK_RenderBufferAlloc( uint32_t unit_size, uint32_t count, vk_lifetime_t lifetime );
|
||||
vk_buffer_lock_t VK_RenderBufferLock( vk_buffer_handle_t handle );
|
||||
void VK_RenderBufferUnlock( vk_buffer_handle_t handle );
|
||||
uint32_t VK_RenderBufferGetOffsetInUnits( vk_buffer_handle_t handle );
|
||||
|
||||
// TODO buffer refcount when doing RTX AS updates? need to store buffer handles somewhere between frames
|
||||
|
||||
|
@ -60,22 +61,20 @@ typedef struct vk_vertex_s {
|
|||
vec2_t lm_tc; //float p3_[2];
|
||||
} vk_vertex_t;
|
||||
|
||||
typedef struct render_draw_s {
|
||||
int lightmap, texture;
|
||||
int render_mode;
|
||||
uint32_t element_count;
|
||||
uint32_t index_offset, vertex_offset;
|
||||
vk_buffer_handle_t index_buffer, vertex_buffer;
|
||||
/* TODO this should be a separate thing? */ struct { float r, g, b; } emissive;
|
||||
} render_draw_t;
|
||||
|
||||
typedef struct {
|
||||
int texture;
|
||||
uint32_t element_count;
|
||||
vk_buffer_handle_t index_buffer, vertex_buffer;
|
||||
uint32_t index_offset, vertex_offset;
|
||||
|
||||
// TODO can be dynamic
|
||||
int texture;
|
||||
|
||||
uint32_t element_count;
|
||||
uint32_t vertex_count;
|
||||
|
||||
// TODO we don't really need this here
|
||||
// as it's used to tie emissive surfaces to geometry in RTX renderer
|
||||
// we can and should infer this dynamically (from texture) when building dynamic light clusters
|
||||
int surface_index;
|
||||
// TODO potentially dynamic int light_cluster;
|
||||
} vk_render_geometry_t;
|
||||
|
||||
typedef struct vk_render_model_s {
|
||||
|
@ -84,11 +83,10 @@ typedef struct vk_render_model_s {
|
|||
int num_geometries;
|
||||
vk_render_geometry_t *geometries;
|
||||
|
||||
// Common for the entire model
|
||||
vk_buffer_handle_t index_buffer, vertex_buffer;
|
||||
|
||||
// TODO potentially dynamic data: textures
|
||||
//qboolean dynamic; // whether this model will require data reupload
|
||||
|
||||
// This model will be one-frame only, its buffers are not preserved between frames
|
||||
qboolean dynamic;
|
||||
|
||||
struct {
|
||||
VkAccelerationStructureKHR blas;
|
||||
|
@ -102,12 +100,12 @@ void VK_RenderModelDraw( vk_render_model_t* model );
|
|||
|
||||
void VK_RenderFrameBegin( void );
|
||||
|
||||
// void VK_RenderObjectBegin( void *tag, const char *name /* expect transient ... */ );
|
||||
// void VK_RenderObjectEnd();
|
||||
void VK_RenderModelDynamicBegin( const char *debug_name, int render_mode );
|
||||
void VK_RenderModelDynamicAddGeometry( const vk_render_geometry_t *geom );
|
||||
void VK_RenderModelDynamicCommit( void );
|
||||
|
||||
void VK_RenderScheduleDraw( const render_draw_t *draw );
|
||||
void VK_RenderFrameEnd( VkCommandBuffer cmdbuf );
|
||||
void VK_RenderFrameEndRTX( VkCommandBuffer cmdbuf, VkImageView img_dst_view, VkImage img_dst, uint32_t w, uint32_t h );
|
||||
|
||||
void VK_RenderDebugLabelBegin( const char *label );
|
||||
void VK_RenderDebugLabelEnd( void );
|
||||
// void VK_RenderDebugLabelBegin( const char *label );
|
||||
// void VK_RenderDebugLabelEnd( void );
|
||||
|
|
|
@ -62,6 +62,7 @@ typedef struct {
|
|||
matrix3x4 transform_row;
|
||||
VkAccelerationStructureKHR accel;
|
||||
uint32_t kusochki_offset;
|
||||
qboolean dynamic;
|
||||
} vk_ray_model_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -108,6 +109,10 @@ static struct {
|
|||
int num_lighttextures;
|
||||
vk_ray_model_t models[MAX_ACCELS];
|
||||
uint32_t scratch_offset; // for building dynamic blases
|
||||
|
||||
// for dynamic models
|
||||
uint32_t buffer_offset_at_frame_begin;
|
||||
int num_kusochki_at_frame_begin;
|
||||
} frame;
|
||||
|
||||
unsigned frame_number;
|
||||
|
@ -243,9 +248,30 @@ void VK_RayFrameBegin( void )
|
|||
{
|
||||
ASSERT(vk_core.rtx);
|
||||
|
||||
// FIXME we depend on the fact that only a single frame can be in flight
|
||||
// currently framectl waits for the queue to complete before returning
|
||||
// so we can be sure here that previous frame is complete and we're free to
|
||||
// destroy/reuse dynamic ASes from previous frame
|
||||
for (int i = 0; i < g_rtx.frame.num_models; ++i) {
|
||||
vk_ray_model_t *model = g_rtx.frame.models + i;
|
||||
if (!model->dynamic)
|
||||
continue;
|
||||
|
||||
// TODO cache and reuse
|
||||
for (int j = 0; j < ARRAYSIZE(g_rtx.blases); ++j) {
|
||||
if (g_rtx.blases[j] == model->accel) {
|
||||
vkDestroyAccelerationStructureKHR(vk_core.device, g_rtx.blases[j], NULL);
|
||||
g_rtx.blases[j] = VK_NULL_HANDLE;
|
||||
model->accel = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_rtx.frame.scratch_offset = 0;
|
||||
g_rtx.frame.num_models = 0;
|
||||
g_rtx.frame.num_lighttextures = 0;
|
||||
g_rtx.frame.buffer_offset_at_frame_begin = g_rtx.map.buffer_offset;
|
||||
g_rtx.frame.num_kusochki_at_frame_begin = g_rtx.map.num_kusochki;
|
||||
}
|
||||
|
||||
void VK_RayFrameAddModelDynamic( VkCommandBuffer cmdbuf, const vk_ray_model_dynamic_t *dynamic)
|
||||
|
@ -703,6 +729,10 @@ void VK_RayFrameEnd(const vk_ray_frame_render_args_t* args)
|
|||
args->dst.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion,
|
||||
VK_FILTER_NEAREST);
|
||||
}
|
||||
|
||||
// Restore dynamic buffer offset
|
||||
g_rtx.map.buffer_offset = g_rtx.frame.buffer_offset_at_frame_begin;
|
||||
g_rtx.map.num_kusochki = g_rtx.frame.num_kusochki_at_frame_begin;
|
||||
}
|
||||
|
||||
static void createLayouts( void ) {
|
||||
|
@ -965,8 +995,8 @@ qboolean VK_RayModelInit( vk_ray_model_init_t args ) {
|
|||
ASSERT(vk_core.rtx);
|
||||
ASSERT(g_rtx.map.num_kusochki <= MAX_KUSOCHKI);
|
||||
|
||||
if (g_rtx.map.num_kusochki == MAX_KUSOCHKI) {
|
||||
gEngine.Con_Printf(S_ERROR "Maximum number of kusochki exceeded\n");
|
||||
if (g_rtx.map.num_kusochki + args.model->num_geometries > MAX_KUSOCHKI) {
|
||||
gEngine.Con_Printf(S_ERROR "Maximum number of kusochki exceeded on model %s\n", args.model->debug_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -981,8 +1011,8 @@ qboolean VK_RayModelInit( vk_ray_model_init_t args ) {
|
|||
for (int i = 0; i < args.model->num_geometries; ++i) {
|
||||
const vk_render_geometry_t *mg = args.model->geometries + i;
|
||||
const uint32_t prim_count = mg->element_count / 3;
|
||||
const uint32_t vertex_offset = args.vertex_offset + mg->vertex_offset;
|
||||
const uint32_t index_offset = args.index_offset + mg->index_offset;
|
||||
const uint32_t vertex_offset = mg->vertex_offset + VK_RenderBufferGetOffsetInUnits(mg->vertex_buffer);
|
||||
const uint32_t index_offset = mg->index_buffer == InvalidHandle ? UINT32_MAX : (mg->index_offset + VK_RenderBufferGetOffsetInUnits(mg->index_buffer));
|
||||
const qboolean is_emissive = ((mg->texture >= 0 && mg->texture < MAX_TEXTURES)
|
||||
? g_emissive_texture_table[mg->texture].set
|
||||
: false);
|
||||
|
@ -996,7 +1026,7 @@ qboolean VK_RayModelInit( vk_ray_model_init_t args ) {
|
|||
.geometry.triangles =
|
||||
(VkAccelerationStructureGeometryTrianglesDataKHR){
|
||||
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR,
|
||||
.indexType = args.index_offset == UINT32_MAX ? VK_INDEX_TYPE_NONE_KHR : VK_INDEX_TYPE_UINT16,
|
||||
.indexType = mg->index_buffer == InvalidHandle ? VK_INDEX_TYPE_NONE_KHR : VK_INDEX_TYPE_UINT16,
|
||||
.maxVertex = mg->vertex_count,
|
||||
.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT,
|
||||
.vertexStride = sizeof(vk_vertex_t),
|
||||
|
@ -1122,6 +1152,7 @@ void VK_RayFrameAddModel( const struct vk_render_model_s *model, const matrix3x4
|
|||
ASSERT(model->rtx.blas != VK_NULL_HANDLE);
|
||||
ray_model->accel = model->rtx.blas;
|
||||
ray_model->kusochki_offset = model->rtx.kusochki_offset;
|
||||
ray_model->dynamic = model->dynamic;
|
||||
memcpy(ray_model->transform_row, *transform_row, sizeof(ray_model->transform_row));
|
||||
g_rtx.frame.num_models++;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ struct vk_render_model_s;
|
|||
typedef struct {
|
||||
struct vk_render_model_s *model;
|
||||
VkBuffer buffer;
|
||||
uint32_t vertex_offset, index_offset;
|
||||
} vk_ray_model_init_t;
|
||||
|
||||
qboolean VK_RayModelInit( vk_ray_model_init_t model_init);
|
||||
|
|
|
@ -706,18 +706,19 @@ static void R_DrawSpriteQuad( mspriteframe_t *frame, vec3_t org, vec3_t v_right,
|
|||
VK_RenderBufferUnlock( vertex_buffer );
|
||||
|
||||
{
|
||||
const render_draw_t draw = {
|
||||
.lightmap = tglob.whiteTexture,
|
||||
.texture = texture,
|
||||
.render_mode = render_mode,
|
||||
.element_count = 6,
|
||||
.vertex_offset = 0,
|
||||
.index_offset = 0,
|
||||
.vertex_buffer = vertex_buffer,
|
||||
.index_buffer = index_buffer,
|
||||
};
|
||||
// TODO
|
||||
// const render_draw_t draw = {
|
||||
// .lightmap = tglob.whiteTexture,
|
||||
// .texture = texture,
|
||||
// .render_mode = render_mode,
|
||||
// .element_count = 6,
|
||||
// .vertex_offset = 0,
|
||||
// .index_offset = 0,
|
||||
// .vertex_buffer = vertex_buffer,
|
||||
// .index_buffer = index_buffer,
|
||||
// };
|
||||
|
||||
VK_RenderScheduleDraw( &draw );
|
||||
// VK_RenderScheduleDraw( &draw );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -940,7 +941,7 @@ 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];
|
||||
|
|
|
@ -600,16 +600,16 @@ float R_StudioEstimateFrame( cl_entity_t *e, mstudioseqdesc_t *pseqdesc )
|
|||
|
||||
if( pseqdesc->numframes <= 1 ) f = 0.0;
|
||||
else f = (e->curstate.frame * (pseqdesc->numframes - 1)) / 256.0f;
|
||||
|
||||
|
||||
f += dfdt;
|
||||
|
||||
if( pseqdesc->flags & STUDIO_LOOPING )
|
||||
if( pseqdesc->flags & STUDIO_LOOPING )
|
||||
{
|
||||
if( pseqdesc->numframes > 1 )
|
||||
f -= (int)(f / (pseqdesc->numframes - 1)) * (pseqdesc->numframes - 1);
|
||||
if( f < 0 ) f += (pseqdesc->numframes - 1);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
if( f >= pseqdesc->numframes - 1.001 )
|
||||
f = pseqdesc->numframes - 1.001;
|
||||
|
@ -719,7 +719,7 @@ StudioCalcBoneAdj
|
|||
void R_StudioCalcBoneAdj( float dadt, float *adj, const byte *pcontroller1, const byte *pcontroller2, byte mouthopen )
|
||||
{
|
||||
mstudiobonecontroller_t *pbonecontroller;
|
||||
float value = 0.0f;
|
||||
float value = 0.0f;
|
||||
int i, j;
|
||||
|
||||
pbonecontroller = (mstudiobonecontroller_t *)((byte *)m_pStudioHeader + m_pStudioHeader->bonecontrollerindex);
|
||||
|
@ -732,7 +732,7 @@ void R_StudioCalcBoneAdj( float dadt, float *adj, const byte *pcontroller1, cons
|
|||
{
|
||||
// mouth hardcoded at controller 4
|
||||
value = (float)mouthopen / 64.0f;
|
||||
value = bound( 0.0f, value, 1.0f );
|
||||
value = bound( 0.0f, value, 1.0f );
|
||||
value = (1.0f - value) * pbonecontroller[j].start + value * pbonecontroller[j].end;
|
||||
}
|
||||
else if( i < 4 )
|
||||
|
@ -746,12 +746,12 @@ void R_StudioCalcBoneAdj( float dadt, float *adj, const byte *pcontroller1, cons
|
|||
int b = (pcontroller2[i] + 128) % 256;
|
||||
value = (( a * dadt ) + ( b * ( 1.0f - dadt )) - 128) * (360.0f / 256.0f) + pbonecontroller[j].start;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
value = ((pcontroller1[i] * dadt + (pcontroller2[i]) * (1.0f - dadt))) * (360.0f / 256.0f) + pbonecontroller[j].start;
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
value = (pcontroller1[i] * dadt + pcontroller2[i] * (1.0f - dadt)) / 255.0f;
|
||||
value = bound( 0.0f, value, 1.0f );
|
||||
|
@ -811,7 +811,7 @@ void R_StudioCalcRotations( cl_entity_t *e, float pos[][3], vec4_t *q, mstudiose
|
|||
|
||||
R_StudioCalcBoneAdj( dadt, adj, e->curstate.controller, e->latched.prevcontroller, e->mouth.mouthopen );
|
||||
|
||||
for( i = 0; i < m_pStudioHeader->numbones; i++, pbone++, panim++ )
|
||||
for( i = 0; i < m_pStudioHeader->numbones; i++, pbone++, panim++ )
|
||||
{
|
||||
gEngine.R_StudioCalcBoneQuaternion( frame, s, pbone, panim, adj, q[i] );
|
||||
gEngine.R_StudioCalcBonePosition( frame, s, pbone, panim, adj, pos[i] );
|
||||
|
@ -850,7 +850,7 @@ void R_StudioMergeBones( cl_entity_t *e, model_t *m_pSubModel )
|
|||
R_StudioCalcRotations( e, pos, q, pseqdesc, panim, f );
|
||||
pbones = (mstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex);
|
||||
|
||||
for( i = 0; i < m_pStudioHeader->numbones; i++ )
|
||||
for( i = 0; i < m_pStudioHeader->numbones; i++ )
|
||||
{
|
||||
for( j = 0; j < g_studio.cached_numbones; j++ )
|
||||
{
|
||||
|
@ -865,15 +865,15 @@ void R_StudioMergeBones( cl_entity_t *e, model_t *m_pSubModel )
|
|||
if( j >= g_studio.cached_numbones )
|
||||
{
|
||||
Matrix3x4_FromOriginQuat( bonematrix, q[i], pos[i] );
|
||||
if( pbones[i].parent == -1 )
|
||||
if( pbones[i].parent == -1 )
|
||||
{
|
||||
Matrix3x4_ConcatTransforms( g_studio.bonestransform[i], g_studio.rotationmatrix, bonematrix );
|
||||
Matrix3x4_Copy( g_studio.lighttransform[i], g_studio.bonestransform[i] );
|
||||
|
||||
// apply client-side effects to the transformation matrix
|
||||
R_StudioFxTransform( e, g_studio.bonestransform[i] );
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
Matrix3x4_ConcatTransforms( g_studio.bonestransform[i], g_studio.bonestransform[pbones[i].parent], bonematrix );
|
||||
Matrix3x4_ConcatTransforms( g_studio.lighttransform[i], g_studio.lighttransform[pbones[i].parent], bonematrix );
|
||||
|
@ -997,7 +997,7 @@ void R_StudioSetupBones( cl_entity_t *e )
|
|||
{
|
||||
qboolean copy_bones = true;
|
||||
|
||||
if( m_pPlayerInfo->gaitsequence >= m_pStudioHeader->numseq )
|
||||
if( m_pPlayerInfo->gaitsequence >= m_pStudioHeader->numseq )
|
||||
m_pPlayerInfo->gaitsequence = 0;
|
||||
|
||||
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pPlayerInfo->gaitsequence;
|
||||
|
@ -1019,18 +1019,18 @@ void R_StudioSetupBones( cl_entity_t *e )
|
|||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < m_pStudioHeader->numbones; i++ )
|
||||
for( i = 0; i < m_pStudioHeader->numbones; i++ )
|
||||
{
|
||||
Matrix3x4_FromOriginQuat( bonematrix, q[i], pos[i] );
|
||||
|
||||
if( pbones[i].parent == -1 )
|
||||
if( pbones[i].parent == -1 )
|
||||
{
|
||||
Matrix3x4_ConcatTransforms( g_studio.bonestransform[i], g_studio.rotationmatrix, bonematrix );
|
||||
Matrix3x4_Copy( g_studio.lighttransform[i], g_studio.bonestransform[i] );
|
||||
|
||||
// apply client-side effects to the transformation matrix
|
||||
R_StudioFxTransform( e, g_studio.bonestransform[i] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Matrix3x4_ConcatTransforms( g_studio.bonestransform[i], g_studio.bonestransform[pbones[i].parent], bonematrix );
|
||||
|
@ -1053,7 +1053,7 @@ static void R_StudioSaveBones( void )
|
|||
pbones = (mstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex);
|
||||
g_studio.cached_numbones = m_pStudioHeader->numbones;
|
||||
|
||||
for( i = 0; i < m_pStudioHeader->numbones; i++ )
|
||||
for( i = 0; i < m_pStudioHeader->numbones; i++ )
|
||||
{
|
||||
Matrix3x4_Copy( g_studio.cached_bonestransform[i], g_studio.bonestransform[i] );
|
||||
Matrix3x4_Copy( g_studio.cached_lighttransform[i], g_studio.lighttransform[i] );
|
||||
|
@ -1131,7 +1131,7 @@ void R_StudioGenerateNormals( void )
|
|||
for( i = 0; i < m_pSubModel->numverts; i++ )
|
||||
VectorClear( g_studio.norms[i] );
|
||||
|
||||
for( j = 0; j < m_pSubModel->nummesh; j++ )
|
||||
for( j = 0; j < m_pSubModel->nummesh; j++ )
|
||||
{
|
||||
short *ptricmds;
|
||||
|
||||
|
@ -1626,8 +1626,8 @@ void R_StudioLighting( float *lv, int bone, int flags, vec3_t normal )
|
|||
if( FBitSet( flags, STUDIO_NF_FLATSHADE ))
|
||||
{
|
||||
illum += g_studio.shadelight * 0.8f;
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
float r, lightcos;
|
||||
|
||||
|
@ -1646,14 +1646,14 @@ void R_StudioLighting( float *lv, int bone, int flags, vec3_t normal )
|
|||
{
|
||||
r += 1.0f;
|
||||
lightcos = (( r - 1.0f ) - lightcos) / r;
|
||||
if( lightcos > 0.0f )
|
||||
illum += g_studio.shadelight * lightcos;
|
||||
if( lightcos > 0.0f )
|
||||
illum += g_studio.shadelight * lightcos;
|
||||
}
|
||||
else
|
||||
{
|
||||
lightcos = (lightcos + ( r - 1.0f )) / r;
|
||||
if( lightcos > 0.0f )
|
||||
illum -= g_studio.shadelight * lightcos;
|
||||
illum -= g_studio.shadelight * lightcos;
|
||||
}
|
||||
|
||||
illum = Q_max( illum, 0.0f );
|
||||
|
@ -1906,7 +1906,7 @@ static int R_StudioMeshCompare( const void *a, const void *b )
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void R_StudioDrawNormalMesh( short *ptricmds, vec3_t *pstudionorms, float s, float t, int render_mode, int texture )
|
||||
static void R_StudioDrawNormalMesh( short *ptricmds, vec3_t *pstudionorms, float s, float t, int texture )
|
||||
{
|
||||
float *lv;
|
||||
int i;
|
||||
|
@ -1928,7 +1928,7 @@ static void R_StudioDrawNormalMesh( short *ptricmds, vec3_t *pstudionorms, float
|
|||
num_indices += (vertices-2) * 3;
|
||||
ptricmds += 4 * vertices;
|
||||
}
|
||||
|
||||
|
||||
ASSERT(num_vertices > 0);
|
||||
ASSERT(num_indices > 0);
|
||||
|
||||
|
@ -2009,18 +2009,22 @@ static void R_StudioDrawNormalMesh( short *ptricmds, vec3_t *pstudionorms, float
|
|||
|
||||
// Render
|
||||
{
|
||||
const render_draw_t draw = {
|
||||
.lightmap = tglob.whiteTexture,
|
||||
const vk_render_geometry_t geometry = {
|
||||
//.lightmap = tglob.whiteTexture,
|
||||
.surface_index = -1,
|
||||
|
||||
.texture = texture,
|
||||
.render_mode = render_mode,
|
||||
.element_count = num_indices,
|
||||
.vertex_offset = 0,
|
||||
.index_offset = 0,
|
||||
|
||||
.vertex_count = num_vertices,
|
||||
.vertex_buffer = vertex_buffer,
|
||||
.vertex_offset = 0,
|
||||
|
||||
.element_count = num_indices,
|
||||
.index_offset = 0,
|
||||
.index_buffer = index_buffer,
|
||||
};
|
||||
|
||||
VK_RenderScheduleDraw( &draw );
|
||||
VK_RenderModelDynamicAddGeometry( &geometry );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2113,7 +2117,7 @@ static void R_StudioDrawPoints( void )
|
|||
|
||||
if( !m_pStudioHeader ) return;
|
||||
|
||||
VK_RenderDebugLabelBegin( m_pSubModel->name );
|
||||
VK_RenderModelDynamicBegin( m_pSubModel->name, RI.currententity->curstate.rendermode );
|
||||
|
||||
g_studio.numverts = g_studio.numelems = 0;
|
||||
|
||||
|
@ -2168,7 +2172,7 @@ static void R_StudioDrawPoints( void )
|
|||
|
||||
R_StudioGenerateNormals();
|
||||
|
||||
for( j = k = 0; j < m_pSubModel->nummesh; j++ )
|
||||
for( j = k = 0; j < m_pSubModel->nummesh; j++ )
|
||||
{
|
||||
g_nFaceFlags = ptexture[pskinref[pmesh[j].skinref]].flags | g_nForceFaceFlags;
|
||||
|
||||
|
@ -2261,7 +2265,7 @@ static void R_StudioDrawPoints( void )
|
|||
R_StudioDrawChromeMesh( ptricmds, pstudionorms, s, t, shellscale );
|
||||
else if( FBitSet( g_nFaceFlags, STUDIO_NF_UV_COORDS ))
|
||||
R_StudioDrawFloatMesh( ptricmds, pstudionorms );
|
||||
else*/ R_StudioDrawNormalMesh( ptricmds, pstudionorms, s, t, RI.currententity->curstate.rendermode, texture );
|
||||
else*/ R_StudioDrawNormalMesh( ptricmds, pstudionorms, s, t, texture );
|
||||
|
||||
/* FIXME VK
|
||||
if( FBitSet( g_nFaceFlags, STUDIO_NF_MASKED ))
|
||||
|
@ -2281,7 +2285,7 @@ static void R_StudioDrawPoints( void )
|
|||
*/
|
||||
}
|
||||
|
||||
VK_RenderDebugLabelEnd();
|
||||
VK_RenderModelDynamicCommit();
|
||||
}
|
||||
|
||||
static void R_StudioSetRemapColors( int newTop, int newBottom )
|
||||
|
@ -2644,7 +2648,7 @@ void GL_StudioSetRenderMode( int rendermode )
|
|||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
GL_StudioDrawShadow
|
||||
|
@ -2787,7 +2791,7 @@ void R_StudioProcessGait( entity_state_t *pplayer )
|
|||
int iBlend;
|
||||
float dt, flYaw; // view direction relative to movement
|
||||
|
||||
if( RI.currententity->curstate.sequence >= m_pStudioHeader->numseq )
|
||||
if( RI.currententity->curstate.sequence >= m_pStudioHeader->numseq )
|
||||
RI.currententity->curstate.sequence = 0;
|
||||
|
||||
dt = bound( 0.0f, g_studio.frametime, 1.0f );
|
||||
|
@ -2835,7 +2839,7 @@ void R_StudioProcessGait( entity_state_t *pplayer )
|
|||
if( RI.currententity->angles[YAW] < -0 ) RI.currententity->angles[YAW] += 360.0f;
|
||||
RI.currententity->latched.prevangles[YAW] = RI.currententity->angles[YAW];
|
||||
|
||||
if( pplayer->gaitsequence >= m_pStudioHeader->numseq )
|
||||
if( pplayer->gaitsequence >= m_pStudioHeader->numseq )
|
||||
pplayer->gaitsequence = 0;
|
||||
|
||||
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + pplayer->gaitsequence;
|
||||
|
@ -2873,7 +2877,7 @@ static int R_StudioDrawPlayer( int flags, entity_state_t *pplayer )
|
|||
|
||||
m_pPlayerInfo = pfnPlayerInfo( m_nPlayerIndex );
|
||||
VectorCopy( RI.currententity->angles, orig_angles );
|
||||
|
||||
|
||||
R_StudioProcessGait( pplayer );
|
||||
|
||||
m_pPlayerInfo->gaitsequence = pplayer->gaitsequence;
|
||||
|
@ -2892,7 +2896,7 @@ static int R_StudioDrawPlayer( int flags, entity_state_t *pplayer )
|
|||
RI.currententity->latched.prevcontroller[1] = RI.currententity->curstate.controller[1];
|
||||
RI.currententity->latched.prevcontroller[2] = RI.currententity->curstate.controller[2];
|
||||
RI.currententity->latched.prevcontroller[3] = RI.currententity->curstate.controller[3];
|
||||
|
||||
|
||||
m_pPlayerInfo = pfnPlayerInfo( m_nPlayerIndex );
|
||||
m_pPlayerInfo->gaitsequence = 0;
|
||||
|
||||
|
@ -3259,7 +3263,7 @@ static void R_StudioLoadTexture( model_t *mod, studiohdr_t *phdr, mstudiotexture
|
|||
int flags = 0;
|
||||
char texname[128], name[128], mdlname[128];
|
||||
texture_t *tx = NULL;
|
||||
|
||||
|
||||
if( ptexture->flags & STUDIO_NF_NORMALMAP )
|
||||
flags |= (TF_NORMALMAP);
|
||||
|
||||
|
|
Loading…
Reference in New Issue