mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-31 13:10:34 +00:00
[vulkan] Load the map's lights into an array
It's not used yet as work needs to be done to better support generic entities, but this is the next step to real-time lighting (though, to be honest, I expect it will be too slow to be usable).
This commit is contained in:
parent
0da3b35ef5
commit
4d8ce22c17
4 changed files with 116 additions and 3 deletions
|
@ -40,11 +40,13 @@ typedef struct qfv_light_s {
|
||||||
vec3_t color;
|
vec3_t color;
|
||||||
float intensity;
|
float intensity;
|
||||||
vec3_t position;
|
vec3_t position;
|
||||||
int radius;
|
float radius;
|
||||||
vec3_t direction;
|
vec3_t direction;
|
||||||
float cone;
|
float cone;
|
||||||
} qfv_light_t;
|
} qfv_light_t;
|
||||||
|
|
||||||
|
typedef struct qfv_lightset_s DARRAY_TYPE (qfv_light_t) qfv_lightset_t;
|
||||||
|
|
||||||
#define NUM_LIGHTS 128
|
#define NUM_LIGHTS 128
|
||||||
|
|
||||||
typedef struct qfv_light_buffer_s {
|
typedef struct qfv_light_buffer_s {
|
||||||
|
@ -52,7 +54,6 @@ typedef struct qfv_light_buffer_s {
|
||||||
qfv_light_t lights[NUM_LIGHTS] __attribute__((aligned(16)));
|
qfv_light_t lights[NUM_LIGHTS] __attribute__((aligned(16)));
|
||||||
} qfv_light_buffer_t;
|
} qfv_light_buffer_t;
|
||||||
|
|
||||||
|
|
||||||
#define LIGHTING_BUFFER_INFOS 1
|
#define LIGHTING_BUFFER_INFOS 1
|
||||||
#define LIGHTING_IMAGE_INFOS 4
|
#define LIGHTING_IMAGE_INFOS 4
|
||||||
|
|
||||||
|
@ -73,6 +74,7 @@ typedef struct lightingctx_s {
|
||||||
VkPipeline pipeline;
|
VkPipeline pipeline;
|
||||||
VkPipelineLayout layout;
|
VkPipelineLayout layout;
|
||||||
VkDeviceMemory light_memory;
|
VkDeviceMemory light_memory;
|
||||||
|
qfv_lightset_t lights;
|
||||||
} lightingctx_t;
|
} lightingctx_t;
|
||||||
|
|
||||||
struct vulkan_ctx_s;
|
struct vulkan_ctx_s;
|
||||||
|
@ -80,5 +82,6 @@ struct vulkan_ctx_s;
|
||||||
void Vulkan_Lighting_Init (struct vulkan_ctx_s *ctx);
|
void Vulkan_Lighting_Init (struct vulkan_ctx_s *ctx);
|
||||||
void Vulkan_Lighting_Shutdown (struct vulkan_ctx_s *ctx);
|
void Vulkan_Lighting_Shutdown (struct vulkan_ctx_s *ctx);
|
||||||
void Vulkan_Lighting_Draw (struct vulkan_ctx_s *ctx);
|
void Vulkan_Lighting_Draw (struct vulkan_ctx_s *ctx);
|
||||||
|
void Vulkan_LoadLights (const char *entity_data, struct vulkan_ctx_s *ctx);
|
||||||
|
|
||||||
#endif//__QF_Vulkan_qf_lighting_h
|
#endif//__QF_Vulkan_qf_lighting_h
|
||||||
|
|
|
@ -9,7 +9,7 @@ struct LightData {
|
||||||
vec3 color;
|
vec3 color;
|
||||||
float intensity;
|
float intensity;
|
||||||
vec3 position;
|
vec3 position;
|
||||||
int radius;
|
float radius;
|
||||||
vec3 direction;
|
vec3 direction;
|
||||||
float cone;
|
float cone;
|
||||||
};
|
};
|
||||||
|
|
|
@ -41,6 +41,10 @@
|
||||||
|
|
||||||
#include "qfalloca.h"
|
#include "qfalloca.h"
|
||||||
|
|
||||||
|
#include "QF/dstring.h"
|
||||||
|
#include "QF/progs.h"
|
||||||
|
#include "QF/qfplist.h"
|
||||||
|
#include "QF/script.h"
|
||||||
#include "QF/sys.h"
|
#include "QF/sys.h"
|
||||||
#include "QF/va.h"
|
#include "QF/va.h"
|
||||||
|
|
||||||
|
@ -203,6 +207,8 @@ Vulkan_Lighting_Init (vulkan_ctx_t *ctx)
|
||||||
lightingctx_t *lctx = calloc (1, sizeof (lightingctx_t));
|
lightingctx_t *lctx = calloc (1, sizeof (lightingctx_t));
|
||||||
ctx->lighting_context = lctx;
|
ctx->lighting_context = lctx;
|
||||||
|
|
||||||
|
DARRAY_INIT (&lctx->lights, 16);
|
||||||
|
|
||||||
size_t frames = ctx->frames.size;
|
size_t frames = ctx->frames.size;
|
||||||
DARRAY_INIT (&lctx->frames, frames);
|
DARRAY_INIT (&lctx->frames, frames);
|
||||||
DARRAY_RESIZE (&lctx->frames, frames);
|
DARRAY_RESIZE (&lctx->frames, frames);
|
||||||
|
@ -295,6 +301,108 @@ Vulkan_Lighting_Shutdown (vulkan_ctx_t *ctx)
|
||||||
}
|
}
|
||||||
dfunc->vkFreeMemory (device->dev, lctx->light_memory, 0);
|
dfunc->vkFreeMemory (device->dev, lctx->light_memory, 0);
|
||||||
dfunc->vkDestroyPipeline (device->dev, lctx->pipeline, 0);
|
dfunc->vkDestroyPipeline (device->dev, lctx->pipeline, 0);
|
||||||
|
DARRAY_CLEAR (&lctx->lights);
|
||||||
free (lctx->frames.a);
|
free (lctx->frames.a);
|
||||||
free (lctx);
|
free (lctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_light (qfv_light_t *light, const plitem_t *entity,
|
||||||
|
const plitem_t *targets)
|
||||||
|
{
|
||||||
|
const char *str;
|
||||||
|
|
||||||
|
if ((str = PL_String (PL_ObjectForKey (entity, "origin")))) {
|
||||||
|
sscanf (str, "%f %f %f", VectorExpandAddr (light->position));
|
||||||
|
}
|
||||||
|
|
||||||
|
light->cone = 1;
|
||||||
|
if ((str = PL_String (PL_ObjectForKey (entity, "target")))) {
|
||||||
|
vec3_t position = {};
|
||||||
|
plitem_t *target = PL_ObjectForKey (targets, str);
|
||||||
|
if (target) {
|
||||||
|
if ((str = PL_String (PL_ObjectForKey (target, "origin")))) {
|
||||||
|
sscanf (str, "%f %f %f", VectorExpandAddr (position));
|
||||||
|
}
|
||||||
|
VectorSubtract (position, light->position, light->direction);
|
||||||
|
VectorNormalize (light->direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
float angle = 40;
|
||||||
|
if ((str = PL_String (PL_ObjectForKey (entity, "angle")))) {
|
||||||
|
angle = atof (str);
|
||||||
|
}
|
||||||
|
light->cone = -cos (angle * M_PI / 360); // half angle
|
||||||
|
}
|
||||||
|
|
||||||
|
light->intensity = 1;
|
||||||
|
if ((str = PL_String (PL_ObjectForKey (entity, "light")))
|
||||||
|
|| (str = PL_String (PL_ObjectForKey (entity, "_light")))) {
|
||||||
|
light->radius = atof (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
VectorSet (1, 1, 1, light->color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Vulkan_LoadLights (const char *entity_data, vulkan_ctx_t *ctx)
|
||||||
|
{
|
||||||
|
lightingctx_t *lctx = ctx->lighting_context;
|
||||||
|
plitem_t *entities = 0;
|
||||||
|
|
||||||
|
lctx->lights.size = 0;
|
||||||
|
|
||||||
|
script_t *script = Script_New ();
|
||||||
|
Script_Start (script, "ent data", entity_data);
|
||||||
|
|
||||||
|
if (Script_GetToken (script, 1)) {
|
||||||
|
if (strequal (script->token->str, "(")) {
|
||||||
|
// new style (plist) entity data
|
||||||
|
entities = PL_GetPropertyList (entity_data, &ctx->hashlinks);
|
||||||
|
} else {
|
||||||
|
// old style entity data
|
||||||
|
Script_UngetToken (script);
|
||||||
|
// FIXME ED_ConvertToPlist aborts if an error is encountered.
|
||||||
|
entities = ED_ConvertToPlist (script, 0, &ctx->hashlinks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Script_Delete (script);
|
||||||
|
|
||||||
|
if (entities) {
|
||||||
|
plitem_t *targets = PL_NewDictionary (&ctx->hashlinks);
|
||||||
|
|
||||||
|
// find all the targets so spotlights can be aimed
|
||||||
|
for (int i = 1; i < PL_A_NumObjects (entities); i++) {
|
||||||
|
plitem_t *entity = PL_ObjectAtIndex (entities, i);
|
||||||
|
const char *targetname = PL_String (PL_ObjectForKey (entity,
|
||||||
|
"targetname"));
|
||||||
|
if (targetname && !PL_ObjectForKey (targets, targetname)) {
|
||||||
|
PL_D_AddObject (targets, targetname, entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < PL_A_NumObjects (entities); i++) {
|
||||||
|
plitem_t *entity = PL_ObjectAtIndex (entities, i);
|
||||||
|
const char *classname = PL_String (PL_ObjectForKey (entity,
|
||||||
|
"classname"));
|
||||||
|
if (classname && strnequal (classname, "light", 5)) {
|
||||||
|
qfv_light_t light = {};
|
||||||
|
|
||||||
|
parse_light (&light, entity, targets);
|
||||||
|
printf ("[%g, %g, %g] %g, [%g %g %g] %g, [%g %g %g] %g\n",
|
||||||
|
VectorExpand (light.color), light.intensity,
|
||||||
|
VectorExpand (light.position), light.radius,
|
||||||
|
VectorExpand (light.direction), light.cone);
|
||||||
|
DARRAY_APPEND (&lctx->lights, light);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// targets does not own the objects, so need to remove them before
|
||||||
|
// freeing targets
|
||||||
|
for (int i = PL_D_NumKeys (targets); i-- > 0; ) {
|
||||||
|
PL_RemoveObjectForKey (targets, PL_KeyAtIndex (targets, i));
|
||||||
|
}
|
||||||
|
PL_Free (targets);
|
||||||
|
PL_Free (entities);
|
||||||
|
}
|
||||||
|
printf ("loaded %zd lights\n", lctx->lights.size);
|
||||||
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include "QF/Vulkan/qf_alias.h"
|
#include "QF/Vulkan/qf_alias.h"
|
||||||
#include "QF/Vulkan/qf_bsp.h"
|
#include "QF/Vulkan/qf_bsp.h"
|
||||||
//#include "QF/Vulkan/qf_iqm.h"
|
//#include "QF/Vulkan/qf_iqm.h"
|
||||||
|
#include "QF/Vulkan/qf_lighting.h"
|
||||||
#include "QF/Vulkan/qf_lightmap.h"
|
#include "QF/Vulkan/qf_lightmap.h"
|
||||||
#include "QF/Vulkan/qf_main.h"
|
#include "QF/Vulkan/qf_main.h"
|
||||||
#include "QF/Vulkan/qf_particles.h"
|
#include "QF/Vulkan/qf_particles.h"
|
||||||
|
@ -217,6 +218,7 @@ Vulkan_NewMap (model_t *worldmodel, struct model_s **models, int num_models,
|
||||||
Vulkan_RegisterTextures (models, num_models, ctx);
|
Vulkan_RegisterTextures (models, num_models, ctx);
|
||||||
Vulkan_BuildLightmaps (models, num_models, ctx);
|
Vulkan_BuildLightmaps (models, num_models, ctx);
|
||||||
Vulkan_BuildDisplayLists (models, num_models, ctx);
|
Vulkan_BuildDisplayLists (models, num_models, ctx);
|
||||||
|
Vulkan_LoadLights (worldmodel->brush.entities, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*void
|
/*void
|
||||||
|
|
Loading…
Reference in a new issue