Merge pull request #1108 from protocultor/gl1_biglightmaps

GL1 big lightmaps and scrap
This commit is contained in:
Yamagi 2024-05-25 16:03:38 +02:00 committed by GitHub
commit 7ffcd990c4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 172 additions and 60 deletions

View file

@ -460,6 +460,10 @@ Set `0` by default.
## Graphics (OpenGL 1.4 only) ## Graphics (OpenGL 1.4 only)
* **gl1_biglightmaps**: Enables lightmaps and scrap to use a bigger
texture size, which means fewer texture switches, improving
performance. Default is `1` (enabled). Requires a `vid_restart`.
* **gl1_intensity**: Sets the color intensity. Must be a floating point * **gl1_intensity**: Sets the color intensity. Must be a floating point
value, at least `1.0` - default is `2.0`. Applied when textures are value, at least `1.0` - default is `2.0`. Applied when textures are
loaded, so it needs a `vid_restart`. loaded, so it needs a `vid_restart`.

View file

@ -85,6 +85,7 @@ Sys_Error(const char *error, ...)
void void
Sys_Quit(void) Sys_Quit(void)
{ {
const qboolean free_console = (dedicated && dedicated->value);
timeEndPeriod(1); timeEndPeriod(1);
#ifndef DEDICATED_ONLY #ifndef DEDICATED_ONLY
@ -93,7 +94,7 @@ Sys_Quit(void)
Qcommon_Shutdown(); Qcommon_Shutdown();
if (dedicated && dedicated->value) if (free_console)
{ {
FreeConsole(); FreeConsole();
} }

View file

@ -31,7 +31,7 @@ int numgltextures;
static int image_max = 0; static int image_max = 0;
int base_textureid; /* gltextures[i] = base_textureid+i */ int base_textureid; /* gltextures[i] = base_textureid+i */
extern qboolean scrap_dirty; extern qboolean scrap_dirty;
extern byte scrap_texels[MAX_SCRAPS][BLOCK_WIDTH * BLOCK_HEIGHT]; extern byte *scrap_texels[MAX_SCRAPS];
static byte intensitytable[256]; static byte intensitytable[256];
static unsigned char gammatable[256]; static unsigned char gammatable[256];
@ -638,11 +638,6 @@ R_BuildPalettedTexture(unsigned char *paletted_texture, unsigned char *scaled,
} }
} }
// Windows headers don't define this constant.
#ifndef GL_GENERATE_MIPMAP
#define GL_GENERATE_MIPMAP 0x8191
#endif
qboolean qboolean
R_Upload32Native(unsigned *data, int width, int height, qboolean mipmap) R_Upload32Native(unsigned *data, int width, int height, qboolean mipmap)
{ {
@ -1045,17 +1040,17 @@ R_LoadPic(const char *name, byte *pic, int width, int realwidth,
{ {
for (j = 0; j < image->width; j++, k++) for (j = 0; j < image->width; j++, k++)
{ {
scrap_texels[texnum][(y + i) * BLOCK_WIDTH + x + j] = pic[k]; scrap_texels[texnum][(y + i) * gl_state.scrap_width + x + j] = pic[k];
} }
} }
image->texnum = TEXNUM_SCRAPS + texnum; image->texnum = TEXNUM_SCRAPS + texnum;
image->scrap = true; image->scrap = true;
image->has_alpha = true; image->has_alpha = true;
image->sl = (x + 0.01) / (float)BLOCK_WIDTH; image->sl = (float)x / gl_state.scrap_width;
image->sh = (x + image->width - 0.01) / (float)BLOCK_WIDTH; image->sh = (float)(x + image->width) / gl_state.scrap_width;
image->tl = (y + 0.01) / (float)BLOCK_WIDTH; image->tl = (float)y / gl_state.scrap_height;
image->th = (y + image->height - 0.01) / (float)BLOCK_WIDTH; image->th = (float)(y + image->height) / gl_state.scrap_height;
} }
else else
{ {

View file

@ -42,13 +42,19 @@ LM_FreeLightmapBuffers(void)
} }
gl_lms.lightmap_buffer[i] = NULL; gl_lms.lightmap_buffer[i] = NULL;
} }
if (gl_lms.allocated)
{
free(gl_lms.allocated);
gl_lms.allocated = NULL;
}
} }
static void static void
LM_AllocLightmapBuffer(int buffer, qboolean clean) LM_AllocLightmapBuffer(int buffer, qboolean clean)
{ {
static const unsigned int lightmap_size = const unsigned int lightmap_size =
BLOCK_WIDTH * BLOCK_HEIGHT * LIGHTMAP_BYTES; gl_state.block_width * gl_state.block_height * LIGHTMAP_BYTES;
if (!gl_lms.lightmap_buffer[buffer]) if (!gl_lms.lightmap_buffer[buffer])
{ {
@ -68,7 +74,7 @@ LM_AllocLightmapBuffer(int buffer, qboolean clean)
void void
LM_InitBlock(void) LM_InitBlock(void)
{ {
memset(gl_lms.allocated, 0, sizeof(gl_lms.allocated)); memset(gl_lms.allocated, 0, gl_state.block_width * sizeof(int));
if (gl_config.multitexture) if (gl_config.multitexture)
{ {
@ -91,7 +97,7 @@ LM_UploadBlock(qboolean dynamic)
{ {
int i; int i;
for (i = 0; i < BLOCK_WIDTH; i++) for (i = 0; i < gl_state.block_width; i++)
{ {
if (gl_lms.allocated[i] > height) if (gl_lms.allocated[i] > height)
{ {
@ -99,7 +105,7 @@ LM_UploadBlock(qboolean dynamic)
} }
} }
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, BLOCK_WIDTH, glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, gl_state.block_width,
height, GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE, height, GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE,
gl_lms.lightmap_buffer[buffer]); gl_lms.lightmap_buffer[buffer]);
} }
@ -107,10 +113,11 @@ LM_UploadBlock(qboolean dynamic)
{ {
gl_lms.internal_format = GL_LIGHTMAP_FORMAT; gl_lms.internal_format = GL_LIGHTMAP_FORMAT;
glTexImage2D(GL_TEXTURE_2D, 0, gl_lms.internal_format, glTexImage2D(GL_TEXTURE_2D, 0, gl_lms.internal_format,
BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_LIGHTMAP_FORMAT, gl_state.block_width, gl_state.block_height,
GL_UNSIGNED_BYTE, gl_lms.lightmap_buffer[buffer]); 0, GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE,
gl_lms.lightmap_buffer[buffer]);
if (++gl_lms.current_lightmap_texture == MAX_LIGHTMAPS) if (++gl_lms.current_lightmap_texture == gl_state.max_lightmaps)
{ {
ri.Sys_Error(ERR_DROP, ri.Sys_Error(ERR_DROP,
"LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n"); "LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n");
@ -127,9 +134,9 @@ LM_AllocBlock(int w, int h, int *x, int *y)
int i, j; int i, j;
int best, best2; int best, best2;
best = BLOCK_HEIGHT; best = gl_state.block_height;
for (i = 0; i < BLOCK_WIDTH - w; i++) for (i = 0; i < gl_state.block_width - w; i++)
{ {
best2 = 0; best2 = 0;
@ -154,7 +161,7 @@ LM_AllocBlock(int w, int h, int *x, int *y)
} }
} }
if (best + h > BLOCK_HEIGHT) if (best + h > gl_state.block_height)
{ {
return false; return false;
} }
@ -222,13 +229,13 @@ LM_BuildPolygonFromSurface(model_t *currentmodel, msurface_t *fa)
s -= fa->texturemins[0]; s -= fa->texturemins[0];
s += fa->light_s * 16; s += fa->light_s * 16;
s += 8; s += 8;
s /= BLOCK_WIDTH * 16; /* fa->texinfo->texture->width; */ s /= gl_state.block_width * 16; /* fa->texinfo->texture->width; */
t = DotProduct(vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; t = DotProduct(vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
t -= fa->texturemins[1]; t -= fa->texturemins[1];
t += fa->light_t * 16; t += fa->light_t * 16;
t += 8; t += 8;
t /= BLOCK_HEIGHT * 16; /* fa->texinfo->texture->height; */ t /= gl_state.block_height * 16; /* fa->texinfo->texture->height; */
poly->verts[i][5] = s; poly->verts[i][5] = s;
poly->verts[i][6] = t; poly->verts[i][6] = t;
@ -265,10 +272,10 @@ LM_CreateSurfaceLightmap(msurface_t *surf)
buffer = (gl_config.multitexture)? surf->lightmaptexturenum : 0; buffer = (gl_config.multitexture)? surf->lightmaptexturenum : 0;
base = gl_lms.lightmap_buffer[buffer]; base = gl_lms.lightmap_buffer[buffer];
base += (surf->light_t * BLOCK_WIDTH + surf->light_s) * LIGHTMAP_BYTES; base += (surf->light_t * gl_state.block_width + surf->light_s) * LIGHTMAP_BYTES;
R_SetCacheState(surf); R_SetCacheState(surf);
R_BuildLightMap(surf, base, BLOCK_WIDTH * LIGHTMAP_BYTES); R_BuildLightMap(surf, base, gl_state.block_width * LIGHTMAP_BYTES);
} }
void void
@ -277,8 +284,13 @@ LM_BeginBuildingLightmaps(model_t *m)
static lightstyle_t lightstyles[MAX_LIGHTSTYLES]; static lightstyle_t lightstyles[MAX_LIGHTSTYLES];
int i; int i;
memset(gl_lms.allocated, 0, sizeof(gl_lms.allocated));
LM_FreeLightmapBuffers(); LM_FreeLightmapBuffers();
gl_lms.allocated = (int*)malloc(gl_state.block_width * sizeof(int));
if (!gl_lms.allocated)
{
ri.Sys_Error(ERR_FATAL, "Could not create lightmap allocator\n");
}
memset(gl_lms.allocated, 0, gl_state.block_width * sizeof(int));
r_framecount = 1; /* no dlightcache */ r_framecount = 1; /* no dlightcache */
@ -317,8 +329,9 @@ LM_BeginBuildingLightmaps(model_t *m)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, gl_lms.internal_format, glTexImage2D(GL_TEXTURE_2D, 0, gl_lms.internal_format,
BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_LIGHTMAP_FORMAT, gl_state.block_width, gl_state.block_height,
GL_UNSIGNED_BYTE, gl_lms.lightmap_buffer[0]); 0, GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE,
gl_lms.lightmap_buffer[0]);
} }
void void

View file

@ -91,6 +91,7 @@ cvar_t *gl1_particle_square;
cvar_t *gl1_palettedtexture; cvar_t *gl1_palettedtexture;
cvar_t *gl1_pointparameters; cvar_t *gl1_pointparameters;
cvar_t *gl1_multitexture; cvar_t *gl1_multitexture;
cvar_t *gl1_biglightmaps;
cvar_t *gl_drawbuffer; cvar_t *gl_drawbuffer;
cvar_t *gl_lightmap; cvar_t *gl_lightmap;
@ -145,6 +146,8 @@ cvar_t *gl1_stereo_convergence;
refimport_t ri; refimport_t ri;
void LM_FreeLightmapBuffers(void); void LM_FreeLightmapBuffers(void);
void Scrap_Free(void);
void Scrap_Init(void);
void void
R_RotateForEntity(entity_t *e) R_RotateForEntity(entity_t *e)
@ -1217,6 +1220,7 @@ R_Register(void)
gl1_palettedtexture = ri.Cvar_Get("r_palettedtextures", "0", CVAR_ARCHIVE); gl1_palettedtexture = ri.Cvar_Get("r_palettedtextures", "0", CVAR_ARCHIVE);
gl1_pointparameters = ri.Cvar_Get("gl1_pointparameters", "1", CVAR_ARCHIVE); gl1_pointparameters = ri.Cvar_Get("gl1_pointparameters", "1", CVAR_ARCHIVE);
gl1_multitexture = ri.Cvar_Get("gl1_multitexture", "2", CVAR_ARCHIVE); gl1_multitexture = ri.Cvar_Get("gl1_multitexture", "2", CVAR_ARCHIVE);
gl1_biglightmaps = ri.Cvar_Get("gl1_biglightmaps", "1", CVAR_ARCHIVE);
gl_drawbuffer = ri.Cvar_Get("gl_drawbuffer", "GL_BACK", 0); gl_drawbuffer = ri.Cvar_Get("gl_drawbuffer", "GL_BACK", 0);
r_vsync = ri.Cvar_Get("r_vsync", "1", CVAR_ARCHIVE); r_vsync = ri.Cvar_Get("r_vsync", "1", CVAR_ARCHIVE);
@ -1397,7 +1401,7 @@ R_SetMode(void)
qboolean qboolean
RI_Init(void) RI_Init(void)
{ {
int j; int j, max_tex_size;
byte *colormap; byte *colormap;
extern float r_turbsin[256]; extern float r_turbsin[256];
@ -1639,8 +1643,41 @@ RI_Init(void)
// ---- // ----
/* Big lightmaps */
R_Printf(PRINT_ALL, " - Big lightmaps: ");
gl_state.block_width = BLOCK_WIDTH;
gl_state.block_height = BLOCK_HEIGHT;
gl_state.max_lightmaps = MAX_LIGHTMAPS;
gl_state.scrap_width = BLOCK_WIDTH;
gl_state.scrap_height = BLOCK_HEIGHT;
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_tex_size);
if (max_tex_size > BLOCK_WIDTH)
{
if (gl1_biglightmaps->value)
{
gl_state.block_width = gl_state.block_height = Q_min(max_tex_size, 512);
gl_state.max_lightmaps = (BLOCK_WIDTH * BLOCK_HEIGHT * MAX_LIGHTMAPS)
/ (gl_state.block_width * gl_state.block_height);
gl_state.scrap_width = gl_state.scrap_height =
(gl_config.npottextures)? Q_min(max_tex_size, 384) : Q_min(max_tex_size, 256);
R_Printf(PRINT_ALL, "Okay\n");
}
else
{
R_Printf(PRINT_ALL, "Disabled\n");
}
}
else
{
R_Printf(PRINT_ALL, "Failed, detected texture size = %d\n", max_tex_size);
}
// ----
R_SetDefaultState(); R_SetDefaultState();
Scrap_Init();
R_InitImages(); R_InitImages();
Mod_Init(); Mod_Init();
R_InitParticleTexture(); R_InitParticleTexture();
@ -1658,6 +1695,7 @@ RI_Shutdown(void)
ri.Cmd_RemoveCommand("gl_strings"); ri.Cmd_RemoveCommand("gl_strings");
LM_FreeLightmapBuffers(); LM_FreeLightmapBuffers();
Scrap_Free();
Mod_FreeAll(); Mod_FreeAll();
R_ShutdownImages(); R_ShutdownImages();

View file

@ -19,7 +19,7 @@
* *
* ======================================================================= * =======================================================================
* *
* Allocate all the little status bar obejcts into a single texture * Allocate all the little status bar objects into a single texture
* to crutch up inefficient hardware / drivers. * to crutch up inefficient hardware / drivers.
* *
* ======================================================================= * =======================================================================
@ -27,10 +27,9 @@
#include "header/local.h" #include "header/local.h"
int scrap_allocated[MAX_SCRAPS][BLOCK_WIDTH]; int *scrap_allocated[MAX_SCRAPS];
byte scrap_texels[MAX_SCRAPS][BLOCK_WIDTH * BLOCK_HEIGHT]; byte *scrap_texels[MAX_SCRAPS];
qboolean scrap_dirty; qboolean scrap_dirty;
int scrap_uploads;
qboolean R_Upload8(byte *data, qboolean R_Upload8(byte *data,
int width, int width,
@ -45,12 +44,14 @@ Scrap_AllocBlock(int w, int h, int *x, int *y)
int i, j; int i, j;
int best, best2; int best, best2;
int texnum; int texnum;
w += 2; // add an empty border to all sides
h += 2;
for (texnum = 0; texnum < MAX_SCRAPS; texnum++) for (texnum = 0; texnum < MAX_SCRAPS; texnum++)
{ {
best = BLOCK_HEIGHT; best = gl_state.scrap_height;
for (i = 0; i < BLOCK_WIDTH - w; i++) for (i = 0; i < gl_state.scrap_width - w; i++)
{ {
best2 = 0; best2 = 0;
@ -74,7 +75,7 @@ Scrap_AllocBlock(int w, int h, int *x, int *y)
} }
} }
if (best + h > BLOCK_HEIGHT) if (best + h > gl_state.scrap_height)
{ {
continue; continue;
} }
@ -83,6 +84,8 @@ Scrap_AllocBlock(int w, int h, int *x, int *y)
{ {
scrap_allocated[texnum][*x + i] = best + h; scrap_allocated[texnum][*x + i] = best + h;
} }
(*x)++; // jump the border
(*y)++;
return texnum; return texnum;
} }
@ -93,9 +96,58 @@ Scrap_AllocBlock(int w, int h, int *x, int *y)
void void
Scrap_Upload(void) Scrap_Upload(void)
{ {
scrap_uploads++;
R_Bind(TEXNUM_SCRAPS); R_Bind(TEXNUM_SCRAPS);
R_Upload8(scrap_texels[0], BLOCK_WIDTH, BLOCK_HEIGHT, false, false); R_Upload8(scrap_texels[0], gl_state.scrap_width,
gl_state.scrap_height, false, false);
scrap_dirty = false; scrap_dirty = false;
} }
void
Scrap_Free(void)
{
for (int i = 0; i < MAX_SCRAPS; i++)
{
if (scrap_allocated[i])
{
free(scrap_allocated[i]);
}
scrap_allocated[i] = NULL;
if (scrap_texels[i])
{
free(scrap_texels[i]);
}
scrap_texels[i] = NULL;
}
}
void
Scrap_Init(void)
{
const unsigned int allocd_size = gl_state.scrap_width * sizeof(int);
const unsigned int texels_size = gl_state.scrap_width
* gl_state.scrap_height * sizeof(byte);
int i;
Scrap_Free();
for (i = 0; i < MAX_SCRAPS; i++)
{
if (!scrap_allocated[i])
{
scrap_allocated[i] = malloc (allocd_size) ;
}
if (!scrap_texels[i])
{
scrap_texels[i] = malloc (texels_size) ;
}
if (!scrap_allocated[i] || !scrap_texels[i])
{
ri.Sys_Error(ERR_FATAL, "Could not allocate scrap memory.\n");
}
memset (scrap_allocated[i], 0, allocd_size); // empty
memset (scrap_texels[i], 255, texels_size); // transparent
}
}

View file

@ -117,7 +117,7 @@ R_DrawTriangleOutlines(void)
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glColor4f(1, 1, 1, 1); glColor4f(1, 1, 1, 1);
for (i = 0; i < MAX_LIGHTMAPS; i++) for (i = 0; i < gl_state.max_lightmaps; i++)
{ {
msurface_t *surf; msurface_t *surf;
@ -269,7 +269,7 @@ R_BlendLightmaps(const model_t *currentmodel)
} }
/* render static lightmaps first */ /* render static lightmaps first */
for (i = 1; i < MAX_LIGHTMAPS; i++) for (i = 1; i < gl_state.max_lightmaps; i++)
{ {
if (gl_lms.lightmap_surfaces[i]) if (gl_lms.lightmap_surfaces[i])
{ {
@ -326,10 +326,10 @@ R_BlendLightmaps(const model_t *currentmodel)
if (LM_AllocBlock(smax, tmax, &surf->dlight_s, &surf->dlight_t)) if (LM_AllocBlock(smax, tmax, &surf->dlight_s, &surf->dlight_t))
{ {
base = gl_lms.lightmap_buffer[0]; base = gl_lms.lightmap_buffer[0];
base += (surf->dlight_t * BLOCK_WIDTH + base += (surf->dlight_t * gl_state.block_width +
surf->dlight_s) * LIGHTMAP_BYTES; surf->dlight_s) * LIGHTMAP_BYTES;
R_BuildLightMap(surf, base, BLOCK_WIDTH * LIGHTMAP_BYTES); R_BuildLightMap(surf, base, gl_state.block_width * LIGHTMAP_BYTES);
} }
else else
{ {
@ -353,8 +353,8 @@ R_BlendLightmaps(const model_t *currentmodel)
} }
R_DrawGLPolyChain(drawsurf->polys, R_DrawGLPolyChain(drawsurf->polys,
(drawsurf->light_s - drawsurf->dlight_s) * (1.0 / 128.0), (drawsurf->light_s - drawsurf->dlight_s) * (1.0 / (float)gl_state.block_width),
(drawsurf->light_t - drawsurf->dlight_t) * (1.0 / 128.0)); (drawsurf->light_t - drawsurf->dlight_t) * (1.0 / (float)gl_state.block_height));
} }
} }
@ -372,10 +372,10 @@ R_BlendLightmaps(const model_t *currentmodel)
} }
base = gl_lms.lightmap_buffer[0]; base = gl_lms.lightmap_buffer[0];
base += (surf->dlight_t * BLOCK_WIDTH + base += (surf->dlight_t * gl_state.block_width +
surf->dlight_s) * LIGHTMAP_BYTES; surf->dlight_s) * LIGHTMAP_BYTES;
R_BuildLightMap(surf, base, BLOCK_WIDTH * LIGHTMAP_BYTES); R_BuildLightMap(surf, base, gl_state.block_width * LIGHTMAP_BYTES);
} }
} }
@ -397,8 +397,8 @@ R_BlendLightmaps(const model_t *currentmodel)
} }
R_DrawGLPolyChain(surf->polys, R_DrawGLPolyChain(surf->polys,
(surf->light_s - surf->dlight_s) * (1.0 / 128.0), (surf->light_s - surf->dlight_s) * (1.0 / (float)gl_state.block_width),
(surf->light_t - surf->dlight_t) * (1.0 / 128.0)); (surf->light_t - surf->dlight_t) * (1.0 / (float)gl_state.block_height));
} }
} }
} }
@ -723,12 +723,12 @@ static void
R_UploadDynamicLights(msurface_t *surf) R_UploadDynamicLights(msurface_t *surf)
{ {
int map, smax, tmax; int map, smax, tmax;
byte temp[BLOCK_WIDTH * BLOCK_HEIGHT];
if ( !gl_config.multitexture || !R_HasDynamicLights(surf, &map) ) if ( !gl_config.multitexture || !R_HasDynamicLights(surf, &map) )
{ {
return; return;
} }
YQ2_VLA(byte, temp, gl_state.block_width * gl_state.block_height);
smax = (surf->extents[0] >> 4) + 1; smax = (surf->extents[0] >> 4) + 1;
tmax = (surf->extents[1] >> 4) + 1; tmax = (surf->extents[1] >> 4) + 1;
@ -738,6 +738,7 @@ R_UploadDynamicLights(msurface_t *surf)
R_Bind(gl_state.lightmap_textures + surf->lightmaptexturenum); R_Bind(gl_state.lightmap_textures + surf->lightmaptexturenum);
glTexSubImage2D(GL_TEXTURE_2D, 0, surf->light_s, surf->light_t, smax, glTexSubImage2D(GL_TEXTURE_2D, 0, surf->light_s, surf->light_t, smax,
tmax, GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE, temp); tmax, GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE, temp);
YQ2_VLAFREE(temp);
} }
/* Upload dynamic lights to each lightmap texture (multitexture path only) */ /* Upload dynamic lights to each lightmap texture (multitexture path only) */
@ -754,9 +755,9 @@ R_RegenAllLightmaps()
return; return;
} }
glPixelStorei(GL_UNPACK_ROW_LENGTH, BLOCK_WIDTH); glPixelStorei(GL_UNPACK_ROW_LENGTH, gl_state.block_width);
for (i = 1; i < MAX_LIGHTMAPS; i++) for (i = 1; i < gl_state.max_lightmaps; i++)
{ {
if (!gl_lms.lightmap_surfaces[i] || !gl_lms.lightmap_buffer[i]) if (!gl_lms.lightmap_surfaces[i] || !gl_lms.lightmap_buffer[i])
{ {
@ -764,8 +765,8 @@ R_RegenAllLightmaps()
} }
affected_lightmap = false; affected_lightmap = false;
bt = BLOCK_HEIGHT; bt = gl_state.block_height;
bl = BLOCK_WIDTH; bl = gl_state.block_width;
bb = br = 0; bb = br = 0;
for (surf = gl_lms.lightmap_surfaces[i]; for (surf = gl_lms.lightmap_surfaces[i];
@ -787,9 +788,9 @@ R_RegenAllLightmaps()
bottom = surf->light_t + tmax; bottom = surf->light_t + tmax;
base = gl_lms.lightmap_buffer[i]; base = gl_lms.lightmap_buffer[i];
base += (top * BLOCK_WIDTH + left) * LIGHTMAP_BYTES; base += (top * gl_state.block_width + left) * LIGHTMAP_BYTES;
R_BuildLightMap(surf, base, BLOCK_WIDTH * LIGHTMAP_BYTES); R_BuildLightMap(surf, base, gl_state.block_width * LIGHTMAP_BYTES);
R_UpdateSurfCache(surf, map); R_UpdateSurfCache(surf, map);
if (left < bl) if (left < bl)
@ -816,7 +817,7 @@ R_RegenAllLightmaps()
} }
base = gl_lms.lightmap_buffer[i]; base = gl_lms.lightmap_buffer[i];
base += (bt * BLOCK_WIDTH + bl) * LIGHTMAP_BYTES; base += (bt * gl_state.block_width + bl) * LIGHTMAP_BYTES;
// upload changes // upload changes
R_Bind(gl_state.lightmap_textures + i); R_Bind(gl_state.lightmap_textures + i);

View file

@ -44,7 +44,7 @@
#define TEXNUM_IMAGES 1153 #define TEXNUM_IMAGES 1153
#define MAX_GLTEXTURES 1024 #define MAX_GLTEXTURES 1024
#define MAX_SCRAPS 1 #define MAX_SCRAPS 1
#define BLOCK_WIDTH 128 #define BLOCK_WIDTH 128 // default values; now defined in glstate_t
#define BLOCK_HEIGHT 128 #define BLOCK_HEIGHT 128
#define REF_VERSION "Yamagi Quake II OpenGL Refresher" #define REF_VERSION "Yamagi Quake II OpenGL Refresher"
#define BACKFACE_EPSILON 0.01 #define BACKFACE_EPSILON 0.01
@ -163,6 +163,7 @@ extern cvar_t *gl1_overbrightbits;
extern cvar_t *gl1_palettedtexture; extern cvar_t *gl1_palettedtexture;
extern cvar_t *gl1_pointparameters; extern cvar_t *gl1_pointparameters;
extern cvar_t *gl1_multitexture; extern cvar_t *gl1_multitexture;
extern cvar_t *gl1_biglightmaps;
extern cvar_t *gl1_particle_min_size; extern cvar_t *gl1_particle_min_size;
extern cvar_t *gl1_particle_max_size; extern cvar_t *gl1_particle_max_size;
@ -390,6 +391,12 @@ typedef struct
enum stereo_modes stereo_mode; enum stereo_modes stereo_mode;
qboolean stencil; qboolean stencil;
int block_width, // replaces BLOCK_WIDTH
block_height, // replaces BLOCK_HEIGHT
max_lightmaps, // the larger the lightmaps, the fewer the max lightmaps
scrap_width, // size for scrap (atlas of 2D elements)
scrap_height;
} glstate_t; } glstate_t;
typedef struct typedef struct
@ -399,7 +406,7 @@ typedef struct
msurface_t *lightmap_surfaces[MAX_LIGHTMAPS]; msurface_t *lightmap_surfaces[MAX_LIGHTMAPS];
int allocated[BLOCK_WIDTH]; int *allocated; // formerly 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 */

View file

@ -49,6 +49,7 @@
#define GL_POINT_SIZE_MIN 0x8126 #define GL_POINT_SIZE_MIN 0x8126
#define GL_POINT_SIZE_MAX 0x8127 #define GL_POINT_SIZE_MAX 0x8127
#define GL_POINT_DISTANCE_ATTENUATION 0x8129 #define GL_POINT_DISTANCE_ATTENUATION 0x8129
#define GL_GENERATE_MIPMAP 0x8191
#endif #endif
#ifndef GL_VERSION_1_3 #ifndef GL_VERSION_1_3