rt: add moving polygon lights support
This commit is contained in:
parent
f9bf0aadd0
commit
3a6bed136a
|
@ -283,7 +283,7 @@ void sampleEmissiveSurfaces(vec3 P, vec3 N, vec3 throughput, vec3 view_dir, Mate
|
|||
|
||||
#elif DO_ALL_IN_CLUSTER
|
||||
const SampleContext ctx = buildSampleContext(P, N, view_dir);
|
||||
const uint num_polygons = min(128, uint(light_grid.clusters[cluster_index].num_polygons));
|
||||
const uint num_polygons = uint(light_grid.clusters[cluster_index].num_polygons);
|
||||
for (uint i = 0; i < num_polygons; ++i) {
|
||||
const uint index = uint(light_grid.clusters[cluster_index].polygons[i]);
|
||||
const PolygonLight poly = lights.polygons[index];
|
||||
|
|
|
@ -19,6 +19,14 @@
|
|||
#include <math.h>
|
||||
#include <memory.h>
|
||||
|
||||
typedef struct vk_brush_model_s {
|
||||
vk_render_model_t render_model;
|
||||
int num_water_surfaces;
|
||||
|
||||
rt_light_add_polygon_t *polylights;
|
||||
int polylights_count;
|
||||
} vk_brush_model_t;
|
||||
|
||||
static struct {
|
||||
struct {
|
||||
int num_vertices, num_indices;
|
||||
|
@ -326,7 +334,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 )
|
||||
void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, const matrix4x4 model )
|
||||
{
|
||||
// Expect all buffers to be bound
|
||||
const model_t *mod = ent->model;
|
||||
|
@ -344,6 +352,13 @@ void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode )
|
|||
if (bmodel->render_model.num_geometries == 0)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < bmodel->polylights_count; ++i) {
|
||||
rt_light_add_polygon_t *polylight = bmodel->polylights + i;
|
||||
polylight->transform_row = (const matrix3x4*)model;
|
||||
polylight->dynamic = true;
|
||||
RT_LightAddPolygon(polylight);
|
||||
}
|
||||
|
||||
for (int i = 0; i < bmodel->render_model.num_geometries; ++i) {
|
||||
vk_render_geometry_t *geom = bmodel->render_model.geometries + i;
|
||||
const int surface_index = geom->surf - mod->surfaces;
|
||||
|
@ -413,6 +428,7 @@ typedef struct {
|
|||
int max_texture_id;
|
||||
int water_surfaces;
|
||||
//int sky_surfaces;
|
||||
int emissive_surfaces;
|
||||
} model_sizes_t;
|
||||
|
||||
static model_sizes_t computeSizes( const model_t *mod ) {
|
||||
|
@ -422,6 +438,7 @@ static model_sizes_t computeSizes( const model_t *mod ) {
|
|||
{
|
||||
const int surface_index = mod->firstmodelsurface + i;
|
||||
const msurface_t *surf = mod->surfaces + surface_index;
|
||||
const int tex_id = surf->texinfo->texture->gl_texturenum;
|
||||
|
||||
sizes.water_surfaces += !!(surf->flags & (SURF_DRAWTURB | SURF_DRAWTURB_QUADS));
|
||||
|
||||
|
@ -431,15 +448,22 @@ static model_sizes_t computeSizes( const model_t *mod ) {
|
|||
++sizes.num_surfaces;
|
||||
sizes.num_vertices += surf->numedges;
|
||||
sizes.num_indices += 3 * (surf->numedges - 1);
|
||||
if (surf->texinfo->texture->gl_texturenum > sizes.max_texture_id)
|
||||
sizes.max_texture_id = surf->texinfo->texture->gl_texturenum;
|
||||
if (tex_id > sizes.max_texture_id)
|
||||
sizes.max_texture_id = tex_id;
|
||||
|
||||
{
|
||||
const xvk_patch_surface_t *const psurf = g_map_entities.patch.surfaces ? g_map_entities.patch.surfaces + surface_index : NULL;
|
||||
vec3_t emissive;
|
||||
if ((psurf && (psurf->flags & Patch_Surface_Emissive)) || (RT_GetEmissiveForTexture(emissive, tex_id)))
|
||||
++sizes.emissive_surfaces;
|
||||
}
|
||||
}
|
||||
|
||||
return sizes;
|
||||
}
|
||||
|
||||
static void loadEmissiveSurface(const model_t *mod, const int surface_index, const msurface_t *surf, const vec3_t emissive) {
|
||||
rt_light_add_polygon_t lpoly;
|
||||
static rt_light_add_polygon_t loadPolyLight(const model_t *mod, const int surface_index, const msurface_t *surf, const vec3_t emissive) {
|
||||
rt_light_add_polygon_t lpoly = {0};
|
||||
lpoly.num_vertices = Q_min(7, surf->numedges);
|
||||
|
||||
// TODO split, don't clip
|
||||
|
@ -456,7 +480,7 @@ static void loadEmissiveSurface(const model_t *mod, const int surface_index, con
|
|||
}
|
||||
|
||||
lpoly.surface = surf;
|
||||
RT_LightAddPolygon(&lpoly);
|
||||
return lpoly;
|
||||
}
|
||||
|
||||
static qboolean loadBrushSurfaces( model_sizes_t sizes, const model_t *mod ) {
|
||||
|
@ -504,11 +528,25 @@ static qboolean loadBrushSurfaces( model_sizes_t sizes, const model_t *mod ) {
|
|||
|
||||
// FIXME move this to rt_light_bsp and static loading
|
||||
{
|
||||
qboolean is_emissive = false;
|
||||
vec3_t emissive;
|
||||
rt_light_add_polygon_t polylight;
|
||||
|
||||
if (psurf && (psurf->flags & Patch_Surface_Emissive)) {
|
||||
loadEmissiveSurface(mod, surface_index, surf, psurf->emissive);
|
||||
is_emissive = true;
|
||||
VectorCopy(psurf->emissive, emissive);
|
||||
} else if (RT_GetEmissiveForTexture(emissive, tex_id)) {
|
||||
loadEmissiveSurface(mod, surface_index, surf, emissive);
|
||||
is_emissive = true;
|
||||
}
|
||||
|
||||
if (is_emissive) {
|
||||
if (bmodel->polylights) {
|
||||
ASSERT(bmodel->polylights_count < sizes.emissive_surfaces);
|
||||
bmodel->polylights[bmodel->polylights_count++] = loadPolyLight(mod, surface_index, surf, emissive);
|
||||
} else {
|
||||
polylight = loadPolyLight(mod, surface_index, surf, emissive);
|
||||
RT_LightAddPolygon(&polylight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -607,6 +645,10 @@ static qboolean loadBrushSurfaces( model_sizes_t sizes, const model_t *mod ) {
|
|||
XVK_RenderBufferUnlock( index_buffer.buffer );
|
||||
XVK_RenderBufferUnlock( vertex_buffer.buffer );
|
||||
|
||||
if (bmodel->polylights) {
|
||||
gEngine.Con_Reportf("WHAT %d %d \n", sizes.emissive_surfaces, bmodel->polylights_count);
|
||||
ASSERT(sizes.emissive_surfaces == bmodel->polylights_count);
|
||||
}
|
||||
ASSERT(sizes.num_surfaces == num_geometries);
|
||||
bmodel->render_model.num_geometries = num_geometries;
|
||||
|
||||
|
@ -640,6 +682,9 @@ qboolean VK_BrushModelLoad( model_t *mod, qboolean map )
|
|||
if (sizes.num_surfaces != 0) {
|
||||
bmodel->render_model.geometries = (vk_render_geometry_t*)((char*)(bmodel + 1));
|
||||
|
||||
if (!map && sizes.emissive_surfaces)
|
||||
bmodel->polylights = Mem_Malloc(vk_core.pool, sizeof(bmodel->polylights[0]) * sizes.emissive_surfaces);
|
||||
|
||||
if (!loadBrushSurfaces(sizes, mod) || !VK_RenderModelInit(&bmodel->render_model)) {
|
||||
gEngine.Con_Printf(S_ERROR "Could not load model %s\n", mod->name);
|
||||
Mem_Free(bmodel);
|
||||
|
@ -663,6 +708,8 @@ void VK_BrushModelDestroy( model_t *mod ) {
|
|||
return;
|
||||
|
||||
VK_RenderModelDestroy(&bmodel->render_model);
|
||||
if (bmodel->polylights)
|
||||
Mem_Free(bmodel->polylights);
|
||||
Mem_Free(bmodel);
|
||||
mod->cache.data = NULL;
|
||||
}
|
||||
|
|
|
@ -8,18 +8,13 @@ struct draw_list_s;
|
|||
struct model_s;
|
||||
struct cl_entity_s;
|
||||
|
||||
typedef struct vk_brush_model_s {
|
||||
vk_render_model_t render_model;
|
||||
int num_water_surfaces;
|
||||
} vk_brush_model_t;
|
||||
|
||||
qboolean VK_BrushInit( void );
|
||||
void VK_BrushShutdown( void );
|
||||
|
||||
qboolean VK_BrushModelLoad( struct model_s *mod, qboolean map);
|
||||
void VK_BrushModelDestroy( struct model_s *mod );
|
||||
|
||||
void VK_BrushModelDraw( const struct cl_entity_s *ent, int render_mode );
|
||||
void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, 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 );
|
||||
|
|
|
@ -1250,6 +1250,7 @@ int RT_LightAddPolygon(const rt_light_add_polygon_t *addpoly) {
|
|||
|
||||
{
|
||||
rt_light_polygon_t *const poly = g_lights.polygons + g_lights.num_polygons;
|
||||
vec3_t *vertices = g_lights.polygon_vertices + g_lights.num_polygon_vertices;
|
||||
vec3_t normal;
|
||||
|
||||
poly->vertices.offset = g_lights.num_polygon_vertices;
|
||||
|
@ -1260,13 +1261,16 @@ int RT_LightAddPolygon(const rt_light_add_polygon_t *addpoly) {
|
|||
VectorSet(normal, 0, 0, 0);
|
||||
|
||||
for (int i = 0; i < addpoly->num_vertices; ++i) {
|
||||
VectorCopy(addpoly->vertices[i], g_lights.polygon_vertices[poly->vertices.offset + i]);
|
||||
VectorAdd(addpoly->vertices[i], poly->center, poly->center);
|
||||
if (addpoly->transform_row)
|
||||
Matrix3x4_VectorTransform(*addpoly->transform_row, addpoly->vertices[i], vertices[i]);
|
||||
else
|
||||
VectorCopy(addpoly->vertices[i], vertices[i]);
|
||||
VectorAdd(vertices[i], poly->center, poly->center);
|
||||
|
||||
if (i > 1) {
|
||||
vec3_t e[2], lnormal;
|
||||
VectorSubtract(addpoly->vertices[i-0], addpoly->vertices[0], e[0]);
|
||||
VectorSubtract(addpoly->vertices[i-1], addpoly->vertices[0], e[1]);
|
||||
VectorSubtract(vertices[i-0], vertices[0], e[0]);
|
||||
VectorSubtract(vertices[i-1], vertices[0], e[1]);
|
||||
CrossProduct(e[0], e[1], lnormal);
|
||||
VectorAdd(lnormal, normal, normal);
|
||||
}
|
||||
|
@ -1274,28 +1278,32 @@ int RT_LightAddPolygon(const rt_light_add_polygon_t *addpoly) {
|
|||
|
||||
poly->area = VectorLength(normal);
|
||||
VectorM(1.f / poly->area, normal, poly->plane);
|
||||
poly->plane[3] = -DotProduct(addpoly->vertices[0], poly->plane);
|
||||
poly->plane[3] = -DotProduct(vertices[0], poly->plane);
|
||||
|
||||
VectorM(1.f / poly->vertices.count, poly->center, poly->center);
|
||||
|
||||
gEngine.Con_Reportf("added polygon light index=%d color=(%f, %f, %f) center=(%f, %f, %f) plane=(%f, %f, %f, %f) area=%f num_vertices=%d\n",
|
||||
g_lights.num_polygons,
|
||||
poly->emissive[0],
|
||||
poly->emissive[1],
|
||||
poly->emissive[2],
|
||||
poly->center[0],
|
||||
poly->center[1],
|
||||
poly->center[2],
|
||||
poly->plane[0],
|
||||
poly->plane[1],
|
||||
poly->plane[2],
|
||||
poly->plane[3],
|
||||
poly->area,
|
||||
poly->vertices.count
|
||||
);
|
||||
if (!addpoly->dynamic || debug_dump_lights.enabled) {
|
||||
gEngine.Con_Reportf("added polygon light index=%d color=(%f, %f, %f) center=(%f, %f, %f) plane=(%f, %f, %f, %f) area=%f num_vertices=%d\n",
|
||||
g_lights.num_polygons,
|
||||
poly->emissive[0],
|
||||
poly->emissive[1],
|
||||
poly->emissive[2],
|
||||
poly->center[0],
|
||||
poly->center[1],
|
||||
poly->center[2],
|
||||
poly->plane[0],
|
||||
poly->plane[1],
|
||||
poly->plane[2],
|
||||
poly->plane[3],
|
||||
poly->area,
|
||||
poly->vertices.count
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
const vk_light_leaf_set_t *const leafs = getMapLeafsAffectedByMapSurface(addpoly->surface);
|
||||
const vk_light_leaf_set_t *const leafs = addpoly->dynamic
|
||||
? getMapLeafsAffectedByMovingSurface( addpoly->surface, addpoly->transform_row )
|
||||
: getMapLeafsAffectedByMapSurface( addpoly->surface );
|
||||
addPolygonLeafSetToClusters(leafs, g_lights.num_polygons);
|
||||
}
|
||||
|
||||
|
|
|
@ -122,5 +122,8 @@ typedef struct {
|
|||
// - bsp/xash/rad/patch-specific stuff
|
||||
// - mostly engine-agnostic light clusters
|
||||
const struct msurface_s *surface;
|
||||
|
||||
qboolean dynamic;
|
||||
const matrix3x4 *transform_row;
|
||||
} rt_light_add_polygon_t;
|
||||
int RT_LightAddPolygon(const rt_light_add_polygon_t *light);
|
||||
|
|
|
@ -577,7 +577,7 @@ static void drawEntity( cl_entity_t *ent, int render_mode )
|
|||
case mod_brush:
|
||||
R_RotateForEntity( model, ent );
|
||||
VK_RenderStateSetMatrixModel( model );
|
||||
VK_BrushModelDraw( ent, render_mode );
|
||||
VK_BrushModelDraw( ent, render_mode, model );
|
||||
break;
|
||||
|
||||
case mod_studio:
|
||||
|
@ -629,7 +629,7 @@ void VK_SceneRender( const ref_viewpass_t *rvp ) {
|
|||
//VK_LightsBakePVL( 0 /* FIXME frame number */);
|
||||
|
||||
VK_RenderStateSetColor( 1.f, 1.f, 1.f, 1.f);
|
||||
VK_BrushModelDraw( world, kRenderNormal );
|
||||
VK_BrushModelDraw( world, kRenderNormal, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue