2009-03-05 09:07:55 +00:00
|
|
|
/*
|
2010-10-22 08:04:31 +00:00
|
|
|
* Copyright (C) 1997-2001 Id Software, Inc.
|
|
|
|
*
|
2010-10-23 08:24:28 +00:00
|
|
|
* 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.
|
2010-10-22 08:04:31 +00:00
|
|
|
*
|
2010-10-23 08:24:28 +00:00
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
2010-10-22 08:04:31 +00:00
|
|
|
* 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
|
2010-10-23 08:24:28 +00:00
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
* 02111-1307, USA.
|
2010-10-22 08:04:31 +00:00
|
|
|
*
|
2010-10-23 08:24:28 +00:00
|
|
|
* =======================================================================
|
|
|
|
*
|
|
|
|
* Surface generation and drawing
|
|
|
|
*
|
|
|
|
* =======================================================================
|
2010-10-25 12:33:55 +00:00
|
|
|
*/
|
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
|
|
|
|
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;
|
|
|
|
|
2010-10-23 08:24:28 +00:00
|
|
|
gllightmapstate_t gl_lms;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-23 08:24:28 +00:00
|
|
|
void LM_InitBlock ( void );
|
|
|
|
void LM_UploadBlock ( qboolean dynamic );
|
|
|
|
qboolean LM_AllocBlock ( int w, int h, int *x, int *y );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-23 08:24:28 +00:00
|
|
|
void R_SetCacheState ( msurface_t *surf );
|
|
|
|
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
|
2010-10-23 08:24:28 +00:00
|
|
|
R_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
|
2010-10-23 08:24:28 +00:00
|
|
|
R_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
|
2010-10-23 08:24:28 +00:00
|
|
|
R_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 )
|
|
|
|
{
|
2010-10-23 08:24:28 +00:00
|
|
|
fprintf( stderr, "BUGFIX: R_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-25 12:33:55 +00:00
|
|
|
* This routine takes all the given light mapped surfaces in the world
|
|
|
|
* and blends them into the framebuffer.
|
|
|
|
*/
|
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 */
|
2010-10-24 08:50:01 +00:00
|
|
|
if ( gl_fullbright->value )
|
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
|
|
|
}
|
|
|
|
|
|
|
|
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-25 12:33:55 +00:00
|
|
|
/* set the appropriate blending mode unless
|
|
|
|
* we're only looking at the lightmaps. */
|
2010-10-22 08:04:31 +00:00
|
|
|
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 09:12:38 +00:00
|
|
|
R_Bind( gl_state.lightmap_textures + i );
|
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
|
|
|
{
|
|
|
|
if ( surf->polys )
|
2010-10-22 08:04:31 +00:00
|
|
|
{
|
2010-10-23 08:24:28 +00:00
|
|
|
R_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 09:12:38 +00:00
|
|
|
R_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
|
|
|
{
|
2010-10-23 08:24:28 +00:00
|
|
|
R_DrawGLPolyChain( drawsurf->polys,
|
2010-10-22 08:04:31 +00:00
|
|
|
( 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
|
|
|
{
|
2010-10-23 08:24:28 +00:00
|
|
|
R_DrawGLPolyChain( surf->polys, ( surf->light_s - surf->dlight_s ) * ( 1.0 / 128.0 ),
|
2010-10-22 08:04:31 +00:00
|
|
|
( 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 )
|
|
|
|
{
|
2010-10-22 09:12:38 +00:00
|
|
|
R_Bind( image->texnum );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* warp texture, no lightmaps */
|
2010-10-22 09:12:38 +00:00
|
|
|
R_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 );
|
2010-10-23 08:53:36 +00:00
|
|
|
R_EmitWaterPolys( fa );
|
2010-10-22 09:12:38 +00:00
|
|
|
R_TexEnv( GL_REPLACE );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-10-22 09:12:38 +00:00
|
|
|
R_Bind( image->texnum );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 09:12:38 +00:00
|
|
|
R_TexEnv( GL_REPLACE );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( fa->texinfo->flags & SURF_FLOWING )
|
|
|
|
{
|
2010-10-23 08:24:28 +00:00
|
|
|
R_DrawGLFlowingPoly( fa );
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
else
|
2010-10-22 08:04:31 +00:00
|
|
|
{
|
2010-10-23 08:24:28 +00:00
|
|
|
R_DrawGLPoly( fa->polys );
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
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 */
|
2011-06-27 14:40:16 +00:00
|
|
|
if ( fa->dlightframe == r_framecount )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
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 );
|
|
|
|
|
2010-10-22 09:12:38 +00:00
|
|
|
R_Bind( gl_state.lightmap_textures + fa->lightmaptexturenum );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
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 );
|
2010-10-22 09:12:38 +00:00
|
|
|
R_TexEnv( GL_MODULATE );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
/* the textures are prescaled up for a better lighting range,
|
2010-10-25 12:33:55 +00:00
|
|
|
* 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 09:12:38 +00:00
|
|
|
R_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 )
|
|
|
|
{
|
2010-10-23 08:53:36 +00:00
|
|
|
R_EmitWaterPolys( s );
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
|
|
|
else if ( s->texinfo->flags & SURF_FLOWING )
|
|
|
|
{
|
2010-10-23 08:24:28 +00:00
|
|
|
R_DrawGLFlowingPoly( s );
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
else
|
2010-10-22 08:04:31 +00:00
|
|
|
{
|
2010-10-23 08:24:28 +00:00
|
|
|
R_DrawGLPoly( s->polys );
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 09:12:38 +00:00
|
|
|
R_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
|
2010-10-23 08:24:28 +00:00
|
|
|
R_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-25 12:33:55 +00:00
|
|
|
if ( !qglSelectTextureSGIS && !qglActiveTextureARB )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-25 12:33:55 +00:00
|
|
|
for ( i = 0, image = gltextures; i < numgltextures; i++, image++ )
|
2010-10-22 08:04:31 +00:00
|
|
|
{
|
2010-10-25 12:33:55 +00:00
|
|
|
if ( !image->registration_sequence )
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
s = image->texturechain;
|
|
|
|
|
|
|
|
if ( !s )
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
c_visible_textures++;
|
|
|
|
|
|
|
|
for ( ; s; s = s->texturechain )
|
|
|
|
{
|
|
|
|
R_RenderBrushPoly( s );
|
|
|
|
}
|
|
|
|
|
|
|
|
image->texturechain = NULL;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2010-10-25 12:33:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for ( i = 0, image = gltextures; i < numgltextures; i++, image++ )
|
|
|
|
{
|
|
|
|
if ( !image->registration_sequence )
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !image->texturechain )
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2010-10-22 08:04:31 +00:00
|
|
|
|
2010-10-25 12:33:55 +00:00
|
|
|
c_visible_textures++;
|
2010-10-22 08:04:31 +00:00
|
|
|
|
2010-10-25 12:33:55 +00:00
|
|
|
for ( s = image->texturechain; s; s = s->texturechain )
|
|
|
|
{
|
|
|
|
if ( !( s->flags & SURF_DRAWTURB ) )
|
|
|
|
{
|
|
|
|
R_RenderBrushPoly( s );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
R_EnableMultitexture( false );
|
|
|
|
|
|
|
|
for ( i = 0, image = gltextures; i < numgltextures; i++, image++ )
|
2010-10-22 08:04:31 +00:00
|
|
|
{
|
2010-10-25 12:33:55 +00:00
|
|
|
if ( !image->registration_sequence )
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
s = image->texturechain;
|
|
|
|
|
|
|
|
if ( !s )
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( ; s; s = s->texturechain )
|
|
|
|
{
|
|
|
|
if ( s->flags & SURF_DRAWTURB )
|
|
|
|
{
|
|
|
|
R_RenderBrushPoly( s );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
image->texturechain = NULL;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2010-10-25 12:33:55 +00:00
|
|
|
}
|
2010-10-22 08:04:31 +00:00
|
|
|
|
2010-10-25 12:33:55 +00:00
|
|
|
R_TexEnv( GL_REPLACE );
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
R_RenderLightmappedPoly ( msurface_t *surf )
|
|
|
|
{
|
|
|
|
int i, nv = surf->polys->numverts;
|
|
|
|
int map;
|
|
|
|
float *v;
|
|
|
|
image_t *image = R_TextureAnimation( surf->texinfo );
|
|
|
|
qboolean is_dynamic = false;
|
|
|
|
unsigned lmtex = surf->lightmaptexturenum;
|
|
|
|
glpoly_t *p;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-25 12:33:55 +00:00
|
|
|
for ( map = 0; map < MAXLIGHTMAPS && surf->styles [ map ] != 255; map++ )
|
|
|
|
{
|
|
|
|
if ( r_newrefdef.lightstyles [ surf->styles [ map ] ].white != surf->cached_light [ map ] )
|
2010-10-22 08:04:31 +00:00
|
|
|
{
|
2010-10-25 12:33:55 +00:00
|
|
|
goto dynamic;
|
2010-10-22 08:04:31 +00:00
|
|
|
}
|
2010-10-25 12:33:55 +00:00
|
|
|
}
|
|
|
|
|
2011-06-27 14:40:16 +00:00
|
|
|
if ( surf->dlightframe == r_framecount )
|
2010-10-25 12:33:55 +00:00
|
|
|
{
|
|
|
|
dynamic:
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-25 12:33:55 +00:00
|
|
|
if ( gl_dynamic->value )
|
|
|
|
{
|
|
|
|
if ( !( surf->texinfo->flags & ( SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP ) ) )
|
|
|
|
{
|
|
|
|
is_dynamic = true;
|
|
|
|
}
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-25 12:33:55 +00:00
|
|
|
if ( is_dynamic )
|
|
|
|
{
|
|
|
|
unsigned temp [ 128 * 128 ];
|
|
|
|
int smax, tmax;
|
|
|
|
|
|
|
|
if ( ( ( surf->styles [ map ] >= 32 ) || ( surf->styles [ map ] == 0 ) ) && ( surf->dlightframe != r_framecount ) )
|
|
|
|
{
|
|
|
|
smax = ( surf->extents [ 0 ] >> 4 ) + 1;
|
|
|
|
tmax = ( surf->extents [ 1 ] >> 4 ) + 1;
|
|
|
|
|
|
|
|
R_BuildLightMap( surf, (void *) temp, smax * 4 );
|
|
|
|
R_SetCacheState( surf );
|
|
|
|
|
|
|
|
R_MBind( QGL_TEXTURE1, gl_state.lightmap_textures + surf->lightmaptexturenum );
|
|
|
|
|
|
|
|
lmtex = surf->lightmaptexturenum;
|
|
|
|
|
|
|
|
qglTexSubImage2D( GL_TEXTURE_2D, 0,
|
|
|
|
surf->light_s, surf->light_t,
|
|
|
|
smax, tmax,
|
|
|
|
GL_LIGHTMAP_FORMAT,
|
|
|
|
GL_UNSIGNED_BYTE, temp );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
smax = ( surf->extents [ 0 ] >> 4 ) + 1;
|
|
|
|
tmax = ( surf->extents [ 1 ] >> 4 ) + 1;
|
|
|
|
|
|
|
|
R_BuildLightMap( surf, (void *) temp, smax * 4 );
|
|
|
|
|
|
|
|
R_MBind( QGL_TEXTURE1, gl_state.lightmap_textures + 0 );
|
|
|
|
|
|
|
|
lmtex = 0;
|
|
|
|
|
|
|
|
qglTexSubImage2D( GL_TEXTURE_2D, 0,
|
|
|
|
surf->light_s, surf->light_t,
|
|
|
|
smax, tmax,
|
|
|
|
GL_LIGHTMAP_FORMAT,
|
|
|
|
GL_UNSIGNED_BYTE, temp );
|
|
|
|
}
|
|
|
|
|
|
|
|
c_brush_polys++;
|
|
|
|
|
|
|
|
R_MBind( QGL_TEXTURE0, image->texnum );
|
|
|
|
R_MBind( QGL_TEXTURE1, gl_state.lightmap_textures + lmtex );
|
|
|
|
|
|
|
|
if ( surf->texinfo->flags & SURF_FLOWING )
|
|
|
|
{
|
|
|
|
float scroll;
|
|
|
|
|
|
|
|
scroll = -64 * ( ( r_newrefdef.time / 40.0 ) - (int) ( r_newrefdef.time / 40.0 ) );
|
|
|
|
|
|
|
|
if ( scroll == 0.0 )
|
|
|
|
{
|
|
|
|
scroll = -64.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( p = surf->polys; p; p = p->chain )
|
|
|
|
{
|
|
|
|
v = p->verts [ 0 ];
|
|
|
|
qglBegin( GL_POLYGON );
|
|
|
|
|
|
|
|
for ( i = 0; i < nv; i++, v += VERTEXSIZE )
|
|
|
|
{
|
|
|
|
qglMTexCoord2fSGIS( QGL_TEXTURE0, ( v [ 3 ] + scroll ), v [ 4 ] );
|
|
|
|
qglMTexCoord2fSGIS( QGL_TEXTURE1, v [ 5 ], v [ 6 ] );
|
|
|
|
qglVertex3fv( v );
|
|
|
|
}
|
|
|
|
|
|
|
|
qglEnd();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for ( p = surf->polys; p; p = p->chain )
|
|
|
|
{
|
|
|
|
v = p->verts [ 0 ];
|
|
|
|
qglBegin( GL_POLYGON );
|
|
|
|
|
|
|
|
for ( i = 0; i < nv; i++, v += VERTEXSIZE )
|
|
|
|
{
|
|
|
|
qglMTexCoord2fSGIS( QGL_TEXTURE0, v [ 3 ], v [ 4 ] );
|
|
|
|
qglMTexCoord2fSGIS( QGL_TEXTURE1, v [ 5 ], v [ 6 ] );
|
|
|
|
qglVertex3fv( v );
|
|
|
|
}
|
|
|
|
|
|
|
|
qglEnd();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
c_brush_polys++;
|
|
|
|
|
|
|
|
R_MBind( QGL_TEXTURE0, image->texnum );
|
|
|
|
R_MBind( QGL_TEXTURE1, gl_state.lightmap_textures + lmtex );
|
|
|
|
|
|
|
|
if ( surf->texinfo->flags & SURF_FLOWING )
|
|
|
|
{
|
|
|
|
float scroll;
|
|
|
|
|
|
|
|
scroll = -64 * ( ( r_newrefdef.time / 40.0 ) - (int) ( r_newrefdef.time / 40.0 ) );
|
|
|
|
|
|
|
|
if ( scroll == 0.0 )
|
|
|
|
{
|
|
|
|
scroll = -64.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( p = surf->polys; p; p = p->chain )
|
|
|
|
{
|
|
|
|
v = p->verts [ 0 ];
|
|
|
|
qglBegin( GL_POLYGON );
|
|
|
|
|
|
|
|
for ( i = 0; i < nv; i++, v += VERTEXSIZE )
|
|
|
|
{
|
|
|
|
qglMTexCoord2fSGIS( QGL_TEXTURE0, ( v [ 3 ] + scroll ), v [ 4 ] );
|
|
|
|
qglMTexCoord2fSGIS( QGL_TEXTURE1, v [ 5 ], v [ 6 ] );
|
|
|
|
qglVertex3fv( v );
|
|
|
|
}
|
|
|
|
|
|
|
|
qglEnd();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for ( p = surf->polys; p; p = p->chain )
|
|
|
|
{
|
|
|
|
v = p->verts [ 0 ];
|
|
|
|
qglBegin( GL_POLYGON );
|
|
|
|
|
|
|
|
for ( i = 0; i < nv; i++, v += VERTEXSIZE )
|
|
|
|
{
|
|
|
|
qglMTexCoord2fSGIS( QGL_TEXTURE0, v [ 3 ], v [ 4 ] );
|
|
|
|
qglMTexCoord2fSGIS( QGL_TEXTURE1, v [ 5 ], v [ 6 ] );
|
|
|
|
qglVertex3fv( v );
|
|
|
|
}
|
|
|
|
|
|
|
|
qglEnd();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
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 );
|
2010-10-22 09:12:38 +00:00
|
|
|
R_TexEnv( GL_MODULATE );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
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 ) )
|
2010-10-25 12:33:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
/* add to the translucent chain */
|
2009-03-05 09:07:55 +00:00
|
|
|
psurf->texturechain = r_alpha_surfaces;
|
|
|
|
r_alpha_surfaces = psurf;
|
|
|
|
}
|
2010-10-25 12:33:55 +00:00
|
|
|
else if ( qglMTexCoord2fSGIS && !( psurf->flags & SURF_DRAWTURB ) )
|
|
|
|
{
|
|
|
|
R_RenderLightmappedPoly( psurf );
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
else
|
|
|
|
{
|
2010-10-25 12:33:55 +00:00
|
|
|
R_EnableMultitexture( false );
|
2009-03-05 09:07:55 +00:00
|
|
|
R_RenderBrushPoly( psurf );
|
2010-10-25 12:33:55 +00:00
|
|
|
R_EnableMultitexture( true );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:04:31 +00:00
|
|
|
if ( !( currententity->flags & RF_TRANSLUCENT ) )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-25 12:33:55 +00:00
|
|
|
if ( !qglMTexCoord2fSGIS )
|
|
|
|
{
|
|
|
|
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 );
|
2010-10-22 09:12:38 +00:00
|
|
|
R_TexEnv( GL_REPLACE );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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 ];
|
2010-10-25 12:33:55 +00:00
|
|
|
e->angles [ 2 ] = -e->angles [ 2 ];
|
2010-10-22 08:04:31 +00:00
|
|
|
R_RotateForEntity( e );
|
2010-10-25 12:33:55 +00:00
|
|
|
e->angles [ 0 ] = -e->angles [ 0 ];
|
2010-10-22 08:04:31 +00:00
|
|
|
e->angles [ 2 ] = -e->angles [ 2 ];
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-25 12:33:55 +00:00
|
|
|
R_EnableMultitexture( true );
|
|
|
|
R_SelectTexture( QGL_TEXTURE0 );
|
2010-10-22 09:12:38 +00:00
|
|
|
R_TexEnv( GL_REPLACE );
|
2010-10-25 12:33:55 +00:00
|
|
|
R_SelectTexture( QGL_TEXTURE1 );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-25 13:21:52 +00:00
|
|
|
if ( !gl_config.mtexcombine )
|
|
|
|
{
|
|
|
|
R_TexEnv( GL_REPLACE );
|
|
|
|
R_SelectTexture( GL_TEXTURE1 );
|
|
|
|
|
|
|
|
if ( gl_lightmap->value )
|
|
|
|
{
|
|
|
|
R_TexEnv( GL_REPLACE );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
R_TexEnv( GL_MODULATE );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
R_TexEnv( GL_COMBINE_EXT );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
|
|
|
|
R_SelectTexture( GL_TEXTURE1 );
|
|
|
|
R_TexEnv( GL_COMBINE_EXT );
|
|
|
|
|
|
|
|
if ( gl_lightmap->value )
|
|
|
|
{
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( gl_overbrightbits->value )
|
|
|
|
{
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, gl_overbrightbits->value );
|
|
|
|
}
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2012-02-09 15:11:35 +00:00
|
|
|
R_DrawInlineBModel();
|
|
|
|
R_EnableMultitexture( false );
|
|
|
|
|
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-25 12:33:55 +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 )
|
2010-10-25 12:33:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
/* 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 ) )
|
2010-10-25 12:33:55 +00:00
|
|
|
{
|
2010-10-22 08:04:31 +00:00
|
|
|
/* 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-25 12:33:55 +00:00
|
|
|
if ( qglMTexCoord2fSGIS && !( surf->flags & SURF_DRAWTURB ) )
|
|
|
|
{
|
|
|
|
R_RenderLightmappedPoly( surf );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* the polygon is visible, so add it to the texture sorted chain */
|
|
|
|
image = R_TextureAnimation( surf->texinfo );
|
|
|
|
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-24 08:50:01 +00:00
|
|
|
if ( !gl_drawworld->value )
|
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
|
|
|
|
|
|
|
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();
|
2010-10-25 12:33:55 +00:00
|
|
|
|
|
|
|
if ( qglMTexCoord2fSGIS )
|
|
|
|
{
|
|
|
|
R_EnableMultitexture( true );
|
|
|
|
|
|
|
|
R_SelectTexture( QGL_TEXTURE0 );
|
|
|
|
R_TexEnv( GL_REPLACE );
|
|
|
|
R_SelectTexture( QGL_TEXTURE1 );
|
|
|
|
|
2010-10-25 13:21:52 +00:00
|
|
|
if ( !gl_config.mtexcombine )
|
2010-10-25 12:33:55 +00:00
|
|
|
{
|
|
|
|
R_TexEnv( GL_REPLACE );
|
2010-10-25 13:21:52 +00:00
|
|
|
R_SelectTexture( GL_TEXTURE1 );
|
|
|
|
|
|
|
|
if ( gl_lightmap->value )
|
|
|
|
{
|
|
|
|
R_TexEnv( GL_REPLACE );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
R_TexEnv( GL_MODULATE );
|
|
|
|
}
|
2010-10-25 12:33:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-10-25 13:21:52 +00:00
|
|
|
R_TexEnv( GL_COMBINE_EXT );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
|
|
|
|
R_SelectTexture( GL_TEXTURE1 );
|
|
|
|
R_TexEnv( GL_COMBINE_EXT );
|
|
|
|
|
|
|
|
if ( gl_lightmap->value )
|
|
|
|
{
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( gl_overbrightbits->value )
|
|
|
|
{
|
|
|
|
qglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, gl_overbrightbits->value );
|
|
|
|
}
|
2010-10-25 12:33:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
R_RecursiveWorldNode( r_worldmodel->nodes );
|
|
|
|
R_EnableMultitexture( false );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
R_RecursiveWorldNode( r_worldmodel->nodes );
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-23 08:24:28 +00:00
|
|
|
R_DrawTextureChains();
|
2010-10-22 08:04:31 +00:00
|
|
|
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;
|
|
|
|
|
2010-10-24 08:50:01 +00:00
|
|
|
if ( ( r_oldviewcluster == r_viewcluster ) && ( r_oldviewcluster2 == r_viewcluster2 ) && !gl_novis->value &&
|
2010-10-22 08:04:31 +00:00
|
|
|
( 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
|
2010-10-25 12:33:55 +00:00
|
|
|
* the pvs ends */
|
2010-10-22 08:04:31 +00:00
|
|
|
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-24 08:50:01 +00:00
|
|
|
if ( gl_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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|