mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-30 00:10:53 +00:00
GL3: Multiple lightmaps/surface with lightstyles works
not sure if this is the very best solution.. Every surface can have up to 4 lightmaps. I now always create 4 lightmaps (in separate textures, so the corresponding texture coordinates are identical), the "fillers" are set to 0, so in the shader they won't make a visible difference. (The shader always adds up lightmaps from 4 textures, but how much they're actually visible depends on lmScales which also will be set to 0 if "unused") If all this turns out to be (too) slow, there could be a special case for surfaces with only one lightmap, I /think/ that's the most common case by far.
This commit is contained in:
parent
5abf60de89
commit
2dc7b6e6eb
6 changed files with 125 additions and 289 deletions
|
@ -27,13 +27,14 @@
|
||||||
|
|
||||||
#include "header/local.h"
|
#include "header/local.h"
|
||||||
|
|
||||||
|
extern gl3lightmapstate_t gl3_lms;
|
||||||
|
|
||||||
#define DLIGHT_CUTOFF 64
|
#define DLIGHT_CUTOFF 64
|
||||||
|
|
||||||
static int r_dlightframecount;
|
static int r_dlightframecount;
|
||||||
static vec3_t pointcolor;
|
static vec3_t pointcolor;
|
||||||
static cplane_t *lightplane; /* used as shadow plane */
|
static cplane_t *lightplane; /* used as shadow plane */
|
||||||
vec3_t lightspot;
|
vec3_t lightspot;
|
||||||
static float s_blocklights[34 * 34 * 3];
|
|
||||||
|
|
||||||
void // bit: 1 << i for light number i, will be or'ed into msurface_t::dlightbits if surface is affected by this light
|
void // bit: 1 << i for light number i, will be or'ed into msurface_t::dlightbits if surface is affected by this light
|
||||||
GL3_MarkLights(dlight_t *light, int bit, mnode_t *node)
|
GL3_MarkLights(dlight_t *light, int bit, mnode_t *node)
|
||||||
|
@ -213,7 +214,7 @@ RecursiveLightPoint(mnode_t *node, vec3_t start, vec3_t end)
|
||||||
|
|
||||||
lightmap += 3 * (dt * ((surf->extents[0] >> 4) + 1) + ds);
|
lightmap += 3 * (dt * ((surf->extents[0] >> 4) + 1) + ds);
|
||||||
|
|
||||||
for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255;
|
for (maps = 0; maps < MAX_LIGHTMAPS_PER_SURFACE && surf->styles[maps] != 255;
|
||||||
maps++)
|
maps++)
|
||||||
{
|
{
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
|
@ -290,6 +291,7 @@ GL3_LightPoint(vec3_t p, vec3_t color)
|
||||||
VectorScale(color, gl_modulate->value, color);
|
VectorScale(color, gl_modulate->value, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 // TODO: REMOVE! (currently kept to look at when writing shader for this)
|
||||||
static void
|
static void
|
||||||
AddDynamicLights(msurface_t *surf)
|
AddDynamicLights(msurface_t *surf)
|
||||||
{
|
{
|
||||||
|
@ -382,31 +384,18 @@ AddDynamicLights(msurface_t *surf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // 0
|
||||||
void
|
|
||||||
GL3_SetCacheState(msurface_t *surf)
|
|
||||||
{
|
|
||||||
int maps;
|
|
||||||
|
|
||||||
for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++)
|
|
||||||
{
|
|
||||||
surf->cached_light[maps] =
|
|
||||||
gl3_newrefdef.lightstyles[surf->styles[maps]].white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Combine and scale multiple lightmaps into the floating format in blocklights
|
* Combine and scale multiple lightmaps into the floating format in blocklights
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
GL3_BuildLightMap(msurface_t *surf, byte *dest, int stride)
|
GL3_BuildLightMap(msurface_t *surf, int offsetInLMbuf, int stride)
|
||||||
{
|
{
|
||||||
int smax, tmax;
|
int smax, tmax;
|
||||||
int r, g, b, a, max;
|
int r, g, b, a, max;
|
||||||
int i, j, size;
|
int i, j, size, map, numMaps;
|
||||||
byte *lightmap;
|
byte *lightmap;
|
||||||
float scale[4];
|
|
||||||
float *bl;
|
|
||||||
|
|
||||||
if (surf->texinfo->flags &
|
if (surf->texinfo->flags &
|
||||||
(SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP))
|
(SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP))
|
||||||
|
@ -418,126 +407,107 @@ GL3_BuildLightMap(msurface_t *surf, byte *dest, int stride)
|
||||||
tmax = (surf->extents[1] >> 4) + 1;
|
tmax = (surf->extents[1] >> 4) + 1;
|
||||||
size = smax * tmax;
|
size = smax * tmax;
|
||||||
|
|
||||||
if (size > (sizeof(s_blocklights) >> 4))
|
stride -= (smax << 2);
|
||||||
|
|
||||||
|
if (size > 34*34*3)
|
||||||
{
|
{
|
||||||
ri.Sys_Error(ERR_DROP, "Bad s_blocklights size");
|
ri.Sys_Error(ERR_DROP, "Bad s_blocklights size");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set to full bright if no light data */
|
// count number of lightmaps surf actually has
|
||||||
|
for (numMaps = 0; numMaps < MAX_LIGHTMAPS_PER_SURFACE && surf->styles[numMaps] != 255; ++numMaps)
|
||||||
|
{}
|
||||||
|
|
||||||
if (!surf->samples)
|
if (!surf->samples)
|
||||||
{
|
{
|
||||||
for (i = 0; i < size * 3; i++)
|
// no lightmap samples? set at least one lightmap to fullbright, rest to 0 as normal
|
||||||
|
|
||||||
|
if (numMaps == 0) numMaps = 1; // make sure at least one lightmap is set to fullbright
|
||||||
|
|
||||||
|
for (map = 0; map < MAX_LIGHTMAPS_PER_SURFACE; ++map)
|
||||||
{
|
{
|
||||||
s_blocklights[i] = 255;
|
// we always create 4 (MAXLIGHTMAP) lightmaps.
|
||||||
|
// if surf has less (numMaps < 4), the remaining ones are zeroed out.
|
||||||
|
// this makes sure that all 4 lightmap textures in gl3state.lightmap_textureIDs[i] have the same layout
|
||||||
|
// and the shader can use the same texture coordinates for all of them
|
||||||
|
|
||||||
|
int c = (map < numMaps) ? 255 : 0;
|
||||||
|
byte* dest = gl3_lms.lightmap_buffers[map] + offsetInLMbuf;
|
||||||
|
|
||||||
|
for (i = 0; i < tmax; i++, dest += stride)
|
||||||
|
{
|
||||||
|
memset(dest, c, 4*smax);
|
||||||
|
dest += 4*smax;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
goto store;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add all the lightmaps */
|
/* add all the lightmaps */
|
||||||
{
|
|
||||||
int maps;
|
|
||||||
|
|
||||||
memset(s_blocklights, 0, sizeof(s_blocklights[0]) * size * 3);
|
STUB_ONCE("TODO: handly dynamic lights (prolly somewhere else entirely)");
|
||||||
|
|
||||||
lightmap = surf->samples;
|
|
||||||
|
|
||||||
for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++)
|
|
||||||
{
|
|
||||||
bl = s_blocklights;
|
|
||||||
|
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
scale[i] = gl_modulate->value *
|
|
||||||
gl3_newrefdef.lightstyles[surf->styles[maps]].rgb[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < size; i++, bl += 3)
|
|
||||||
{
|
|
||||||
bl[0] += lightmap[i * 3 + 0] * scale[0];
|
|
||||||
bl[1] += lightmap[i * 3 + 1] * scale[1];
|
|
||||||
bl[2] += lightmap[i * 3 + 2] * scale[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
lightmap += size * 3; /* skip to next lightmap */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* add all the dynamic lights */
|
/* add all the dynamic lights */
|
||||||
if (surf->dlightframe == gl3_framecount)
|
if (surf->dlightframe == gl3_framecount)
|
||||||
{
|
{
|
||||||
AddDynamicLights(surf);
|
AddDynamicLights(surf);
|
||||||
}
|
}
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
store:
|
// as we don't apply scale here anymore, nor blend the numMaps lightmaps together,
|
||||||
|
// the code has gotten a lot easier and we can copy directly from surf->samples to dest
|
||||||
|
// without converting to float first etc
|
||||||
|
|
||||||
stride -= (smax << 2);
|
lightmap = surf->samples;
|
||||||
bl = s_blocklights;
|
|
||||||
|
|
||||||
for (i = 0; i < tmax; i++, dest += stride)
|
for(map=0; map<numMaps; ++map)
|
||||||
{
|
{
|
||||||
for (j = 0; j < smax; j++)
|
byte* dest = gl3_lms.lightmap_buffers[map] + offsetInLMbuf;
|
||||||
|
int idxInLightmap = 0;
|
||||||
|
for (i = 0; i < tmax; i++, dest += stride)
|
||||||
{
|
{
|
||||||
r = Q_ftol(bl[0]);
|
for (j = 0; j < smax; j++)
|
||||||
g = Q_ftol(bl[1]);
|
|
||||||
b = Q_ftol(bl[2]);
|
|
||||||
|
|
||||||
/* catch negative lights */
|
|
||||||
if (r < 0)
|
|
||||||
{
|
{
|
||||||
r = 0;
|
r = lightmap[idxInLightmap * 3 + 0];
|
||||||
|
g = lightmap[idxInLightmap * 3 + 1];
|
||||||
|
b = lightmap[idxInLightmap * 3 + 2];
|
||||||
|
|
||||||
|
/* determine the brightest of the three color components */
|
||||||
|
if (r > g) max = r;
|
||||||
|
else max = g;
|
||||||
|
|
||||||
|
if (b > max) max = b;
|
||||||
|
|
||||||
|
/* alpha is ONLY used for the mono lightmap case. For this
|
||||||
|
reason we set it to the brightest of the color components
|
||||||
|
so that things don't get too dim. */
|
||||||
|
a = max;
|
||||||
|
|
||||||
|
dest[0] = r;
|
||||||
|
dest[1] = g;
|
||||||
|
dest[2] = b;
|
||||||
|
dest[3] = a;
|
||||||
|
|
||||||
|
dest += 4;
|
||||||
|
++idxInLightmap;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (g < 0)
|
lightmap += size * 3; /* skip to next lightmap */
|
||||||
{
|
}
|
||||||
g = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b < 0)
|
for ( ; map < MAX_LIGHTMAPS_PER_SURFACE; ++map)
|
||||||
{
|
{
|
||||||
b = 0;
|
// like above, fill up remaining lightmaps with 0
|
||||||
}
|
|
||||||
|
|
||||||
/* determine the brightest of the three color components */
|
byte* dest = gl3_lms.lightmap_buffers[map] + offsetInLMbuf;
|
||||||
if (r > g)
|
|
||||||
{
|
|
||||||
max = r;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
max = g;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b > max)
|
for (i = 0; i < tmax; i++, dest += stride)
|
||||||
{
|
{
|
||||||
max = b;
|
memset(dest, 0, 4*smax);
|
||||||
}
|
dest += 4*smax;
|
||||||
|
|
||||||
/* alpha is ONLY used for the mono lightmap case. For this
|
|
||||||
reason we set it to the brightest of the color components
|
|
||||||
so that things don't get too dim. */
|
|
||||||
a = max;
|
|
||||||
|
|
||||||
/* rescale all the color components if the
|
|
||||||
intensity of the greatest channel exceeds
|
|
||||||
1.0 */
|
|
||||||
if (max > 255)
|
|
||||||
{
|
|
||||||
float t = 255.0F / max;
|
|
||||||
|
|
||||||
r = r * t;
|
|
||||||
g = g * t;
|
|
||||||
b = b * t;
|
|
||||||
a = a * t;
|
|
||||||
}
|
|
||||||
|
|
||||||
dest[0] = r;
|
|
||||||
dest[1] = g;
|
|
||||||
dest[2] = b;
|
|
||||||
dest[3] = a;
|
|
||||||
|
|
||||||
bl += 3;
|
|
||||||
dest += 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,53 +39,32 @@ GL3_LM_InitBlock(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GL3_LM_UploadBlock(qboolean dynamic)
|
GL3_LM_UploadBlock(void)
|
||||||
{
|
{
|
||||||
int texture;
|
int map;
|
||||||
int height = 0;
|
|
||||||
|
|
||||||
if (dynamic)
|
// NOTE: we don't use the dynamic lightmap anymore - all lightmaps are loaded at level load
|
||||||
{
|
// and not changed after that. they're blended dynamically depending on light styles
|
||||||
texture = 0;
|
// though, and dynamic lights are (will be) applied in shader, hopefully per fragment.
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
texture = gl3_lms.current_lightmap_texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
GL3_BindLightmap(texture);
|
GL3_BindLightmap(gl3_lms.current_lightmap_texture);
|
||||||
GL3_SelectTMU(GL_TEXTURE1);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
|
|
||||||
if (dynamic)
|
// upload all 4 lightmaps
|
||||||
|
for(map=0; map < MAX_LIGHTMAPS_PER_SURFACE; ++map)
|
||||||
{
|
{
|
||||||
int i;
|
GL3_SelectTMU(GL_TEXTURE1+map); // this relies on GL_TEXTURE2 being GL_TEXTURE1+1 etc
|
||||||
STUB_ONCE("TODO: dynamic lightmap!");
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
for (i = 0; i < BLOCK_WIDTH; i++)
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
{
|
|
||||||
if (gl3_lms.allocated[i] > height)
|
|
||||||
{
|
|
||||||
height = gl3_lms.allocated[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, BLOCK_WIDTH,
|
|
||||||
height, GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE,
|
|
||||||
gl3_lms.lightmap_buffer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gl3_lms.internal_format = GL_LIGHTMAP_FORMAT;
|
gl3_lms.internal_format = GL_LIGHTMAP_FORMAT;
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, gl3_lms.internal_format,
|
glTexImage2D(GL_TEXTURE_2D, 0, gl3_lms.internal_format,
|
||||||
BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_LIGHTMAP_FORMAT,
|
BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_LIGHTMAP_FORMAT,
|
||||||
GL_UNSIGNED_BYTE, gl3_lms.lightmap_buffer);
|
GL_UNSIGNED_BYTE, gl3_lms.lightmap_buffers[map]);
|
||||||
|
}
|
||||||
|
|
||||||
if (++gl3_lms.current_lightmap_texture == MAX_LIGHTMAPS)
|
if (++gl3_lms.current_lightmap_texture == MAX_LIGHTMAPS)
|
||||||
{
|
{
|
||||||
ri.Sys_Error(ERR_DROP,
|
ri.Sys_Error(ERR_DROP, "LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n");
|
||||||
"LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +191,6 @@ void
|
||||||
GL3_LM_CreateSurfaceLightmap(msurface_t *surf)
|
GL3_LM_CreateSurfaceLightmap(msurface_t *surf)
|
||||||
{
|
{
|
||||||
int smax, tmax;
|
int smax, tmax;
|
||||||
byte *base;
|
|
||||||
|
|
||||||
if (surf->flags & (SURF_DRAWSKY | SURF_DRAWTURB))
|
if (surf->flags & (SURF_DRAWSKY | SURF_DRAWTURB))
|
||||||
{
|
{
|
||||||
|
@ -224,7 +202,7 @@ GL3_LM_CreateSurfaceLightmap(msurface_t *surf)
|
||||||
|
|
||||||
if (!GL3_LM_AllocBlock(smax, tmax, &surf->light_s, &surf->light_t))
|
if (!GL3_LM_AllocBlock(smax, tmax, &surf->light_s, &surf->light_t))
|
||||||
{
|
{
|
||||||
GL3_LM_UploadBlock(false);
|
GL3_LM_UploadBlock();
|
||||||
GL3_LM_InitBlock();
|
GL3_LM_InitBlock();
|
||||||
|
|
||||||
if (!GL3_LM_AllocBlock(smax, tmax, &surf->light_s, &surf->light_t))
|
if (!GL3_LM_AllocBlock(smax, tmax, &surf->light_s, &surf->light_t))
|
||||||
|
@ -236,11 +214,7 @@ GL3_LM_CreateSurfaceLightmap(msurface_t *surf)
|
||||||
|
|
||||||
surf->lightmaptexturenum = gl3_lms.current_lightmap_texture;
|
surf->lightmaptexturenum = gl3_lms.current_lightmap_texture;
|
||||||
|
|
||||||
base = gl3_lms.lightmap_buffer;
|
GL3_BuildLightMap(surf, (surf->light_t * BLOCK_WIDTH + surf->light_s) * LIGHTMAP_BYTES, BLOCK_WIDTH * LIGHTMAP_BYTES);
|
||||||
base += (surf->light_t * BLOCK_WIDTH + surf->light_s) * LIGHTMAP_BYTES;
|
|
||||||
|
|
||||||
GL3_SetCacheState(surf);
|
|
||||||
GL3_BuildLightMap(surf, base, BLOCK_WIDTH * LIGHTMAP_BYTES);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -268,24 +242,15 @@ GL3_LM_BeginBuildingLightmaps(gl3model_t *m)
|
||||||
|
|
||||||
gl3_newrefdef.lightstyles = lightstyles;
|
gl3_newrefdef.lightstyles = lightstyles;
|
||||||
|
|
||||||
STUB_ONCE("TODO: IMPLEMENT!");
|
|
||||||
|
|
||||||
gl3_lms.current_lightmap_texture = 1;
|
gl3_lms.current_lightmap_texture = 1;
|
||||||
gl3_lms.internal_format = GL_LIGHTMAP_FORMAT;
|
gl3_lms.internal_format = GL_LIGHTMAP_FORMAT;
|
||||||
|
|
||||||
/* initialize the dynamic lightmap texture */
|
// Note: the dynamic lightmap used to be initialized here, we don't use that anymore.
|
||||||
GL3_SelectTMU(GL_TEXTURE1);
|
|
||||||
GL3_BindLightmap(0);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, gl3_lms.internal_format,
|
|
||||||
BLOCK_WIDTH, BLOCK_HEIGHT, 0,
|
|
||||||
GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE, dummy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GL3_LM_EndBuildingLightmaps(void)
|
GL3_LM_EndBuildingLightmaps(void)
|
||||||
{
|
{
|
||||||
GL3_LM_UploadBlock(false);
|
GL3_LM_UploadBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -525,8 +525,7 @@ Mod_LoadFaces(lump_t *l)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create lightmaps and polygons */
|
/* create lightmaps and polygons */
|
||||||
if (!(out->texinfo->flags &
|
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP)))
|
||||||
(SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP)))
|
|
||||||
{
|
{
|
||||||
GL3_LM_CreateSurfaceLightmap(out);
|
GL3_LM_CreateSurfaceLightmap(out);
|
||||||
}
|
}
|
||||||
|
|
|
@ -264,12 +264,12 @@ DrawTriangleOutlines(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
UpdateLMscales(const hmm_vec4 lmScales[MAXLIGHTMAPS], gl3ShaderInfo_t* si)
|
UpdateLMscales(const hmm_vec4 lmScales[MAX_LIGHTMAPS_PER_SURFACE], gl3ShaderInfo_t* si)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
qboolean hasChanged = false;
|
qboolean hasChanged = false;
|
||||||
|
|
||||||
for(i=0; i<MAXLIGHTMAPS; ++i)
|
for(i=0; i<MAX_LIGHTMAPS_PER_SURFACE; ++i)
|
||||||
{
|
{
|
||||||
if(hasChanged)
|
if(hasChanged)
|
||||||
{
|
{
|
||||||
|
@ -287,7 +287,7 @@ UpdateLMscales(const hmm_vec4 lmScales[MAXLIGHTMAPS], gl3ShaderInfo_t* si)
|
||||||
|
|
||||||
if(hasChanged)
|
if(hasChanged)
|
||||||
{
|
{
|
||||||
glUniform4fv(si->uniLmScales, MAXLIGHTMAPS, si->lmScales[0].Elements);
|
glUniform4fv(si->uniLmScales, MAX_LIGHTMAPS_PER_SURFACE, si->lmScales[0].Elements);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,7 +347,7 @@ RenderBrushPoly(msurface_t *fa)
|
||||||
// R_TexEnv(GL_REPLACE); TODO!
|
// R_TexEnv(GL_REPLACE); TODO!
|
||||||
}
|
}
|
||||||
|
|
||||||
hmm_vec4 lmScales[MAXLIGHTMAPS] = {0};
|
hmm_vec4 lmScales[MAX_LIGHTMAPS_PER_SURFACE] = {0};
|
||||||
lmScales[0] = HMM_Vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
lmScales[0] = HMM_Vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
// TODO: bind all the lightmaps
|
// TODO: bind all the lightmaps
|
||||||
|
@ -355,7 +355,7 @@ RenderBrushPoly(msurface_t *fa)
|
||||||
GL3_BindLightmap(fa->lightmaptexturenum);
|
GL3_BindLightmap(fa->lightmaptexturenum);
|
||||||
|
|
||||||
// Any dynamic lights on this surface?
|
// Any dynamic lights on this surface?
|
||||||
for (map = 0; map < MAXLIGHTMAPS && fa->styles[map] != 255; map++)
|
for (map = 0; map < MAX_LIGHTMAPS_PER_SURFACE && fa->styles[map] != 255; map++)
|
||||||
{
|
{
|
||||||
lmScales[map].R = gl3_newrefdef.lightstyles[fa->styles[map]].rgb[0];
|
lmScales[map].R = gl3_newrefdef.lightstyles[fa->styles[map]].rgb[0];
|
||||||
lmScales[map].G = gl3_newrefdef.lightstyles[fa->styles[map]].rgb[1];
|
lmScales[map].G = gl3_newrefdef.lightstyles[fa->styles[map]].rgb[1];
|
||||||
|
@ -375,77 +375,6 @@ RenderBrushPoly(msurface_t *fa)
|
||||||
UpdateLMscales(lmScales, &gl3state.si3Dlm);
|
UpdateLMscales(lmScales, &gl3state.si3Dlm);
|
||||||
GL3_DrawGLPoly(fa->polys);
|
GL3_DrawGLPoly(fa->polys);
|
||||||
}
|
}
|
||||||
|
|
||||||
STUB_ONCE("TODO: dynamic lightmap in shaders");
|
|
||||||
|
|
||||||
/* check for lightmap modification */
|
|
||||||
for (maps = 0; maps < MAXLIGHTMAPS && fa->styles[maps] != 255; maps++)
|
|
||||||
{
|
|
||||||
if (gl3_newrefdef.lightstyles[fa->styles[maps]].white !=
|
|
||||||
fa->cached_light[maps])
|
|
||||||
{
|
|
||||||
goto dynamic;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* dynamic this frame or dynamic previously */
|
|
||||||
if (fa->dlightframe == gl3_framecount)
|
|
||||||
{
|
|
||||||
dynamic:
|
|
||||||
|
|
||||||
if (gl_dynamic->value)
|
|
||||||
{
|
|
||||||
if (!(fa->texinfo->flags &
|
|
||||||
(SURF_SKY | SURF_TRANS33 |
|
|
||||||
SURF_TRANS66 | SURF_WARP)))
|
|
||||||
{
|
|
||||||
is_dynamic = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STUB_ONCE("TODO: lightmap support (=> esp. LM textures)")
|
|
||||||
|
|
||||||
// TODO: 2D texture array für lightmaps?
|
|
||||||
if (is_dynamic)
|
|
||||||
{
|
|
||||||
/*if (((fa->styles[maps] >= 32) ||
|
|
||||||
(fa->styles[maps] == 0)) &&
|
|
||||||
(fa->dlightframe != gl3_framecount))
|
|
||||||
{
|
|
||||||
// undo dynamic light changes, put into non-dynamic lightmap chain?
|
|
||||||
// (not totally sure what's happening here)
|
|
||||||
|
|
||||||
unsigned temp[34 * 34];
|
|
||||||
int smax, tmax;
|
|
||||||
|
|
||||||
smax = (fa->extents[0] >> 4) + 1;
|
|
||||||
tmax = (fa->extents[1] >> 4) + 1;
|
|
||||||
|
|
||||||
GL3_BuildLightMap(fa, (void *)temp, smax * 4);
|
|
||||||
GL3_SetCacheState(fa);
|
|
||||||
|
|
||||||
GL3_SelectTMU(GL_TEXTURE1);
|
|
||||||
GL3_BindLightmap(fa->lightmaptexturenum);
|
|
||||||
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, fa->light_s, fa->light_t,
|
|
||||||
smax, tmax, GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE, temp);
|
|
||||||
|
|
||||||
fa->lightmapchain = gl3_lms.lightmap_surfaces[fa->lightmaptexturenum];
|
|
||||||
gl3_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa;
|
|
||||||
}
|
|
||||||
else*/
|
|
||||||
{
|
|
||||||
// dynamic lights: add to dynamic lightmap chain
|
|
||||||
fa->lightmapchain = gl3_lms.lightmap_surfaces[0];
|
|
||||||
gl3_lms.lightmap_surfaces[0] = fa;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // non-dynamic lightmap chain
|
|
||||||
{
|
|
||||||
fa->lightmapchain = gl3_lms.lightmap_surfaces[fa->lightmaptexturenum];
|
|
||||||
gl3_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -471,8 +400,6 @@ GL3_DrawAlphaSurfaces(void)
|
||||||
//intens = gl3state.inverse_intensity;
|
//intens = gl3state.inverse_intensity;
|
||||||
STUB_ONCE("Something about inverse intensity??");
|
STUB_ONCE("Something about inverse intensity??");
|
||||||
|
|
||||||
STUB_ONCE("TODO: more shaders for rendering brushes (w/o lightmap for translucent etc)");
|
|
||||||
|
|
||||||
for (s = gl3_alpha_surfaces; s != NULL; s = s->texturechain)
|
for (s = gl3_alpha_surfaces; s != NULL; s = s->texturechain)
|
||||||
{
|
{
|
||||||
GL3_Bind(s->texinfo->image->texnum);
|
GL3_Bind(s->texinfo->image->texnum);
|
||||||
|
@ -573,7 +500,7 @@ RenderLightmappedPoly(msurface_t *surf)
|
||||||
unsigned lmtex;
|
unsigned lmtex;
|
||||||
unsigned temp[128 * 128];
|
unsigned temp[128 * 128];
|
||||||
|
|
||||||
hmm_vec4 lmScales[MAXLIGHTMAPS] = {0};
|
hmm_vec4 lmScales[MAX_LIGHTMAPS_PER_SURFACE] = {0};
|
||||||
lmScales[0] = HMM_Vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
lmScales[0] = HMM_Vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
image = TextureAnimation(surf->texinfo);
|
image = TextureAnimation(surf->texinfo);
|
||||||
|
@ -585,7 +512,7 @@ RenderLightmappedPoly(msurface_t *surf)
|
||||||
&& "RenderLightMappedPoly mustn't be called with transparent, sky or warping surfaces!");
|
&& "RenderLightMappedPoly mustn't be called with transparent, sky or warping surfaces!");
|
||||||
|
|
||||||
// Any dynamic lights on this surface?
|
// Any dynamic lights on this surface?
|
||||||
for (map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++)
|
for (map = 0; map < MAX_LIGHTMAPS_PER_SURFACE && surf->styles[map] != 255; map++)
|
||||||
{
|
{
|
||||||
lmScales[map].R = gl3_newrefdef.lightstyles[surf->styles[map]].rgb[0];
|
lmScales[map].R = gl3_newrefdef.lightstyles[surf->styles[map]].rgb[0];
|
||||||
lmScales[map].G = gl3_newrefdef.lightstyles[surf->styles[map]].rgb[1];
|
lmScales[map].G = gl3_newrefdef.lightstyles[surf->styles[map]].rgb[1];
|
||||||
|
@ -598,35 +525,19 @@ RenderLightmappedPoly(msurface_t *surf)
|
||||||
{
|
{
|
||||||
if (gl_dynamic->value)
|
if (gl_dynamic->value)
|
||||||
{
|
{
|
||||||
if (!(surf->texinfo->flags & (SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP)))
|
is_dynamic = true;
|
||||||
{
|
|
||||||
is_dynamic = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 // TODO!
|
#if 0 // TODO!
|
||||||
if (is_dynamic)
|
if (is_dynamic)
|
||||||
{
|
{
|
||||||
// Dynamic lights on a surface
|
// Dynamic lights on a surface - NOTE: this is handled via lmScales
|
||||||
if (((surf->styles[map] >= 32) || (surf->styles[map] == 0)) && (surf->dlightframe != r_framecount))
|
if (((surf->styles[map] >= 32) || (surf->styles[map] == 0)) && (surf->dlightframe != r_framecount))
|
||||||
{
|
{
|
||||||
smax = (surf->extents[0] >> 4) + 1;
|
|
||||||
tmax = (surf->extents[1] >> 4) + 1;
|
|
||||||
|
|
||||||
//GL3_BuildLightMap(surf, (void *) temp, smax * 4);
|
|
||||||
//GL3_SetCacheState(surf);
|
|
||||||
//R_MBind(GL_TEXTURE1_ARB, gl_state.lightmap_textures + surf->lightmaptexturenum);
|
|
||||||
//GL3_BindLightmap(surf->lightmaptexturenum);
|
|
||||||
|
|
||||||
//lmtex = surf->lightmaptexturenum;
|
|
||||||
|
|
||||||
FIXME;
|
|
||||||
|
|
||||||
//glTexSubImage2D(GL_TEXTURE_2D, 0, surf->light_s, surf->light_t, smax,
|
|
||||||
// tmax, GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE, temp);
|
|
||||||
}
|
}
|
||||||
else // Normal dynamic lights
|
else // Normal dynamic lights - NOTE: This is still missing, but will not be done by creating a dynamic lightmap.
|
||||||
{
|
{
|
||||||
smax = (surf->extents[0] >> 4) + 1;
|
smax = (surf->extents[0] >> 4) + 1;
|
||||||
tmax = (surf->extents[1] >> 4) + 1;
|
tmax = (surf->extents[1] >> 4) + 1;
|
||||||
|
@ -646,16 +557,14 @@ RenderLightmappedPoly(msurface_t *surf)
|
||||||
R_MBind(GL_TEXTURE0_ARB, image->texnum);
|
R_MBind(GL_TEXTURE0_ARB, image->texnum);
|
||||||
R_MBind(GL_TEXTURE1_ARB, gl_state.lightmap_textures + lmtex);
|
R_MBind(GL_TEXTURE1_ARB, gl_state.lightmap_textures + lmtex);
|
||||||
}
|
}
|
||||||
else // No dynamic lights
|
|
||||||
#endif // 0
|
|
||||||
{
|
|
||||||
c_brush_polys++;
|
|
||||||
|
|
||||||
//R_MBind(GL_TEXTURE0_ARB, image->texnum);
|
#endif // 0
|
||||||
GL3_Bind(image->texnum);
|
|
||||||
//R_MBind(GL_TEXTURE1_ARB, gl_state.lightmap_textures + lmtex);
|
c_brush_polys++;
|
||||||
GL3_BindLightmap(lmtex);
|
|
||||||
}
|
GL3_Bind(image->texnum);
|
||||||
|
GL3_BindLightmap(lmtex);
|
||||||
|
|
||||||
|
|
||||||
if (surf->texinfo->flags & SURF_FLOWING)
|
if (surf->texinfo->flags & SURF_FLOWING)
|
||||||
{
|
{
|
||||||
|
@ -783,10 +692,6 @@ GL3_DrawBrushModel(entity_t *e)
|
||||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
STUB_ONCE("TODO: something about setting color to 1,1,1,1");
|
|
||||||
//glColor4f(1, 1, 1, 1);
|
|
||||||
memset(gl3_lms.lightmap_surfaces, 0, sizeof(gl3_lms.lightmap_surfaces));
|
|
||||||
|
|
||||||
VectorSubtract(gl3_newrefdef.vieworg, e->origin, modelorg);
|
VectorSubtract(gl3_newrefdef.vieworg, e->origin, modelorg);
|
||||||
|
|
||||||
if (rotated)
|
if (rotated)
|
||||||
|
@ -999,17 +904,14 @@ GL3_DrawWorld(void)
|
||||||
ent.frame = (int)(gl3_newrefdef.time * 2);
|
ent.frame = (int)(gl3_newrefdef.time * 2);
|
||||||
currententity = &ent;
|
currententity = &ent;
|
||||||
|
|
||||||
gl3state.currenttexture = -1; //s[0] = gl3state.currenttextures[1] = -1;
|
gl3state.currenttexture = -1;
|
||||||
|
|
||||||
STUB_ONCE("somehow set color to 1,1,1,1 maybe");
|
STUB_ONCE("somehow set color to 1,1,1,1 maybe");
|
||||||
//glColor4f(1, 1, 1, 1);
|
//glColor4f(1, 1, 1, 1);
|
||||||
|
|
||||||
memset(gl3_lms.lightmap_surfaces, 0, sizeof(gl3_lms.lightmap_surfaces));
|
|
||||||
|
|
||||||
GL3_ClearSkyBox();
|
GL3_ClearSkyBox();
|
||||||
RecursiveWorldNode(gl3_worldmodel->nodes);
|
RecursiveWorldNode(gl3_worldmodel->nodes);
|
||||||
DrawTextureChains();
|
DrawTextureChains();
|
||||||
//BlendLightmaps();
|
|
||||||
GL3_DrawSkyBox();
|
GL3_DrawSkyBox();
|
||||||
DrawTriangleOutlines();
|
DrawTriangleOutlines();
|
||||||
|
|
||||||
|
|
|
@ -262,13 +262,13 @@ typedef struct
|
||||||
int internal_format;
|
int internal_format;
|
||||||
int current_lightmap_texture; // index into gl3state.lightmap_textureIDs[]
|
int current_lightmap_texture; // index into gl3state.lightmap_textureIDs[]
|
||||||
|
|
||||||
msurface_t *lightmap_surfaces[MAX_LIGHTMAPS];
|
//msurface_t *lightmap_surfaces[MAX_LIGHTMAPS]; - no more lightmap chains, lightmaps are rendered multitextured
|
||||||
|
|
||||||
int allocated[BLOCK_WIDTH];
|
int allocated[BLOCK_WIDTH];
|
||||||
|
|
||||||
/* the lightmap texture data needs to be kept in
|
/* the lightmap texture data needs to be kept in
|
||||||
main memory so texsubimage can update properly */
|
main memory so texsubimage can update properly */
|
||||||
byte lightmap_buffer[4 * BLOCK_WIDTH * BLOCK_HEIGHT];
|
byte lightmap_buffers[MAX_LIGHTMAPS_PER_SURFACE][4 * BLOCK_WIDTH * BLOCK_HEIGHT];
|
||||||
} gl3lightmapstate_t;
|
} gl3lightmapstate_t;
|
||||||
|
|
||||||
// used for vertex array elements when drawing brushes, sprites, sky and more
|
// used for vertex array elements when drawing brushes, sprites, sky and more
|
||||||
|
@ -408,14 +408,13 @@ extern void GL3_ImageList_f(void);
|
||||||
extern void GL3_MarkLights(dlight_t *light, int bit, mnode_t *node);
|
extern void GL3_MarkLights(dlight_t *light, int bit, mnode_t *node);
|
||||||
extern void GL3_PushDlights(void);
|
extern void GL3_PushDlights(void);
|
||||||
extern void GL3_LightPoint(vec3_t p, vec3_t color);
|
extern void GL3_LightPoint(vec3_t p, vec3_t color);
|
||||||
extern void GL3_SetCacheState(msurface_t *surf);
|
extern void GL3_BuildLightMap(msurface_t *surf, int offsetInLMbuf, int stride);
|
||||||
extern void GL3_BuildLightMap(msurface_t *surf, byte *dest, int stride);
|
|
||||||
|
|
||||||
// gl3_lightmap.c
|
// gl3_lightmap.c
|
||||||
#define GL_LIGHTMAP_FORMAT GL_RGBA
|
#define GL_LIGHTMAP_FORMAT GL_RGBA
|
||||||
|
|
||||||
extern void GL3_LM_InitBlock(void);
|
extern void GL3_LM_InitBlock(void);
|
||||||
extern void GL3_LM_UploadBlock(qboolean dynamic);
|
extern void GL3_LM_UploadBlock(void);
|
||||||
extern qboolean GL3_LM_AllocBlock(int w, int h, int *x, int *y);
|
extern qboolean GL3_LM_AllocBlock(int w, int h, int *x, int *y);
|
||||||
extern void GL3_LM_BuildPolygonFromSurface(msurface_t *fa);
|
extern void GL3_LM_BuildPolygonFromSurface(msurface_t *fa);
|
||||||
extern void GL3_LM_CreateSurfaceLightmap(msurface_t *surf);
|
extern void GL3_LM_CreateSurfaceLightmap(msurface_t *surf);
|
||||||
|
|
|
@ -104,7 +104,7 @@ typedef struct msurface_s
|
||||||
|
|
||||||
glpoly_t *polys; /* multiple if warped */
|
glpoly_t *polys; /* multiple if warped */
|
||||||
struct msurface_s *texturechain;
|
struct msurface_s *texturechain;
|
||||||
struct msurface_s *lightmapchain;
|
// struct msurface_s *lightmapchain; not used/needed anymore
|
||||||
|
|
||||||
mtexinfo_t *texinfo;
|
mtexinfo_t *texinfo;
|
||||||
|
|
||||||
|
@ -114,7 +114,8 @@ typedef struct msurface_s
|
||||||
|
|
||||||
int lightmaptexturenum;
|
int lightmaptexturenum;
|
||||||
byte styles[MAXLIGHTMAPS];
|
byte styles[MAXLIGHTMAPS];
|
||||||
float cached_light[MAXLIGHTMAPS]; /* values currently used in lightmap */
|
// I think cached_light is not used/needed anymore
|
||||||
|
//float cached_light[MAXLIGHTMAPS]; /* values currently used in lightmap */
|
||||||
byte *samples; /* [numstyles*surfsize] */
|
byte *samples; /* [numstyles*surfsize] */
|
||||||
} msurface_t;
|
} msurface_t;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue