(Optionally) Use glTexSubImage2D for lightmap updates. Doesn't give as large a boost as I'd hoped, but will matter far more as other optimizations happen. New cvars gl_lightmap_align does nothing yet, and gl_lightmap_subimage only works in mode 0 and 1. Mode 2 (should be fastest mode on most cards) will eventully get implemented...

This commit is contained in:
Ragnvald Maartmann-Moe IV 2001-08-02 02:18:04 +00:00
parent 4a81fc6e32
commit 6e9b51edfc
5 changed files with 104 additions and 55 deletions

View file

@ -24,10 +24,15 @@ extern struct cvar_s *gl_fires;
extern struct cvar_s *gl_keeptjunctions;
extern struct cvar_s *gl_lerp_anim;
extern struct cvar_s *gl_libgl;
extern struct cvar_s *gl_lightmap_align;
extern struct cvar_s *gl_lightmap_components;
extern struct cvar_s *gl_lightmap_subimage;
extern struct cvar_s *gl_max_size;
extern struct cvar_s *gl_multitexture;
extern struct cvar_s *gl_nocolors;
extern struct cvar_s *gl_occlusion;
extern struct cvar_s *gl_particle_mip;
extern struct cvar_s *gl_particle_size;
extern struct cvar_s *gl_picmip;
extern struct cvar_s *gl_playermip;
extern struct cvar_s *gl_reporttjunctions;
@ -36,7 +41,6 @@ extern struct cvar_s *gl_sky_divide;
extern struct cvar_s *gl_skymultipass;
extern struct cvar_s *gl_texsort;
extern struct cvar_s *gl_triplebuffer;
extern struct cvar_s *gl_occlusion;
extern struct cvar_s *r_aliasstats;
extern struct cvar_s *r_aliastransadj;

View file

@ -41,7 +41,6 @@
#include "QF/cvar.h"
#include "QF/render.h"
#include "QF/GL/defines.h"
#include "QF/GL/funcs.h"
@ -50,6 +49,7 @@
extern float v_blend[4];
void
R_AnimateLight (void)
{

View file

@ -40,7 +40,6 @@
#include <stdio.h>
#include <stdlib.h>
#include "compat.h"
#include "QF/console.h"
#include "QF/cvar.h"
#include "QF/locs.h"
@ -51,7 +50,6 @@
#include "QF/sound.h"
#include "QF/sys.h"
#include "QF/vid.h"
#include "QF/GL/defines.h"
#include "QF/GL/funcs.h"
#include "QF/GL/qf_screen.h"
@ -59,6 +57,7 @@
#include "QF/GL/qf_rsurf.h"
#include "QF/GL/qf_rlight.h"
#include "compat.h"
#include "r_cvar.h"
#include "r_dynamic.h"
#include "r_local.h"

View file

@ -40,15 +40,9 @@
#include <math.h>
#include <stdio.h>
#include "compat.h"
#include "QF/cvar.h"
#include "QF/render.h"
#include "QF/sys.h"
#include "r_cvar.h"
#include "r_local.h"
#include "r_shared.h"
#include "QF/GL/defines.h"
#include "QF/GL/funcs.h"
#include "QF/GL/qf_textures.h"
@ -56,43 +50,46 @@
#include "QF/GL/qf_vid.h"
#include "QF/GL/qf_sky.h"
#include "compat.h"
#include "r_cvar.h"
#include "r_local.h"
#include "r_shared.h"
void EmitWaterPolys (msurface_t *fa);
qboolean r_cache_thrash;
int skytexturenum;
extern vec3_t shadecolor; // Ender (Extend) Colormod
int active_lightmaps;
int dlightdivtable[8192];
int gl_internalformat;
int lightmap_bytes; // 1, 3, or 4
int lightmap_textures;
unsigned int blocklights[18 * 18 * 3];
#define BLOCK_WIDTH 128
#define BLOCK_HEIGHT 128
int skytexturenum;
// LordHavoc: since lightmaps are now allocated only as needed, allow a ridiculous number :)
#define MAX_LIGHTMAPS 1024
int active_lightmaps;
#define BLOCK_WIDTH 128 // 256
#define BLOCK_HEIGHT 128 // 256
typedef struct glRect_s {
unsigned char l, t, w, h;
} glRect_t;
glpoly_t *lightmap_polys[MAX_LIGHTMAPS];
glpoly_t *fullbright_polys[MAX_GLTEXTURES];
qboolean lightmap_modified[MAX_LIGHTMAPS];
glRect_t lightmap_rectchange[MAX_LIGHTMAPS];
int allocated[MAX_LIGHTMAPS][BLOCK_WIDTH];
// the lightmap texture data needs to be kept in
// main memory so texsubimage can update properly
// keep lightmap texture data in main memory so texsubimage can update properly
// LordHavoc: changed to be allocated at runtime (typically lower memory usage)
byte *lightmaps[MAX_LIGHTMAPS];
// unsigned int blocklights[BLOCK_WIDTH * BLOCK_HEIGHT * 3];
unsigned int blocklights[18 * 18 * 3];
int allocated[MAX_LIGHTMAPS][BLOCK_WIDTH];
typedef struct glRect_s {
unsigned short l, t, w, h;
} glRect_t;
glpoly_t *fullbright_polys[MAX_GLTEXTURES];
qboolean lightmap_modified[MAX_LIGHTMAPS];
glpoly_t *lightmap_polys[MAX_LIGHTMAPS];
glRect_t lightmap_rectchange[MAX_LIGHTMAPS];
msurface_t *waterchain = NULL;
msurface_t *sky_chain;
@ -101,7 +98,11 @@ msurface_t *sky_chain;
void
glrsurf_init (void)
{
int s;
memset (&lightmaps, 0, sizeof (lightmaps));
dlightdivtable[0] = 1048576 >> 7;
for (s = 1; s < 8192; s++)
dlightdivtable[s] = 1048576 / (s << 7);
}
@ -131,10 +132,6 @@ R_ForceLightUpdate (void)
}
int dlightdivtable[8192];
int dlightdivtableinitialized = 0;
/*
R_AddDynamicLights
@ -156,13 +153,6 @@ R_AddDynamicLights (msurface_t *surf)
long long k;
#endif
if (!dlightdivtableinitialized) {
dlightdivtable[0] = 1048576 >> 7;
for (s = 1; s < 8192; s++)
dlightdivtable[s] = 1048576 / (s << 7);
dlightdivtableinitialized = 1;
}
smax = (surf->extents[0] >> 4) + 1;
tmax = (surf->extents[1] >> 4) + 1;
@ -370,13 +360,28 @@ extern float speedscale; // for top sky and bottom sky
void
GL_UploadLightmap (int i, int x, int y, int w, int h)
{
/* qfglTexSubImage2D (GL_TEXTURE_2D, 0, 0, y, BLOCK_WIDTH, h, gl_lightmap_format,
GL_UNSIGNED_BYTE,
lightmaps[i] + (y * BLOCK_WIDTH) * lightmap_bytes);
/* qfglTexSubImage2D (GL_TEXTURE_2D, 0, 0, y, BLOCK_WIDTH, h,
gl_lightmap_format, GL_UNSIGNED_BYTE,
lightmaps[i] + (y * BLOCK_WIDTH) * lightmap_bytes);
*/
qfglTexImage2D (GL_TEXTURE_2D, 0, gl_internalformat, BLOCK_WIDTH,
BLOCK_HEIGHT, 0, gl_lightmap_format,
GL_UNSIGNED_BYTE, lightmaps[i]);
switch (gl_lightmap_subimage->int_val) {
case 2:
qfglTexSubImage2D (GL_TEXTURE_2D, 0, x, y, w, h,
gl_lightmap_format, GL_UNSIGNED_BYTE,
lightmaps[i] + (y * BLOCK_WIDTH) * lightmap_bytes);
break;
case 1:
qfglTexSubImage2D (GL_TEXTURE_2D, 0, 0, y, BLOCK_WIDTH, h,
gl_lightmap_format, GL_UNSIGNED_BYTE,
lightmaps[i] + (y * BLOCK_WIDTH) * lightmap_bytes);
break;
default:
case 0:
qfglTexImage2D (GL_TEXTURE_2D, 0, gl_internalformat, BLOCK_WIDTH,
BLOCK_HEIGHT, 0, gl_lightmap_format, GL_UNSIGNED_BYTE,
lightmaps[i]);
break;
}
}
@ -502,7 +507,6 @@ R_RenderFullbrights (void)
float *v;
qfglBlendFunc (GL_ONE, GL_ONE);
for (i = 1; i < MAX_GLTEXTURES; i++) {
if (!fullbright_polys[i])
continue;
@ -992,8 +996,8 @@ AllocBlock (int w, int h, int *x, int *y)
// LordHavoc: allocate lightmaps only as needed
if (!lightmaps[texnum])
lightmaps[texnum] = calloc (BLOCK_WIDTH * BLOCK_HEIGHT, lightmap_bytes); // DESPAIR: was 3, not lightmap_bytes
lightmaps[texnum] = calloc (BLOCK_WIDTH * BLOCK_HEIGHT,
lightmap_bytes);
for (i = 0; i < w; i++)
allocated[texnum][*x + i] = best + h;
@ -1149,6 +1153,26 @@ GL_BuildLightmaps (model_t **models, int num_models)
texture_extension_number += MAX_LIGHTMAPS;
}
/*
// FIXME: use callback to set lightmapalign/lightmapalignmask, avoid
// checking it every frame
if (gl_lightmap_align->int_val < 1)
gl_lightmap_align = 1;
else if (gl_lightmap_align->int_val > 16)
gl_lightmap_align = 16;
lightmapalign = 1;
while (lightmapalign < gl_lightmapalign.value)
lightmapalign <<= 1;
gl_lightmapalign.value = lightmapalign;
lightmapalignmask = ~(lightmapalign - 1);
if (gl_lightmap_subimage->int_val < 1)
{
lightmapalign = 1;
lightmapalignmask = ~0;
}
*/
// FIXME: don't call unnecessarily every frame.
switch (gl_lightmap_components->int_val) {
case 1:
gl_internalformat = 1;
@ -1164,7 +1188,7 @@ GL_BuildLightmaps (model_t **models, int num_models)
default:
gl_internalformat = 3;
gl_lightmap_format = GL_RGBA;
lightmap_bytes = 4;
lightmap_bytes = 3;
break;
}

View file

@ -34,6 +34,7 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "QF/cvar.h"
extern cvar_t *gl_sky_divide; // FIXME
@ -63,9 +64,14 @@ cvar_t *gl_fires;
cvar_t *gl_keeptjunctions;
cvar_t *gl_lerp_anim;
cvar_t *gl_libgl;
cvar_t *gl_lightmap_align;
cvar_t *gl_lightmap_components;
cvar_t *gl_lightmap_subimage;
cvar_t *gl_max_size;
cvar_t *gl_nocolors;
cvar_t *gl_occlusion;
cvar_t *gl_particle_mip;
cvar_t *gl_particle_size;
cvar_t *gl_picmip;
cvar_t *gl_playermip;
cvar_t *gl_reporttjunctions;
@ -73,7 +79,6 @@ cvar_t *gl_sky_clip;
cvar_t *gl_skymultipass;
cvar_t *gl_texsort;
cvar_t *gl_triplebuffer;
cvar_t *gl_occlusion;
cvar_t *r_aliasstats;
cvar_t *r_aliastransadj;
@ -172,13 +177,32 @@ R_Init_Cvars (void)
"Toggles model animation interpolation");
gl_libgl = Cvar_Get ("gl_libgl", "libGL.so.1", CVAR_ROM, NULL,
"The GL library to use. (path optional)");
gl_lightmap_align = Cvar_Get ("gl_lightmap_align", "1", CVAR_NONE, NULL,
"Workaround for nvidia slow path. Set to 4 "
"or 16 if you have an nvidia 3d "
"accelerator, set to 1 otherwise.");
gl_lightmap_components = Cvar_Get ("gl_lightmap_components", "4", CVAR_ROM,
NULL, "Lightmap texture components. 1 "
"is greyscale, 3 is RGB, 4 is RGBA.");
gl_lightmap_subimage = Cvar_Get ("gl_lightmap_subimage", "1", CVAR_NONE,
NULL, "Lightmap Update method. Default 2 "
"updates a minimum 'dirty rectangle' "
"around the area changed. 1 updates "
"every line that changed. 0 updates the "
"entire lightmap.");
gl_max_size = Cvar_Get ("gl_max_size", "1024", CVAR_NONE, NULL,
"Texture dimension");
gl_nocolors = Cvar_Get ("gl_nocolors", "0", CVAR_NONE, NULL,
"Set to 1, turns off all player colors");
gl_occlusion = Cvar_Get ("gl_occlusion", "0", CVAR_NONE, NULL,
"Toggles experimental alias model occlusion "
"tests.");
gl_particle_mip = Cvar_Get ("gl_particle_mip", "0", CVAR_NONE, NULL,
"Toggles particle texture mipmapping.");
gl_particle_size = Cvar_Get ("gl_particle_size", "5", CVAR_NONE, NULL,
"Vertical and horizontal size of particle "
"textures as a power of 2. Default is 5 "
"(32 texel square).");
gl_picmip = Cvar_Get ("gl_picmip", "0", CVAR_NONE, NULL, "Dimensions of "
"textures. 0 is normal, 1 is half, 2 is 1/4");
gl_playermip = Cvar_Get ("gl_playermip", "0", CVAR_NONE, NULL,
@ -192,8 +216,6 @@ R_Init_Cvars (void)
gl_skymultipass = Cvar_Get ("gl_skymultipass", "1", CVAR_ARCHIVE, NULL,
"controls whether the skydome is single or "
"double pass");
gl_occlusion = Cvar_Get ("gl_occlusion", "0", CVAR_NONE, NULL,
"Toggles experimental alias model occlusion tests.");
gl_texsort = Cvar_Get ("gl_texsort", "1", CVAR_NONE, NULL, "None");
gl_triplebuffer = Cvar_Get ("gl_triplebuffer", "1", CVAR_ARCHIVE, NULL,
"Set to 1 by default. Fixes status bar "