mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-21 18:01:15 +00:00
[vulkan] Partially document bsp rendering
This did involve changing some field names and a little bit of cleanup, but I've got a better handle on what's going on (I think I was in one of those coding trances where I quickly forget how things work).
This commit is contained in:
parent
3e7f2f0578
commit
aafb3c1d98
3 changed files with 259 additions and 81 deletions
|
@ -39,13 +39,27 @@
|
|||
|
||||
#include "QF/simd/types.h"
|
||||
|
||||
/** \defgroup vulkan_bsp Brush model rendering
|
||||
\ingroup vulkan
|
||||
*/
|
||||
|
||||
/** Represent a single face (polygon) of a brush model.
|
||||
*
|
||||
* There is one of these for each face in the bsp (brush) model, built at run
|
||||
* time when the model is loaded (actually, after all models are loaded but
|
||||
* before rendering begins).
|
||||
*/
|
||||
typedef struct bsp_face_s {
|
||||
uint32_t first_index;
|
||||
uint32_t index_count;
|
||||
uint32_t tex_id;
|
||||
uint32_t flags;
|
||||
uint32_t first_index; ///< index of first index in poly_indices
|
||||
uint32_t index_count; ///< includes primitive restart
|
||||
uint32_t tex_id; ///< texture bound to this face (maybe animated)
|
||||
uint32_t flags; ///< face drawing (alpha, side, sky, turb)
|
||||
} bsp_face_t;
|
||||
|
||||
/** Represent a brush model, both main and sub-model.
|
||||
*
|
||||
* Used for rendering non-world models.
|
||||
*/
|
||||
typedef struct bsp_model_s {
|
||||
uint32_t first_face;
|
||||
uint32_t face_count;
|
||||
|
@ -62,21 +76,57 @@ typedef struct texmip_s {
|
|||
uint32_t offsets[MIPLEVELS];
|
||||
} texmip_t;
|
||||
#endif
|
||||
/** \defgroup vulkan_bsp_texanim Animated Textures
|
||||
* \ingroup vulkan_bsp
|
||||
*
|
||||
* Brush models support texture animations. For general details, see
|
||||
* \ref bsp_texture_animation. These structures allow for quick lookup
|
||||
* of the correct texture to use in an animation cycle, or even whether there
|
||||
* is an animation cycle.
|
||||
*/
|
||||
///@{
|
||||
/** Represent a texture's animation group.
|
||||
*
|
||||
* Every texture is in an animation group, even when not animated. When the
|
||||
* texture is not animated, `count` is 1, otherwise `count` is the number of
|
||||
* frames in the group, thus every texture has at least one frame.
|
||||
*
|
||||
* Each texture in a particular groupp shares the same `base` frame, with
|
||||
* `offset` giving the texture's relative frame number within the group.
|
||||
* The current frame is given by `base + (anim_index + offset) % count` where
|
||||
* `anim_index` is the global time-based texture animation frame.
|
||||
*/
|
||||
typedef struct texanim_s {
|
||||
uint16_t base;
|
||||
byte offset;
|
||||
byte count;
|
||||
uint16_t base; ///< first frame in group
|
||||
byte offset; ///< relative frame in group
|
||||
byte count; ///< number of frames in group
|
||||
} texanim_t;
|
||||
|
||||
/** Holds texture animation data for brush models.
|
||||
*
|
||||
* Brush models support one or two texture animation groups, based on the
|
||||
* entity's frame (0 or non-0). When the entity's frame is 0, group 0 is used,
|
||||
* otherwise group 1 is used. If there is no alternate (group 1) animation
|
||||
* data for the texture, then the texture's group 0 data is copied to group 1
|
||||
* in order to avoid coplications in selecting which texture a face is to use.
|
||||
*
|
||||
* As all of a group's frames are together, `frame_map` is used to get the
|
||||
* actual texture id for the frame.
|
||||
*/
|
||||
typedef struct texdata_s {
|
||||
// texname_t *names;
|
||||
// texmip_t **mips;
|
||||
texanim_t *anim_main;
|
||||
texanim_t *anim_alt;
|
||||
uint16_t *anim_map;
|
||||
texanim_t *anim_main; ///< group 0 animations
|
||||
texanim_t *anim_alt; ///< group 1 animations
|
||||
uint16_t *frame_map; ///< map from texture frame to texture id
|
||||
// int num_tex;
|
||||
} texdata_t;
|
||||
///@}
|
||||
|
||||
/** \defgroup vulkan_bsp_draw Brush model drawing
|
||||
* \ingroup vulkan_bsp
|
||||
*/
|
||||
///@{
|
||||
typedef struct vulktex_s {
|
||||
struct qfv_tex_s *tex;
|
||||
VkDescriptorSet descriptor;
|
||||
|
@ -86,57 +136,186 @@ typedef struct vulktex_s {
|
|||
typedef struct regtexset_s
|
||||
DARRAY_TYPE (vulktex_t *) regtexset_t;
|
||||
|
||||
/** Represent a single draw call.
|
||||
*
|
||||
* For each texture that has faces to be rendered, one or more draw calls is
|
||||
* made. Normally, only one call per texture is made, but if different models
|
||||
* use the same texture, then a separate draw call is made for each model.
|
||||
* When multiple entities use the same model, instanced rendering is used to
|
||||
* draw all the faces sharing a texture for all the entities using that model.
|
||||
* Thus when there are multiple draw calls for a single texture, they are
|
||||
* grouped together so there is only one bind per texture.
|
||||
*
|
||||
* The index buffer is populated every frame with the vertex indices of the
|
||||
* faces to be rendered for the current frame, grouped by texture and instance
|
||||
* id (model render id).
|
||||
*
|
||||
* The model render id is assigned after models are loaded but before rendering
|
||||
* begins and remains constant until the next time models are loaded (level
|
||||
* change).
|
||||
*
|
||||
* The entid buffer is also populated every frame with the render id of the
|
||||
* entities to be drawn that frame, It is used to map gl_InstanceIndex to
|
||||
* entity id so as to look up the entity's transform and color (and any other
|
||||
* data in the future).
|
||||
*
|
||||
* \dot
|
||||
* digraph vulkan_bsp_draw_call {
|
||||
* layout=dot; rankdir=LR; compound=true; nodesep=1.0;
|
||||
* vertices [shape=none,label=< <table border="1" cellborder="1">
|
||||
* <tr><td>vertex</td></tr>
|
||||
* <tr><td>vertex</td></tr>
|
||||
* <tr><td>...</td></tr>
|
||||
* <tr><td port="p">vertex</td></tr>
|
||||
* <tr><td>vertex</td></tr>
|
||||
* </table> >];
|
||||
* indices [shape=none,label=< <table border="1" cellborder="1">
|
||||
* <tr><td>index</td></tr>
|
||||
* <tr><td>index</td></tr>
|
||||
* <tr><td>...</td></tr>
|
||||
* <tr><td port="p">index</td></tr>
|
||||
* <tr><td>index</td></tr>
|
||||
* </table> >];
|
||||
* entids [shape=none,label=< <table border="1" cellborder="1">
|
||||
* <tr><td>entid</td></tr>
|
||||
* <tr><td>...</td></tr>
|
||||
* <tr><td port="p">entid</td></tr>
|
||||
* <tr><td>entid</td></tr>
|
||||
* <tr><td>...</td></tr>
|
||||
* <tr><td>entid</td></tr>
|
||||
* </table> >];
|
||||
* entdata [shape=none,label=< <table border="1" cellborder="1">
|
||||
* <tr><td>transform</td><td>color</td></tr>
|
||||
* <tr><td>transform</td><td>color</td></tr>
|
||||
* <tr><td colspan="2">...</td></tr>
|
||||
* <tr><td port="p">transform</td><td>color</td></tr>
|
||||
* <tr><td colspan="2">...</td></tr>
|
||||
* <tr><td>transform</td><td>color</td></tr>
|
||||
* </table> >];
|
||||
* drawcall [shape=none,label=< <table border="1" cellborder="1">
|
||||
* <tr><td port="tex" >tex_id</td></tr>
|
||||
* <tr><td >inst_id</td></tr>
|
||||
* <tr><td port="ind" >first_index</td></tr>
|
||||
* <tr><td >index_count</td></tr>
|
||||
* <tr><td port="inst">first_instance</td></tr>
|
||||
* <tr><td >instance_count</td></tr>
|
||||
* </table> >];
|
||||
* textures [shape=none,label=< <table border="1" cellborder="1">
|
||||
* <tr><td>texture</td></tr>
|
||||
* <tr><td>texture</td></tr>
|
||||
* <tr><td port="p">texture</td></tr>
|
||||
* <tr><td>...</td></tr>
|
||||
* <tr><td>texture</td></tr>
|
||||
* </table> >];
|
||||
* vertex [label="vertex shader"];
|
||||
* fragment [label="fragment shader"];
|
||||
* drawcall:tex -> textures:p;
|
||||
* drawcall:ind -> indices:p;
|
||||
* drawcall:inst -> entids:p;
|
||||
* entids:p -> entdata:p;
|
||||
* indices:p -> vertices:p;
|
||||
* vertex -> entdata [label="storage buffer"];
|
||||
* vertex -> entids [label="per instance"];
|
||||
* vertex -> indices [label="index buffer"];
|
||||
* vertex -> vertices [label="per vertex"];
|
||||
* fragment -> textures [label="per call"];
|
||||
* }
|
||||
* \enddot
|
||||
*/
|
||||
///@{
|
||||
typedef struct bsp_draw_s {
|
||||
uint32_t tex_id;
|
||||
uint32_t inst_id;
|
||||
uint32_t index_count;
|
||||
uint32_t instance_count;
|
||||
uint32_t first_index;
|
||||
uint32_t first_instance;
|
||||
uint32_t tex_id; ///< texture to bind for this draw call
|
||||
uint32_t inst_id; ///< model render id owning this draw call
|
||||
uint32_t index_count; ///< number of indices for this draw call
|
||||
uint32_t instance_count; ///< number of instances to draw
|
||||
uint32_t first_index; ///< index into index buffer
|
||||
uint32_t first_instance; ///< index into entid buffer
|
||||
} bsp_draw_t;
|
||||
|
||||
typedef struct bsp_drawset_s
|
||||
DARRAY_TYPE (bsp_draw_t) bsp_drawset_t;
|
||||
///@}
|
||||
|
||||
/** Tag models that are to be queued for translucent drawing.
|
||||
*/
|
||||
#define INST_ALPHA (1u<<31)
|
||||
|
||||
/** Representation of a single face queued for drawing.
|
||||
*/
|
||||
///@{
|
||||
typedef struct instface_s {
|
||||
uint32_t inst_id;
|
||||
uint32_t face;
|
||||
uint32_t inst_id; ///< model render id owning this face
|
||||
uint32_t face; ///< index of face in context array
|
||||
} instface_t;
|
||||
|
||||
typedef struct bsp_instfaceset_s
|
||||
DARRAY_TYPE (instface_t) bsp_instfaceset_t;
|
||||
///@}
|
||||
|
||||
/** Track entities using a model.
|
||||
*/
|
||||
///@{
|
||||
typedef struct bsp_modelentset_s
|
||||
DARRAY_TYPE (uint32_t) bsp_modelentset_t;
|
||||
|
||||
/** Represent a single model and the entities using it.
|
||||
*/
|
||||
typedef struct bsp_instance_s {
|
||||
int first_instance;
|
||||
bsp_modelentset_t entities;
|
||||
int first_instance; ///< index into entid buffer
|
||||
bsp_modelentset_t entities; ///< list of entity render ids using this model
|
||||
} bsp_instance_t;
|
||||
///@}
|
||||
|
||||
typedef struct bsp_pass_s {
|
||||
vec4f_t position;
|
||||
plane_t *frustum;
|
||||
const struct mod_brush_s *brush;
|
||||
struct bspctx_s *bsp_context;
|
||||
uint32_t *indices; // points into index buffer
|
||||
uint32_t index_count; // number of indices written to buffer
|
||||
uint32_t *entid_data; // points into entid buffer
|
||||
uint32_t entid_count;
|
||||
int vis_frame;
|
||||
int *face_frames;
|
||||
int *leaf_frames;
|
||||
int *node_frames;
|
||||
bsp_instfaceset_t *face_queue;
|
||||
regtexset_t *textures;
|
||||
int num_queues;
|
||||
bsp_drawset_t *draw_queues;
|
||||
uint32_t inst_id;
|
||||
bsp_instance_t *instances;
|
||||
int ent_frame;
|
||||
vec4f_t position; ///< view position
|
||||
plane_t *frustum; ///< view frustum for culling
|
||||
const struct mod_brush_s *brush;///< data for current model
|
||||
struct bspctx_s *bsp_context; ///< owning bsp context
|
||||
/** \name GPU data
|
||||
*
|
||||
* The indices to be drawn and the entity ids associated with each draw
|
||||
* instance are updated each frame. The pointers are to the per-frame
|
||||
* mapped buffers for the respective data.
|
||||
*/
|
||||
///@{
|
||||
uint32_t *indices; ///< polygon vertex indices
|
||||
uint32_t index_count; ///< number of indices written to buffer
|
||||
uint32_t *entid_data; ///< instance id to entity id map
|
||||
uint32_t entid_count; ///< numer of entids written to buffer
|
||||
///@}
|
||||
/** \name Potentially Visible Sets
|
||||
*
|
||||
* For an object to be in the PVS, its frame id must match the current
|
||||
* visibility frame id, thus clearing all sets is done by incrementing
|
||||
* `vis_frame`, and adding an object to the PVS is done by setting its
|
||||
* current frame id to the current visibility frame id.
|
||||
*/
|
||||
///@{
|
||||
int vis_frame; ///< current visibility frame id
|
||||
int *face_frames; ///< per-face visibility frame ids
|
||||
int *leaf_frames; ///< per-leaf visibility frame ids
|
||||
int *node_frames; ///< per-node visibility frame ids
|
||||
///@}
|
||||
bsp_instfaceset_t *face_queue; ///< per-texture face queues
|
||||
regtexset_t *textures; ///< textures to bind when emitting calls
|
||||
int num_queues; ///< number of pipeline queues
|
||||
bsp_drawset_t *draw_queues; ///< per-pipeline draw queues
|
||||
uint32_t inst_id; ///< render id of current model
|
||||
bsp_instance_t *instances; ///< per-model entid lists
|
||||
// FIXME There are several potential optimizations here:
|
||||
// 1) ent_frame could be forced to be 0 or 1 and then used to index a
|
||||
// two-element array of texanim pointers
|
||||
// 2) ent_frame could be a pointer to the correct texanim array
|
||||
// 3) could update a tex_id map each frame and unconditionally index that
|
||||
//
|
||||
// As the texture id is used for selecting the face queue, 3 could be used
|
||||
// for mapping all textures to 1 or two queues for shadow rendering
|
||||
int ent_frame; ///< animation frame of current entity
|
||||
} bsp_pass_t;
|
||||
///@}
|
||||
|
||||
/// \ingroup vulkan_bsp
|
||||
///@{
|
||||
typedef enum {
|
||||
QFV_bspDepth,
|
||||
QFV_bspGBuffer,
|
||||
|
@ -159,31 +338,33 @@ typedef struct bspframe_s {
|
|||
typedef struct bspframeset_s
|
||||
DARRAY_TYPE (bspframe_t) bspframeset_t;
|
||||
|
||||
/** Main BSP context structure
|
||||
*
|
||||
* This holds all the state and resources needed for rendering brush models.
|
||||
*/
|
||||
typedef struct bspctx_s {
|
||||
regtexset_t registered_textures;
|
||||
|
||||
struct qfv_tex_s *default_skysheet;
|
||||
struct qfv_tex_s *skysheet_tex;
|
||||
|
||||
struct qfv_tex_s *default_skybox;
|
||||
struct qfv_tex_s *skybox_tex;
|
||||
VkDescriptorSet skybox_descriptor;
|
||||
|
||||
vulktex_t notexture;
|
||||
vulktex_t notexture; ///< replacement for invalid textures
|
||||
|
||||
struct scrap_s *light_scrap;
|
||||
struct qfv_stagebuf_s *light_stage;
|
||||
|
||||
bsp_model_t *models;
|
||||
bsp_face_t *faces;
|
||||
uint32_t *poly_indices;
|
||||
int num_models; ///< number of loaded brush models
|
||||
bsp_model_t *models; ///< all loaded brush models
|
||||
bsp_face_t *faces; ///< all faces from all loaded brush models
|
||||
uint32_t *poly_indices; ///< face indices from all loaded brush models
|
||||
|
||||
texdata_t texdata;
|
||||
int anim_index;
|
||||
regtexset_t registered_textures;///< textures for all loaded brush models
|
||||
texdata_t texdata; ///< texture animation data
|
||||
int anim_index; ///< texture animation frame (5fps)
|
||||
struct qfv_tex_s *default_skysheet;
|
||||
struct qfv_tex_s *skysheet_tex; ///< scrolling sky texture for current map
|
||||
|
||||
int model_id;
|
||||
struct qfv_tex_s *default_skybox;
|
||||
struct qfv_tex_s *skybox_tex; ///< sky box texture for current map
|
||||
VkDescriptorSet skybox_descriptor;
|
||||
|
||||
bsp_pass_t main_pass; // camera view depth, gbuffer, etc
|
||||
bsp_pass_t main_pass; ///< camera view depth, gbuffer, etc
|
||||
|
||||
VkSampler sampler;
|
||||
VkPipelineLayout layout;
|
||||
|
@ -207,7 +388,6 @@ typedef struct bspctx_s {
|
|||
|
||||
struct vulkan_ctx_s;
|
||||
struct qfv_renderframe_s;
|
||||
void Vulkan_ClearElements (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_DrawWorld (struct qfv_renderframe_s *rFrame);
|
||||
void Vulkan_DrawSky (struct qfv_renderframe_s *rFrame);
|
||||
void Vulkan_DrawWaterSurfaces (struct qfv_renderframe_s *rFrame);
|
||||
|
@ -219,5 +399,6 @@ void Vulkan_BuildDisplayLists (model_t **models, int num_models,
|
|||
struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Bsp_Init (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Bsp_Shutdown (struct vulkan_ctx_s *ctx);
|
||||
///@}
|
||||
|
||||
#endif//__QF_Vulkan_qf_bsp_h
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
#endif
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
/** \defgroup vulkan Vulkan Renderer
|
||||
*/
|
||||
|
||||
enum {
|
||||
QFV_rp_shadowmap,
|
||||
QFV_rp_main,
|
||||
|
|
|
@ -91,14 +91,12 @@ static const char * __attribute__((used)) bsp_pass_names[] = {
|
|||
};
|
||||
|
||||
static QFV_Subpass subpass_map[] = {
|
||||
QFV_passDepth, // QFV_bspDepth
|
||||
QFV_passGBuffer, // QFV_bspGBuffer
|
||||
QFV_passTranslucent, // QFV_bspSky
|
||||
QFV_passTranslucent, // QFV_bspTurb
|
||||
[QFV_bspDepth] = QFV_passDepth,
|
||||
[QFV_bspGBuffer] = QFV_passGBuffer,
|
||||
[QFV_bspSky] = QFV_passTranslucent,
|
||||
[QFV_bspTurb] = QFV_passTranslucent,
|
||||
};
|
||||
|
||||
#define ALLOC_CHUNK 64
|
||||
|
||||
static void
|
||||
add_texture (texture_t *tx, vulkan_ctx_t *ctx)
|
||||
{
|
||||
|
@ -113,12 +111,6 @@ add_texture (texture_t *tx, vulkan_ctx_t *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_ClearElements (vulkan_ctx_t *ctx)
|
||||
{
|
||||
// bspctx_t *bctx = ctx->bsp_context;
|
||||
}
|
||||
|
||||
static inline void
|
||||
chain_surface (const bsp_face_t *face, bsp_pass_t *pass, const bspctx_t *bctx)
|
||||
{
|
||||
|
@ -128,7 +120,7 @@ chain_surface (const bsp_face_t *face, bsp_pass_t *pass, const bspctx_t *bctx)
|
|||
const texanim_t *anim = ent_frame ? &bctx->texdata.anim_alt[face->tex_id]
|
||||
: &bctx->texdata.anim_main[face->tex_id];
|
||||
int anim_ind = (bctx->anim_index + anim->offset) % anim->count;
|
||||
int tex_id = bctx->texdata.anim_map[anim->base + anim_ind];
|
||||
int tex_id = bctx->texdata.frame_map[anim->base + anim_ind];
|
||||
DARRAY_APPEND (&pass->face_queue[tex_id],
|
||||
((instface_t) { pass->inst_id, face - bctx->faces }));
|
||||
}
|
||||
|
@ -165,7 +157,6 @@ clear_textures (vulkan_ctx_t *ctx)
|
|||
void
|
||||
Vulkan_RegisterTextures (model_t **models, int num_models, vulkan_ctx_t *ctx)
|
||||
{
|
||||
|
||||
clear_textures (ctx);
|
||||
add_texture (r_notexture_mip, ctx);
|
||||
{
|
||||
|
@ -209,11 +200,13 @@ Vulkan_RegisterTextures (model_t **models, int num_models, vulkan_ctx_t *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
// 2.5 for two texanim_t structs (32-bits each) and 1 uint16_t for each
|
||||
// element
|
||||
size_t texdata_size = 2.5 * num_tex * sizeof (texanim_t);
|
||||
texanim_t *texdata = Hunk_AllocName (0, texdata_size, "texdata");
|
||||
bctx->texdata.anim_main = texdata;
|
||||
bctx->texdata.anim_alt = texdata + num_tex;
|
||||
bctx->texdata.anim_map = (uint16_t *) (texdata + 2 * num_tex);
|
||||
bctx->texdata.frame_map = (uint16_t *) (texdata + 2 * num_tex);
|
||||
int16_t map_index = 0;
|
||||
for (int i = 0; i < num_tex; i++) {
|
||||
texanim_t *anim = bctx->texdata.anim_main + i;
|
||||
|
@ -222,7 +215,7 @@ Vulkan_RegisterTextures (model_t **models, int num_models, vulkan_ctx_t *ctx)
|
|||
continue;
|
||||
}
|
||||
*anim = (texanim_t) { .base = map_index, .offset = 0, .count = 1 };
|
||||
bctx->texdata.anim_map[anim->base] = i;
|
||||
bctx->texdata.frame_map[anim->base] = i;
|
||||
|
||||
if (textures[i]->anim_total > 1) {
|
||||
// bsp loader multiplies anim_total by ANIM_CYCLE to slow the
|
||||
|
@ -240,7 +233,7 @@ Vulkan_RegisterTextures (model_t **models, int num_models, vulkan_ctx_t *ctx)
|
|||
}
|
||||
*a = *anim;
|
||||
a->offset = j;
|
||||
bctx->texdata.anim_map[a->base + a->offset] = vtex->tex_id;
|
||||
bctx->texdata.frame_map[a->base + a->offset] = vtex->tex_id;
|
||||
tx = tx->anim_next;
|
||||
}
|
||||
if (tx != textures[i]) {
|
||||
|
@ -260,6 +253,7 @@ Vulkan_RegisterTextures (model_t **models, int num_models, vulkan_ctx_t *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
// create face queue arrays
|
||||
bctx->main_pass.face_queue = malloc (num_tex * sizeof (bsp_instfaceset_t));
|
||||
for (int i = 0; i < num_tex; i++) {
|
||||
bctx->main_pass.face_queue[i]
|
||||
|
@ -379,11 +373,11 @@ Vulkan_BuildDisplayLists (model_t **models, int num_models, vulkan_ctx_t *ctx)
|
|||
face_sets[i] = (facerefset_t) DARRAY_STATIC_INIT (1024);
|
||||
}
|
||||
|
||||
for (int i = 0; i < bctx->model_id; i++) {
|
||||
for (int i = 0; i < bctx->num_models; i++) {
|
||||
DARRAY_CLEAR (&bctx->main_pass.instances[i].entities);
|
||||
}
|
||||
free (bctx->main_pass.instances);
|
||||
bctx->model_id = 0;
|
||||
bctx->num_models = 0;
|
||||
|
||||
// run through all surfaces, chaining them to their textures, thus
|
||||
// effectively sorting the surfaces by texture (without worrying about
|
||||
|
@ -396,7 +390,7 @@ Vulkan_BuildDisplayLists (model_t **models, int num_models, vulkan_ctx_t *ctx)
|
|||
if (!m || m->type != mod_brush) {
|
||||
continue;
|
||||
}
|
||||
m->render_id = bctx->model_id++;
|
||||
m->render_id = bctx->num_models++;
|
||||
if (*m->path == '*') {
|
||||
continue;
|
||||
}
|
||||
|
@ -422,9 +416,9 @@ Vulkan_BuildDisplayLists (model_t **models, int num_models, vulkan_ctx_t *ctx)
|
|||
}
|
||||
face_base += brush->numsurfaces;
|
||||
}
|
||||
bctx->main_pass.instances = malloc (bctx->model_id
|
||||
bctx->main_pass.instances = malloc (bctx->num_models
|
||||
* sizeof (bsp_instance_t));
|
||||
for (int i = 0; i < bctx->model_id; i++) {
|
||||
for (int i = 0; i < bctx->num_models; i++) {
|
||||
DARRAY_INIT (&bctx->main_pass.instances[i].entities, 16);
|
||||
}
|
||||
// All vertices from all brush models go into one giant vbo.
|
||||
|
@ -469,7 +463,7 @@ Vulkan_BuildDisplayLists (model_t **models, int num_models, vulkan_ctx_t *ctx)
|
|||
free (bctx->faces);
|
||||
free (bctx->poly_indices);
|
||||
free (bctx->models);
|
||||
bctx->models = malloc (bctx->model_id * sizeof (bsp_model_t));
|
||||
bctx->models = malloc (bctx->num_models * sizeof (bsp_model_t));
|
||||
bctx->faces = malloc (face_base * sizeof (bsp_face_t));
|
||||
bctx->poly_indices = malloc (index_count * sizeof (uint32_t));
|
||||
|
||||
|
@ -943,7 +937,7 @@ clear_queues (bspctx_t *bctx, bsp_pass_t *pass)
|
|||
for (int i = 0; i < pass->num_queues; i++) {
|
||||
DARRAY_RESIZE (&pass->draw_queues[i], 0);
|
||||
}
|
||||
for (int i = 0; i < bctx->model_id; i++) {
|
||||
for (int i = 0; i < bctx->num_models; i++) {
|
||||
pass->instances[i].first_instance = -1;
|
||||
DARRAY_RESIZE (&pass->instances[i].entities, 0);
|
||||
}
|
||||
|
@ -1507,7 +1501,7 @@ Vulkan_Bsp_Shutdown (struct vulkan_ctx_s *ctx)
|
|||
free (bctx->models);
|
||||
|
||||
free (bctx->main_pass.draw_queues);
|
||||
for (int i = 0; i < bctx->model_id; i++) {
|
||||
for (int i = 0; i < bctx->num_models; i++) {
|
||||
DARRAY_CLEAR (&bctx->main_pass.instances[i].entities);
|
||||
}
|
||||
free (bctx->main_pass.instances);
|
||||
|
|
Loading…
Reference in a new issue