mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-29 20:20:43 +00:00
(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:
parent
4a81fc6e32
commit
6e9b51edfc
5 changed files with 104 additions and 55 deletions
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 "
|
||||
|
|
Loading…
Reference in a new issue