mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
Implement the bulk of the lightmap code.
Now just to get surface rendering going and hook in the lights.
This commit is contained in:
parent
0993803006
commit
8a5658ed61
4 changed files with 295 additions and 2 deletions
46
include/QF/GLSL/qf_lightmap.h
Normal file
46
include/QF/GLSL/qf_lightmap.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
qf_lightmap.h
|
||||||
|
|
||||||
|
GLSL lightmap stuff from the renderer.
|
||||||
|
|
||||||
|
Copyright (C) 1996-1997 Id Software, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to:
|
||||||
|
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
59 Temple Place - Suite 330
|
||||||
|
Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
$Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __QF_GLSL_lightmap_h
|
||||||
|
#define __QF_GLSL_lightmap_h
|
||||||
|
|
||||||
|
// LordHavoc: since lightmaps are now allocated only as needed, allow a ridiculous number :)
|
||||||
|
#define MAX_LIGHTMAPS 1024
|
||||||
|
#define BLOCK_WIDTH 64
|
||||||
|
#define BLOCK_HEIGHT 64
|
||||||
|
|
||||||
|
extern model_t *currentmodel;
|
||||||
|
extern mvertex_t *r_pcurrentvertbase;
|
||||||
|
|
||||||
|
void BuildSurfaceDisplayList (msurface_t *fa);
|
||||||
|
void gl_lightmap_init (void);
|
||||||
|
void R_BuildLightmaps (struct model_s **models, int num_models);
|
||||||
|
void R_CalcLightmaps (void);
|
||||||
|
extern void (*R_BuildLightMap) (msurface_t *surf);
|
||||||
|
|
||||||
|
#endif//__QF_GLSL_lightmap_h
|
|
@ -160,6 +160,7 @@ typedef struct msurface_s {
|
||||||
mtexinfo_t *texinfo;
|
mtexinfo_t *texinfo;
|
||||||
|
|
||||||
// lighting info
|
// lighting info
|
||||||
|
struct subpic_s *lightpic; ///< light map texture ref (glsl)
|
||||||
int dlightframe;
|
int dlightframe;
|
||||||
int dlightbits;
|
int dlightbits;
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ shader_gen= \
|
||||||
quaketxt.vc
|
quaketxt.vc
|
||||||
|
|
||||||
glsl_src = \
|
glsl_src = \
|
||||||
glsl_alias.c glsl_draw.c glsl_main.c glsl_particles.c glsl_screen.c \
|
glsl_alias.c glsl_draw.c glsl_lightmap.c glsl_main.c glsl_particles.c \
|
||||||
glsl_sprite.c glsl_textures.c
|
glsl_screen.c glsl_sprite.c glsl_textures.c
|
||||||
|
|
||||||
if BUILD_GLSL
|
if BUILD_GLSL
|
||||||
noinst_LTLIBRARIES= libglsl.la
|
noinst_LTLIBRARIES= libglsl.la
|
||||||
|
|
246
libs/video/renderer/glsl/glsl_lightmap.c
Normal file
246
libs/video/renderer/glsl/glsl_lightmap.c
Normal file
|
@ -0,0 +1,246 @@
|
||||||
|
/*
|
||||||
|
glsl_lightmap.c
|
||||||
|
|
||||||
|
GLSL lightmaps
|
||||||
|
|
||||||
|
Copyright (C) 1996-1997 Id Software, Inc.
|
||||||
|
Copyright (C) 2000 Joseph Carter <knghtbrd@debian.org>
|
||||||
|
Copyright (C) 2012 Bill Currie <bill@taniwha.org>
|
||||||
|
|
||||||
|
Author: Bill Currie <bill@taniwha.org>
|
||||||
|
Date: 2012/1/6
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to:
|
||||||
|
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
59 Temple Place - Suite 330
|
||||||
|
Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static __attribute__ ((used)) const char rcsid[] = "$Id$";
|
||||||
|
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_STRINGS_H
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "QF/render.h"
|
||||||
|
#include "QF/sys.h"
|
||||||
|
|
||||||
|
#include "QF/GLSL/defines.h"
|
||||||
|
#include "QF/GLSL/funcs.h"
|
||||||
|
#include "QF/GLSL/qf_alias.h"
|
||||||
|
#include "QF/GLSL/qf_lightmap.h"
|
||||||
|
#include "QF/GLSL/qf_textures.h"
|
||||||
|
#include "QF/GLSL/qf_vid.h"
|
||||||
|
|
||||||
|
#include "r_local.h"
|
||||||
|
|
||||||
|
#define BLOCK_SIZE (BLOCK_WIDTH * BLOCK_HEIGHT)
|
||||||
|
|
||||||
|
static scrap_t *light_scrap;
|
||||||
|
static byte *light_data;
|
||||||
|
static unsigned *blocklights;
|
||||||
|
static int bl_extents[2];
|
||||||
|
|
||||||
|
void (*R_BuildLightMap) (msurface_t *surf);
|
||||||
|
|
||||||
|
static void
|
||||||
|
R_AddDynamicLights_1 (msurface_t *surf)
|
||||||
|
{
|
||||||
|
unsigned lnum;
|
||||||
|
int sd, td;
|
||||||
|
float dist, rad, minlight;
|
||||||
|
vec3_t impact, local, lightorigin;
|
||||||
|
int s, t;
|
||||||
|
int smax, tmax;
|
||||||
|
mtexinfo_t *tex;
|
||||||
|
|
||||||
|
smax = (surf->extents[0] >> 4) + 1;
|
||||||
|
tmax = (surf->extents[1] >> 4) + 1;
|
||||||
|
tex = surf->texinfo;
|
||||||
|
|
||||||
|
for (lnum = 0; lnum < r_maxdlights; lnum++) {
|
||||||
|
if (!(surf->dlightbits & (1 << lnum)))
|
||||||
|
continue; // not lit by this light
|
||||||
|
|
||||||
|
VectorSubtract (r_dlights[lnum].origin, currententity->origin,
|
||||||
|
lightorigin);
|
||||||
|
rad = r_dlights[lnum].radius;
|
||||||
|
dist = DotProduct (lightorigin, surf->plane->normal)
|
||||||
|
- surf->plane->dist;
|
||||||
|
rad -= fabs (dist);
|
||||||
|
minlight = r_dlights[lnum].minlight;
|
||||||
|
if (rad < minlight)
|
||||||
|
continue;
|
||||||
|
minlight = rad - minlight;
|
||||||
|
|
||||||
|
VectorMultSub (lightorigin, dist, surf->plane->normal, impact);
|
||||||
|
|
||||||
|
local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3];
|
||||||
|
local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3];
|
||||||
|
|
||||||
|
local[0] -= surf->texturemins[0];
|
||||||
|
local[1] -= surf->texturemins[1];
|
||||||
|
|
||||||
|
for (t = 0; t < tmax; t++) {
|
||||||
|
td = local[1] - t * 16;
|
||||||
|
if (td < 0)
|
||||||
|
td = -td;
|
||||||
|
for (s = 0; s < smax; s++) {
|
||||||
|
sd = local[0] - s * 16;
|
||||||
|
if (sd < 0)
|
||||||
|
sd = -sd;
|
||||||
|
if (sd > td)
|
||||||
|
dist = sd + (td >> 1);
|
||||||
|
else
|
||||||
|
dist = td + (sd >> 1);
|
||||||
|
if (dist < minlight)
|
||||||
|
blocklights[t * smax + s] += (rad - dist) * 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
R_BuildLightMap_1 (msurface_t *surf)
|
||||||
|
{
|
||||||
|
int smax, tmax, size;
|
||||||
|
unsigned scale, t;
|
||||||
|
int i;
|
||||||
|
byte *out;
|
||||||
|
|
||||||
|
smax = (surf->extents[0] >> 4) + 1;
|
||||||
|
tmax = (surf->extents[1] >> 4) + 1;
|
||||||
|
size = smax * tmax;
|
||||||
|
|
||||||
|
// clear to no light
|
||||||
|
memset (blocklights, 0, size * sizeof (blocklights[0]));
|
||||||
|
if (!r_worldentity.model->lightdata) {
|
||||||
|
// because we by-pass the inversion, "no light" = "full bright"
|
||||||
|
GL_SubpicUpdate (surf->lightpic, (byte *) blocklights);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add all the lightmaps
|
||||||
|
if (surf->samples) {
|
||||||
|
int lmap;
|
||||||
|
byte *lightmap = surf->samples;
|
||||||
|
|
||||||
|
for (lmap = 0; lmap < MAXLIGHTMAPS && surf->styles[lmap] != 255;
|
||||||
|
lmap++) {
|
||||||
|
unsigned int *bl;
|
||||||
|
|
||||||
|
scale = d_lightstylevalue[surf->styles[lmap]];
|
||||||
|
surf->cached_light[lmap] = scale;
|
||||||
|
bl = blocklights;
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
*bl++ += *lightmap++ * scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// add all the dynamic lights
|
||||||
|
if (surf->dlightframe == r_framecount)
|
||||||
|
R_AddDynamicLights_1 (surf);
|
||||||
|
|
||||||
|
// bound, invert, and shift
|
||||||
|
out = (byte *) blocklights;
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
t = (255 * 256 - (int) blocklights[i]) >> (8 - VID_CBITS);
|
||||||
|
|
||||||
|
t = max (t, 1 << 6);
|
||||||
|
*out++ = t >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
GL_SubpicUpdate (surf->lightpic, (byte *) blocklights);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
R_CalcLightmaps (void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_surf_lightmap (msurface_t *surf)
|
||||||
|
{
|
||||||
|
int smax, tmax;
|
||||||
|
smax = (surf->extents[0] >> 4) + 1;
|
||||||
|
tmax = (surf->extents[1] >> 4) + 1;
|
||||||
|
surf->lightpic = GL_ScrapSubpic (light_scrap, smax, tmax);
|
||||||
|
if (!surf->lightpic)
|
||||||
|
Sys_Error ("FIXME taniwha is being lazy");
|
||||||
|
if (smax > bl_extents[0])
|
||||||
|
bl_extents[0] = smax;
|
||||||
|
if (tmax > bl_extents[1])
|
||||||
|
bl_extents[1] = tmax;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
R_BuildLightmaps (model_t **models, int num_models)
|
||||||
|
{
|
||||||
|
int i, j, size;
|
||||||
|
model_t *m;
|
||||||
|
|
||||||
|
//FIXME RGB support
|
||||||
|
if (!light_scrap) {
|
||||||
|
light_scrap = GL_CreateScrap (2048, GL_LUMINANCE);
|
||||||
|
light_data = malloc (BLOCK_SIZE * MAX_LIGHTMAPS);
|
||||||
|
}
|
||||||
|
R_BuildLightMap = R_BuildLightMap_1;
|
||||||
|
|
||||||
|
bl_extents[1] = bl_extents[0] = 0;
|
||||||
|
for (j = 1; j < num_models; j++) {
|
||||||
|
m = models[j];
|
||||||
|
if (!m)
|
||||||
|
break;
|
||||||
|
if (m->name[0] == '*') {
|
||||||
|
// sub model surfaces are processed as part of the main model
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// non-bsp models don't have surfaces.
|
||||||
|
for (i = 0; i < m->numsurfaces; i++) {
|
||||||
|
msurface_t *surf = m->surfaces + i;
|
||||||
|
surf->lightpic = 0; // paranoia
|
||||||
|
if (surf->flags & SURF_DRAWTURB)
|
||||||
|
continue;
|
||||||
|
if (surf->flags & SURF_DRAWSKY)
|
||||||
|
continue;
|
||||||
|
create_surf_lightmap (surf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size = bl_extents[0] * bl_extents[1] * 3; // * 3 for rgb support
|
||||||
|
blocklights = realloc (blocklights, size * sizeof (blocklights[0]));
|
||||||
|
for (j = 1; j < num_models; j++) {
|
||||||
|
m = models[j];
|
||||||
|
if (!m)
|
||||||
|
break;
|
||||||
|
if (m->name[0] == '*') {
|
||||||
|
// sub model surfaces are processed as part of the main model
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// non-bsp models don't have surfaces.
|
||||||
|
for (i = 0; i < m->numsurfaces; i++) {
|
||||||
|
msurface_t *surf = m->surfaces + i;
|
||||||
|
if (surf->lightpic)
|
||||||
|
R_BuildLightMap (surf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue