mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-25 05:51:01 +00:00
GLES1 renderer: lightmap copies
Available in both GL1 and GLES1. Keep multiple copies of "the same" lightmap on video memory; they are actually different, because they're used in different frames. This is a workaround for the usage of glTexSubImage2D() for dynamic lighting, since modifying textures used recently causes slowdown in embedded/mobile devices. Controlled by gl1_lightmapcopies cvar; default in GL1 is `0`, while in GLES1 is `1`.
This commit is contained in:
parent
0596d23e4c
commit
b72c465214
6 changed files with 181 additions and 86 deletions
|
@ -492,6 +492,12 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable`
|
||||||
* **gl1_stencilshadow**: If `gl_shadows` is set to `1`, this makes them
|
* **gl1_stencilshadow**: If `gl_shadows` is set to `1`, this makes them
|
||||||
look a bit better (no flickering) by using the stencil buffer.
|
look a bit better (no flickering) by using the stencil buffer.
|
||||||
|
|
||||||
|
* **gl1_lightmapcopies**: When enabled (`1`), keep multiple copies of the
|
||||||
|
same lightmap rotating, shifting to a different one when drawing a new
|
||||||
|
frame. Meant for mobile/embedded devices, where changing textures just
|
||||||
|
displayed (dynamic lighting) causes slowdown. By default in GL1 is
|
||||||
|
disabled, while in GLES1 is enabled. `vid_restart` needed.
|
||||||
|
|
||||||
* **gl1_discardfb**: Only available in ES1. If set to `1` (default),
|
* **gl1_discardfb**: Only available in ES1. If set to `1` (default),
|
||||||
send a hint to discard framebuffers after finishing a frame. Useful
|
send a hint to discard framebuffers after finishing a frame. Useful
|
||||||
for GPUs that attempt to reuse them, something Quake 2 doesn't do.
|
for GPUs that attempt to reuse them, something Quake 2 doesn't do.
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#define GLBUFFER_RESET vtx_ptr = idx_ptr = 0; gl_buf.vt = gl_buf.tx = gl_buf.cl = 0;
|
#define GLBUFFER_RESET vtx_ptr = idx_ptr = 0; gl_buf.vt = gl_buf.tx = gl_buf.cl = 0;
|
||||||
|
|
||||||
glbuffer_t gl_buf; // our drawing buffer, used globally
|
glbuffer_t gl_buf; // our drawing buffer, used globally
|
||||||
|
int cur_lm_copy; // which lightmap copy to use (when lightmapcopies=on)
|
||||||
|
|
||||||
static GLushort vtx_ptr, idx_ptr; // pointers for array positions in gl_buf
|
static GLushort vtx_ptr, idx_ptr; // pointers for array positions in gl_buf
|
||||||
|
|
||||||
|
@ -181,7 +182,13 @@ R_ApplyGLBuffer(void)
|
||||||
if (mtex)
|
if (mtex)
|
||||||
{
|
{
|
||||||
// TMU 1: Lightmap texture
|
// TMU 1: Lightmap texture
|
||||||
R_MBind(GL_TEXTURE1, gl_state.lightmap_textures + gl_buf.texture[1]);
|
int lmtexture = gl_state.lightmap_textures + gl_buf.texture[1];
|
||||||
|
if (gl_config.lightmapcopies)
|
||||||
|
{
|
||||||
|
// Bind appropiate lightmap copy for this frame
|
||||||
|
lmtexture += gl_state.max_lightmaps * cur_lm_copy;
|
||||||
|
}
|
||||||
|
R_MBind(GL_TEXTURE1, lmtexture);
|
||||||
|
|
||||||
if (gl1_overbrightbits->value)
|
if (gl1_overbrightbits->value)
|
||||||
{
|
{
|
||||||
|
|
|
@ -87,7 +87,7 @@ LM_UploadBlock(qboolean dynamic)
|
||||||
{
|
{
|
||||||
const int texture = (dynamic)? 0 : gl_lms.current_lightmap_texture;
|
const int texture = (dynamic)? 0 : gl_lms.current_lightmap_texture;
|
||||||
const int buffer = (gl_config.multitexture)? gl_lms.current_lightmap_texture : 0;
|
const int buffer = (gl_config.multitexture)? gl_lms.current_lightmap_texture : 0;
|
||||||
int height = 0;
|
int height = 0, i;
|
||||||
|
|
||||||
R_Bind(gl_state.lightmap_textures + texture);
|
R_Bind(gl_state.lightmap_textures + texture);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
@ -95,8 +95,6 @@ LM_UploadBlock(qboolean dynamic)
|
||||||
|
|
||||||
if (dynamic)
|
if (dynamic)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < gl_state.block_width; i++)
|
for (i = 0; i < gl_state.block_width; i++)
|
||||||
{
|
{
|
||||||
if (gl_lms.allocated[i] > height)
|
if (gl_lms.allocated[i] > height)
|
||||||
|
@ -117,6 +115,21 @@ LM_UploadBlock(qboolean dynamic)
|
||||||
0, GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE,
|
0, GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE,
|
||||||
gl_lms.lightmap_buffer[buffer]);
|
gl_lms.lightmap_buffer[buffer]);
|
||||||
|
|
||||||
|
if (gl_config.lightmapcopies && buffer != 0)
|
||||||
|
{
|
||||||
|
// Upload to all lightmap copies
|
||||||
|
for (i = 1; i < MAX_LIGHTMAP_COPIES; i++)
|
||||||
|
{
|
||||||
|
R_Bind(gl_state.lightmap_textures + (gl_state.max_lightmaps * i) + texture);
|
||||||
|
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, gl_lms.internal_format,
|
||||||
|
gl_state.block_width, gl_state.block_height,
|
||||||
|
0, GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE,
|
||||||
|
gl_lms.lightmap_buffer[buffer]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (++gl_lms.current_lightmap_texture == gl_state.max_lightmaps)
|
if (++gl_lms.current_lightmap_texture == gl_state.max_lightmaps)
|
||||||
{
|
{
|
||||||
ri.Sys_Error(ERR_DROP,
|
ri.Sys_Error(ERR_DROP,
|
||||||
|
|
|
@ -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_lightmapcopies;
|
||||||
cvar_t *gl1_discardfb;
|
cvar_t *gl1_discardfb;
|
||||||
|
|
||||||
cvar_t *gl_drawbuffer;
|
cvar_t *gl_drawbuffer;
|
||||||
|
@ -1171,6 +1172,12 @@ RI_RenderFrame(refdef_t *fd)
|
||||||
R_SetGL2D();
|
R_SetGL2D();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef YQ2_GL1_GLES
|
||||||
|
#define DEFAULT_LMCOPIES "1"
|
||||||
|
#else
|
||||||
|
#define DEFAULT_LMCOPIES "0"
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
R_Register(void)
|
R_Register(void)
|
||||||
{
|
{
|
||||||
|
@ -1225,6 +1232,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", "1", CVAR_ARCHIVE);
|
gl1_multitexture = ri.Cvar_Get("gl1_multitexture", "1", CVAR_ARCHIVE);
|
||||||
|
gl1_lightmapcopies = ri.Cvar_Get("gl1_lightmapcopies", DEFAULT_LMCOPIES, CVAR_ARCHIVE);
|
||||||
#ifdef YQ2_GL1_GLES
|
#ifdef YQ2_GL1_GLES
|
||||||
gl1_discardfb = ri.Cvar_Get("gl1_discardfb", "1", CVAR_ARCHIVE);
|
gl1_discardfb = ri.Cvar_Get("gl1_discardfb", "1", CVAR_ARCHIVE);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1265,6 +1273,8 @@ R_Register(void)
|
||||||
ri.Cmd_AddCommand("gl_strings", R_Strings);
|
ri.Cmd_AddCommand("gl_strings", R_Strings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef DEFAULT_LMCOPIES
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Changes the video mode
|
* Changes the video mode
|
||||||
*/
|
*/
|
||||||
|
@ -1645,6 +1655,28 @@ RI_Init(void)
|
||||||
|
|
||||||
// ----
|
// ----
|
||||||
|
|
||||||
|
/* Lightmap copies: keep multiple copies of "the same" lightmap on video memory.
|
||||||
|
* All of them are actually different, because they are affected by different dynamic lighting,
|
||||||
|
* in different frames. This is not meant for Immediate-Mode Rendering systems (desktop),
|
||||||
|
* but for Tile-Based / Deferred Rendering ones (embedded / mobile), since active manipulation
|
||||||
|
* of textures already being used in the last few frames can cause slowdown on these systems.
|
||||||
|
* Needless to say, GPU memory usage is highly increased, so watch out in low memory situations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
R_Printf(PRINT_ALL, " - Lightmap copies: ");
|
||||||
|
gl_config.lightmapcopies = false;
|
||||||
|
if (gl_config.multitexture && gl1_lightmapcopies->value)
|
||||||
|
{
|
||||||
|
gl_config.lightmapcopies = true;
|
||||||
|
R_Printf(PRINT_ALL, "Okay\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "Disabled\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
|
||||||
/* Discard framebuffer: Available only on GLES1, enables the use of a "performance hint"
|
/* Discard framebuffer: Available only on GLES1, enables the use of a "performance hint"
|
||||||
* to the graphic driver, to get rid of the contents of the depth and stencil buffers.
|
* to the graphic driver, to get rid of the contents of the depth and stencil buffers.
|
||||||
* Useful for some GPUs that may attempt to keep them and/or write them back to
|
* Useful for some GPUs that may attempt to keep them and/or write them back to
|
||||||
|
|
|
@ -28,12 +28,18 @@
|
||||||
|
|
||||||
#include "header/local.h"
|
#include "header/local.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int top, bottom, left, right;
|
||||||
|
} lmrect_t;
|
||||||
|
|
||||||
int c_visible_lightmaps;
|
int c_visible_lightmaps;
|
||||||
int c_visible_textures;
|
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;
|
||||||
|
|
||||||
gllightmapstate_t gl_lms;
|
gllightmapstate_t gl_lms;
|
||||||
|
extern int cur_lm_copy;
|
||||||
|
|
||||||
void LM_InitBlock(void);
|
void LM_InitBlock(void);
|
||||||
void LM_UploadBlock(qboolean dynamic);
|
void LM_UploadBlock(qboolean dynamic);
|
||||||
|
@ -519,52 +525,6 @@ R_DrawAlphaSurfaces(void)
|
||||||
r_alpha_surfaces = NULL;
|
r_alpha_surfaces = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qboolean
|
|
||||||
R_HasDynamicLights(msurface_t *surf, int *mapNum)
|
|
||||||
{
|
|
||||||
int map;
|
|
||||||
qboolean is_dynamic = false;
|
|
||||||
|
|
||||||
if ( r_fullbright->value || !gl1_dynamic->value ||
|
|
||||||
(surf->texinfo->flags & (SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP)) )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Any dynamic lights on this surface?
|
|
||||||
for (map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++)
|
|
||||||
{
|
|
||||||
if (r_newrefdef.lightstyles[surf->styles[map]].white != surf->cached_light[map])
|
|
||||||
{
|
|
||||||
is_dynamic = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No matter if it is this frame or was in the previous one: has dynamic lights
|
|
||||||
if ( !is_dynamic && (surf->dlightframe == r_framecount || surf->dirty_lightmap) )
|
|
||||||
{
|
|
||||||
is_dynamic = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mapNum)
|
|
||||||
{
|
|
||||||
*mapNum = map;
|
|
||||||
}
|
|
||||||
return is_dynamic;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
R_UpdateSurfCache(msurface_t *surf, int map)
|
|
||||||
{
|
|
||||||
if ( ((surf->styles[map] >= 32) || (surf->styles[map] == 0))
|
|
||||||
&& (surf->dlightframe != r_framecount) )
|
|
||||||
{
|
|
||||||
R_SetCacheState(surf);
|
|
||||||
}
|
|
||||||
surf->dirty_lightmap = (surf->dlightframe == r_framecount);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
R_RenderLightmappedPoly(entity_t *currententity, msurface_t *surf)
|
R_RenderLightmappedPoly(entity_t *currententity, msurface_t *surf)
|
||||||
{
|
{
|
||||||
|
@ -599,11 +559,37 @@ R_RenderLightmappedPoly(entity_t *currententity, msurface_t *surf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add "adding" area to "obj" */
|
||||||
|
static void
|
||||||
|
R_JoinAreas(lmrect_t *adding, lmrect_t *obj)
|
||||||
|
{
|
||||||
|
if (adding->top < obj->top)
|
||||||
|
{
|
||||||
|
obj->top = adding->top;
|
||||||
|
}
|
||||||
|
if (adding->bottom > obj->bottom)
|
||||||
|
{
|
||||||
|
obj->bottom = adding->bottom;
|
||||||
|
}
|
||||||
|
if (adding->left < obj->left)
|
||||||
|
{
|
||||||
|
obj->left = adding->left;
|
||||||
|
}
|
||||||
|
if (adding->right > obj->right)
|
||||||
|
{
|
||||||
|
obj->right = adding->right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Upload dynamic lights to each lightmap texture (multitexture path only) */
|
/* Upload dynamic lights to each lightmap texture (multitexture path only) */
|
||||||
static void
|
static void
|
||||||
R_RegenAllLightmaps()
|
R_RegenAllLightmaps()
|
||||||
{
|
{
|
||||||
int i, map, smax, tmax, top, bottom, left, right, bt, bb, bl, br;
|
static lmrect_t lmchange[MAX_LIGHTMAP_COPIES][MAX_LIGHTMAPS];
|
||||||
|
static qboolean altered[MAX_LIGHTMAP_COPIES][MAX_LIGHTMAPS];
|
||||||
|
|
||||||
|
int i, map, smax, tmax, cc, lmtex;
|
||||||
|
lmrect_t current, best;
|
||||||
msurface_t *surf;
|
msurface_t *surf;
|
||||||
byte *base;
|
byte *base;
|
||||||
qboolean affected_lightmap;
|
qboolean affected_lightmap;
|
||||||
|
@ -611,11 +597,19 @@ R_RegenAllLightmaps()
|
||||||
qboolean pixelstore_set = false;
|
qboolean pixelstore_set = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( !gl_config.multitexture )
|
if ( !gl_config.multitexture || r_fullbright->value || !gl1_dynamic->value )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cc = lmtex = 0;
|
||||||
|
if (gl_config.lightmapcopies)
|
||||||
|
{
|
||||||
|
cur_lm_copy = (cur_lm_copy + 1) % MAX_LIGHTMAP_COPIES; // alternate between calls
|
||||||
|
cc = cur_lm_copy;
|
||||||
|
lmtex = gl_state.max_lightmaps * cc;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 1; i < gl_state.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])
|
||||||
|
@ -624,57 +618,94 @@ R_RegenAllLightmaps()
|
||||||
}
|
}
|
||||||
|
|
||||||
affected_lightmap = false;
|
affected_lightmap = false;
|
||||||
bt = gl_state.block_height;
|
best.top = gl_state.block_height;
|
||||||
bl = gl_state.block_width;
|
best.left = gl_state.block_width;
|
||||||
bb = br = 0;
|
best.bottom = best.right = 0;
|
||||||
|
|
||||||
for (surf = gl_lms.lightmap_surfaces[i];
|
for (surf = gl_lms.lightmap_surfaces[i];
|
||||||
surf != 0;
|
surf != 0;
|
||||||
surf = surf->lightmapchain)
|
surf = surf->lightmapchain)
|
||||||
{
|
{
|
||||||
if ( !R_HasDynamicLights(surf, &map) )
|
if (surf->texinfo->flags & (SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Any dynamic lights on this surface?
|
||||||
|
for (map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++)
|
||||||
|
{
|
||||||
|
if (r_newrefdef.lightstyles[surf->styles[map]].white != surf->cached_light[map])
|
||||||
|
{
|
||||||
|
goto dynamic_surf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Doesn't matter if it is this frame or was in the previous one: surface has dynamic lights
|
||||||
|
if ( surf->dlightframe == r_framecount || surf->dirty_lightmap )
|
||||||
|
{
|
||||||
|
goto dynamic_surf;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue; // no dynamic lights affect this surface in this frame
|
||||||
|
|
||||||
|
dynamic_surf:
|
||||||
affected_lightmap = true;
|
affected_lightmap = true;
|
||||||
smax = (surf->extents[0] >> 4) + 1;
|
smax = (surf->extents[0] >> 4) + 1;
|
||||||
tmax = (surf->extents[1] >> 4) + 1;
|
tmax = (surf->extents[1] >> 4) + 1;
|
||||||
|
|
||||||
left = surf->light_s;
|
current.left = surf->light_s;
|
||||||
right = surf->light_s + smax;
|
current.right = surf->light_s + smax;
|
||||||
top = surf->light_t;
|
current.top = surf->light_t;
|
||||||
bottom = surf->light_t + tmax;
|
current.bottom = surf->light_t + tmax;
|
||||||
|
|
||||||
base = gl_lms.lightmap_buffer[i];
|
base = gl_lms.lightmap_buffer[i];
|
||||||
base += (top * gl_state.block_width + left) * LIGHTMAP_BYTES;
|
base += (current.top * gl_state.block_width + current.left) * LIGHTMAP_BYTES;
|
||||||
|
|
||||||
R_BuildLightMap(surf, base, gl_state.block_width * LIGHTMAP_BYTES);
|
R_BuildLightMap(surf, base, gl_state.block_width * LIGHTMAP_BYTES);
|
||||||
R_UpdateSurfCache(surf, map);
|
|
||||||
|
|
||||||
if (left < bl)
|
if ( ((surf->styles[map] >= 32) || (surf->styles[map] == 0))
|
||||||
|
&& (surf->dlightframe != r_framecount) )
|
||||||
{
|
{
|
||||||
bl = left;
|
R_SetCacheState(surf);
|
||||||
}
|
|
||||||
if (right > br)
|
|
||||||
{
|
|
||||||
br = right;
|
|
||||||
}
|
|
||||||
if (top < bt)
|
|
||||||
{
|
|
||||||
bt = top;
|
|
||||||
}
|
|
||||||
if (bottom > bb)
|
|
||||||
{
|
|
||||||
bb = bottom;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!affected_lightmap)
|
surf->dirty_lightmap = (surf->dlightframe == r_framecount);
|
||||||
|
R_JoinAreas(¤t, &best);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gl_config.lightmapcopies && !affected_lightmap)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gl_config.lightmapcopies)
|
||||||
|
{
|
||||||
|
// add all the changes that have happened in the last few frames,
|
||||||
|
// at least just for consistency between them...
|
||||||
|
qboolean apply_changes = affected_lightmap;
|
||||||
|
current = best; // save state for next frames... +
|
||||||
|
|
||||||
|
for (int k = 0; k < MAX_LIGHTMAP_COPIES; k++)
|
||||||
|
{
|
||||||
|
if (altered[k][i])
|
||||||
|
{
|
||||||
|
apply_changes = true;
|
||||||
|
R_JoinAreas(&lmchange[k][i], &best);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
altered[cc][i] = affected_lightmap;
|
||||||
|
if (affected_lightmap)
|
||||||
|
{
|
||||||
|
lmchange[cc][i] = current; // + ...here
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!apply_changes)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef YQ2_GL1_GLES
|
#ifndef YQ2_GL1_GLES
|
||||||
if (!pixelstore_set)
|
if (!pixelstore_set)
|
||||||
{
|
{
|
||||||
|
@ -687,16 +718,20 @@ R_RegenAllLightmaps()
|
||||||
base = gl_lms.lightmap_buffer[i];
|
base = gl_lms.lightmap_buffer[i];
|
||||||
|
|
||||||
#ifdef YQ2_GL1_GLES
|
#ifdef YQ2_GL1_GLES
|
||||||
base += (bt * gl_state.block_width) * LIGHTMAP_BYTES;
|
base += (best.top * gl_state.block_width) * LIGHTMAP_BYTES;
|
||||||
|
|
||||||
R_Bind(gl_state.lightmap_textures + i);
|
R_Bind(gl_state.lightmap_textures + i + lmtex);
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, bt, gl_state.block_width, bb - bt,
|
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, best.top,
|
||||||
|
gl_state.block_width, best.bottom - best.top,
|
||||||
GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE, base);
|
GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE, base);
|
||||||
#else
|
#else
|
||||||
base += (bt * gl_state.block_width + bl) * LIGHTMAP_BYTES;
|
base += (best.top * gl_state.block_width + best.left) * LIGHTMAP_BYTES;
|
||||||
|
|
||||||
R_Bind(gl_state.lightmap_textures + i);
|
R_Bind(gl_state.lightmap_textures + i + lmtex);
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, bl, bt, br - bl, bb - bt,
|
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, best.left, best.top,
|
||||||
|
best.right - best.left, best.bottom - best.top,
|
||||||
GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE, base);
|
GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE, base);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,9 +50,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_LIGHTMAPS 128
|
#define MAX_LIGHTMAPS 128
|
||||||
|
#define MAX_LIGHTMAP_COPIES 3 // Meant for tile / deferred rendering platforms
|
||||||
#define MAX_SCRAPS 1
|
#define MAX_SCRAPS 1
|
||||||
#define TEXNUM_LIGHTMAPS 1024
|
#define TEXNUM_LIGHTMAPS 1024
|
||||||
#define TEXNUM_SCRAPS (TEXNUM_LIGHTMAPS + MAX_LIGHTMAPS)
|
#define TEXNUM_SCRAPS (TEXNUM_LIGHTMAPS + MAX_LIGHTMAPS * MAX_LIGHTMAP_COPIES)
|
||||||
#define TEXNUM_IMAGES (TEXNUM_SCRAPS + MAX_SCRAPS)
|
#define TEXNUM_IMAGES (TEXNUM_SCRAPS + MAX_SCRAPS)
|
||||||
#define MAX_GLTEXTURES 1024
|
#define MAX_GLTEXTURES 1024
|
||||||
#define BLOCK_WIDTH 128 // default values; now defined in glstate_t
|
#define BLOCK_WIDTH 128 // default values; now defined in glstate_t
|
||||||
|
@ -429,6 +430,7 @@ typedef struct
|
||||||
qboolean palettedtexture;
|
qboolean palettedtexture;
|
||||||
qboolean pointparameters;
|
qboolean pointparameters;
|
||||||
qboolean multitexture;
|
qboolean multitexture;
|
||||||
|
qboolean lightmapcopies; // many copies of same lightmap, for embedded
|
||||||
qboolean discardfb;
|
qboolean discardfb;
|
||||||
|
|
||||||
// ----
|
// ----
|
||||||
|
|
Loading…
Reference in a new issue