mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-02-20 19:02:23 +00:00
- Benenne alle Funktionen in gl_rsurf um
- Lightmaps in ne eigene Datei
This commit is contained in:
parent
d6acc3b4ea
commit
4c9536e400
4 changed files with 356 additions and 314 deletions
6
Makefile
6
Makefile
|
@ -325,6 +325,7 @@ OPENGL_OBJS = \
|
|||
build/ref_gl/r_draw.o \
|
||||
build/ref_gl/r_image.o \
|
||||
build/ref_gl/r_light.o \
|
||||
build/ref_gl/r_lightmap.o \
|
||||
build/ref_gl/r_mesh.o \
|
||||
build/ref_gl/r_model.o \
|
||||
build/ref_gl/r_main.o \
|
||||
|
@ -781,7 +782,10 @@ build/ref_gl/r_image.o: src/refresh/r_image.c
|
|||
|
||||
build/ref_gl/r_light.o: src/refresh/r_light.c
|
||||
$(CC) $(CFLAGS_OPENGL) -o $@ -c $<
|
||||
|
||||
|
||||
build/ref_gl/r_lightmap.o: src/refresh/r_lightmap.c
|
||||
$(CC) $(CFLAGS_OPENGL) -o $@ -c $<
|
||||
|
||||
build/ref_gl/r_mesh.o: src/refresh/r_mesh.c
|
||||
$(CC) $(CFLAGS_OPENGL) -o $@ -c $<
|
||||
|
||||
|
|
|
@ -1,59 +1,45 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 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 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
|
||||
* 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 the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
* =======================================================================
|
||||
*
|
||||
* Surface generation and drawing
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "header/local.h"
|
||||
|
||||
#define DYNAMIC_LIGHT_WIDTH 128
|
||||
#define DYNAMIC_LIGHT_HEIGHT 128
|
||||
#define LIGHTMAP_BYTES 4
|
||||
#define MAX_LIGHTMAPS 128
|
||||
#define GL_LIGHTMAP_FORMAT GL_RGBA
|
||||
|
||||
int c_visible_lightmaps;
|
||||
int c_visible_textures;
|
||||
static vec3_t modelorg; /* relative to viewpoint */
|
||||
msurface_t *r_alpha_surfaces;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int internal_format;
|
||||
int current_lightmap_texture;
|
||||
gllightmapstate_t gl_lms;
|
||||
|
||||
msurface_t *lightmap_surfaces [ MAX_LIGHTMAPS ];
|
||||
void LM_InitBlock ( void );
|
||||
void LM_UploadBlock ( qboolean dynamic );
|
||||
qboolean LM_AllocBlock ( int w, int h, int *x, int *y );
|
||||
|
||||
int allocated [ BLOCK_WIDTH ];
|
||||
|
||||
/* the lightmap texture data needs to be kept in
|
||||
main memory so texsubimage can update properly */
|
||||
byte lightmap_buffer [ 4 * BLOCK_WIDTH * BLOCK_HEIGHT ];
|
||||
} gllightmapstate_t;
|
||||
|
||||
static gllightmapstate_t gl_lms;
|
||||
|
||||
static void LM_InitBlock ( void );
|
||||
static void LM_UploadBlock ( qboolean dynamic );
|
||||
static qboolean LM_AllocBlock ( int w, int h, int *x, int *y );
|
||||
|
||||
extern void R_SetCacheState ( msurface_t *surf );
|
||||
extern void R_BuildLightMap ( msurface_t *surf, byte *dest, int stride );
|
||||
void R_SetCacheState ( msurface_t *surf );
|
||||
void R_BuildLightMap ( msurface_t *surf, byte *dest, int stride );
|
||||
|
||||
/*
|
||||
* Returns the proper texture for a given time and base texture
|
||||
|
@ -80,7 +66,7 @@ R_TextureAnimation ( mtexinfo_t *tex )
|
|||
}
|
||||
|
||||
void
|
||||
DrawGLPoly ( glpoly_t *p )
|
||||
R_DrawGLPoly ( glpoly_t *p )
|
||||
{
|
||||
int i;
|
||||
float *v;
|
||||
|
@ -98,7 +84,7 @@ DrawGLPoly ( glpoly_t *p )
|
|||
}
|
||||
|
||||
void
|
||||
DrawGLFlowingPoly ( msurface_t *fa )
|
||||
R_DrawGLFlowingPoly ( msurface_t *fa )
|
||||
{
|
||||
int i;
|
||||
float *v;
|
||||
|
@ -169,7 +155,7 @@ R_DrawTriangleOutlines ( void )
|
|||
}
|
||||
|
||||
void
|
||||
DrawGLPolyChain ( glpoly_t *p, float soffset, float toffset )
|
||||
R_DrawGLPolyChain ( glpoly_t *p, float soffset, float toffset )
|
||||
{
|
||||
if ( ( soffset == 0 ) && ( toffset == 0 ) )
|
||||
{
|
||||
|
@ -182,7 +168,7 @@ DrawGLPolyChain ( glpoly_t *p, float soffset, float toffset )
|
|||
|
||||
if ( v == NULL )
|
||||
{
|
||||
fprintf( stderr, "BUGFIX: DrawGLPolyChain: v==NULL\n" );
|
||||
fprintf( stderr, "BUGFIX: R_DrawGLPolyChain: v==NULL\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -279,7 +265,7 @@ R_BlendLightmaps ( void )
|
|||
{
|
||||
if ( surf->polys )
|
||||
{
|
||||
DrawGLPolyChain( surf->polys, 0, 0 );
|
||||
R_DrawGLPolyChain( surf->polys, 0, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -326,7 +312,7 @@ R_BlendLightmaps ( void )
|
|||
{
|
||||
if ( drawsurf->polys )
|
||||
{
|
||||
DrawGLPolyChain( drawsurf->polys,
|
||||
R_DrawGLPolyChain( drawsurf->polys,
|
||||
( drawsurf->light_s - drawsurf->dlight_s ) * ( 1.0 / 128.0 ),
|
||||
( drawsurf->light_t - drawsurf->dlight_t ) * ( 1.0 / 128.0 ) );
|
||||
}
|
||||
|
@ -360,7 +346,7 @@ R_BlendLightmaps ( void )
|
|||
{
|
||||
if ( surf->polys )
|
||||
{
|
||||
DrawGLPolyChain( surf->polys, ( surf->light_s - surf->dlight_s ) * ( 1.0 / 128.0 ),
|
||||
R_DrawGLPolyChain( surf->polys, ( surf->light_s - surf->dlight_s ) * ( 1.0 / 128.0 ),
|
||||
( surf->light_t - surf->dlight_t ) * ( 1.0 / 128.0 ) );
|
||||
}
|
||||
}
|
||||
|
@ -407,11 +393,11 @@ R_RenderBrushPoly ( msurface_t *fa )
|
|||
|
||||
if ( fa->texinfo->flags & SURF_FLOWING )
|
||||
{
|
||||
DrawGLFlowingPoly( fa );
|
||||
R_DrawGLFlowingPoly( fa );
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawGLPoly( fa->polys );
|
||||
R_DrawGLPoly( fa->polys );
|
||||
}
|
||||
|
||||
/* check for lightmap modification */
|
||||
|
@ -519,11 +505,11 @@ R_DrawAlphaSurfaces ( void )
|
|||
}
|
||||
else if ( s->texinfo->flags & SURF_FLOWING )
|
||||
{
|
||||
DrawGLFlowingPoly( s );
|
||||
R_DrawGLFlowingPoly( s );
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawGLPoly( s->polys );
|
||||
R_DrawGLPoly( s->polys );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -535,7 +521,7 @@ R_DrawAlphaSurfaces ( void )
|
|||
}
|
||||
|
||||
void
|
||||
DrawTextureChains ( void )
|
||||
R_DrawTextureChains ( void )
|
||||
{
|
||||
int i;
|
||||
msurface_t *s;
|
||||
|
@ -862,7 +848,7 @@ R_DrawWorld ( void )
|
|||
R_ClearSkyBox();
|
||||
R_RecursiveWorldNode( r_worldmodel->nodes );
|
||||
|
||||
DrawTextureChains();
|
||||
R_DrawTextureChains();
|
||||
R_BlendLightmaps();
|
||||
|
||||
R_DrawSkyBox();
|
||||
|
@ -962,269 +948,3 @@ R_MarkLeaves ( void )
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
LM_InitBlock ( void )
|
||||
{
|
||||
memset( gl_lms.allocated, 0, sizeof ( gl_lms.allocated ) );
|
||||
}
|
||||
|
||||
static void
|
||||
LM_UploadBlock ( qboolean dynamic )
|
||||
{
|
||||
int texture;
|
||||
int height = 0;
|
||||
|
||||
if ( dynamic )
|
||||
{
|
||||
texture = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
texture = gl_lms.current_lightmap_texture;
|
||||
}
|
||||
|
||||
R_Bind( gl_state.lightmap_textures + texture );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
|
||||
if ( dynamic )
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < BLOCK_WIDTH; i++ )
|
||||
{
|
||||
if ( gl_lms.allocated [ i ] > height )
|
||||
{
|
||||
height = gl_lms.allocated [ i ];
|
||||
}
|
||||
}
|
||||
|
||||
qglTexSubImage2D( GL_TEXTURE_2D,
|
||||
0,
|
||||
0, 0,
|
||||
BLOCK_WIDTH, height,
|
||||
GL_LIGHTMAP_FORMAT,
|
||||
GL_UNSIGNED_BYTE,
|
||||
gl_lms.lightmap_buffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
qglTexImage2D( GL_TEXTURE_2D,
|
||||
0,
|
||||
gl_lms.internal_format,
|
||||
BLOCK_WIDTH, BLOCK_HEIGHT,
|
||||
0,
|
||||
GL_LIGHTMAP_FORMAT,
|
||||
GL_UNSIGNED_BYTE,
|
||||
gl_lms.lightmap_buffer );
|
||||
|
||||
if ( ++gl_lms.current_lightmap_texture == MAX_LIGHTMAPS )
|
||||
{
|
||||
ri.Sys_Error( ERR_DROP, "LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* returns a texture number and the position inside it */
|
||||
static qboolean
|
||||
LM_AllocBlock ( int w, int h, int *x, int *y )
|
||||
{
|
||||
int i, j;
|
||||
int best, best2;
|
||||
|
||||
best = BLOCK_HEIGHT;
|
||||
|
||||
for ( i = 0; i < BLOCK_WIDTH - w; i++ )
|
||||
{
|
||||
best2 = 0;
|
||||
|
||||
for ( j = 0; j < w; j++ )
|
||||
{
|
||||
if ( gl_lms.allocated [ i + j ] >= best )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ( gl_lms.allocated [ i + j ] > best2 )
|
||||
{
|
||||
best2 = gl_lms.allocated [ i + j ];
|
||||
}
|
||||
}
|
||||
|
||||
if ( j == w )
|
||||
{
|
||||
/* this is a valid spot */
|
||||
*x = i;
|
||||
*y = best = best2;
|
||||
}
|
||||
}
|
||||
|
||||
if ( best + h > BLOCK_HEIGHT )
|
||||
{
|
||||
return ( false );
|
||||
}
|
||||
|
||||
for ( i = 0; i < w; i++ )
|
||||
{
|
||||
gl_lms.allocated [ *x + i ] = best + h;
|
||||
}
|
||||
|
||||
return ( true );
|
||||
}
|
||||
|
||||
void
|
||||
GL_BuildPolygonFromSurface ( msurface_t *fa )
|
||||
{
|
||||
int i, lindex, lnumverts;
|
||||
medge_t *pedges, *r_pedge;
|
||||
int vertpage;
|
||||
float *vec;
|
||||
float s, t;
|
||||
glpoly_t *poly;
|
||||
vec3_t total;
|
||||
|
||||
/* reconstruct the polygon */
|
||||
pedges = currentmodel->edges;
|
||||
lnumverts = fa->numedges;
|
||||
vertpage = 0;
|
||||
|
||||
VectorClear( total );
|
||||
|
||||
/* draw texture */
|
||||
poly = Hunk_Alloc( sizeof ( glpoly_t ) + ( lnumverts - 4 ) * VERTEXSIZE * sizeof ( float ) );
|
||||
poly->next = fa->polys;
|
||||
poly->flags = fa->flags;
|
||||
fa->polys = poly;
|
||||
poly->numverts = lnumverts;
|
||||
|
||||
for ( i = 0; i < lnumverts; i++ )
|
||||
{
|
||||
lindex = currentmodel->surfedges [ fa->firstedge + i ];
|
||||
|
||||
if ( lindex > 0 )
|
||||
{
|
||||
r_pedge = &pedges [ lindex ];
|
||||
vec = currentmodel->vertexes [ r_pedge->v [ 0 ] ].position;
|
||||
}
|
||||
else
|
||||
{
|
||||
r_pedge = &pedges [ -lindex ];
|
||||
vec = currentmodel->vertexes [ r_pedge->v [ 1 ] ].position;
|
||||
}
|
||||
|
||||
s = DotProduct( vec, fa->texinfo->vecs [ 0 ] ) + fa->texinfo->vecs [ 0 ] [ 3 ];
|
||||
s /= fa->texinfo->image->width;
|
||||
|
||||
t = DotProduct( vec, fa->texinfo->vecs [ 1 ] ) + fa->texinfo->vecs [ 1 ] [ 3 ];
|
||||
t /= fa->texinfo->image->height;
|
||||
|
||||
VectorAdd( total, vec, total );
|
||||
VectorCopy( vec, poly->verts [ i ] );
|
||||
poly->verts [ i ] [ 3 ] = s;
|
||||
poly->verts [ i ] [ 4 ] = t;
|
||||
|
||||
/* lightmap texture coordinates */
|
||||
s = DotProduct( vec, fa->texinfo->vecs [ 0 ] ) + fa->texinfo->vecs [ 0 ] [ 3 ];
|
||||
s -= fa->texturemins [ 0 ];
|
||||
s += fa->light_s * 16;
|
||||
s += 8;
|
||||
s /= BLOCK_WIDTH * 16; /* fa->texinfo->texture->width; */
|
||||
|
||||
t = DotProduct( vec, fa->texinfo->vecs [ 1 ] ) + fa->texinfo->vecs [ 1 ] [ 3 ];
|
||||
t -= fa->texturemins [ 1 ];
|
||||
t += fa->light_t * 16;
|
||||
t += 8;
|
||||
t /= BLOCK_HEIGHT * 16; /* fa->texinfo->texture->height; */
|
||||
|
||||
poly->verts [ i ] [ 5 ] = s;
|
||||
poly->verts [ i ] [ 6 ] = t;
|
||||
}
|
||||
|
||||
poly->numverts = lnumverts;
|
||||
}
|
||||
|
||||
void
|
||||
GL_CreateSurfaceLightmap ( msurface_t *surf )
|
||||
{
|
||||
int smax, tmax;
|
||||
byte *base;
|
||||
|
||||
if ( surf->flags & ( SURF_DRAWSKY | SURF_DRAWTURB ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
smax = ( surf->extents [ 0 ] >> 4 ) + 1;
|
||||
tmax = ( surf->extents [ 1 ] >> 4 ) + 1;
|
||||
|
||||
if ( !LM_AllocBlock( smax, tmax, &surf->light_s, &surf->light_t ) )
|
||||
{
|
||||
LM_UploadBlock( false );
|
||||
LM_InitBlock();
|
||||
|
||||
if ( !LM_AllocBlock( smax, tmax, &surf->light_s, &surf->light_t ) )
|
||||
{
|
||||
ri.Sys_Error( ERR_FATAL, "Consecutive calls to LM_AllocBlock(%d,%d) failed\n", smax, tmax );
|
||||
}
|
||||
}
|
||||
|
||||
surf->lightmaptexturenum = gl_lms.current_lightmap_texture;
|
||||
|
||||
base = gl_lms.lightmap_buffer;
|
||||
base += ( surf->light_t * BLOCK_WIDTH + surf->light_s ) * LIGHTMAP_BYTES;
|
||||
|
||||
R_SetCacheState( surf );
|
||||
R_BuildLightMap( surf, base, BLOCK_WIDTH * LIGHTMAP_BYTES );
|
||||
}
|
||||
|
||||
void
|
||||
GL_BeginBuildingLightmaps ( model_t *m )
|
||||
{
|
||||
static lightstyle_t lightstyles [ MAX_LIGHTSTYLES ];
|
||||
int i;
|
||||
unsigned dummy [ 128 * 128 ];
|
||||
|
||||
memset( gl_lms.allocated, 0, sizeof ( gl_lms.allocated ) );
|
||||
|
||||
r_framecount = 1;/* no dlightcache */
|
||||
|
||||
/* setup the base lightstyles so the lightmaps won't have to be regenerated
|
||||
the first time they're seen */
|
||||
for ( i = 0; i < MAX_LIGHTSTYLES; i++ )
|
||||
{
|
||||
lightstyles [ i ].rgb [ 0 ] = 1;
|
||||
lightstyles [ i ].rgb [ 1 ] = 1;
|
||||
lightstyles [ i ].rgb [ 2 ] = 1;
|
||||
lightstyles [ i ].white = 3;
|
||||
}
|
||||
|
||||
r_newrefdef.lightstyles = lightstyles;
|
||||
|
||||
if ( !gl_state.lightmap_textures )
|
||||
{
|
||||
gl_state.lightmap_textures = TEXNUM_LIGHTMAPS;
|
||||
}
|
||||
|
||||
gl_lms.current_lightmap_texture = 1;
|
||||
gl_lms.internal_format = gl_tex_solid_format;
|
||||
|
||||
/* initialize the dynamic lightmap texture */
|
||||
R_Bind( gl_state.lightmap_textures + 0 );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
qglTexImage2D( GL_TEXTURE_2D,
|
||||
0,
|
||||
gl_lms.internal_format,
|
||||
BLOCK_WIDTH, BLOCK_HEIGHT,
|
||||
0,
|
||||
GL_LIGHTMAP_FORMAT,
|
||||
GL_UNSIGNED_BYTE,
|
||||
dummy );
|
||||
}
|
||||
|
||||
void
|
||||
GL_EndBuildingLightmaps ( void )
|
||||
{
|
||||
LM_UploadBlock( false );
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,11 @@
|
|||
#define REF_VERSION "Yamagi Quake II OpenGL Refresher"
|
||||
#define MAX_LBM_HEIGHT 480
|
||||
#define BACKFACE_EPSILON 0.01
|
||||
#define DYNAMIC_LIGHT_WIDTH 128
|
||||
#define DYNAMIC_LIGHT_HEIGHT 128
|
||||
#define LIGHTMAP_BYTES 4
|
||||
#define MAX_LIGHTMAPS 128
|
||||
#define GL_LIGHTMAP_FORMAT GL_RGBA
|
||||
|
||||
/* up / down */
|
||||
#define PITCH 0
|
||||
|
@ -355,6 +360,20 @@ typedef struct
|
|||
unsigned char originalBlueGammaTable [ 256 ];
|
||||
} glstate_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int internal_format;
|
||||
int current_lightmap_texture;
|
||||
|
||||
msurface_t *lightmap_surfaces [ MAX_LIGHTMAPS ];
|
||||
|
||||
int allocated [ BLOCK_WIDTH ];
|
||||
|
||||
/* the lightmap texture data needs to be kept in
|
||||
main memory so texsubimage can update properly */
|
||||
byte lightmap_buffer [ 4 * BLOCK_WIDTH * BLOCK_HEIGHT ];
|
||||
} gllightmapstate_t;
|
||||
|
||||
extern glconfig_t gl_config;
|
||||
extern glstate_t gl_state;
|
||||
extern refimport_t ri;
|
||||
|
|
299
src/refresh/r_lightmap.c
Normal file
299
src/refresh/r_lightmap.c
Normal file
|
@ -0,0 +1,299 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 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 the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Lightmap handling
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
||||
#include "header/local.h"
|
||||
|
||||
extern gllightmapstate_t gl_lms;
|
||||
|
||||
void R_SetCacheState ( msurface_t *surf );
|
||||
void R_BuildLightMap ( msurface_t *surf, byte *dest, int stride );
|
||||
|
||||
static void
|
||||
LM_InitBlock ( void )
|
||||
{
|
||||
memset( gl_lms.allocated, 0, sizeof ( gl_lms.allocated ) );
|
||||
}
|
||||
|
||||
static void
|
||||
LM_UploadBlock ( qboolean dynamic )
|
||||
{
|
||||
int texture;
|
||||
int height = 0;
|
||||
|
||||
if ( dynamic )
|
||||
{
|
||||
texture = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
texture = gl_lms.current_lightmap_texture;
|
||||
}
|
||||
|
||||
R_Bind( gl_state.lightmap_textures + texture );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
|
||||
if ( dynamic )
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < BLOCK_WIDTH; i++ )
|
||||
{
|
||||
if ( gl_lms.allocated [ i ] > height )
|
||||
{
|
||||
height = gl_lms.allocated [ i ];
|
||||
}
|
||||
}
|
||||
|
||||
qglTexSubImage2D( GL_TEXTURE_2D,
|
||||
0,
|
||||
0, 0,
|
||||
BLOCK_WIDTH, height,
|
||||
GL_LIGHTMAP_FORMAT,
|
||||
GL_UNSIGNED_BYTE,
|
||||
gl_lms.lightmap_buffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
qglTexImage2D( GL_TEXTURE_2D,
|
||||
0,
|
||||
gl_lms.internal_format,
|
||||
BLOCK_WIDTH, BLOCK_HEIGHT,
|
||||
0,
|
||||
GL_LIGHTMAP_FORMAT,
|
||||
GL_UNSIGNED_BYTE,
|
||||
gl_lms.lightmap_buffer );
|
||||
|
||||
if ( ++gl_lms.current_lightmap_texture == MAX_LIGHTMAPS )
|
||||
{
|
||||
ri.Sys_Error( ERR_DROP, "LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* returns a texture number and the position inside it */
|
||||
static qboolean
|
||||
LM_AllocBlock ( int w, int h, int *x, int *y )
|
||||
{
|
||||
int i, j;
|
||||
int best, best2;
|
||||
|
||||
best = BLOCK_HEIGHT;
|
||||
|
||||
for ( i = 0; i < BLOCK_WIDTH - w; i++ )
|
||||
{
|
||||
best2 = 0;
|
||||
|
||||
for ( j = 0; j < w; j++ )
|
||||
{
|
||||
if ( gl_lms.allocated [ i + j ] >= best )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ( gl_lms.allocated [ i + j ] > best2 )
|
||||
{
|
||||
best2 = gl_lms.allocated [ i + j ];
|
||||
}
|
||||
}
|
||||
|
||||
if ( j == w )
|
||||
{
|
||||
/* this is a valid spot */
|
||||
*x = i;
|
||||
*y = best = best2;
|
||||
}
|
||||
}
|
||||
|
||||
if ( best + h > BLOCK_HEIGHT )
|
||||
{
|
||||
return ( false );
|
||||
}
|
||||
|
||||
for ( i = 0; i < w; i++ )
|
||||
{
|
||||
gl_lms.allocated [ *x + i ] = best + h;
|
||||
}
|
||||
|
||||
return ( true );
|
||||
}
|
||||
|
||||
void
|
||||
GL_BuildPolygonFromSurface ( msurface_t *fa )
|
||||
{
|
||||
int i, lindex, lnumverts;
|
||||
medge_t *pedges, *r_pedge;
|
||||
int vertpage;
|
||||
float *vec;
|
||||
float s, t;
|
||||
glpoly_t *poly;
|
||||
vec3_t total;
|
||||
|
||||
/* reconstruct the polygon */
|
||||
pedges = currentmodel->edges;
|
||||
lnumverts = fa->numedges;
|
||||
vertpage = 0;
|
||||
|
||||
VectorClear( total );
|
||||
|
||||
/* draw texture */
|
||||
poly = Hunk_Alloc( sizeof ( glpoly_t ) + ( lnumverts - 4 ) * VERTEXSIZE * sizeof ( float ) );
|
||||
poly->next = fa->polys;
|
||||
poly->flags = fa->flags;
|
||||
fa->polys = poly;
|
||||
poly->numverts = lnumverts;
|
||||
|
||||
for ( i = 0; i < lnumverts; i++ )
|
||||
{
|
||||
lindex = currentmodel->surfedges [ fa->firstedge + i ];
|
||||
|
||||
if ( lindex > 0 )
|
||||
{
|
||||
r_pedge = &pedges [ lindex ];
|
||||
vec = currentmodel->vertexes [ r_pedge->v [ 0 ] ].position;
|
||||
}
|
||||
else
|
||||
{
|
||||
r_pedge = &pedges [ -lindex ];
|
||||
vec = currentmodel->vertexes [ r_pedge->v [ 1 ] ].position;
|
||||
}
|
||||
|
||||
s = DotProduct( vec, fa->texinfo->vecs [ 0 ] ) + fa->texinfo->vecs [ 0 ] [ 3 ];
|
||||
s /= fa->texinfo->image->width;
|
||||
|
||||
t = DotProduct( vec, fa->texinfo->vecs [ 1 ] ) + fa->texinfo->vecs [ 1 ] [ 3 ];
|
||||
t /= fa->texinfo->image->height;
|
||||
|
||||
VectorAdd( total, vec, total );
|
||||
VectorCopy( vec, poly->verts [ i ] );
|
||||
poly->verts [ i ] [ 3 ] = s;
|
||||
poly->verts [ i ] [ 4 ] = t;
|
||||
|
||||
/* lightmap texture coordinates */
|
||||
s = DotProduct( vec, fa->texinfo->vecs [ 0 ] ) + fa->texinfo->vecs [ 0 ] [ 3 ];
|
||||
s -= fa->texturemins [ 0 ];
|
||||
s += fa->light_s * 16;
|
||||
s += 8;
|
||||
s /= BLOCK_WIDTH * 16; /* fa->texinfo->texture->width; */
|
||||
|
||||
t = DotProduct( vec, fa->texinfo->vecs [ 1 ] ) + fa->texinfo->vecs [ 1 ] [ 3 ];
|
||||
t -= fa->texturemins [ 1 ];
|
||||
t += fa->light_t * 16;
|
||||
t += 8;
|
||||
t /= BLOCK_HEIGHT * 16; /* fa->texinfo->texture->height; */
|
||||
|
||||
poly->verts [ i ] [ 5 ] = s;
|
||||
poly->verts [ i ] [ 6 ] = t;
|
||||
}
|
||||
|
||||
poly->numverts = lnumverts;
|
||||
}
|
||||
|
||||
void
|
||||
GL_CreateSurfaceLightmap ( msurface_t *surf )
|
||||
{
|
||||
int smax, tmax;
|
||||
byte *base;
|
||||
|
||||
if ( surf->flags & ( SURF_DRAWSKY | SURF_DRAWTURB ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
smax = ( surf->extents [ 0 ] >> 4 ) + 1;
|
||||
tmax = ( surf->extents [ 1 ] >> 4 ) + 1;
|
||||
|
||||
if ( !LM_AllocBlock( smax, tmax, &surf->light_s, &surf->light_t ) )
|
||||
{
|
||||
LM_UploadBlock( false );
|
||||
LM_InitBlock();
|
||||
|
||||
if ( !LM_AllocBlock( smax, tmax, &surf->light_s, &surf->light_t ) )
|
||||
{
|
||||
ri.Sys_Error( ERR_FATAL, "Consecutive calls to LM_AllocBlock(%d,%d) failed\n", smax, tmax );
|
||||
}
|
||||
}
|
||||
|
||||
surf->lightmaptexturenum = gl_lms.current_lightmap_texture;
|
||||
|
||||
base = gl_lms.lightmap_buffer;
|
||||
base += ( surf->light_t * BLOCK_WIDTH + surf->light_s ) * LIGHTMAP_BYTES;
|
||||
|
||||
R_SetCacheState( surf );
|
||||
R_BuildLightMap( surf, base, BLOCK_WIDTH * LIGHTMAP_BYTES );
|
||||
}
|
||||
|
||||
void
|
||||
GL_BeginBuildingLightmaps ( model_t *m )
|
||||
{
|
||||
static lightstyle_t lightstyles [ MAX_LIGHTSTYLES ];
|
||||
int i;
|
||||
unsigned dummy [ 128 * 128 ];
|
||||
|
||||
memset( gl_lms.allocated, 0, sizeof ( gl_lms.allocated ) );
|
||||
|
||||
r_framecount = 1;/* no dlightcache */
|
||||
|
||||
/* setup the base lightstyles so the lightmaps won't have to be regenerated
|
||||
the first time they're seen */
|
||||
for ( i = 0; i < MAX_LIGHTSTYLES; i++ )
|
||||
{
|
||||
lightstyles [ i ].rgb [ 0 ] = 1;
|
||||
lightstyles [ i ].rgb [ 1 ] = 1;
|
||||
lightstyles [ i ].rgb [ 2 ] = 1;
|
||||
lightstyles [ i ].white = 3;
|
||||
}
|
||||
|
||||
r_newrefdef.lightstyles = lightstyles;
|
||||
|
||||
if ( !gl_state.lightmap_textures )
|
||||
{
|
||||
gl_state.lightmap_textures = TEXNUM_LIGHTMAPS;
|
||||
}
|
||||
|
||||
gl_lms.current_lightmap_texture = 1;
|
||||
gl_lms.internal_format = gl_tex_solid_format;
|
||||
|
||||
/* initialize the dynamic lightmap texture */
|
||||
R_Bind( gl_state.lightmap_textures + 0 );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
qglTexImage2D( GL_TEXTURE_2D,
|
||||
0,
|
||||
gl_lms.internal_format,
|
||||
BLOCK_WIDTH, BLOCK_HEIGHT,
|
||||
0,
|
||||
GL_LIGHTMAP_FORMAT,
|
||||
GL_UNSIGNED_BYTE,
|
||||
dummy );
|
||||
}
|
||||
|
||||
void
|
||||
GL_EndBuildingLightmaps ( void )
|
||||
{
|
||||
LM_UploadBlock( false );
|
||||
}
|
||||
|
Loading…
Reference in a new issue