mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-29 15:51:45 +00:00
R_RecursiveLightPoint: Share part of light logic
This commit is contained in:
parent
a381c9dc5d
commit
8f5a40710b
18 changed files with 548 additions and 1108 deletions
1
Makefile
1
Makefile
|
@ -1141,6 +1141,7 @@ REFVK_OBJS_ := \
|
||||||
src/client/refresh/vk/vk_draw.o \
|
src/client/refresh/vk/vk_draw.o \
|
||||||
src/client/refresh/vk/vk_image.o \
|
src/client/refresh/vk/vk_image.o \
|
||||||
src/client/refresh/vk/vk_light.o \
|
src/client/refresh/vk/vk_light.o \
|
||||||
|
src/client/refresh/vk/vk_lightmap.o \
|
||||||
src/client/refresh/vk/vk_mesh.o \
|
src/client/refresh/vk/vk_mesh.o \
|
||||||
src/client/refresh/vk/vk_model.o \
|
src/client/refresh/vk/vk_model.o \
|
||||||
src/client/refresh/vk/vk_pipeline.o \
|
src/client/refresh/vk/vk_pipeline.o \
|
||||||
|
|
|
@ -92,3 +92,126 @@ BSPX_LightGridValue(const bspxlightgrid_t *grid, const lightstyle_t *lightstyles
|
||||||
|
|
||||||
VectorScale(res_diffuse, 1.0/s, res_diffuse); //average the successful ones
|
VectorScale(res_diffuse, 1.0/s, res_diffuse); //average the successful ones
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
R_RecursiveLightPoint(const msurface_t *surfaces, const mnode_t *node,
|
||||||
|
const lightstyle_t *lightstyles, const vec3_t start, const vec3_t end,
|
||||||
|
vec3_t pointcolor, vec3_t lightspot, float modulate)
|
||||||
|
{
|
||||||
|
float front, back, frac;
|
||||||
|
int side;
|
||||||
|
cplane_t *plane;
|
||||||
|
vec3_t mid;
|
||||||
|
const msurface_t *surf;
|
||||||
|
int s, t, ds, dt;
|
||||||
|
int i;
|
||||||
|
mtexinfo_t *tex;
|
||||||
|
byte *lightmap;
|
||||||
|
int maps;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (node->contents != CONTENTS_NODE)
|
||||||
|
{
|
||||||
|
return -1; /* didn't hit anything */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate mid point */
|
||||||
|
plane = node->plane;
|
||||||
|
front = DotProduct(start, plane->normal) - plane->dist;
|
||||||
|
back = DotProduct(end, plane->normal) - plane->dist;
|
||||||
|
side = front < 0;
|
||||||
|
|
||||||
|
if ((back < 0) == side)
|
||||||
|
{
|
||||||
|
return R_RecursiveLightPoint(surfaces, node->children[side],
|
||||||
|
lightstyles, start, end, pointcolor, lightspot, modulate);
|
||||||
|
}
|
||||||
|
|
||||||
|
frac = front / (front - back);
|
||||||
|
mid[0] = start[0] + (end[0] - start[0]) * frac;
|
||||||
|
mid[1] = start[1] + (end[1] - start[1]) * frac;
|
||||||
|
mid[2] = start[2] + (end[2] - start[2]) * frac;
|
||||||
|
|
||||||
|
/* go down front side */
|
||||||
|
r = R_RecursiveLightPoint(surfaces, node->children[side],
|
||||||
|
lightstyles, start, mid, pointcolor, lightspot, modulate);
|
||||||
|
if (r >= 0)
|
||||||
|
{
|
||||||
|
return r; /* hit something */
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((back < 0) == side)
|
||||||
|
{
|
||||||
|
return -1; /* didn't hit anuthing */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for impact on this node */
|
||||||
|
VectorCopy(mid, lightspot);
|
||||||
|
|
||||||
|
surf = surfaces + node->firstsurface;
|
||||||
|
for (i = 0; i < node->numsurfaces; i++, surf++)
|
||||||
|
{
|
||||||
|
if (surf->flags & (SURF_DRAWTURB | SURF_DRAWSKY))
|
||||||
|
{
|
||||||
|
continue; /* no lightmaps */
|
||||||
|
}
|
||||||
|
|
||||||
|
tex = surf->texinfo;
|
||||||
|
|
||||||
|
s = DotProduct(mid, tex->vecs[0]) + tex->vecs[0][3];
|
||||||
|
t = DotProduct(mid, tex->vecs[1]) + tex->vecs[1][3];
|
||||||
|
|
||||||
|
if ((s < surf->texturemins[0]) ||
|
||||||
|
(t < surf->texturemins[1]))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ds = s - surf->texturemins[0];
|
||||||
|
dt = t - surf->texturemins[1];
|
||||||
|
|
||||||
|
if ((ds > surf->extents[0]) || (dt > surf->extents[1]))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!surf->samples)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ds >>= surf->lmshift;
|
||||||
|
dt >>= surf->lmshift;
|
||||||
|
|
||||||
|
lightmap = surf->samples;
|
||||||
|
VectorCopy(vec3_origin, pointcolor);
|
||||||
|
|
||||||
|
lightmap += 3 * (dt * ((surf->extents[0] >> surf->lmshift) + 1) + ds);
|
||||||
|
|
||||||
|
for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++)
|
||||||
|
{
|
||||||
|
const float *rgb;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
rgb = lightstyles[surf->styles[maps]].rgb;
|
||||||
|
|
||||||
|
/* Apply light level to models */
|
||||||
|
for (j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
float scale;
|
||||||
|
|
||||||
|
scale = rgb[j] * modulate;
|
||||||
|
pointcolor[j] += lightmap[j] * scale * (1.0 / 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
lightmap += 3 * ((surf->extents[0] >> surf->lmshift) + 1) *
|
||||||
|
((surf->extents[1] >> surf->lmshift) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* go down back side */
|
||||||
|
return R_RecursiveLightPoint(surfaces, node->children[!side],
|
||||||
|
lightstyles, mid, end, pointcolor, lightspot, modulate);
|
||||||
|
}
|
||||||
|
|
|
@ -181,129 +181,6 @@ R_PushDlights(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
R_RecursiveLightPoint(const msurface_t *surfaces, const mnode_t *node,
|
|
||||||
const lightstyle_t *lightstyles, const vec3_t start, const vec3_t end,
|
|
||||||
vec3_t pointcolor, vec3_t lightspot)
|
|
||||||
{
|
|
||||||
float front, back, frac;
|
|
||||||
int side;
|
|
||||||
cplane_t *plane;
|
|
||||||
vec3_t mid;
|
|
||||||
const msurface_t *surf;
|
|
||||||
int s, t, ds, dt;
|
|
||||||
int i;
|
|
||||||
mtexinfo_t *tex;
|
|
||||||
byte *lightmap;
|
|
||||||
int maps;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (node->contents != CONTENTS_NODE)
|
|
||||||
{
|
|
||||||
return -1; /* didn't hit anything */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* calculate mid point */
|
|
||||||
plane = node->plane;
|
|
||||||
front = DotProduct(start, plane->normal) - plane->dist;
|
|
||||||
back = DotProduct(end, plane->normal) - plane->dist;
|
|
||||||
side = front < 0;
|
|
||||||
|
|
||||||
if ((back < 0) == side)
|
|
||||||
{
|
|
||||||
return R_RecursiveLightPoint(surfaces, node->children[side],
|
|
||||||
lightstyles, start, end, pointcolor, lightspot);
|
|
||||||
}
|
|
||||||
|
|
||||||
frac = front / (front - back);
|
|
||||||
mid[0] = start[0] + (end[0] - start[0]) * frac;
|
|
||||||
mid[1] = start[1] + (end[1] - start[1]) * frac;
|
|
||||||
mid[2] = start[2] + (end[2] - start[2]) * frac;
|
|
||||||
|
|
||||||
/* go down front side */
|
|
||||||
r = R_RecursiveLightPoint(surfaces, node->children[side],
|
|
||||||
lightstyles, start, mid, pointcolor, lightspot);
|
|
||||||
if (r >= 0)
|
|
||||||
{
|
|
||||||
return r; /* hit something */
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((back < 0) == side)
|
|
||||||
{
|
|
||||||
return -1; /* didn't hit anuthing */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for impact on this node */
|
|
||||||
VectorCopy(mid, lightspot);
|
|
||||||
|
|
||||||
surf = surfaces + node->firstsurface;
|
|
||||||
for (i = 0; i < node->numsurfaces; i++, surf++)
|
|
||||||
{
|
|
||||||
if (surf->flags & (SURF_DRAWTURB | SURF_DRAWSKY))
|
|
||||||
{
|
|
||||||
continue; /* no lightmaps */
|
|
||||||
}
|
|
||||||
|
|
||||||
tex = surf->texinfo;
|
|
||||||
|
|
||||||
s = DotProduct(mid, tex->vecs[0]) + tex->vecs[0][3];
|
|
||||||
t = DotProduct(mid, tex->vecs[1]) + tex->vecs[1][3];
|
|
||||||
|
|
||||||
if ((s < surf->texturemins[0]) ||
|
|
||||||
(t < surf->texturemins[1]))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ds = s - surf->texturemins[0];
|
|
||||||
dt = t - surf->texturemins[1];
|
|
||||||
|
|
||||||
if ((ds > surf->extents[0]) || (dt > surf->extents[1]))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!surf->samples)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ds >>= surf->lmshift;
|
|
||||||
dt >>= surf->lmshift;
|
|
||||||
|
|
||||||
lightmap = surf->samples;
|
|
||||||
VectorCopy(vec3_origin, pointcolor);
|
|
||||||
|
|
||||||
lightmap += 3 * (dt * ((surf->extents[0] >> surf->lmshift) + 1) + ds);
|
|
||||||
|
|
||||||
for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++)
|
|
||||||
{
|
|
||||||
const float *rgb;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
rgb = lightstyles[surf->styles[maps]].rgb;
|
|
||||||
|
|
||||||
/* Apply light level to models */
|
|
||||||
for (j = 0; j < 3; j++)
|
|
||||||
{
|
|
||||||
float scale;
|
|
||||||
|
|
||||||
scale = rgb[j] * r_modulate->value;
|
|
||||||
pointcolor[j] += lightmap[j] * scale * (1.0 / 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
lightmap += 3 * ((surf->extents[0] >> surf->lmshift) + 1) *
|
|
||||||
((surf->extents[1] >> surf->lmshift) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* go down back side */
|
|
||||||
return R_RecursiveLightPoint(surfaces, node->children[!side],
|
|
||||||
lightstyles, mid, end, pointcolor, lightspot);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
R_LightPoint(entity_t *currententity, vec3_t p, vec3_t color)
|
R_LightPoint(entity_t *currententity, vec3_t p, vec3_t color)
|
||||||
{
|
{
|
||||||
|
@ -324,7 +201,7 @@ R_LightPoint(entity_t *currententity, vec3_t p, vec3_t color)
|
||||||
end[2] = p[2] - 2048;
|
end[2] = p[2] - 2048;
|
||||||
|
|
||||||
r = R_RecursiveLightPoint(r_worldmodel->surfaces, r_worldmodel->nodes,
|
r = R_RecursiveLightPoint(r_worldmodel->surfaces, r_worldmodel->nodes,
|
||||||
r_newrefdef.lightstyles, p, end, pointcolor, lightspot);
|
r_newrefdef.lightstyles, p, end, pointcolor, lightspot, r_modulate->value);
|
||||||
|
|
||||||
if (r == -1)
|
if (r == -1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,8 +27,6 @@
|
||||||
#ifndef REF_MODEL_H
|
#ifndef REF_MODEL_H
|
||||||
#define REF_MODEL_H
|
#define REF_MODEL_H
|
||||||
|
|
||||||
#include "../../ref_model.h"
|
|
||||||
|
|
||||||
/* Whole model */
|
/* Whole model */
|
||||||
|
|
||||||
typedef struct model_s
|
typedef struct model_s
|
||||||
|
|
|
@ -106,129 +106,6 @@ GL3_PushDlights(void)
|
||||||
GL3_UpdateUBOLights();
|
GL3_UpdateUBOLights();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
R_RecursiveLightPoint(const msurface_t *surfaces, const mnode_t *node,
|
|
||||||
const lightstyle_t *lightstyles, const vec3_t start, const vec3_t end,
|
|
||||||
vec3_t pointcolor, vec3_t lightspot)
|
|
||||||
{
|
|
||||||
float front, back, frac;
|
|
||||||
int side;
|
|
||||||
cplane_t *plane;
|
|
||||||
vec3_t mid;
|
|
||||||
const msurface_t *surf;
|
|
||||||
int s, t, ds, dt;
|
|
||||||
int i;
|
|
||||||
mtexinfo_t *tex;
|
|
||||||
byte *lightmap;
|
|
||||||
int maps;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (node->contents != CONTENTS_NODE)
|
|
||||||
{
|
|
||||||
return -1; /* didn't hit anything */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* calculate mid point */
|
|
||||||
plane = node->plane;
|
|
||||||
front = DotProduct(start, plane->normal) - plane->dist;
|
|
||||||
back = DotProduct(end, plane->normal) - plane->dist;
|
|
||||||
side = front < 0;
|
|
||||||
|
|
||||||
if ((back < 0) == side)
|
|
||||||
{
|
|
||||||
return R_RecursiveLightPoint(surfaces, node->children[side],
|
|
||||||
lightstyles, start, end, pointcolor, lightspot);
|
|
||||||
}
|
|
||||||
|
|
||||||
frac = front / (front - back);
|
|
||||||
mid[0] = start[0] + (end[0] - start[0]) * frac;
|
|
||||||
mid[1] = start[1] + (end[1] - start[1]) * frac;
|
|
||||||
mid[2] = start[2] + (end[2] - start[2]) * frac;
|
|
||||||
|
|
||||||
/* go down front side */
|
|
||||||
r = R_RecursiveLightPoint(surfaces, node->children[side],
|
|
||||||
lightstyles, start, mid, pointcolor, lightspot);
|
|
||||||
if (r >= 0)
|
|
||||||
{
|
|
||||||
return r; /* hit something */
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((back < 0) == side)
|
|
||||||
{
|
|
||||||
return -1; /* didn't hit anuthing */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for impact on this node */
|
|
||||||
VectorCopy(mid, lightspot);
|
|
||||||
|
|
||||||
surf = surfaces + node->firstsurface;
|
|
||||||
for (i = 0; i < node->numsurfaces; i++, surf++)
|
|
||||||
{
|
|
||||||
if (surf->flags & (SURF_DRAWTURB | SURF_DRAWSKY))
|
|
||||||
{
|
|
||||||
continue; /* no lightmaps */
|
|
||||||
}
|
|
||||||
|
|
||||||
tex = surf->texinfo;
|
|
||||||
|
|
||||||
s = DotProduct(mid, tex->vecs[0]) + tex->vecs[0][3];
|
|
||||||
t = DotProduct(mid, tex->vecs[1]) + tex->vecs[1][3];
|
|
||||||
|
|
||||||
if ((s < surf->texturemins[0]) ||
|
|
||||||
(t < surf->texturemins[1]))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ds = s - surf->texturemins[0];
|
|
||||||
dt = t - surf->texturemins[1];
|
|
||||||
|
|
||||||
if ((ds > surf->extents[0]) || (dt > surf->extents[1]))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!surf->samples)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ds >>= surf->lmshift;
|
|
||||||
dt >>= surf->lmshift;
|
|
||||||
|
|
||||||
lightmap = surf->samples;
|
|
||||||
VectorCopy(vec3_origin, pointcolor);
|
|
||||||
|
|
||||||
lightmap += 3 * (dt * ((surf->extents[0] >> surf->lmshift) + 1) + ds);
|
|
||||||
|
|
||||||
for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++)
|
|
||||||
{
|
|
||||||
const float *rgb;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
rgb = lightstyles[surf->styles[maps]].rgb;
|
|
||||||
|
|
||||||
/* Apply light level to models */
|
|
||||||
for (j = 0; j < 3; j++)
|
|
||||||
{
|
|
||||||
float scale;
|
|
||||||
|
|
||||||
scale = rgb[j] * r_modulate->value;
|
|
||||||
pointcolor[j] += lightmap[j] * scale * (1.0 / 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
lightmap += 3 * ((surf->extents[0] >> surf->lmshift) + 1) *
|
|
||||||
((surf->extents[1] >> surf->lmshift) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* go down back side */
|
|
||||||
return R_RecursiveLightPoint(surfaces, node->children[!side],
|
|
||||||
lightstyles, mid, end, pointcolor, lightspot);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
GL3_LightPoint(entity_t *currententity, vec3_t p, vec3_t color)
|
GL3_LightPoint(entity_t *currententity, vec3_t p, vec3_t color)
|
||||||
{
|
{
|
||||||
|
@ -252,7 +129,7 @@ GL3_LightPoint(entity_t *currententity, vec3_t p, vec3_t color)
|
||||||
// TODO: don't just aggregate the color, but also save position of brightest+nearest light
|
// TODO: don't just aggregate the color, but also save position of brightest+nearest light
|
||||||
// for shadow position and maybe lighting on model?
|
// for shadow position and maybe lighting on model?
|
||||||
r = R_RecursiveLightPoint(gl3_worldmodel->surfaces, gl3_worldmodel->nodes,
|
r = R_RecursiveLightPoint(gl3_worldmodel->surfaces, gl3_worldmodel->nodes,
|
||||||
gl3_newrefdef.lightstyles, p, end, pointcolor, lightspot);
|
gl3_newrefdef.lightstyles, p, end, pointcolor, lightspot, r_modulate->value);
|
||||||
|
|
||||||
if (r == -1)
|
if (r == -1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,40 +36,6 @@ typedef struct gl3_alias_vtx_s {
|
||||||
|
|
||||||
/* in memory representation */
|
/* in memory representation */
|
||||||
|
|
||||||
typedef struct msurface_s
|
|
||||||
{
|
|
||||||
int visframe; /* should be drawn when node is crossed */
|
|
||||||
|
|
||||||
cplane_t *plane;
|
|
||||||
int flags;
|
|
||||||
|
|
||||||
int firstedge; /* look up in model->surfedges[], negative numbers */
|
|
||||||
int numedges; /* are backwards edges */
|
|
||||||
|
|
||||||
short texturemins[2];
|
|
||||||
short extents[2];
|
|
||||||
short lmshift;
|
|
||||||
|
|
||||||
int light_s, light_t; /* gl lightmap coordinates */
|
|
||||||
int dlight_s, dlight_t; /* gl lightmap coordinates for dynamic lightmaps */
|
|
||||||
|
|
||||||
mpoly_t *polys; /* multiple if warped */
|
|
||||||
struct msurface_s *texturechain;
|
|
||||||
// struct msurface_s *lightmapchain; not used/needed anymore
|
|
||||||
|
|
||||||
mtexinfo_t *texinfo;
|
|
||||||
|
|
||||||
/* lighting info */
|
|
||||||
int dlightframe;
|
|
||||||
int dlightbits;
|
|
||||||
|
|
||||||
int lightmaptexturenum;
|
|
||||||
byte styles[MAXLIGHTMAPS]; // MAXLIGHTMAPS = MAX_LIGHTMAPS_PER_SURFACE (defined in local.h)
|
|
||||||
// I think cached_light is not used/needed anymore
|
|
||||||
//float cached_light[MAXLIGHTMAPS]; /* values currently used in lightmap */
|
|
||||||
byte *samples; /* [numstyles*surfsize] */
|
|
||||||
} msurface_t;
|
|
||||||
|
|
||||||
/* Whole model */
|
/* Whole model */
|
||||||
|
|
||||||
// this, must be struct model_s, not gl3model_s,
|
// this, must be struct model_s, not gl3model_s,
|
||||||
|
|
|
@ -106,129 +106,6 @@ GL4_PushDlights(void)
|
||||||
GL4_UpdateUBOLights();
|
GL4_UpdateUBOLights();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
R_RecursiveLightPoint(const msurface_t *surfaces, const mnode_t *node,
|
|
||||||
const lightstyle_t *lightstyles, const vec3_t start, const vec3_t end,
|
|
||||||
vec3_t pointcolor, vec3_t lightspot)
|
|
||||||
{
|
|
||||||
float front, back, frac;
|
|
||||||
int side;
|
|
||||||
cplane_t *plane;
|
|
||||||
vec3_t mid;
|
|
||||||
const msurface_t *surf;
|
|
||||||
int s, t, ds, dt;
|
|
||||||
int i;
|
|
||||||
mtexinfo_t *tex;
|
|
||||||
byte *lightmap;
|
|
||||||
int maps;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (node->contents != CONTENTS_NODE)
|
|
||||||
{
|
|
||||||
return -1; /* didn't hit anything */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* calculate mid point */
|
|
||||||
plane = node->plane;
|
|
||||||
front = DotProduct(start, plane->normal) - plane->dist;
|
|
||||||
back = DotProduct(end, plane->normal) - plane->dist;
|
|
||||||
side = front < 0;
|
|
||||||
|
|
||||||
if ((back < 0) == side)
|
|
||||||
{
|
|
||||||
return R_RecursiveLightPoint(surfaces, node->children[side],
|
|
||||||
lightstyles, start, end, pointcolor, lightspot);
|
|
||||||
}
|
|
||||||
|
|
||||||
frac = front / (front - back);
|
|
||||||
mid[0] = start[0] + (end[0] - start[0]) * frac;
|
|
||||||
mid[1] = start[1] + (end[1] - start[1]) * frac;
|
|
||||||
mid[2] = start[2] + (end[2] - start[2]) * frac;
|
|
||||||
|
|
||||||
/* go down front side */
|
|
||||||
r = R_RecursiveLightPoint(surfaces, node->children[side],
|
|
||||||
lightstyles, start, mid, pointcolor, lightspot);
|
|
||||||
if (r >= 0)
|
|
||||||
{
|
|
||||||
return r; /* hit something */
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((back < 0) == side)
|
|
||||||
{
|
|
||||||
return -1; /* didn't hit anuthing */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for impact on this node */
|
|
||||||
VectorCopy(mid, lightspot);
|
|
||||||
|
|
||||||
surf = surfaces + node->firstsurface;
|
|
||||||
for (i = 0; i < node->numsurfaces; i++, surf++)
|
|
||||||
{
|
|
||||||
if (surf->flags & (SURF_DRAWTURB | SURF_DRAWSKY))
|
|
||||||
{
|
|
||||||
continue; /* no lightmaps */
|
|
||||||
}
|
|
||||||
|
|
||||||
tex = surf->texinfo;
|
|
||||||
|
|
||||||
s = DotProduct(mid, tex->vecs[0]) + tex->vecs[0][3];
|
|
||||||
t = DotProduct(mid, tex->vecs[1]) + tex->vecs[1][3];
|
|
||||||
|
|
||||||
if ((s < surf->texturemins[0]) ||
|
|
||||||
(t < surf->texturemins[1]))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ds = s - surf->texturemins[0];
|
|
||||||
dt = t - surf->texturemins[1];
|
|
||||||
|
|
||||||
if ((ds > surf->extents[0]) || (dt > surf->extents[1]))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!surf->samples)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ds >>= surf->lmshift;
|
|
||||||
dt >>= surf->lmshift;
|
|
||||||
|
|
||||||
lightmap = surf->samples;
|
|
||||||
VectorCopy(vec3_origin, pointcolor);
|
|
||||||
|
|
||||||
lightmap += 3 * (dt * ((surf->extents[0] >> surf->lmshift) + 1) + ds);
|
|
||||||
|
|
||||||
for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++)
|
|
||||||
{
|
|
||||||
const float *rgb;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
rgb = lightstyles[surf->styles[maps]].rgb;
|
|
||||||
|
|
||||||
/* Apply light level to models */
|
|
||||||
for (j = 0; j < 3; j++)
|
|
||||||
{
|
|
||||||
float scale;
|
|
||||||
|
|
||||||
scale = rgb[j] * r_modulate->value;
|
|
||||||
pointcolor[j] += lightmap[j] * scale * (1.0 / 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
lightmap += 3 * ((surf->extents[0] >> surf->lmshift) + 1) *
|
|
||||||
((surf->extents[1] >> surf->lmshift) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* go down back side */
|
|
||||||
return R_RecursiveLightPoint(surfaces, node->children[!side],
|
|
||||||
lightstyles, mid, end, pointcolor, lightspot);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
GL4_LightPoint(entity_t *currententity, vec3_t p, vec3_t color)
|
GL4_LightPoint(entity_t *currententity, vec3_t p, vec3_t color)
|
||||||
{
|
{
|
||||||
|
@ -252,7 +129,7 @@ GL4_LightPoint(entity_t *currententity, vec3_t p, vec3_t color)
|
||||||
// TODO: don't just aggregate the color, but also save position of brightest+nearest light
|
// TODO: don't just aggregate the color, but also save position of brightest+nearest light
|
||||||
// for shadow position and maybe lighting on model?
|
// for shadow position and maybe lighting on model?
|
||||||
r = R_RecursiveLightPoint(gl4_worldmodel->surfaces, gl4_worldmodel->nodes,
|
r = R_RecursiveLightPoint(gl4_worldmodel->surfaces, gl4_worldmodel->nodes,
|
||||||
gl4_newrefdef.lightstyles, p, end, pointcolor, lightspot);
|
gl4_newrefdef.lightstyles, p, end, pointcolor, lightspot, r_modulate->value);
|
||||||
|
|
||||||
if (r == -1)
|
if (r == -1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,40 +36,6 @@ typedef struct gl4_alias_vtx_s {
|
||||||
|
|
||||||
/* in memory representation */
|
/* in memory representation */
|
||||||
|
|
||||||
typedef struct msurface_s
|
|
||||||
{
|
|
||||||
int visframe; /* should be drawn when node is crossed */
|
|
||||||
|
|
||||||
cplane_t *plane;
|
|
||||||
int flags;
|
|
||||||
|
|
||||||
int firstedge; /* look up in model->surfedges[], negative numbers */
|
|
||||||
int numedges; /* are backwards edges */
|
|
||||||
|
|
||||||
short texturemins[2];
|
|
||||||
short extents[2];
|
|
||||||
short lmshift;
|
|
||||||
|
|
||||||
int light_s, light_t; /* gl lightmap coordinates */
|
|
||||||
int dlight_s, dlight_t; /* gl lightmap coordinates for dynamic lightmaps */
|
|
||||||
|
|
||||||
mpoly_t *polys; /* multiple if warped */
|
|
||||||
struct msurface_s *texturechain;
|
|
||||||
// struct msurface_s *lightmapchain; not used/needed anymore
|
|
||||||
|
|
||||||
mtexinfo_t *texinfo;
|
|
||||||
|
|
||||||
/* lighting info */
|
|
||||||
int dlightframe;
|
|
||||||
int dlightbits;
|
|
||||||
|
|
||||||
int lightmaptexturenum;
|
|
||||||
byte styles[MAXLIGHTMAPS]; // MAXLIGHTMAPS = MAX_LIGHTMAPS_PER_SURFACE (defined in local.h)
|
|
||||||
// I think cached_light is not used/needed anymore
|
|
||||||
//float cached_light[MAXLIGHTMAPS]; /* values currently used in lightmap */
|
|
||||||
byte *samples; /* [numstyles*surfsize] */
|
|
||||||
} msurface_t;
|
|
||||||
|
|
||||||
/* Whole model */
|
/* Whole model */
|
||||||
|
|
||||||
// this, must be struct model_s, not gl4model_s,
|
// this, must be struct model_s, not gl4model_s,
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
|
|
||||||
/* in memory representation */
|
|
||||||
|
|
||||||
typedef struct msurface_s
|
|
||||||
{
|
|
||||||
int visframe; /* should be drawn when node is crossed */
|
|
||||||
|
|
||||||
cplane_t *plane;
|
|
||||||
int flags;
|
|
||||||
|
|
||||||
int firstedge; /* look up in model->surfedges[], negative numbers */
|
|
||||||
int numedges; /* are backwards edges */
|
|
||||||
|
|
||||||
short texturemins[2];
|
|
||||||
short extents[2];
|
|
||||||
short lmshift;
|
|
||||||
|
|
||||||
int light_s, light_t; /* gl lightmap coordinates */
|
|
||||||
int dlight_s, dlight_t; /* gl lightmap coordinates for dynamic lightmaps */
|
|
||||||
|
|
||||||
mpoly_t *polys; /* multiple if warped */
|
|
||||||
struct msurface_s *texturechain;
|
|
||||||
struct msurface_s *lightmapchain;
|
|
||||||
|
|
||||||
mtexinfo_t *texinfo;
|
|
||||||
|
|
||||||
/* decoupled lm */
|
|
||||||
float lmvecs[2][4];
|
|
||||||
float lmvlen[2];
|
|
||||||
|
|
||||||
/* lighting info */
|
|
||||||
int dlightframe;
|
|
||||||
int dlightbits;
|
|
||||||
|
|
||||||
int lightmaptexturenum;
|
|
||||||
byte styles[MAXLIGHTMAPS];
|
|
||||||
float cached_light[MAXLIGHTMAPS]; /* values currently used in lightmap */
|
|
||||||
byte *samples; /* [numstyles*surfsize] */
|
|
||||||
} msurface_t;
|
|
|
@ -121,9 +121,11 @@ enum {
|
||||||
SURF_UNDERWATER = 0x80
|
SURF_UNDERWATER = 0x80
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* in memory representation */
|
||||||
|
|
||||||
typedef struct mvertex_s
|
typedef struct mvertex_s
|
||||||
{
|
{
|
||||||
vec3_t position;
|
vec3_t position;
|
||||||
} mvertex_t;
|
} mvertex_t;
|
||||||
|
|
||||||
typedef struct medge_s
|
typedef struct medge_s
|
||||||
|
@ -184,22 +186,80 @@ typedef struct mleaf_s
|
||||||
* (ok, it has the layout used for rendering brushes, but is not used there)
|
* (ok, it has the layout used for rendering brushes, but is not used there)
|
||||||
*/
|
*/
|
||||||
typedef struct mvtx_s {
|
typedef struct mvtx_s {
|
||||||
vec3_t pos;
|
vec3_t pos;
|
||||||
float texCoord[2];
|
float texCoord[2];
|
||||||
float lmTexCoord[2]; /* lightmap texture coordinate (sometimes unused) */
|
float lmTexCoord[2]; /* lightmap texture coordinate (sometimes unused) */
|
||||||
vec3_t normal;
|
vec3_t normal;
|
||||||
int lightFlags; /* bit i set means: dynlight i affects surface */
|
int lightFlags; /* bit i set means: dynlight i affects surface */
|
||||||
} mvtx_t;
|
} mvtx_t;
|
||||||
|
|
||||||
typedef struct mpoly_s
|
typedef struct mpoly_s
|
||||||
{
|
{
|
||||||
struct mpoly_s *next;
|
struct mpoly_s *next;
|
||||||
struct mpoly_s *chain;
|
struct mpoly_s *chain;
|
||||||
int numverts;
|
int numverts;
|
||||||
int flags; /* for SURF_UNDERWATER (not needed anymore?) */
|
int flags; /* for SURF_UNDERWATER (not needed anymore?) */
|
||||||
mvtx_t verts[4]; /* variable sized */
|
mvtx_t verts[4]; /* variable sized */
|
||||||
} mpoly_t;
|
} mpoly_t;
|
||||||
|
|
||||||
|
/* soft render specific surface cache */
|
||||||
|
typedef struct surfcache_s
|
||||||
|
{
|
||||||
|
struct surfcache_s *next;
|
||||||
|
struct surfcache_s **owner; /* NULL is an empty chunk of memory */
|
||||||
|
int lightadj[MAXLIGHTMAPS]; /* checked for strobe flush */
|
||||||
|
int dlight;
|
||||||
|
int size; /* including header */
|
||||||
|
unsigned width;
|
||||||
|
unsigned height; /* DEBUG only needed for debug */
|
||||||
|
float mipscale;
|
||||||
|
struct image_s *image;
|
||||||
|
byte data[4]; /* width * height elements */
|
||||||
|
} surfcache_t;
|
||||||
|
|
||||||
|
typedef struct msurface_s
|
||||||
|
{
|
||||||
|
int visframe; /* should be drawn when node is crossed */
|
||||||
|
|
||||||
|
cplane_t *plane;
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
int firstedge; /* look up in model->surfedges[], negative numbers */
|
||||||
|
int numedges; /* are backwards edges */
|
||||||
|
|
||||||
|
short texturemins[2];
|
||||||
|
short extents[2];
|
||||||
|
short lmshift;
|
||||||
|
|
||||||
|
int light_s, light_t; /* lightmap coordinates */
|
||||||
|
int dlight_s, dlight_t; /* lightmap coordinates for dynamic lightmaps */
|
||||||
|
|
||||||
|
mpoly_t *polys; /* multiple if warped */
|
||||||
|
struct msurface_s *texturechain;
|
||||||
|
struct msurface_s *lightmapchain;
|
||||||
|
|
||||||
|
mtexinfo_t *texinfo;
|
||||||
|
|
||||||
|
/* decoupled lm */
|
||||||
|
float lmvecs[2][4];
|
||||||
|
float lmvlen[2];
|
||||||
|
|
||||||
|
/* lighting info */
|
||||||
|
int dlightframe;
|
||||||
|
int dlightbits;
|
||||||
|
|
||||||
|
int lightmaptexturenum;
|
||||||
|
byte styles[MAXLIGHTMAPS];
|
||||||
|
byte *samples; /* [numstyles*surfsize] */
|
||||||
|
|
||||||
|
/* unused in gl* renders */
|
||||||
|
float cached_light[MAXLIGHTMAPS]; /* values currently used in lightmap */
|
||||||
|
|
||||||
|
/* used in soft only */
|
||||||
|
struct msurface_s *nextalphasurface;
|
||||||
|
struct surfcache_s *cachespots[MIPLEVELS]; /* surface generation data */
|
||||||
|
} msurface_t;
|
||||||
|
|
||||||
/* BSPX Light octtree */
|
/* BSPX Light octtree */
|
||||||
#define LGNODE_LEAF (1u<<31)
|
#define LGNODE_LEAF (1u<<31)
|
||||||
#define LGNODE_MISSING (1u<<30)
|
#define LGNODE_MISSING (1u<<30)
|
||||||
|
@ -306,5 +366,8 @@ extern void R_BoundPoly(int numverts, float *verts, vec3_t mins, vec3_t maxs);
|
||||||
extern bspxlightgrid_t *BSPX_LightGridLoad(const bspx_header_t *bspx_header, const byte *mod_base);
|
extern bspxlightgrid_t *BSPX_LightGridLoad(const bspx_header_t *bspx_header, const byte *mod_base);
|
||||||
extern void BSPX_LightGridValue(const bspxlightgrid_t *grid, const lightstyle_t *lightstyles,
|
extern void BSPX_LightGridValue(const bspxlightgrid_t *grid, const lightstyle_t *lightstyles,
|
||||||
const vec3_t point, vec3_t res_diffuse);
|
const vec3_t point, vec3_t res_diffuse);
|
||||||
|
extern int R_RecursiveLightPoint(const msurface_t *surfaces, const mnode_t *node,
|
||||||
|
const lightstyle_t *lightstyles, const vec3_t start, const vec3_t end,
|
||||||
|
vec3_t pointcolor, vec3_t lightspot, float modulate);
|
||||||
|
|
||||||
#endif /* SRC_CLIENT_REFRESH_REF_SHARED_H_ */
|
#endif /* SRC_CLIENT_REFRESH_REF_SHARED_H_ */
|
||||||
|
|
|
@ -252,20 +252,6 @@ typedef struct clipplane_s
|
||||||
byte rightedge;
|
byte rightedge;
|
||||||
} clipplane_t;
|
} clipplane_t;
|
||||||
|
|
||||||
typedef struct surfcache_s
|
|
||||||
{
|
|
||||||
struct surfcache_s *next;
|
|
||||||
struct surfcache_s **owner; // NULL is an empty chunk of memory
|
|
||||||
int lightadj[MAXLIGHTMAPS]; // checked for strobe flush
|
|
||||||
int dlight;
|
|
||||||
int size; // including header
|
|
||||||
unsigned width;
|
|
||||||
unsigned height; // DEBUG only needed for debug
|
|
||||||
float mipscale;
|
|
||||||
image_t *image;
|
|
||||||
byte data[4]; // width * height elements
|
|
||||||
} surfcache_t;
|
|
||||||
|
|
||||||
typedef struct espan_s
|
typedef struct espan_s
|
||||||
{
|
{
|
||||||
int u, v, count;
|
int u, v, count;
|
||||||
|
|
|
@ -42,35 +42,6 @@ BRUSH MODELS
|
||||||
// in memory representation
|
// in memory representation
|
||||||
//
|
//
|
||||||
|
|
||||||
typedef struct msurface_s
|
|
||||||
{
|
|
||||||
int visframe; // should be drawn when node is crossed
|
|
||||||
|
|
||||||
int dlightframe;
|
|
||||||
int dlightbits;
|
|
||||||
|
|
||||||
cplane_t *plane;
|
|
||||||
int flags;
|
|
||||||
|
|
||||||
int firstedge; // look up in model->surfedges[], negative numbers
|
|
||||||
int numedges; // are backwards edges
|
|
||||||
|
|
||||||
// surface generation data
|
|
||||||
struct surfcache_s *cachespots[MIPLEVELS];
|
|
||||||
|
|
||||||
short texturemins[2];
|
|
||||||
short extents[2];
|
|
||||||
short lmshift;
|
|
||||||
|
|
||||||
mtexinfo_t *texinfo;
|
|
||||||
|
|
||||||
// lighting info
|
|
||||||
byte styles[MAXLIGHTMAPS];
|
|
||||||
byte *samples; // [numstyles*surfsize*3]
|
|
||||||
|
|
||||||
struct msurface_s *nextalphasurface;
|
|
||||||
} msurface_t;
|
|
||||||
|
|
||||||
//===================================================================
|
//===================================================================
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -75,128 +75,6 @@ LIGHT SAMPLING
|
||||||
|
|
||||||
=============================================================================
|
=============================================================================
|
||||||
*/
|
*/
|
||||||
static int
|
|
||||||
R_RecursiveLightPoint(const msurface_t *surfaces, const mnode_t *node,
|
|
||||||
const lightstyle_t *lightstyles, const vec3_t start, const vec3_t end,
|
|
||||||
vec3_t pointcolor, vec3_t lightspot)
|
|
||||||
{
|
|
||||||
float front, back, frac;
|
|
||||||
int side;
|
|
||||||
cplane_t *plane;
|
|
||||||
vec3_t mid;
|
|
||||||
const msurface_t *surf;
|
|
||||||
int s, t, ds, dt;
|
|
||||||
int i;
|
|
||||||
mtexinfo_t *tex;
|
|
||||||
byte *lightmap;
|
|
||||||
int maps;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (node->contents != CONTENTS_NODE)
|
|
||||||
{
|
|
||||||
return -1; /* didn't hit anything */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* calculate mid point */
|
|
||||||
plane = node->plane;
|
|
||||||
front = DotProduct(start, plane->normal) - plane->dist;
|
|
||||||
back = DotProduct(end, plane->normal) - plane->dist;
|
|
||||||
side = front < 0;
|
|
||||||
|
|
||||||
if ((back < 0) == side)
|
|
||||||
{
|
|
||||||
return R_RecursiveLightPoint(surfaces, node->children[side],
|
|
||||||
lightstyles, start, end, pointcolor, lightspot);
|
|
||||||
}
|
|
||||||
|
|
||||||
frac = front / (front - back);
|
|
||||||
mid[0] = start[0] + (end[0] - start[0]) * frac;
|
|
||||||
mid[1] = start[1] + (end[1] - start[1]) * frac;
|
|
||||||
mid[2] = start[2] + (end[2] - start[2]) * frac;
|
|
||||||
|
|
||||||
/* go down front side */
|
|
||||||
r = R_RecursiveLightPoint(surfaces, node->children[side],
|
|
||||||
lightstyles, start, mid, pointcolor, lightspot);
|
|
||||||
if (r >= 0)
|
|
||||||
{
|
|
||||||
return r; /* hit something */
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((back < 0) == side)
|
|
||||||
{
|
|
||||||
return -1; /* didn't hit anuthing */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for impact on this node */
|
|
||||||
VectorCopy(mid, lightspot);
|
|
||||||
|
|
||||||
surf = surfaces + node->firstsurface;
|
|
||||||
for (i = 0; i < node->numsurfaces; i++, surf++)
|
|
||||||
{
|
|
||||||
if (surf->flags & (SURF_DRAWTURB | SURF_DRAWSKY))
|
|
||||||
{
|
|
||||||
continue; /* no lightmaps */
|
|
||||||
}
|
|
||||||
|
|
||||||
tex = surf->texinfo;
|
|
||||||
|
|
||||||
s = DotProduct(mid, tex->vecs[0]) + tex->vecs[0][3];
|
|
||||||
t = DotProduct(mid, tex->vecs[1]) + tex->vecs[1][3];
|
|
||||||
|
|
||||||
if ((s < surf->texturemins[0]) ||
|
|
||||||
(t < surf->texturemins[1]))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ds = s - surf->texturemins[0];
|
|
||||||
dt = t - surf->texturemins[1];
|
|
||||||
|
|
||||||
if ((ds > surf->extents[0]) || (dt > surf->extents[1]))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!surf->samples)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ds >>= surf->lmshift;
|
|
||||||
dt >>= surf->lmshift;
|
|
||||||
|
|
||||||
lightmap = surf->samples;
|
|
||||||
VectorCopy(vec3_origin, pointcolor);
|
|
||||||
|
|
||||||
lightmap += 3 * (dt * ((surf->extents[0] >> surf->lmshift) + 1) + ds);
|
|
||||||
|
|
||||||
for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++)
|
|
||||||
{
|
|
||||||
const float *rgb;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
rgb = lightstyles[surf->styles[maps]].rgb;
|
|
||||||
|
|
||||||
/* Apply light level to models */
|
|
||||||
for (j = 0; j < 3; j++)
|
|
||||||
{
|
|
||||||
float scale;
|
|
||||||
|
|
||||||
scale = rgb[j] * r_modulate->value;
|
|
||||||
pointcolor[j] += lightmap[j] * scale * (1.0 / 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
lightmap += 3 * ((surf->extents[0] >> surf->lmshift) + 1) *
|
|
||||||
((surf->extents[1] >> surf->lmshift) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* go down back side */
|
|
||||||
return R_RecursiveLightPoint(surfaces, node->children[!side],
|
|
||||||
lightstyles, mid, end, pointcolor, lightspot);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3_t lightspot;
|
vec3_t lightspot;
|
||||||
|
|
||||||
|
@ -226,7 +104,7 @@ R_LightPoint (const entity_t *currententity, vec3_t p, vec3_t color)
|
||||||
end[2] = p[2] - 2048;
|
end[2] = p[2] - 2048;
|
||||||
|
|
||||||
r = R_RecursiveLightPoint(r_worldmodel->surfaces, r_worldmodel->nodes,
|
r = R_RecursiveLightPoint(r_worldmodel->surfaces, r_worldmodel->nodes,
|
||||||
r_newrefdef.lightstyles, p, end, pointcolor, lightspot);
|
r_newrefdef.lightstyles, p, end, pointcolor, lightspot, r_modulate->value);
|
||||||
|
|
||||||
if (r == -1)
|
if (r == -1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -258,6 +258,10 @@ void Vk_ShutdownImages (void);
|
||||||
void Vk_FreeUnusedImages (void);
|
void Vk_FreeUnusedImages (void);
|
||||||
qboolean Vk_ImageHasFreeSpace(void);
|
qboolean Vk_ImageHasFreeSpace(void);
|
||||||
|
|
||||||
|
void LM_InitBlock(void);
|
||||||
|
void LM_UploadBlock(qboolean dynamic);
|
||||||
|
qboolean LM_AllocBlock(int w, int h, int *x, int *y);
|
||||||
|
|
||||||
void RE_BeginRegistration (const char *model);
|
void RE_BeginRegistration (const char *model);
|
||||||
struct model_s *RE_RegisterModel (const char *name);
|
struct model_s *RE_RegisterModel (const char *name);
|
||||||
struct image_s *RE_RegisterSkin (const char *name);
|
struct image_s *RE_RegisterSkin (const char *name);
|
||||||
|
@ -298,6 +302,24 @@ typedef struct
|
||||||
#define MAX_LIGHTMAPS 256
|
#define MAX_LIGHTMAPS 256
|
||||||
#define DYNLIGHTMAP_OFFSET MAX_LIGHTMAPS
|
#define DYNLIGHTMAP_OFFSET MAX_LIGHTMAPS
|
||||||
|
|
||||||
|
#define BLOCK_WIDTH 128
|
||||||
|
#define BLOCK_HEIGHT 128
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int current_lightmap_texture;
|
||||||
|
|
||||||
|
msurface_t *lightmap_surfaces[MAX_LIGHTMAPS];
|
||||||
|
|
||||||
|
int allocated[BLOCK_WIDTH];
|
||||||
|
|
||||||
|
// the lightmap texture data needs to be kept in
|
||||||
|
// main memory so texsubimage can update properly
|
||||||
|
byte lightmap_buffer[4*BLOCK_WIDTH*BLOCK_HEIGHT];
|
||||||
|
} vklightmapstate_t;
|
||||||
|
|
||||||
|
extern vklightmapstate_t vk_lms;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
float inverse_intensity;
|
float inverse_intensity;
|
||||||
|
|
|
@ -47,8 +47,6 @@ BRUSH MODELS
|
||||||
// in memory representation
|
// in memory representation
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "../../ref_model.h"
|
|
||||||
|
|
||||||
/* Whole model */
|
/* Whole model */
|
||||||
|
|
||||||
typedef struct model_s
|
typedef struct model_s
|
||||||
|
|
|
@ -173,129 +173,6 @@ LIGHT SAMPLING
|
||||||
|
|
||||||
vec3_t lightspot;
|
vec3_t lightspot;
|
||||||
|
|
||||||
static int
|
|
||||||
R_RecursiveLightPoint(const msurface_t *surfaces, const mnode_t *node,
|
|
||||||
const lightstyle_t *lightstyles, const vec3_t start, const vec3_t end,
|
|
||||||
vec3_t pointcolor, vec3_t lightspot)
|
|
||||||
{
|
|
||||||
float front, back, frac;
|
|
||||||
int side;
|
|
||||||
cplane_t *plane;
|
|
||||||
vec3_t mid;
|
|
||||||
const msurface_t *surf;
|
|
||||||
int s, t, ds, dt;
|
|
||||||
int i;
|
|
||||||
mtexinfo_t *tex;
|
|
||||||
byte *lightmap;
|
|
||||||
int maps;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (node->contents != CONTENTS_NODE)
|
|
||||||
{
|
|
||||||
return -1; /* didn't hit anything */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* calculate mid point */
|
|
||||||
plane = node->plane;
|
|
||||||
front = DotProduct(start, plane->normal) - plane->dist;
|
|
||||||
back = DotProduct(end, plane->normal) - plane->dist;
|
|
||||||
side = front < 0;
|
|
||||||
|
|
||||||
if ((back < 0) == side)
|
|
||||||
{
|
|
||||||
return R_RecursiveLightPoint(surfaces, node->children[side],
|
|
||||||
lightstyles, start, end, pointcolor, lightspot);
|
|
||||||
}
|
|
||||||
|
|
||||||
frac = front / (front - back);
|
|
||||||
mid[0] = start[0] + (end[0] - start[0]) * frac;
|
|
||||||
mid[1] = start[1] + (end[1] - start[1]) * frac;
|
|
||||||
mid[2] = start[2] + (end[2] - start[2]) * frac;
|
|
||||||
|
|
||||||
/* go down front side */
|
|
||||||
r = R_RecursiveLightPoint(surfaces, node->children[side],
|
|
||||||
lightstyles, start, mid, pointcolor, lightspot);
|
|
||||||
if (r >= 0)
|
|
||||||
{
|
|
||||||
return r; /* hit something */
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((back < 0) == side)
|
|
||||||
{
|
|
||||||
return -1; /* didn't hit anuthing */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for impact on this node */
|
|
||||||
VectorCopy(mid, lightspot);
|
|
||||||
|
|
||||||
surf = surfaces + node->firstsurface;
|
|
||||||
for (i = 0; i < node->numsurfaces; i++, surf++)
|
|
||||||
{
|
|
||||||
if (surf->flags & (SURF_DRAWTURB | SURF_DRAWSKY))
|
|
||||||
{
|
|
||||||
continue; /* no lightmaps */
|
|
||||||
}
|
|
||||||
|
|
||||||
tex = surf->texinfo;
|
|
||||||
|
|
||||||
s = DotProduct(mid, tex->vecs[0]) + tex->vecs[0][3];
|
|
||||||
t = DotProduct(mid, tex->vecs[1]) + tex->vecs[1][3];
|
|
||||||
|
|
||||||
if ((s < surf->texturemins[0]) ||
|
|
||||||
(t < surf->texturemins[1]))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ds = s - surf->texturemins[0];
|
|
||||||
dt = t - surf->texturemins[1];
|
|
||||||
|
|
||||||
if ((ds > surf->extents[0]) || (dt > surf->extents[1]))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!surf->samples)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ds >>= surf->lmshift;
|
|
||||||
dt >>= surf->lmshift;
|
|
||||||
|
|
||||||
lightmap = surf->samples;
|
|
||||||
VectorCopy(vec3_origin, pointcolor);
|
|
||||||
|
|
||||||
lightmap += 3 * (dt * ((surf->extents[0] >> surf->lmshift) + 1) + ds);
|
|
||||||
|
|
||||||
for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++)
|
|
||||||
{
|
|
||||||
const float *rgb;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
rgb = lightstyles[surf->styles[maps]].rgb;
|
|
||||||
|
|
||||||
/* Apply light level to models */
|
|
||||||
for (j = 0; j < 3; j++)
|
|
||||||
{
|
|
||||||
float scale;
|
|
||||||
|
|
||||||
scale = rgb[j] * r_modulate->value;
|
|
||||||
pointcolor[j] += lightmap[j] * scale * (1.0 / 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
lightmap += 3 * ((surf->extents[0] >> surf->lmshift) + 1) *
|
|
||||||
((surf->extents[1] >> surf->lmshift) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* go down back side */
|
|
||||||
return R_RecursiveLightPoint(surfaces, node->children[!side],
|
|
||||||
lightstyles, mid, end, pointcolor, lightspot);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
R_LightPoint(vec3_t p, vec3_t color, entity_t *currententity)
|
R_LightPoint(vec3_t p, vec3_t color, entity_t *currententity)
|
||||||
{
|
{
|
||||||
|
@ -315,7 +192,7 @@ R_LightPoint(vec3_t p, vec3_t color, entity_t *currententity)
|
||||||
end[2] = p[2] - 2048;
|
end[2] = p[2] - 2048;
|
||||||
|
|
||||||
r = R_RecursiveLightPoint(r_worldmodel->surfaces, r_worldmodel->nodes,
|
r = R_RecursiveLightPoint(r_worldmodel->surfaces, r_worldmodel->nodes,
|
||||||
r_newrefdef.lightstyles, p, end, pointcolor, lightspot);
|
r_newrefdef.lightstyles, p, end, pointcolor, lightspot, r_modulate->value);
|
||||||
|
|
||||||
if (r == -1)
|
if (r == -1)
|
||||||
{
|
{
|
||||||
|
|
322
src/client/refresh/vk/vk_lightmap.c
Normal file
322
src/client/refresh/vk/vk_lightmap.c
Normal file
|
@ -0,0 +1,322 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||||
|
* Copyright (C) 2018-2019 Krzysztof Kondrak
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* =======================================================================
|
||||||
|
*
|
||||||
|
* Lightmap handling
|
||||||
|
*
|
||||||
|
* =======================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "header/local.h"
|
||||||
|
|
||||||
|
#define LIGHTMAP_BYTES 4
|
||||||
|
|
||||||
|
void
|
||||||
|
LM_InitBlock(void)
|
||||||
|
{
|
||||||
|
memset(vk_lms.allocated, 0, sizeof(vk_lms.allocated));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LM_UploadBlock(qboolean dynamic)
|
||||||
|
{
|
||||||
|
int texture;
|
||||||
|
|
||||||
|
if (dynamic)
|
||||||
|
{
|
||||||
|
texture = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
texture = vk_lms.current_lightmap_texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynamic)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int height = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < BLOCK_WIDTH; i++)
|
||||||
|
{
|
||||||
|
if (vk_lms.allocated[i] > height)
|
||||||
|
{
|
||||||
|
height = vk_lms.allocated[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVk_UpdateTextureData(&vk_state.lightmap_textures[texture], vk_lms.lightmap_buffer, 0, 0, BLOCK_WIDTH, height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (vk_state.lightmap_textures[texture].resource.image != VK_NULL_HANDLE)
|
||||||
|
{
|
||||||
|
QVk_UpdateTextureData(&vk_state.lightmap_textures[texture], vk_lms.lightmap_buffer, 0, 0, BLOCK_WIDTH, BLOCK_HEIGHT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QVVKTEXTURE_CLEAR(vk_state.lightmap_textures[texture]);
|
||||||
|
QVk_CreateTexture(&vk_state.lightmap_textures[texture], vk_lms.lightmap_buffer,
|
||||||
|
BLOCK_WIDTH, BLOCK_HEIGHT, vk_current_lmap_sampler, false);
|
||||||
|
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[texture].resource.image,
|
||||||
|
VK_OBJECT_TYPE_IMAGE, va("Image: dynamic lightmap #%d", texture));
|
||||||
|
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[texture].imageView,
|
||||||
|
VK_OBJECT_TYPE_IMAGE_VIEW, va("Image View: dynamic lightmap #%d", texture));
|
||||||
|
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[texture].descriptorSet,
|
||||||
|
VK_OBJECT_TYPE_DESCRIPTOR_SET, va("Descriptor Set: dynamic lightmap #%d", texture));
|
||||||
|
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[texture].resource.memory,
|
||||||
|
VK_OBJECT_TYPE_DEVICE_MEMORY, va("Memory: dynamic lightmap #%d", texture));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (++vk_lms.current_lightmap_texture == MAX_LIGHTMAPS)
|
||||||
|
{
|
||||||
|
ri.Sys_Error(ERR_DROP,
|
||||||
|
"%s() - MAX_LIGHTMAPS exceeded\n", __func__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* returns a texture number and the position inside it
|
||||||
|
*/
|
||||||
|
qboolean
|
||||||
|
LM_AllocBlock(int w, int h, int *x, int *y)
|
||||||
|
{
|
||||||
|
int i, best;
|
||||||
|
|
||||||
|
best = BLOCK_HEIGHT;
|
||||||
|
|
||||||
|
for (i = 0; i < BLOCK_WIDTH - w; i++)
|
||||||
|
{
|
||||||
|
int j, best2;
|
||||||
|
|
||||||
|
best2 = 0;
|
||||||
|
|
||||||
|
for (j = 0; j < w; j++)
|
||||||
|
{
|
||||||
|
if (vk_lms.allocated[i + j] >= best)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vk_lms.allocated[i + j] > best2)
|
||||||
|
{
|
||||||
|
best2 = vk_lms.allocated[i + j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j == w)
|
||||||
|
{
|
||||||
|
/* this is a valid spot */
|
||||||
|
*x = i;
|
||||||
|
*y = best = best2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (best + h > BLOCK_HEIGHT)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < w; i++)
|
||||||
|
{
|
||||||
|
vk_lms.allocated[*x + i] = best + h;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Vk_BuildPolygonFromSurface(model_t *currentmodel, msurface_t *fa)
|
||||||
|
{
|
||||||
|
int i, lnumverts;
|
||||||
|
medge_t *pedges, *r_pedge;
|
||||||
|
float *vec;
|
||||||
|
mpoly_t *poly;
|
||||||
|
vec3_t total;
|
||||||
|
vec3_t normal;
|
||||||
|
|
||||||
|
/* reconstruct the polygon */
|
||||||
|
pedges = currentmodel->edges;
|
||||||
|
lnumverts = fa->numedges;
|
||||||
|
|
||||||
|
VectorClear(total);
|
||||||
|
|
||||||
|
/* draw texture */
|
||||||
|
poly = Hunk_Alloc(sizeof(mpoly_t) +
|
||||||
|
(lnumverts - 4) * sizeof(mvtx_t));
|
||||||
|
poly->next = fa->polys;
|
||||||
|
poly->flags = fa->flags;
|
||||||
|
fa->polys = poly;
|
||||||
|
poly->numverts = lnumverts;
|
||||||
|
|
||||||
|
VectorCopy(fa->plane->normal, normal);
|
||||||
|
|
||||||
|
if(fa->flags & SURF_PLANEBACK)
|
||||||
|
{
|
||||||
|
// if for some reason the normal sticks to the back of the plane, invert it
|
||||||
|
// so it's usable for the shader
|
||||||
|
for (i=0; i<3; ++i) normal[i] = -normal[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < lnumverts; i++)
|
||||||
|
{
|
||||||
|
mvtx_t* vert;
|
||||||
|
float s, t;
|
||||||
|
int lindex;
|
||||||
|
|
||||||
|
vert = &poly->verts[i];
|
||||||
|
|
||||||
|
lindex = currentmodel->surfedges[fa->firstedge + i];
|
||||||
|
|
||||||
|
if (lindex > 0)
|
||||||
|
{
|
||||||
|
r_pedge = &pedges[lindex];
|
||||||
|
vec = currentmodel->vertexes[r_pedge->v[0]].position;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r_pedge = &pedges[-lindex];
|
||||||
|
vec = currentmodel->vertexes[r_pedge->v[1]].position;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = DotProduct(vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
|
||||||
|
s /= fa->texinfo->image->width;
|
||||||
|
|
||||||
|
t = DotProduct(vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
|
||||||
|
t /= fa->texinfo->image->height;
|
||||||
|
|
||||||
|
VectorAdd(total, vec, total);
|
||||||
|
VectorCopy(vec, vert->pos);
|
||||||
|
vert->texCoord[0] = s;
|
||||||
|
vert->texCoord[1] = t;
|
||||||
|
|
||||||
|
/* lightmap texture coordinates */
|
||||||
|
s = DotProduct(vec, fa->lmvecs[0]) + fa->lmvecs[0][3];
|
||||||
|
s -= fa->texturemins[0];
|
||||||
|
s += fa->light_s * (1 << fa->lmshift);
|
||||||
|
s += (1 << fa->lmshift) * 0.5;
|
||||||
|
s /= BLOCK_WIDTH * (1 << fa->lmshift);
|
||||||
|
|
||||||
|
t = DotProduct(vec, fa->lmvecs[1]) + fa->lmvecs[1][3];
|
||||||
|
t -= fa->texturemins[1];
|
||||||
|
t += fa->light_t * (1 << fa->lmshift);
|
||||||
|
t += (1 << fa->lmshift) * 0.5;
|
||||||
|
t /= BLOCK_HEIGHT * (1 << fa->lmshift);
|
||||||
|
|
||||||
|
vert->lmTexCoord[0] = s;
|
||||||
|
vert->lmTexCoord[1] = t;
|
||||||
|
|
||||||
|
VectorCopy(normal, vert->normal);
|
||||||
|
vert->lightFlags = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Vk_CreateSurfaceLightmap(msurface_t *surf)
|
||||||
|
{
|
||||||
|
int smax, tmax;
|
||||||
|
byte *base;
|
||||||
|
|
||||||
|
if (surf->flags & (SURF_DRAWSKY | SURF_DRAWTURB))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
smax = (surf->extents[0] >> surf->lmshift) + 1;
|
||||||
|
tmax = (surf->extents[1] >> surf->lmshift) + 1;
|
||||||
|
|
||||||
|
if (!LM_AllocBlock(smax, tmax, &surf->light_s, &surf->light_t))
|
||||||
|
{
|
||||||
|
LM_UploadBlock(false);
|
||||||
|
LM_InitBlock();
|
||||||
|
|
||||||
|
if (!LM_AllocBlock(smax, tmax, &surf->light_s, &surf->light_t))
|
||||||
|
{
|
||||||
|
ri.Sys_Error(ERR_FATAL,
|
||||||
|
"%s: Consecutive calls to LM_AllocBlock(%d,%d) failed\n",
|
||||||
|
__func__, smax, tmax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
surf->lightmaptexturenum = vk_lms.current_lightmap_texture;
|
||||||
|
|
||||||
|
base = vk_lms.lightmap_buffer;
|
||||||
|
base += (surf->light_t * BLOCK_WIDTH + surf->light_s) * LIGHTMAP_BYTES;
|
||||||
|
|
||||||
|
R_SetCacheState(surf);
|
||||||
|
R_BuildLightMap(surf, base, BLOCK_WIDTH * LIGHTMAP_BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Vk_BeginBuildingLightmaps(model_t *m)
|
||||||
|
{
|
||||||
|
static lightstyle_t lightstyles[MAX_LIGHTSTYLES];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memset(vk_lms.allocated, 0, sizeof(vk_lms.allocated));
|
||||||
|
|
||||||
|
r_framecount = 1; /* no dlightcache */
|
||||||
|
|
||||||
|
/* setup the base lightstyles so the lightmaps
|
||||||
|
won't have to be regenerated the first time
|
||||||
|
they're seen */
|
||||||
|
for (i = 0; i < MAX_LIGHTSTYLES; i++)
|
||||||
|
{
|
||||||
|
lightstyles[i].rgb[0] = 1;
|
||||||
|
lightstyles[i].rgb[1] = 1;
|
||||||
|
lightstyles[i].rgb[2] = 1;
|
||||||
|
lightstyles[i].white = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
r_newrefdef.lightstyles = lightstyles;
|
||||||
|
|
||||||
|
vk_lms.current_lightmap_texture = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** initialize the dynamic lightmap textures
|
||||||
|
*/
|
||||||
|
if (vk_state.lightmap_textures[DYNLIGHTMAP_OFFSET].resource.image == VK_NULL_HANDLE)
|
||||||
|
{
|
||||||
|
for (i = DYNLIGHTMAP_OFFSET; i < MAX_LIGHTMAPS*2; i++)
|
||||||
|
{
|
||||||
|
unsigned dummy[BLOCK_WIDTH * BLOCK_HEIGHT];
|
||||||
|
|
||||||
|
QVVKTEXTURE_CLEAR(vk_state.lightmap_textures[i]);
|
||||||
|
QVk_CreateTexture(&vk_state.lightmap_textures[i], (unsigned char*)dummy,
|
||||||
|
BLOCK_WIDTH, BLOCK_HEIGHT, vk_current_lmap_sampler, false);
|
||||||
|
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[i].resource.image,
|
||||||
|
VK_OBJECT_TYPE_IMAGE, va("Image: dynamic lightmap #%d", i));
|
||||||
|
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[i].imageView,
|
||||||
|
VK_OBJECT_TYPE_IMAGE_VIEW, va("Image View: dynamic lightmap #%d", i));
|
||||||
|
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[i].descriptorSet,
|
||||||
|
VK_OBJECT_TYPE_DESCRIPTOR_SET, va("Descriptor Set: dynamic lightmap #%d", i));
|
||||||
|
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[i].resource.memory,
|
||||||
|
VK_OBJECT_TYPE_DEVICE_MEMORY, va("Memory: dynamic lightmap #%d", i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Vk_EndBuildingLightmaps(void)
|
||||||
|
{
|
||||||
|
LM_UploadBlock(false);
|
||||||
|
}
|
||||||
|
|
|
@ -34,29 +34,7 @@ int c_visible_textures;
|
||||||
static vec3_t modelorg; /* relative to viewpoint */
|
static vec3_t modelorg; /* relative to viewpoint */
|
||||||
msurface_t *r_alpha_surfaces;
|
msurface_t *r_alpha_surfaces;
|
||||||
|
|
||||||
static void LM_InitBlock(void);
|
vklightmapstate_t vk_lms;
|
||||||
static void LM_UploadBlock(qboolean dynamic);
|
|
||||||
static qboolean LM_AllocBlock(int w, int h, int *x, int *y);
|
|
||||||
|
|
||||||
#define LIGHTMAP_BYTES 4
|
|
||||||
|
|
||||||
#define BLOCK_WIDTH 128
|
|
||||||
#define BLOCK_HEIGHT 128
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int current_lightmap_texture;
|
|
||||||
|
|
||||||
msurface_t *lightmap_surfaces[MAX_LIGHTMAPS];
|
|
||||||
|
|
||||||
int allocated[BLOCK_WIDTH];
|
|
||||||
|
|
||||||
// the lightmap texture data needs to be kept in
|
|
||||||
// main memory so texsubimage can update properly
|
|
||||||
byte lightmap_buffer[4*BLOCK_WIDTH*BLOCK_HEIGHT];
|
|
||||||
} vklightmapstate_t;
|
|
||||||
|
|
||||||
static vklightmapstate_t vk_lms;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
DrawVkPoly(mpoly_t *p, image_t *texture, float *color)
|
DrawVkPoly(mpoly_t *p, image_t *texture, float *color)
|
||||||
|
@ -1038,304 +1016,3 @@ R_MarkLeaves(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
=============================================================================
|
|
||||||
|
|
||||||
LIGHTMAP ALLOCATION
|
|
||||||
|
|
||||||
=============================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void LM_InitBlock( void )
|
|
||||||
{
|
|
||||||
memset(vk_lms.allocated, 0, sizeof(vk_lms.allocated));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
LM_UploadBlock(qboolean dynamic)
|
|
||||||
{
|
|
||||||
int texture;
|
|
||||||
|
|
||||||
if (dynamic)
|
|
||||||
{
|
|
||||||
texture = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
texture = vk_lms.current_lightmap_texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dynamic)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int height = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < BLOCK_WIDTH; i++)
|
|
||||||
{
|
|
||||||
if (vk_lms.allocated[i] > height)
|
|
||||||
{
|
|
||||||
height = vk_lms.allocated[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QVk_UpdateTextureData(&vk_state.lightmap_textures[texture], vk_lms.lightmap_buffer, 0, 0, BLOCK_WIDTH, height);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (vk_state.lightmap_textures[texture].resource.image != VK_NULL_HANDLE)
|
|
||||||
{
|
|
||||||
QVk_UpdateTextureData(&vk_state.lightmap_textures[texture], vk_lms.lightmap_buffer, 0, 0, BLOCK_WIDTH, BLOCK_HEIGHT);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QVVKTEXTURE_CLEAR(vk_state.lightmap_textures[texture]);
|
|
||||||
QVk_CreateTexture(&vk_state.lightmap_textures[texture], vk_lms.lightmap_buffer,
|
|
||||||
BLOCK_WIDTH, BLOCK_HEIGHT, vk_current_lmap_sampler, false);
|
|
||||||
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[texture].resource.image,
|
|
||||||
VK_OBJECT_TYPE_IMAGE, va("Image: dynamic lightmap #%d", texture));
|
|
||||||
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[texture].imageView,
|
|
||||||
VK_OBJECT_TYPE_IMAGE_VIEW, va("Image View: dynamic lightmap #%d", texture));
|
|
||||||
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[texture].descriptorSet,
|
|
||||||
VK_OBJECT_TYPE_DESCRIPTOR_SET, va("Descriptor Set: dynamic lightmap #%d", texture));
|
|
||||||
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[texture].resource.memory,
|
|
||||||
VK_OBJECT_TYPE_DEVICE_MEMORY, va("Memory: dynamic lightmap #%d", texture));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (++vk_lms.current_lightmap_texture == MAX_LIGHTMAPS)
|
|
||||||
{
|
|
||||||
ri.Sys_Error(ERR_DROP,
|
|
||||||
"%s() - MAX_LIGHTMAPS exceeded\n", __func__);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* returns a texture number and the position inside it
|
|
||||||
*/
|
|
||||||
static qboolean
|
|
||||||
LM_AllocBlock(int w, int h, int *x, int *y)
|
|
||||||
{
|
|
||||||
int i, best;
|
|
||||||
|
|
||||||
best = BLOCK_HEIGHT;
|
|
||||||
|
|
||||||
for (i = 0; i < BLOCK_WIDTH - w; i++)
|
|
||||||
{
|
|
||||||
int j, best2;
|
|
||||||
|
|
||||||
best2 = 0;
|
|
||||||
|
|
||||||
for (j = 0; j < w; j++)
|
|
||||||
{
|
|
||||||
if (vk_lms.allocated[i + j] >= best)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vk_lms.allocated[i + j] > best2)
|
|
||||||
{
|
|
||||||
best2 = vk_lms.allocated[i + j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j == w)
|
|
||||||
{
|
|
||||||
/* this is a valid spot */
|
|
||||||
*x = i;
|
|
||||||
*y = best = best2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (best + h > BLOCK_HEIGHT)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < w; i++)
|
|
||||||
{
|
|
||||||
vk_lms.allocated[*x + i] = best + h;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vk_BuildPolygonFromSurface(model_t *currentmodel, msurface_t *fa)
|
|
||||||
{
|
|
||||||
int i, lnumverts;
|
|
||||||
medge_t *pedges, *r_pedge;
|
|
||||||
float *vec;
|
|
||||||
mpoly_t *poly;
|
|
||||||
vec3_t total;
|
|
||||||
vec3_t normal;
|
|
||||||
|
|
||||||
/* reconstruct the polygon */
|
|
||||||
pedges = currentmodel->edges;
|
|
||||||
lnumverts = fa->numedges;
|
|
||||||
|
|
||||||
VectorClear(total);
|
|
||||||
|
|
||||||
/* draw texture */
|
|
||||||
poly = Hunk_Alloc(sizeof(mpoly_t) +
|
|
||||||
(lnumverts - 4) * sizeof(mvtx_t));
|
|
||||||
poly->next = fa->polys;
|
|
||||||
poly->flags = fa->flags;
|
|
||||||
fa->polys = poly;
|
|
||||||
poly->numverts = lnumverts;
|
|
||||||
|
|
||||||
VectorCopy(fa->plane->normal, normal);
|
|
||||||
|
|
||||||
if(fa->flags & SURF_PLANEBACK)
|
|
||||||
{
|
|
||||||
// if for some reason the normal sticks to the back of the plane, invert it
|
|
||||||
// so it's usable for the shader
|
|
||||||
for (i=0; i<3; ++i) normal[i] = -normal[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < lnumverts; i++)
|
|
||||||
{
|
|
||||||
mvtx_t* vert;
|
|
||||||
float s, t;
|
|
||||||
int lindex;
|
|
||||||
|
|
||||||
vert = &poly->verts[i];
|
|
||||||
|
|
||||||
lindex = currentmodel->surfedges[fa->firstedge + i];
|
|
||||||
|
|
||||||
if (lindex > 0)
|
|
||||||
{
|
|
||||||
r_pedge = &pedges[lindex];
|
|
||||||
vec = currentmodel->vertexes[r_pedge->v[0]].position;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
r_pedge = &pedges[-lindex];
|
|
||||||
vec = currentmodel->vertexes[r_pedge->v[1]].position;
|
|
||||||
}
|
|
||||||
|
|
||||||
s = DotProduct(vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
|
|
||||||
s /= fa->texinfo->image->width;
|
|
||||||
|
|
||||||
t = DotProduct(vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
|
|
||||||
t /= fa->texinfo->image->height;
|
|
||||||
|
|
||||||
VectorAdd(total, vec, total);
|
|
||||||
VectorCopy(vec, vert->pos);
|
|
||||||
vert->texCoord[0] = s;
|
|
||||||
vert->texCoord[1] = t;
|
|
||||||
|
|
||||||
/* lightmap texture coordinates */
|
|
||||||
s = DotProduct(vec, fa->lmvecs[0]) + fa->lmvecs[0][3];
|
|
||||||
s -= fa->texturemins[0];
|
|
||||||
s += fa->light_s * (1 << fa->lmshift);
|
|
||||||
s += (1 << fa->lmshift) * 0.5;
|
|
||||||
s /= BLOCK_WIDTH * (1 << fa->lmshift);
|
|
||||||
|
|
||||||
t = DotProduct(vec, fa->lmvecs[1]) + fa->lmvecs[1][3];
|
|
||||||
t -= fa->texturemins[1];
|
|
||||||
t += fa->light_t * (1 << fa->lmshift);
|
|
||||||
t += (1 << fa->lmshift) * 0.5;
|
|
||||||
t /= BLOCK_HEIGHT * (1 << fa->lmshift);
|
|
||||||
|
|
||||||
vert->lmTexCoord[0] = s;
|
|
||||||
vert->lmTexCoord[1] = t;
|
|
||||||
|
|
||||||
VectorCopy(normal, vert->normal);
|
|
||||||
vert->lightFlags = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vk_CreateSurfaceLightmap(msurface_t *surf)
|
|
||||||
{
|
|
||||||
int smax, tmax;
|
|
||||||
byte *base;
|
|
||||||
|
|
||||||
if (surf->flags & (SURF_DRAWSKY | SURF_DRAWTURB))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
smax = (surf->extents[0] >> surf->lmshift) + 1;
|
|
||||||
tmax = (surf->extents[1] >> surf->lmshift) + 1;
|
|
||||||
|
|
||||||
if (!LM_AllocBlock(smax, tmax, &surf->light_s, &surf->light_t))
|
|
||||||
{
|
|
||||||
LM_UploadBlock(false);
|
|
||||||
LM_InitBlock();
|
|
||||||
|
|
||||||
if (!LM_AllocBlock(smax, tmax, &surf->light_s, &surf->light_t))
|
|
||||||
{
|
|
||||||
ri.Sys_Error(ERR_FATAL,
|
|
||||||
"%s: Consecutive calls to LM_AllocBlock(%d,%d) failed\n",
|
|
||||||
__func__, smax, tmax);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
surf->lightmaptexturenum = vk_lms.current_lightmap_texture;
|
|
||||||
|
|
||||||
base = vk_lms.lightmap_buffer;
|
|
||||||
base += (surf->light_t * BLOCK_WIDTH + surf->light_s) * LIGHTMAP_BYTES;
|
|
||||||
|
|
||||||
R_SetCacheState(surf);
|
|
||||||
R_BuildLightMap(surf, base, BLOCK_WIDTH * LIGHTMAP_BYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vk_BeginBuildingLightmaps(model_t *m)
|
|
||||||
{
|
|
||||||
static lightstyle_t lightstyles[MAX_LIGHTSTYLES];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
memset(vk_lms.allocated, 0, sizeof(vk_lms.allocated));
|
|
||||||
|
|
||||||
r_framecount = 1; /* no dlightcache */
|
|
||||||
|
|
||||||
/* setup the base lightstyles so the lightmaps
|
|
||||||
won't have to be regenerated the first time
|
|
||||||
they're seen */
|
|
||||||
for (i = 0; i < MAX_LIGHTSTYLES; i++)
|
|
||||||
{
|
|
||||||
lightstyles[i].rgb[0] = 1;
|
|
||||||
lightstyles[i].rgb[1] = 1;
|
|
||||||
lightstyles[i].rgb[2] = 1;
|
|
||||||
lightstyles[i].white = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
r_newrefdef.lightstyles = lightstyles;
|
|
||||||
|
|
||||||
vk_lms.current_lightmap_texture = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
** initialize the dynamic lightmap textures
|
|
||||||
*/
|
|
||||||
if (vk_state.lightmap_textures[DYNLIGHTMAP_OFFSET].resource.image == VK_NULL_HANDLE)
|
|
||||||
{
|
|
||||||
for (i = DYNLIGHTMAP_OFFSET; i < MAX_LIGHTMAPS*2; i++)
|
|
||||||
{
|
|
||||||
unsigned dummy[BLOCK_WIDTH * BLOCK_HEIGHT];
|
|
||||||
|
|
||||||
QVVKTEXTURE_CLEAR(vk_state.lightmap_textures[i]);
|
|
||||||
QVk_CreateTexture(&vk_state.lightmap_textures[i], (unsigned char*)dummy,
|
|
||||||
BLOCK_WIDTH, BLOCK_HEIGHT, vk_current_lmap_sampler, false);
|
|
||||||
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[i].resource.image,
|
|
||||||
VK_OBJECT_TYPE_IMAGE, va("Image: dynamic lightmap #%d", i));
|
|
||||||
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[i].imageView,
|
|
||||||
VK_OBJECT_TYPE_IMAGE_VIEW, va("Image View: dynamic lightmap #%d", i));
|
|
||||||
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[i].descriptorSet,
|
|
||||||
VK_OBJECT_TYPE_DESCRIPTOR_SET, va("Descriptor Set: dynamic lightmap #%d", i));
|
|
||||||
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[i].resource.memory,
|
|
||||||
VK_OBJECT_TYPE_DEVICE_MEMORY, va("Memory: dynamic lightmap #%d", i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vk_EndBuildingLightmaps(void)
|
|
||||||
{
|
|
||||||
LM_UploadBlock(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue