2009-03-05 09:07:55 +00:00
|
|
|
/*
|
2010-10-22 08:04:31 +00:00
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
*/
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2009-03-05 13:08:47 +00:00
|
|
|
#include <assert.h>
|
2009-03-05 11:03:08 +00:00
|
|
|
#include "header/local.h"
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
#define DYNAMIC_LIGHT_WIDTH 128
|
|
|
|
#define DYNAMIC_LIGHT_HEIGHT 128
|
|
|
|
#define LIGHTMAP_BYTES 4
|
2010-10-22 08:04:31 +00:00
|
|
|
#define MAX_LIGHTMAPS 128
|
2009-03-05 09:07:55 +00:00
|
|
|
#define GL_LIGHTMAP_FORMAT GL_RGBA
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
int c_visible_lightmaps;
|
|
|
|
int c_visible_textures;
|
|
|
|
static vec3_t modelorg; /* relative to viewpoint */
|
|
|
|
msurface_t *r_alpha_surfaces;
|
|
|
|
|
2009-03-05 09:07:55 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int internal_format;
|
2010-10-22 08:04:31 +00:00
|
|
|
int current_lightmap_texture;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
msurface_t *lightmap_surfaces [ MAX_LIGHTMAPS ];
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
int allocated [ BLOCK_WIDTH ];
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* the lightmap texture data needs to be kept in
|
|
|
|
main memory so texsubimage can update properly */
|
|
|
|
byte lightmap_buffer [ 4 * BLOCK_WIDTH * BLOCK_HEIGHT ];
|
2009-03-05 09:07:55 +00:00
|
|
|
} gllightmapstate_t;
|
|
|
|
|
|
|
|
static gllightmapstate_t gl_lms;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
static void LM_InitBlock ( void );
|
|
|
|
static void LM_UploadBlock ( qboolean dynamic );
|
|
|
|
static qboolean LM_AllocBlock ( int w, int h, int *x, int *y );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
extern void R_SetCacheState ( msurface_t *surf );
|
|
|
|
extern void R_BuildLightMap ( msurface_t *surf, byte *dest, int stride );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
/*
|
2010-10-22 08:04:31 +00:00
|
|
|
* Returns the proper texture for a given time and base texture
|
|
|
|
*/
|
|
|
|
image_t *
|
|
|
|
R_TextureAnimation ( mtexinfo_t *tex )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
int c;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( !tex->next )
|
|
|
|
{
|
|
|
|
return ( tex->image );
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
c = currententity->frame % tex->numframes;
|
2010-10-22 08:04:31 +00:00
|
|
|
|
|
|
|
while ( c )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
|
|
|
tex = tex->next;
|
|
|
|
c--;
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
return ( tex->image );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
void
|
|
|
|
DrawGLPoly ( glpoly_t *p )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
int i;
|
|
|
|
float *v;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
qglBegin( GL_POLYGON );
|
|
|
|
v = p->verts [ 0 ];
|
|
|
|
|
|
|
|
for ( i = 0; i < p->numverts; i++, v += VERTEXSIZE )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
qglTexCoord2f( v [ 3 ], v [ 4 ] );
|
|
|
|
qglVertex3fv( v );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
2010-10-22 08:04:31 +00:00
|
|
|
|
|
|
|
qglEnd();
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
void
|
|
|
|
DrawGLFlowingPoly ( msurface_t *fa )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
int i;
|
|
|
|
float *v;
|
2009-03-05 09:07:55 +00:00
|
|
|
glpoly_t *p;
|
2010-10-22 08:04:31 +00:00
|
|
|
float scroll;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
p = fa->polys;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
scroll = -64 * ( ( r_newrefdef.time / 40.0 ) - (int) ( r_newrefdef.time / 40.0 ) );
|
|
|
|
|
|
|
|
if ( scroll == 0.0 )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
scroll = -64.0;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
qglBegin( GL_POLYGON );
|
|
|
|
v = p->verts [ 0 ];
|
|
|
|
|
|
|
|
for ( i = 0; i < p->numverts; i++, v += VERTEXSIZE )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
qglTexCoord2f( ( v [ 3 ] + scroll ), v [ 4 ] );
|
|
|
|
qglVertex3fv( v );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
2010-10-22 08:04:31 +00:00
|
|
|
|
|
|
|
qglEnd();
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
void
|
|
|
|
R_DrawTriangleOutlines ( void )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
int i, j;
|
|
|
|
glpoly_t *p;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( !gl_showtris->value )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
return;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
qglDisable( GL_TEXTURE_2D );
|
|
|
|
qglDisable( GL_DEPTH_TEST );
|
|
|
|
qglColor4f( 1, 1, 1, 1 );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
for ( i = 0; i < MAX_LIGHTMAPS; i++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
|
|
|
msurface_t *surf;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
for ( surf = gl_lms.lightmap_surfaces [ i ]; surf != 0; surf = surf->lightmapchain )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
|
|
|
p = surf->polys;
|
2010-10-22 08:04:31 +00:00
|
|
|
|
|
|
|
for ( ; p; p = p->chain )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
for ( j = 2; j < p->numverts; j++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
qglBegin( GL_LINE_STRIP );
|
|
|
|
qglVertex3fv( p->verts [ 0 ] );
|
|
|
|
qglVertex3fv( p->verts [ j - 1 ] );
|
|
|
|
qglVertex3fv( p->verts [ j ] );
|
|
|
|
qglVertex3fv( p->verts [ 0 ] );
|
|
|
|
qglEnd();
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
qglEnable( GL_DEPTH_TEST );
|
|
|
|
qglEnable( GL_TEXTURE_2D );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
void
|
|
|
|
DrawGLPolyChain ( glpoly_t *p, float soffset, float toffset )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( ( soffset == 0 ) && ( toffset == 0 ) )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
|
|
|
for ( ; p != 0; p = p->chain )
|
|
|
|
{
|
|
|
|
float *v;
|
|
|
|
int j;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
v = p->verts [ 0 ];
|
|
|
|
|
|
|
|
if ( v == NULL )
|
|
|
|
{
|
|
|
|
fprintf( stderr, "BUGFIX: DrawGLPolyChain: v==NULL\n" );
|
2009-03-05 09:07:55 +00:00
|
|
|
return;
|
|
|
|
}
|
2010-10-22 08:04:31 +00:00
|
|
|
|
|
|
|
qglBegin( GL_POLYGON );
|
|
|
|
|
|
|
|
for ( j = 0; j < p->numverts; j++, v += VERTEXSIZE )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
qglTexCoord2f( v [ 5 ], v [ 6 ] );
|
|
|
|
qglVertex3fv( v );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
2010-10-22 08:04:31 +00:00
|
|
|
|
|
|
|
qglEnd();
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for ( ; p != 0; p = p->chain )
|
|
|
|
{
|
|
|
|
float *v;
|
|
|
|
int j;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
qglBegin( GL_POLYGON );
|
|
|
|
v = p->verts [ 0 ];
|
|
|
|
|
|
|
|
for ( j = 0; j < p->numverts; j++, v += VERTEXSIZE )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
qglTexCoord2f( v [ 5 ] - soffset, v [ 6 ] - toffset );
|
|
|
|
qglVertex3fv( v );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
2010-10-22 08:04:31 +00:00
|
|
|
|
|
|
|
qglEnd();
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-10-22 08:04:31 +00:00
|
|
|
* This routine takes all the given light mapped surfaces in the world
|
|
|
|
* and blends them into the framebuffer.
|
2009-03-05 09:07:55 +00:00
|
|
|
*/
|
2010-10-22 08:04:31 +00:00
|
|
|
void
|
|
|
|
R_BlendLightmaps ( void )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
int i;
|
|
|
|
msurface_t *surf, *newdrawsurf = 0;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* don't bother if we're set to fullbright */
|
|
|
|
if ( r_fullbright->value )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
return;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( !r_worldmodel->lightdata )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
return;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* don't bother writing Z */
|
2009-03-05 09:07:55 +00:00
|
|
|
qglDepthMask( 0 );
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* set the appropriate blending mode unless
|
|
|
|
we're only looking at the lightmaps. */
|
|
|
|
if ( !gl_lightmap->value )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
qglEnable( GL_BLEND );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
if ( gl_saturatelighting->value )
|
|
|
|
{
|
|
|
|
qglBlendFunc( GL_ONE, GL_ONE );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-10-22 08:20:49 +00:00
|
|
|
qglBlendFunc( GL_ZERO, GL_SRC_COLOR );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( currentmodel == r_worldmodel )
|
2010-10-22 08:04:31 +00:00
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
c_visible_lightmaps = 0;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* render static lightmaps first */
|
2009-03-05 09:07:55 +00:00
|
|
|
for ( i = 1; i < MAX_LIGHTMAPS; i++ )
|
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( gl_lms.lightmap_surfaces [ i ] )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( currentmodel == r_worldmodel )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
c_visible_lightmaps++;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
GL_Bind( gl_state.lightmap_textures + i );
|
|
|
|
|
|
|
|
for ( surf = gl_lms.lightmap_surfaces [ i ]; surf != 0; surf = surf->lightmapchain )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
|
|
|
if ( surf->polys )
|
2010-10-22 08:04:31 +00:00
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
DrawGLPolyChain( surf->polys, 0, 0 );
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* render dynamic lightmaps */
|
2009-03-05 09:07:55 +00:00
|
|
|
if ( gl_dynamic->value )
|
|
|
|
{
|
|
|
|
LM_InitBlock();
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
GL_Bind( gl_state.lightmap_textures + 0 );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( currentmodel == r_worldmodel )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
c_visible_lightmaps++;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
newdrawsurf = gl_lms.lightmap_surfaces [ 0 ];
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
for ( surf = gl_lms.lightmap_surfaces [ 0 ]; surf != 0; surf = surf->lightmapchain )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
int smax, tmax;
|
|
|
|
byte *base;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
smax = ( surf->extents [ 0 ] >> 4 ) + 1;
|
|
|
|
tmax = ( surf->extents [ 1 ] >> 4 ) + 1;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
if ( LM_AllocBlock( smax, tmax, &surf->dlight_s, &surf->dlight_t ) )
|
|
|
|
{
|
|
|
|
base = gl_lms.lightmap_buffer;
|
|
|
|
base += ( surf->dlight_t * BLOCK_WIDTH + surf->dlight_s ) * LIGHTMAP_BYTES;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
R_BuildLightMap( surf, base, BLOCK_WIDTH * LIGHTMAP_BYTES );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
msurface_t *drawsurf;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* upload what we have so far */
|
2009-03-05 09:07:55 +00:00
|
|
|
LM_UploadBlock( true );
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* draw all surfaces that use this lightmap */
|
2009-03-05 09:07:55 +00:00
|
|
|
for ( drawsurf = newdrawsurf; drawsurf != surf; drawsurf = drawsurf->lightmapchain )
|
|
|
|
{
|
|
|
|
if ( drawsurf->polys )
|
2010-10-22 08:04:31 +00:00
|
|
|
{
|
|
|
|
DrawGLPolyChain( drawsurf->polys,
|
|
|
|
( drawsurf->light_s - drawsurf->dlight_s ) * ( 1.0 / 128.0 ),
|
|
|
|
( drawsurf->light_t - drawsurf->dlight_t ) * ( 1.0 / 128.0 ) );
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
newdrawsurf = drawsurf;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* clear the block */
|
2009-03-05 09:07:55 +00:00
|
|
|
LM_InitBlock();
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* try uploading the block now */
|
2009-03-05 09:07:55 +00:00
|
|
|
if ( !LM_AllocBlock( smax, tmax, &surf->dlight_s, &surf->dlight_t ) )
|
|
|
|
{
|
|
|
|
ri.Sys_Error( ERR_FATAL, "Consecutive calls to LM_AllocBlock(%d,%d) failed (dynamic)\n", smax, tmax );
|
|
|
|
}
|
|
|
|
|
|
|
|
base = gl_lms.lightmap_buffer;
|
|
|
|
base += ( surf->dlight_t * BLOCK_WIDTH + surf->dlight_s ) * LIGHTMAP_BYTES;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
R_BuildLightMap( surf, base, BLOCK_WIDTH * LIGHTMAP_BYTES );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* draw remainder of dynamic lightmaps that haven't been uploaded yet */
|
2009-03-05 09:07:55 +00:00
|
|
|
if ( newdrawsurf )
|
2010-10-22 08:04:31 +00:00
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
LM_UploadBlock( true );
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
for ( surf = newdrawsurf; surf != 0; surf = surf->lightmapchain )
|
|
|
|
{
|
|
|
|
if ( surf->polys )
|
2010-10-22 08:04:31 +00:00
|
|
|
{
|
|
|
|
DrawGLPolyChain( surf->polys, ( surf->light_s - surf->dlight_s ) * ( 1.0 / 128.0 ),
|
|
|
|
( surf->light_t - surf->dlight_t ) * ( 1.0 / 128.0 ) );
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* restore state */
|
|
|
|
qglDisable( GL_BLEND );
|
|
|
|
qglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
2009-03-05 09:07:55 +00:00
|
|
|
qglDepthMask( 1 );
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
void
|
|
|
|
R_RenderBrushPoly ( msurface_t *fa )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
int maps;
|
|
|
|
image_t *image;
|
2009-03-05 09:07:55 +00:00
|
|
|
qboolean is_dynamic = false;
|
|
|
|
|
|
|
|
c_brush_polys++;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
image = R_TextureAnimation( fa->texinfo );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( fa->flags & SURF_DRAWTURB )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
GL_Bind( image->texnum );
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* warp texture, no lightmaps */
|
2009-03-05 09:07:55 +00:00
|
|
|
GL_TexEnv( GL_MODULATE );
|
2010-10-22 08:04:31 +00:00
|
|
|
qglColor4f( gl_state.inverse_intensity,
|
|
|
|
gl_state.inverse_intensity,
|
|
|
|
gl_state.inverse_intensity,
|
|
|
|
1.0F );
|
|
|
|
EmitWaterPolys( fa );
|
2009-03-05 09:07:55 +00:00
|
|
|
GL_TexEnv( GL_REPLACE );
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GL_Bind( image->texnum );
|
|
|
|
|
|
|
|
GL_TexEnv( GL_REPLACE );
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( fa->texinfo->flags & SURF_FLOWING )
|
|
|
|
{
|
|
|
|
DrawGLFlowingPoly( fa );
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
else
|
2010-10-22 08:04:31 +00:00
|
|
|
{
|
|
|
|
DrawGLPoly( fa->polys );
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* check for lightmap modification */
|
|
|
|
for ( maps = 0; maps < MAXLIGHTMAPS && fa->styles [ maps ] != 255; maps++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( r_newrefdef.lightstyles [ fa->styles [ maps ] ].white != fa->cached_light [ maps ] )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
goto dynamic;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* dynamic this frame or dynamic previously */
|
2009-03-05 09:07:55 +00:00
|
|
|
if ( ( fa->dlightframe == r_framecount ) )
|
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
dynamic:
|
|
|
|
|
2009-03-05 09:07:55 +00:00
|
|
|
if ( gl_dynamic->value )
|
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( !( fa->texinfo->flags & ( SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP ) ) )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
|
|
|
is_dynamic = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( is_dynamic )
|
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( ( ( fa->styles [ maps ] >= 32 ) || ( fa->styles [ maps ] == 0 ) ) && ( fa->dlightframe != r_framecount ) )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
unsigned temp [ 34 * 34 ];
|
|
|
|
int smax, tmax;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
smax = ( fa->extents [ 0 ] >> 4 ) + 1;
|
|
|
|
tmax = ( fa->extents [ 1 ] >> 4 ) + 1;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
R_BuildLightMap( fa, (void *) temp, smax * 4 );
|
2009-03-05 09:07:55 +00:00
|
|
|
R_SetCacheState( fa );
|
|
|
|
|
|
|
|
GL_Bind( gl_state.lightmap_textures + fa->lightmaptexturenum );
|
|
|
|
|
|
|
|
qglTexSubImage2D( GL_TEXTURE_2D, 0,
|
2010-10-22 08:04:31 +00:00
|
|
|
fa->light_s, fa->light_t,
|
|
|
|
smax, tmax,
|
|
|
|
GL_LIGHTMAP_FORMAT,
|
|
|
|
GL_UNSIGNED_BYTE, temp );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
fa->lightmapchain = gl_lms.lightmap_surfaces [ fa->lightmaptexturenum ];
|
|
|
|
gl_lms.lightmap_surfaces [ fa->lightmaptexturenum ] = fa;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
fa->lightmapchain = gl_lms.lightmap_surfaces [ 0 ];
|
|
|
|
gl_lms.lightmap_surfaces [ 0 ] = fa;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
fa->lightmapchain = gl_lms.lightmap_surfaces [ fa->lightmaptexturenum ];
|
|
|
|
gl_lms.lightmap_surfaces [ fa->lightmaptexturenum ] = fa;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-10-22 08:04:31 +00:00
|
|
|
* Draw water surfaces and windows.
|
|
|
|
* The BSP tree is waled front to back, so unwinding the chain
|
|
|
|
* of alpha_surfaces will draw back to front, giving proper ordering.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
R_DrawAlphaSurfaces ( void )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
msurface_t *s;
|
|
|
|
float intens;
|
|
|
|
|
|
|
|
/* go back to the world matrix */
|
|
|
|
qglLoadMatrixf( r_world_matrix );
|
|
|
|
|
|
|
|
qglEnable( GL_BLEND );
|
2009-03-05 09:07:55 +00:00
|
|
|
GL_TexEnv( GL_MODULATE );
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* the textures are prescaled up for a better lighting range,
|
|
|
|
so scale it back down */
|
2009-03-05 09:07:55 +00:00
|
|
|
intens = gl_state.inverse_intensity;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
for ( s = r_alpha_surfaces; s; s = s->texturechain )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
GL_Bind( s->texinfo->image->texnum );
|
2009-03-05 09:07:55 +00:00
|
|
|
c_brush_polys++;
|
2010-10-22 08:04:31 +00:00
|
|
|
|
|
|
|
if ( s->texinfo->flags & SURF_TRANS33 )
|
|
|
|
{
|
|
|
|
qglColor4f( intens, intens, intens, 0.33 );
|
|
|
|
}
|
|
|
|
else if ( s->texinfo->flags & SURF_TRANS66 )
|
|
|
|
{
|
|
|
|
qglColor4f( intens, intens, intens, 0.66 );
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
else
|
2010-10-22 08:04:31 +00:00
|
|
|
{
|
|
|
|
qglColor4f( intens, intens, intens, 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( s->flags & SURF_DRAWTURB )
|
|
|
|
{
|
|
|
|
EmitWaterPolys( s );
|
|
|
|
}
|
|
|
|
else if ( s->texinfo->flags & SURF_FLOWING )
|
|
|
|
{
|
|
|
|
DrawGLFlowingPoly( s );
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
else
|
2010-10-22 08:04:31 +00:00
|
|
|
{
|
|
|
|
DrawGLPoly( s->polys );
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GL_TexEnv( GL_REPLACE );
|
2010-10-22 08:04:31 +00:00
|
|
|
qglColor4f( 1, 1, 1, 1 );
|
|
|
|
qglDisable( GL_BLEND );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
r_alpha_surfaces = NULL;
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
void
|
|
|
|
DrawTextureChains ( void )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
int i;
|
|
|
|
msurface_t *s;
|
|
|
|
image_t *image;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
c_visible_textures = 0;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
for ( i = 0, image = gltextures; i < numgltextures; i++, image++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( !image->registration_sequence )
|
|
|
|
{
|
2009-10-04 10:27:55 +00:00
|
|
|
continue;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
|
|
|
|
2009-10-04 10:27:55 +00:00
|
|
|
s = image->texturechain;
|
2010-10-22 08:04:31 +00:00
|
|
|
|
|
|
|
if ( !s )
|
|
|
|
{
|
2009-10-04 10:27:55 +00:00
|
|
|
continue;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
|
|
|
|
2009-10-04 10:27:55 +00:00
|
|
|
c_visible_textures++;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
for ( ; s; s = s->texturechain )
|
|
|
|
{
|
|
|
|
R_RenderBrushPoly( s );
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2009-10-04 10:27:55 +00:00
|
|
|
image->texturechain = NULL;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GL_TexEnv( GL_REPLACE );
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
void
|
|
|
|
R_DrawInlineBModel ( void )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
int i, k;
|
|
|
|
cplane_t *pplane;
|
|
|
|
float dot;
|
|
|
|
msurface_t *psurf;
|
|
|
|
dlight_t *lt;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* calculate dynamic lighting for bmodel */
|
2009-03-05 09:07:55 +00:00
|
|
|
if ( !gl_flashblend->value )
|
|
|
|
{
|
|
|
|
lt = r_newrefdef.dlights;
|
2010-10-22 08:04:31 +00:00
|
|
|
|
|
|
|
for ( k = 0; k < r_newrefdef.num_dlights; k++, lt++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
R_MarkLights( lt, 1 << k, currentmodel->nodes + currentmodel->firstnode );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
psurf = ¤tmodel->surfaces [ currentmodel->firstmodelsurface ];
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
if ( currententity->flags & RF_TRANSLUCENT )
|
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
qglEnable( GL_BLEND );
|
|
|
|
qglColor4f( 1, 1, 1, 0.25 );
|
2009-03-05 09:07:55 +00:00
|
|
|
GL_TexEnv( GL_MODULATE );
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* draw texture */
|
|
|
|
for ( i = 0; i < currentmodel->nummodelsurfaces; i++, psurf++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
/* find which side of the node we are on */
|
2009-03-05 09:07:55 +00:00
|
|
|
pplane = psurf->plane;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
dot = DotProduct( modelorg, pplane->normal ) - pplane->dist;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* draw the polygon */
|
|
|
|
if ( ( ( psurf->flags & SURF_PLANEBACK ) && ( dot < -BACKFACE_EPSILON ) ) ||
|
|
|
|
( !( psurf->flags & SURF_PLANEBACK ) && ( dot > BACKFACE_EPSILON ) ) )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( psurf->texinfo->flags & ( SURF_TRANS33 | SURF_TRANS66 ) )
|
|
|
|
{
|
|
|
|
/* add to the translucent chain */
|
2009-03-05 09:07:55 +00:00
|
|
|
psurf->texturechain = r_alpha_surfaces;
|
|
|
|
r_alpha_surfaces = psurf;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
R_RenderBrushPoly( psurf );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( !( currententity->flags & RF_TRANSLUCENT ) )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
R_BlendLightmaps();
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
qglDisable( GL_BLEND );
|
|
|
|
qglColor4f( 1, 1, 1, 1 );
|
2009-03-05 09:07:55 +00:00
|
|
|
GL_TexEnv( GL_REPLACE );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
void
|
|
|
|
R_DrawBrushModel ( entity_t *e )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
vec3_t mins, maxs;
|
|
|
|
int i;
|
|
|
|
qboolean rotated;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( currentmodel->nummodelsurfaces == 0 )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
return;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
currententity = e;
|
2010-10-22 08:04:31 +00:00
|
|
|
gl_state.currenttextures [ 0 ] = gl_state.currenttextures [ 1 ] = -1;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( e->angles [ 0 ] || e->angles [ 1 ] || e->angles [ 2 ] )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
|
|
|
rotated = true;
|
2010-10-22 08:04:31 +00:00
|
|
|
|
|
|
|
for ( i = 0; i < 3; i++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
mins [ i ] = e->origin [ i ] - currentmodel->radius;
|
|
|
|
maxs [ i ] = e->origin [ i ] + currentmodel->radius;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rotated = false;
|
2010-10-22 08:04:31 +00:00
|
|
|
VectorAdd( e->origin, currentmodel->mins, mins );
|
|
|
|
VectorAdd( e->origin, currentmodel->maxs, maxs );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( R_CullBox( mins, maxs ) )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
return;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
qglColor3f( 1, 1, 1 );
|
|
|
|
memset( gl_lms.lightmap_surfaces, 0, sizeof ( gl_lms.lightmap_surfaces ) );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
VectorSubtract( r_newrefdef.vieworg, e->origin, modelorg );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( rotated )
|
|
|
|
{
|
|
|
|
vec3_t temp;
|
|
|
|
vec3_t forward, right, up;
|
|
|
|
|
|
|
|
VectorCopy( modelorg, temp );
|
|
|
|
AngleVectors( e->angles, forward, right, up );
|
|
|
|
modelorg [ 0 ] = DotProduct( temp, forward );
|
|
|
|
modelorg [ 1 ] = -DotProduct( temp, right );
|
|
|
|
modelorg [ 2 ] = DotProduct( temp, up );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
qglPushMatrix();
|
|
|
|
e->angles [ 0 ] = -e->angles [ 0 ];
|
|
|
|
e->angles [ 2 ] = -e->angles [ 2 ];
|
|
|
|
R_RotateForEntity( e );
|
|
|
|
e->angles [ 0 ] = -e->angles [ 0 ];
|
|
|
|
e->angles [ 2 ] = -e->angles [ 2 ];
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
GL_TexEnv( GL_REPLACE );
|
|
|
|
GL_TexEnv( GL_MODULATE );
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
R_DrawInlineBModel();
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
qglPopMatrix();
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
void
|
|
|
|
R_RecursiveWorldNode ( mnode_t *node )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
int c, side, sidebit;
|
|
|
|
cplane_t *plane;
|
|
|
|
msurface_t *surf, **mark;
|
|
|
|
mleaf_t *pleaf;
|
|
|
|
float dot;
|
|
|
|
image_t *image;
|
|
|
|
|
|
|
|
if ( node->contents == CONTENTS_SOLID )
|
|
|
|
{
|
|
|
|
return; /* solid */
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( node->visframe != r_visframecount )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
return;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( R_CullBox( node->minmaxs, node->minmaxs + 3 ) )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
return;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* if a leaf node, draw stuff */
|
|
|
|
if ( node->contents != -1 )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
pleaf = (mleaf_t *) node;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* check for door connected areas */
|
|
|
|
if ( r_newrefdef.areabits )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( !( r_newrefdef.areabits [ pleaf->area >> 3 ] & ( 1 << ( pleaf->area & 7 ) ) ) )
|
|
|
|
{
|
|
|
|
return; /* not visible */
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mark = pleaf->firstmarksurface;
|
|
|
|
c = pleaf->nummarksurfaces;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( c )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
( *mark )->visframe = r_framecount;
|
2009-03-05 09:07:55 +00:00
|
|
|
mark++;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
|
|
|
while ( --c );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* node is just a decision point, so go down the apropriate sides
|
|
|
|
find which side of the node we are on */
|
2009-03-05 09:07:55 +00:00
|
|
|
plane = node->plane;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
switch ( plane->type )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
case PLANE_X:
|
|
|
|
dot = modelorg [ 0 ] - plane->dist;
|
|
|
|
break;
|
|
|
|
case PLANE_Y:
|
|
|
|
dot = modelorg [ 1 ] - plane->dist;
|
|
|
|
break;
|
|
|
|
case PLANE_Z:
|
|
|
|
dot = modelorg [ 2 ] - plane->dist;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
dot = DotProduct( modelorg, plane->normal ) - plane->dist;
|
|
|
|
break;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( dot >= 0 )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
|
|
|
side = 0;
|
|
|
|
sidebit = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
side = 1;
|
|
|
|
sidebit = SURF_PLANEBACK;
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* recurse down the children, front side first */
|
|
|
|
R_RecursiveWorldNode( node->children [ side ] );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* draw stuff */
|
|
|
|
for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c; c--, surf++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( surf->visframe != r_framecount )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
continue;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( ( surf->flags & SURF_PLANEBACK ) != sidebit )
|
|
|
|
{
|
|
|
|
continue; /* wrong side */
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( surf->texinfo->flags & SURF_SKY )
|
|
|
|
{
|
|
|
|
/* just adds to visible sky bounds */
|
|
|
|
R_AddSkySurface( surf );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
2010-10-22 08:04:31 +00:00
|
|
|
else if ( surf->texinfo->flags & ( SURF_TRANS33 | SURF_TRANS66 ) )
|
|
|
|
{
|
|
|
|
/* add to the translucent chain */
|
2009-03-05 09:07:55 +00:00
|
|
|
surf->texturechain = r_alpha_surfaces;
|
|
|
|
r_alpha_surfaces = surf;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
/* the polygon is visible, so add it to the texture */
|
|
|
|
image = R_TextureAnimation( surf->texinfo );
|
2009-10-04 10:27:55 +00:00
|
|
|
surf->texturechain = image->texturechain;
|
|
|
|
image->texturechain = surf;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* recurse down the back side */
|
|
|
|
R_RecursiveWorldNode( node->children [ !side ] );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
void
|
|
|
|
R_DrawWorld ( void )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
entity_t ent;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( !r_drawworld->value )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
return;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
|
2010-10-22 08:04:31 +00:00
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
return;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
currentmodel = r_worldmodel;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
VectorCopy( r_newrefdef.vieworg, modelorg );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* auto cycle the world frame for texture animation */
|
|
|
|
memset( &ent, 0, sizeof ( ent ) );
|
|
|
|
ent.frame = (int) ( r_newrefdef.time * 2 );
|
2009-03-05 09:07:55 +00:00
|
|
|
currententity = &ent;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
gl_state.currenttextures [ 0 ] = gl_state.currenttextures [ 1 ] = -1;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
qglColor3f( 1, 1, 1 );
|
|
|
|
memset( gl_lms.lightmap_surfaces, 0, sizeof ( gl_lms.lightmap_surfaces ) );
|
|
|
|
R_ClearSkyBox();
|
|
|
|
R_RecursiveWorldNode( r_worldmodel->nodes );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
DrawTextureChains();
|
|
|
|
R_BlendLightmaps();
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
R_DrawSkyBox();
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
R_DrawTriangleOutlines();
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
/*
|
2010-10-22 08:04:31 +00:00
|
|
|
* Mark the leaves and nodes that are in the PVS for the current
|
|
|
|
* cluster
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
R_MarkLeaves ( void )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
byte *vis;
|
|
|
|
byte fatvis [ MAX_MAP_LEAFS / 8 ];
|
|
|
|
mnode_t *node;
|
|
|
|
int i, c;
|
|
|
|
mleaf_t *leaf;
|
|
|
|
int cluster;
|
|
|
|
|
|
|
|
if ( ( r_oldviewcluster == r_viewcluster ) && ( r_oldviewcluster2 == r_viewcluster2 ) && !r_novis->value &&
|
|
|
|
( r_viewcluster != -1 ) )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
return;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* development aid to let you run around and see exactly where
|
|
|
|
the pvs ends */
|
|
|
|
if ( gl_lockpvs->value )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
return;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
r_visframecount++;
|
|
|
|
r_oldviewcluster = r_viewcluster;
|
|
|
|
r_oldviewcluster2 = r_viewcluster2;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( r_novis->value || ( r_viewcluster == -1 ) || !r_worldmodel->vis )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
/* mark everything */
|
|
|
|
for ( i = 0; i < r_worldmodel->numleafs; i++ )
|
|
|
|
{
|
|
|
|
r_worldmodel->leafs [ i ].visframe = r_visframecount;
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( i = 0; i < r_worldmodel->numnodes; i++ )
|
|
|
|
{
|
|
|
|
r_worldmodel->nodes [ i ].visframe = r_visframecount;
|
|
|
|
}
|
|
|
|
|
2009-03-05 09:07:55 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
vis = Mod_ClusterPVS( r_viewcluster, r_worldmodel );
|
|
|
|
|
|
|
|
/* may have to combine two clusters because of solid water boundaries */
|
|
|
|
if ( r_viewcluster2 != r_viewcluster )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
memcpy( fatvis, vis, ( r_worldmodel->numleafs + 7 ) / 8 );
|
|
|
|
vis = Mod_ClusterPVS( r_viewcluster2, r_worldmodel );
|
|
|
|
c = ( r_worldmodel->numleafs + 31 ) / 32;
|
|
|
|
|
|
|
|
for ( i = 0; i < c; i++ )
|
|
|
|
{
|
|
|
|
( (int *) fatvis ) [ i ] |= ( (int *) vis ) [ i ];
|
|
|
|
}
|
|
|
|
|
2009-03-05 09:07:55 +00:00
|
|
|
vis = fatvis;
|
|
|
|
}
|
2010-10-22 08:04:31 +00:00
|
|
|
|
|
|
|
for ( i = 0, leaf = r_worldmodel->leafs; i < r_worldmodel->numleafs; i++, leaf++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
|
|
|
cluster = leaf->cluster;
|
2010-10-22 08:04:31 +00:00
|
|
|
|
|
|
|
if ( cluster == -1 )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
continue;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( vis [ cluster >> 3 ] & ( 1 << ( cluster & 7 ) ) )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
node = (mnode_t *) leaf;
|
|
|
|
|
2009-03-05 09:07:55 +00:00
|
|
|
do
|
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( node->visframe == r_visframecount )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
break;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
|
|
|
|
2009-03-05 09:07:55 +00:00
|
|
|
node->visframe = r_visframecount;
|
|
|
|
node = node->parent;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
|
|
|
while ( node );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
static void
|
|
|
|
LM_InitBlock ( void )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
memset( gl_lms.allocated, 0, sizeof ( gl_lms.allocated ) );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
static void
|
|
|
|
LM_UploadBlock ( qboolean dynamic )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
|
|
|
int texture;
|
|
|
|
int height = 0;
|
|
|
|
|
|
|
|
if ( dynamic )
|
|
|
|
{
|
|
|
|
texture = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
texture = gl_lms.current_lightmap_texture;
|
|
|
|
}
|
|
|
|
|
|
|
|
GL_Bind( gl_state.lightmap_textures + texture );
|
2010-10-22 08:04:31 +00:00
|
|
|
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
|
|
|
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
if ( dynamic )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for ( i = 0; i < BLOCK_WIDTH; i++ )
|
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( gl_lms.allocated [ i ] > height )
|
|
|
|
{
|
|
|
|
height = gl_lms.allocated [ i ];
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
qglTexSubImage2D( GL_TEXTURE_2D,
|
|
|
|
0,
|
|
|
|
0, 0,
|
|
|
|
BLOCK_WIDTH, height,
|
|
|
|
GL_LIGHTMAP_FORMAT,
|
|
|
|
GL_UNSIGNED_BYTE,
|
|
|
|
gl_lms.lightmap_buffer );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
qglTexImage2D( GL_TEXTURE_2D,
|
|
|
|
0,
|
|
|
|
gl_lms.internal_format,
|
|
|
|
BLOCK_WIDTH, BLOCK_HEIGHT,
|
|
|
|
0,
|
|
|
|
GL_LIGHTMAP_FORMAT,
|
|
|
|
GL_UNSIGNED_BYTE,
|
|
|
|
gl_lms.lightmap_buffer );
|
|
|
|
|
2009-03-05 09:07:55 +00:00
|
|
|
if ( ++gl_lms.current_lightmap_texture == MAX_LIGHTMAPS )
|
2010-10-22 08:04:31 +00:00
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
ri.Sys_Error( ERR_DROP, "LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n" );
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* returns a texture number and the position inside it */
|
|
|
|
static qboolean
|
|
|
|
LM_AllocBlock ( int w, int h, int *x, int *y )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
int i, j;
|
|
|
|
int best, best2;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
best = BLOCK_HEIGHT;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
for ( i = 0; i < BLOCK_WIDTH - w; i++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
|
|
|
best2 = 0;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
for ( j = 0; j < w; j++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( gl_lms.allocated [ i + j ] >= best )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
break;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( gl_lms.allocated [ i + j ] > best2 )
|
|
|
|
{
|
|
|
|
best2 = gl_lms.allocated [ i + j ];
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
2010-10-22 08:04:31 +00:00
|
|
|
|
|
|
|
if ( j == w )
|
|
|
|
{
|
|
|
|
/* this is a valid spot */
|
2009-03-05 09:07:55 +00:00
|
|
|
*x = i;
|
|
|
|
*y = best = best2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( best + h > BLOCK_HEIGHT )
|
|
|
|
{
|
|
|
|
return ( false );
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
for ( i = 0; i < w; i++ )
|
|
|
|
{
|
|
|
|
gl_lms.allocated [ *x + i ] = best + h;
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
return ( true );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
void
|
|
|
|
GL_BuildPolygonFromSurface ( msurface_t *fa )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
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 */
|
2009-03-05 09:07:55 +00:00
|
|
|
pedges = currentmodel->edges;
|
|
|
|
lnumverts = fa->numedges;
|
|
|
|
vertpage = 0;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
VectorClear( total );
|
|
|
|
|
|
|
|
/* draw texture */
|
|
|
|
poly = Hunk_Alloc( sizeof ( glpoly_t ) + ( lnumverts - 4 ) * VERTEXSIZE * sizeof ( float ) );
|
2009-03-05 09:07:55 +00:00
|
|
|
poly->next = fa->polys;
|
|
|
|
poly->flags = fa->flags;
|
|
|
|
fa->polys = poly;
|
|
|
|
poly->numverts = lnumverts;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
for ( i = 0; i < lnumverts; i++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
lindex = currentmodel->surfedges [ fa->firstedge + i ];
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( lindex > 0 )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
r_pedge = &pedges [ lindex ];
|
|
|
|
vec = currentmodel->vertexes [ r_pedge->v [ 0 ] ].position;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
r_pedge = &pedges [ -lindex ];
|
|
|
|
vec = currentmodel->vertexes [ r_pedge->v [ 1 ] ].position;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
2010-10-22 08:04:31 +00:00
|
|
|
|
|
|
|
s = DotProduct( vec, fa->texinfo->vecs [ 0 ] ) + fa->texinfo->vecs [ 0 ] [ 3 ];
|
2009-03-05 09:07:55 +00:00
|
|
|
s /= fa->texinfo->image->width;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
t = DotProduct( vec, fa->texinfo->vecs [ 1 ] ) + fa->texinfo->vecs [ 1 ] [ 3 ];
|
2009-03-05 09:07:55 +00:00
|
|
|
t /= fa->texinfo->image->height;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
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;
|
2009-03-05 09:07:55 +00:00
|
|
|
s += 8;
|
2010-10-22 08:04:31 +00:00
|
|
|
s /= BLOCK_WIDTH * 16; /* fa->texinfo->texture->width; */
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
t = DotProduct( vec, fa->texinfo->vecs [ 1 ] ) + fa->texinfo->vecs [ 1 ] [ 3 ];
|
|
|
|
t -= fa->texturemins [ 1 ];
|
|
|
|
t += fa->light_t * 16;
|
2009-03-05 09:07:55 +00:00
|
|
|
t += 8;
|
2010-10-22 08:04:31 +00:00
|
|
|
t /= BLOCK_HEIGHT * 16; /* fa->texinfo->texture->height; */
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
poly->verts [ i ] [ 5 ] = s;
|
|
|
|
poly->verts [ i ] [ 6 ] = t;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
poly->numverts = lnumverts;
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
void
|
|
|
|
GL_CreateSurfaceLightmap ( msurface_t *surf )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
int smax, tmax;
|
|
|
|
byte *base;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( surf->flags & ( SURF_DRAWSKY | SURF_DRAWTURB ) )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
return;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
smax = ( surf->extents [ 0 ] >> 4 ) + 1;
|
|
|
|
tmax = ( surf->extents [ 1 ] >> 4 ) + 1;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
if ( !LM_AllocBlock( smax, tmax, &surf->light_s, &surf->light_t ) )
|
|
|
|
{
|
|
|
|
LM_UploadBlock( false );
|
|
|
|
LM_InitBlock();
|
2010-10-22 08:04:31 +00:00
|
|
|
|
2009-03-05 09:07:55 +00:00
|
|
|
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;
|
2010-10-22 08:04:31 +00:00
|
|
|
base += ( surf->light_t * BLOCK_WIDTH + surf->light_s ) * LIGHTMAP_BYTES;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
R_SetCacheState( surf );
|
2010-10-22 08:04:31 +00:00
|
|
|
R_BuildLightMap( surf, base, BLOCK_WIDTH * LIGHTMAP_BYTES );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
void
|
|
|
|
GL_BeginBuildingLightmaps ( model_t *m )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
static lightstyle_t lightstyles [ MAX_LIGHTSTYLES ];
|
|
|
|
int i;
|
|
|
|
unsigned dummy [ 128 * 128 ];
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
memset( gl_lms.allocated, 0, sizeof ( gl_lms.allocated ) );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
r_framecount = 1;/* no dlightcache */
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* 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++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
lightstyles [ i ].rgb [ 0 ] = 1;
|
|
|
|
lightstyles [ i ].rgb [ 1 ] = 1;
|
|
|
|
lightstyles [ i ].rgb [ 2 ] = 1;
|
|
|
|
lightstyles [ i ].white = 3;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
2010-10-22 08:04:31 +00:00
|
|
|
|
2009-03-05 09:07:55 +00:00
|
|
|
r_newrefdef.lightstyles = lightstyles;
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( !gl_state.lightmap_textures )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
gl_state.lightmap_textures = TEXNUM_LIGHTMAPS;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gl_lms.current_lightmap_texture = 1;
|
2010-10-22 08:20:49 +00:00
|
|
|
gl_lms.internal_format = gl_tex_solid_format;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* initialize the dynamic lightmap texture */
|
2009-03-05 09:07:55 +00:00
|
|
|
GL_Bind( gl_state.lightmap_textures + 0 );
|
2010-10-22 08:04:31 +00:00
|
|
|
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 );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
void
|
|
|
|
GL_EndBuildingLightmaps ( void )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
|
|
|
LM_UploadBlock( false );
|
|
|
|
}
|
|
|
|
|