2009-03-05 09:07:55 +00:00
|
|
|
/*
|
2010-10-22 08:13:03 +00:00
|
|
|
* Copyright (C) 1997-2001 Id Software, Inc.
|
|
|
|
*
|
2010-10-23 08:53:36 +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:13:03 +00:00
|
|
|
*
|
2010-10-23 08:53:36 +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:13:03 +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:53:36 +00:00
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
* 02111-1307, USA.
|
2010-10-22 08:13:03 +00:00
|
|
|
*
|
2010-10-23 08:53:36 +00:00
|
|
|
* =======================================================================
|
|
|
|
*
|
|
|
|
* Warps. Used on water surfaces und for skybox rotation.
|
|
|
|
*
|
|
|
|
* =======================================================================
|
2010-10-25 12:55:59 +00:00
|
|
|
*/
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
#include "header/local.h"
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
#define TURBSCALE ( 256.0 / ( 2 * M_PI ) )
|
|
|
|
#define SUBDIVIDE_SIZE 64
|
|
|
|
#define ON_EPSILON 0.1 /* point on plane side epsilon */
|
2010-10-25 12:55:59 +00:00
|
|
|
#define MAX_CLIP_VERTS 64
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
extern model_t *loadmodel;
|
|
|
|
char skyname [ MAX_QPATH ];
|
|
|
|
float skyrotate;
|
|
|
|
vec3_t skyaxis;
|
|
|
|
image_t *sky_images [ 6 ];
|
|
|
|
msurface_t *warpface;
|
|
|
|
int skytexorder [ 6 ] = { 0, 2, 1, 3, 4, 5 };
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
/* 3dstudio environment map names */
|
2010-10-25 12:55:59 +00:00
|
|
|
char *suf [ 6 ] = { "rt", "bk", "lf", "ft", "up", "dn" };
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
float r_turbsin[] = {
|
|
|
|
#include "constants/warpsin.h"
|
|
|
|
};
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
vec3_t skyclip [ 6 ] = {
|
|
|
|
{ 1, 1, 0 },
|
|
|
|
{ 1, -1, 0 },
|
|
|
|
{ 0, -1, 1 },
|
|
|
|
{ 0, 1, 1 },
|
|
|
|
{ 1, 0, 1 },
|
|
|
|
{ -1, 0, 1 }
|
|
|
|
};
|
|
|
|
int c_sky;
|
|
|
|
|
|
|
|
int st_to_vec [ 6 ] [ 3 ] = {
|
|
|
|
{ 3, -1, 2 },
|
|
|
|
{ -3, 1, 2 },
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
{ 1, 3, 2 },
|
|
|
|
{ -1, -3, 2 },
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
{ -2, -1, 3 }, /* 0 degrees yaw, look straight up */
|
|
|
|
{ 2, -1, -3 } /* look straight down */
|
|
|
|
};
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
int vec_to_st [ 6 ] [ 3 ] = {
|
|
|
|
{ -2, 3, 1 },
|
|
|
|
{ 2, 3, -1 },
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
{ 1, 3, 2 },
|
|
|
|
{ -1, 3, -2 },
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
{ -2, -1, 3 },
|
|
|
|
{ -2, 1, -3 }
|
|
|
|
};
|
|
|
|
|
|
|
|
float skymins [ 2 ] [ 6 ], skymaxs [ 2 ] [ 6 ];
|
|
|
|
float sky_min, sky_max;
|
2010-10-25 12:55:59 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
void
|
2010-10-23 08:53:36 +00:00
|
|
|
R_BoundPoly ( int numverts, float *verts, vec3_t mins, vec3_t maxs )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
int i, j;
|
|
|
|
float *v;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
mins [ 0 ] = mins [ 1 ] = mins [ 2 ] = 9999;
|
|
|
|
maxs [ 0 ] = maxs [ 1 ] = maxs [ 2 ] = -9999;
|
2009-03-05 09:07:55 +00:00
|
|
|
v = verts;
|
2010-10-22 08:13:03 +00:00
|
|
|
|
|
|
|
for ( i = 0; i < numverts; i++ )
|
|
|
|
{
|
|
|
|
for ( j = 0; j < 3; j++, v++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
if ( *v < mins [ j ] )
|
|
|
|
{
|
|
|
|
mins [ j ] = *v;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( *v > maxs [ j ] )
|
|
|
|
{
|
|
|
|
maxs [ j ] = *v;
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
void
|
2010-10-23 08:53:36 +00:00
|
|
|
R_SubdividePolygon ( int numverts, float *verts )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
int i, j, k;
|
|
|
|
vec3_t mins, maxs;
|
|
|
|
float m;
|
|
|
|
float *v;
|
|
|
|
vec3_t front [ 64 ], back [ 64 ];
|
|
|
|
int f, b;
|
|
|
|
float dist [ 64 ];
|
|
|
|
float frac;
|
|
|
|
glpoly_t *poly;
|
|
|
|
float s, t;
|
|
|
|
vec3_t total;
|
|
|
|
float total_s, total_t;
|
|
|
|
|
|
|
|
if ( numverts > 60 )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
ri.Sys_Error( ERR_DROP, "numverts = %i", numverts );
|
|
|
|
}
|
|
|
|
|
2010-10-23 08:53:36 +00:00
|
|
|
R_BoundPoly( numverts, verts, mins, maxs );
|
2010-10-22 08:13:03 +00:00
|
|
|
|
|
|
|
for ( i = 0; i < 3; i++ )
|
|
|
|
{
|
|
|
|
m = ( mins [ i ] + maxs [ i ] ) * 0.5;
|
|
|
|
m = SUBDIVIDE_SIZE * floor( m / SUBDIVIDE_SIZE + 0.5 );
|
|
|
|
|
|
|
|
if ( maxs [ i ] - m < 8 )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
continue;
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( m - mins [ i ] < 8 )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
continue;
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
/* cut it */
|
2009-03-05 09:07:55 +00:00
|
|
|
v = verts + i;
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
for ( j = 0; j < numverts; j++, v += 3 )
|
|
|
|
{
|
|
|
|
dist [ j ] = *v - m;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* wrap cases */
|
|
|
|
dist [ j ] = dist [ 0 ];
|
|
|
|
v -= i;
|
|
|
|
VectorCopy( verts, v );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
f = b = 0;
|
|
|
|
v = verts;
|
2010-10-22 08:13:03 +00:00
|
|
|
|
|
|
|
for ( j = 0; j < numverts; j++, v += 3 )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
if ( dist [ j ] >= 0 )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
VectorCopy( v, front [ f ] );
|
2009-03-05 09:07:55 +00:00
|
|
|
f++;
|
|
|
|
}
|
2010-10-22 08:13:03 +00:00
|
|
|
|
|
|
|
if ( dist [ j ] <= 0 )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
VectorCopy( v, back [ b ] );
|
2009-03-05 09:07:55 +00:00
|
|
|
b++;
|
|
|
|
}
|
2010-10-22 08:13:03 +00:00
|
|
|
|
|
|
|
if ( ( dist [ j ] == 0 ) || ( dist [ j + 1 ] == 0 ) )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
continue;
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( ( dist [ j ] > 0 ) != ( dist [ j + 1 ] > 0 ) )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
/* clip point */
|
|
|
|
frac = dist [ j ] / ( dist [ j ] - dist [ j + 1 ] );
|
|
|
|
|
|
|
|
for ( k = 0; k < 3; k++ )
|
|
|
|
{
|
|
|
|
front [ f ] [ k ] = back [ b ] [ k ] = v [ k ] + frac * ( v [ 3 + k ] - v [ k ] );
|
|
|
|
}
|
|
|
|
|
2009-03-05 09:07:55 +00:00
|
|
|
f++;
|
|
|
|
b++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-23 08:53:36 +00:00
|
|
|
R_SubdividePolygon( f, front [ 0 ] );
|
|
|
|
R_SubdividePolygon( b, back [ 0 ] );
|
2009-03-05 09:07:55 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
/* add a point in the center to help keep warp valid */
|
|
|
|
poly = Hunk_Alloc( sizeof ( glpoly_t ) + ( ( numverts - 4 ) + 2 ) * VERTEXSIZE * sizeof ( float ) );
|
2009-03-05 09:07:55 +00:00
|
|
|
poly->next = warpface->polys;
|
|
|
|
warpface->polys = poly;
|
2010-10-22 08:13:03 +00:00
|
|
|
poly->numverts = numverts + 2;
|
|
|
|
VectorClear( total );
|
2009-03-05 09:07:55 +00:00
|
|
|
total_s = 0;
|
|
|
|
total_t = 0;
|
2010-10-22 08:13:03 +00:00
|
|
|
|
|
|
|
for ( i = 0; i < numverts; i++, verts += 3 )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
VectorCopy( verts, poly->verts [ i + 1 ] );
|
|
|
|
s = DotProduct( verts, warpface->texinfo->vecs [ 0 ] );
|
|
|
|
t = DotProduct( verts, warpface->texinfo->vecs [ 1 ] );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
total_s += s;
|
|
|
|
total_t += t;
|
2010-10-22 08:13:03 +00:00
|
|
|
VectorAdd( total, verts, total );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
poly->verts [ i + 1 ] [ 3 ] = s;
|
|
|
|
poly->verts [ i + 1 ] [ 4 ] = t;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
VectorScale( total, ( 1.0 / numverts ), poly->verts [ 0 ] );
|
|
|
|
poly->verts [ 0 ] [ 3 ] = total_s / numverts;
|
|
|
|
poly->verts [ 0 ] [ 4 ] = total_t / numverts;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
/* copy first vertex to last */
|
|
|
|
memcpy( poly->verts [ i + 1 ], poly->verts [ 1 ], sizeof ( poly->verts [ 0 ] ) );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-10-22 08:13:03 +00:00
|
|
|
* Breaks a polygon up along axial 64 unit
|
|
|
|
* boundaries so that turbulent and sky warps
|
|
|
|
* can be done reasonably.
|
|
|
|
*/
|
|
|
|
void
|
2010-10-23 08:53:36 +00:00
|
|
|
R_SubdivideSurface ( msurface_t *fa )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
vec3_t verts [ 64 ];
|
|
|
|
int numverts;
|
|
|
|
int i;
|
|
|
|
int lindex;
|
|
|
|
float *vec;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
warpface = fa;
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
/* convert edges back to a normal polygon */
|
2009-03-05 09:07:55 +00:00
|
|
|
numverts = 0;
|
2010-10-22 08:13:03 +00:00
|
|
|
|
|
|
|
for ( i = 0; i < fa->numedges; i++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
lindex = loadmodel->surfedges [ fa->firstedge + i ];
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
if ( lindex > 0 )
|
|
|
|
{
|
|
|
|
vec = loadmodel->vertexes [ loadmodel->edges [ lindex ].v [ 0 ] ].position;
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
else
|
2010-10-22 08:13:03 +00:00
|
|
|
{
|
|
|
|
vec = loadmodel->vertexes [ loadmodel->edges [ -lindex ].v [ 1 ] ].position;
|
|
|
|
}
|
|
|
|
|
|
|
|
VectorCopy( vec, verts [ numverts ] );
|
2009-03-05 09:07:55 +00:00
|
|
|
numverts++;
|
|
|
|
}
|
|
|
|
|
2010-10-23 08:53:36 +00:00
|
|
|
R_SubdividePolygon( numverts, verts [ 0 ] );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-10-22 08:13:03 +00:00
|
|
|
* Does a water warp on the pre-fragmented glpoly_t chain
|
|
|
|
*/
|
|
|
|
void
|
2010-10-23 08:53:36 +00:00
|
|
|
R_EmitWaterPolys ( msurface_t *fa )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
glpoly_t *p, *bp;
|
|
|
|
float *v;
|
|
|
|
int i;
|
|
|
|
float s, t, os, ot;
|
|
|
|
float scroll;
|
|
|
|
float rdt = r_newrefdef.time;
|
|
|
|
|
|
|
|
if ( fa->texinfo->flags & SURF_FLOWING )
|
|
|
|
{
|
|
|
|
scroll = -64 * ( ( r_newrefdef.time * 0.5 ) - (int) ( r_newrefdef.time * 0.5 ) );
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
else
|
2010-10-22 08:13:03 +00:00
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
scroll = 0;
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for ( bp = fa->polys; bp; bp = bp->next )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
|
|
|
p = bp;
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
qglBegin( GL_TRIANGLE_FAN );
|
|
|
|
|
|
|
|
for ( i = 0, v = p->verts [ 0 ]; i < p->numverts; i++, v += VERTEXSIZE )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
os = v [ 3 ];
|
|
|
|
ot = v [ 4 ];
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
s = os + r_turbsin [ (int) ( ( ot * 0.125 + r_newrefdef.time ) * TURBSCALE ) & 255 ];
|
2009-03-05 09:07:55 +00:00
|
|
|
s += scroll;
|
2010-10-22 08:13:03 +00:00
|
|
|
s *= ( 1.0 / 64 );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
t = ot + r_turbsin [ (int) ( ( os * 0.125 + rdt ) * TURBSCALE ) & 255 ];
|
|
|
|
t *= ( 1.0 / 64 );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
qglTexCoord2f( s, t );
|
|
|
|
qglVertex3fv( v );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
2010-10-22 08:13:03 +00:00
|
|
|
|
|
|
|
qglEnd();
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
void
|
2010-10-23 08:53:36 +00:00
|
|
|
R_DrawSkyPolygon ( int nump, vec3_t vecs )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
int i, j;
|
|
|
|
vec3_t v, av;
|
|
|
|
float s, t, dv;
|
|
|
|
int axis;
|
|
|
|
float *vp;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
c_sky++;
|
2009-03-05 13:08:47 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
/* decide which face it maps to */
|
|
|
|
VectorCopy( vec3_origin, v );
|
|
|
|
|
|
|
|
for ( i = 0, vp = vecs; i < nump; i++, vp += 3 )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
VectorAdd( vp, v, v );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
2010-10-22 08:13:03 +00:00
|
|
|
|
|
|
|
av [ 0 ] = fabs( v [ 0 ] );
|
|
|
|
av [ 1 ] = fabs( v [ 1 ] );
|
|
|
|
av [ 2 ] = fabs( v [ 2 ] );
|
|
|
|
|
|
|
|
if ( ( av [ 0 ] > av [ 1 ] ) && ( av [ 0 ] > av [ 2 ] ) )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
if ( v [ 0 ] < 0 )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
axis = 1;
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
else
|
2010-10-22 08:13:03 +00:00
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
axis = 0;
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
2010-10-22 08:13:03 +00:00
|
|
|
else if ( ( av [ 1 ] > av [ 2 ] ) && ( av [ 1 ] > av [ 0 ] ) )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
if ( v [ 1 ] < 0 )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
axis = 3;
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
else
|
2010-10-22 08:13:03 +00:00
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
axis = 2;
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
if ( v [ 2 ] < 0 )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
axis = 5;
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
else
|
2010-10-22 08:13:03 +00:00
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
axis = 4;
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
/* project new texture coords */
|
|
|
|
for ( i = 0; i < nump; i++, vecs += 3 )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
j = vec_to_st [ axis ] [ 2 ];
|
|
|
|
|
|
|
|
if ( j > 0 )
|
|
|
|
{
|
|
|
|
dv = vecs [ j - 1 ];
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
else
|
2010-10-22 08:13:03 +00:00
|
|
|
{
|
|
|
|
dv = -vecs [ -j - 1 ];
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( dv < 0.001 )
|
|
|
|
{
|
|
|
|
continue; /* don't divide by zero */
|
|
|
|
}
|
|
|
|
|
|
|
|
j = vec_to_st [ axis ] [ 0 ];
|
|
|
|
|
|
|
|
if ( j < 0 )
|
|
|
|
{
|
|
|
|
s = -vecs [ -j - 1 ] / dv;
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
else
|
2010-10-22 08:13:03 +00:00
|
|
|
{
|
|
|
|
s = vecs [ j - 1 ] / dv;
|
|
|
|
}
|
|
|
|
|
|
|
|
j = vec_to_st [ axis ] [ 1 ];
|
|
|
|
|
|
|
|
if ( j < 0 )
|
|
|
|
{
|
|
|
|
t = -vecs [ -j - 1 ] / dv;
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
else
|
2010-10-22 08:13:03 +00:00
|
|
|
{
|
|
|
|
t = vecs [ j - 1 ] / dv;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( s < skymins [ 0 ] [ axis ] )
|
|
|
|
{
|
|
|
|
skymins [ 0 ] [ axis ] = s;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( t < skymins [ 1 ] [ axis ] )
|
|
|
|
{
|
|
|
|
skymins [ 1 ] [ axis ] = t;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( s > skymaxs [ 0 ] [ axis ] )
|
|
|
|
{
|
|
|
|
skymaxs [ 0 ] [ axis ] = s;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( t > skymaxs [ 1 ] [ axis ] )
|
|
|
|
{
|
|
|
|
skymaxs [ 1 ] [ axis ] = t;
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
void
|
2010-10-23 08:53:36 +00:00
|
|
|
R_ClipSkyPolygon ( int nump, vec3_t vecs, int stage )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
float *norm;
|
|
|
|
float *v;
|
|
|
|
qboolean front, back;
|
|
|
|
float d, e;
|
|
|
|
float dists [ MAX_CLIP_VERTS ];
|
|
|
|
int sides [ MAX_CLIP_VERTS ];
|
|
|
|
vec3_t newv [ 2 ] [ MAX_CLIP_VERTS ];
|
|
|
|
int newc [ 2 ];
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
if ( nump > MAX_CLIP_VERTS - 2 )
|
|
|
|
{
|
2010-10-23 08:53:36 +00:00
|
|
|
ri.Sys_Error( ERR_DROP, "R_ClipSkyPolygon: MAX_CLIP_VERTS" );
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( stage == 6 )
|
2010-10-25 12:55:59 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
/* fully clipped, so draw it */
|
2010-10-23 08:53:36 +00:00
|
|
|
R_DrawSkyPolygon( nump, vecs );
|
2009-03-05 09:07:55 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
front = back = false;
|
2010-10-22 08:13:03 +00:00
|
|
|
norm = skyclip [ stage ];
|
|
|
|
|
|
|
|
for ( i = 0, v = vecs; i < nump; i++, v += 3 )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
d = DotProduct( v, norm );
|
|
|
|
|
|
|
|
if ( d > ON_EPSILON )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
|
|
|
front = true;
|
2010-10-22 08:13:03 +00:00
|
|
|
sides [ i ] = SIDE_FRONT;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
2010-10-22 08:13:03 +00:00
|
|
|
else if ( d < -ON_EPSILON )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
|
|
|
back = true;
|
2010-10-22 08:13:03 +00:00
|
|
|
sides [ i ] = SIDE_BACK;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
else
|
2010-10-22 08:13:03 +00:00
|
|
|
{
|
|
|
|
sides [ i ] = SIDE_ON;
|
|
|
|
}
|
|
|
|
|
|
|
|
dists [ i ] = d;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
if ( !front || !back )
|
2010-10-25 12:55:59 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
/* not clipped */
|
2010-10-23 08:53:36 +00:00
|
|
|
R_ClipSkyPolygon( nump, vecs, stage + 1 );
|
2009-03-05 09:07:55 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
/* clip it */
|
|
|
|
sides [ i ] = sides [ 0 ];
|
|
|
|
dists [ i ] = dists [ 0 ];
|
|
|
|
VectorCopy( vecs, ( vecs + ( i * 3 ) ) );
|
|
|
|
newc [ 0 ] = newc [ 1 ] = 0;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
for ( i = 0, v = vecs; i < nump; i++, v += 3 )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
switch ( sides [ i ] )
|
|
|
|
{
|
|
|
|
case SIDE_FRONT:
|
|
|
|
VectorCopy( v, newv [ 0 ] [ newc [ 0 ] ] );
|
|
|
|
newc [ 0 ]++;
|
|
|
|
break;
|
|
|
|
case SIDE_BACK:
|
|
|
|
VectorCopy( v, newv [ 1 ] [ newc [ 1 ] ] );
|
|
|
|
newc [ 1 ]++;
|
|
|
|
break;
|
|
|
|
case SIDE_ON:
|
|
|
|
VectorCopy( v, newv [ 0 ] [ newc [ 0 ] ] );
|
|
|
|
newc [ 0 ]++;
|
|
|
|
VectorCopy( v, newv [ 1 ] [ newc [ 1 ] ] );
|
|
|
|
newc [ 1 ]++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ( sides [ i ] == SIDE_ON ) || ( sides [ i + 1 ] == SIDE_ON ) || ( sides [ i + 1 ] == sides [ i ] ) )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
continue;
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
d = dists [ i ] / ( dists [ i ] - dists [ i + 1 ] );
|
|
|
|
|
|
|
|
for ( j = 0; j < 3; j++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
e = v [ j ] + d * ( v [ j + 3 ] - v [ j ] );
|
|
|
|
newv [ 0 ] [ newc [ 0 ] ] [ j ] = e;
|
|
|
|
newv [ 1 ] [ newc [ 1 ] ] [ j ] = e;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
2010-10-22 08:13:03 +00:00
|
|
|
|
|
|
|
newc [ 0 ]++;
|
|
|
|
newc [ 1 ]++;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
/* continue */
|
2010-10-23 08:53:36 +00:00
|
|
|
R_ClipSkyPolygon( newc [ 0 ], newv [ 0 ] [ 0 ], stage + 1 );
|
|
|
|
R_ClipSkyPolygon( newc [ 1 ], newv [ 1 ] [ 0 ], stage + 1 );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
void
|
|
|
|
R_AddSkySurface ( msurface_t *fa )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
int i;
|
|
|
|
vec3_t verts [ MAX_CLIP_VERTS ];
|
|
|
|
glpoly_t *p;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
/* calculate vertex values for sky box */
|
|
|
|
for ( p = fa->polys; p; p = p->next )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
for ( i = 0; i < p->numverts; i++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
VectorSubtract( p->verts [ i ], r_origin, verts [ i ] );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
2010-10-22 08:13:03 +00:00
|
|
|
|
2010-10-23 08:53:36 +00:00
|
|
|
R_ClipSkyPolygon( p->numverts, verts [ 0 ], 0 );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
void
|
|
|
|
R_ClearSkyBox ( void )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
int i;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
for ( i = 0; i < 6; i++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
skymins [ 0 ] [ i ] = skymins [ 1 ] [ i ] = 9999;
|
|
|
|
skymaxs [ 0 ] [ i ] = skymaxs [ 1 ] [ i ] = -9999;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
void
|
2010-10-23 08:53:36 +00:00
|
|
|
R_MakeSkyVec ( float s, float t, int axis )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
vec3_t v, b;
|
|
|
|
int j, k;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
b [ 0 ] = s * 2300;
|
|
|
|
b [ 1 ] = t * 2300;
|
|
|
|
b [ 2 ] = 2300;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
for ( j = 0; j < 3; j++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
k = st_to_vec [ axis ] [ j ];
|
|
|
|
|
|
|
|
if ( k < 0 )
|
|
|
|
{
|
|
|
|
v [ j ] = -b [ -k - 1 ];
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
else
|
2010-10-22 08:13:03 +00:00
|
|
|
{
|
|
|
|
v [ j ] = b [ k - 1 ];
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
/* avoid bilerp seam */
|
|
|
|
s = ( s + 1 ) * 0.5;
|
|
|
|
t = ( t + 1 ) * 0.5;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
if ( s < sky_min )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
s = sky_min;
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
|
|
|
else if ( s > sky_max )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
s = sky_max;
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( t < sky_min )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
t = sky_min;
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
|
|
|
else if ( t > sky_max )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
t = sky_max;
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
|
|
|
t = 1.0 - t;
|
2010-10-22 08:13:03 +00:00
|
|
|
qglTexCoord2f( s, t );
|
|
|
|
qglVertex3fv( v );
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
void
|
|
|
|
R_DrawSkyBox ( void )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
int i;
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
if ( skyrotate )
|
|
|
|
{ /* check for no sky at all */
|
|
|
|
for ( i = 0; i < 6; i++ )
|
|
|
|
{
|
|
|
|
if ( ( skymins [ 0 ] [ i ] < skymaxs [ 0 ] [ i ] ) &&
|
|
|
|
( skymins [ 1 ] [ i ] < skymaxs [ 1 ] [ i ] ) )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
break;
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( i == 6 )
|
|
|
|
{
|
|
|
|
return; /* nothing visible */
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
qglPushMatrix();
|
|
|
|
qglTranslatef( r_origin [ 0 ], r_origin [ 1 ], r_origin [ 2 ] );
|
|
|
|
qglRotatef( r_newrefdef.time * skyrotate, skyaxis [ 0 ], skyaxis [ 1 ], skyaxis [ 2 ] );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
for ( i = 0; i < 6; i++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
if ( skyrotate )
|
2010-10-25 12:55:59 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
skymins [ 0 ] [ i ] = -1;
|
|
|
|
skymins [ 1 ] [ i ] = -1;
|
|
|
|
skymaxs [ 0 ] [ i ] = 1;
|
|
|
|
skymaxs [ 1 ] [ i ] = 1;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
if ( ( skymins [ 0 ] [ i ] >= skymaxs [ 0 ] [ i ] ) ||
|
|
|
|
( skymins [ 1 ] [ i ] >= skymaxs [ 1 ] [ i ] ) )
|
|
|
|
{
|
2009-03-05 09:07:55 +00:00
|
|
|
continue;
|
2010-10-22 08:13:03 +00:00
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 09:12:38 +00:00
|
|
|
R_Bind( sky_images [ skytexorder [ i ] ]->texnum );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
qglBegin( GL_QUADS );
|
2010-10-23 08:53:36 +00:00
|
|
|
R_MakeSkyVec( skymins [ 0 ] [ i ], skymins [ 1 ] [ i ], i );
|
|
|
|
R_MakeSkyVec( skymins [ 0 ] [ i ], skymaxs [ 1 ] [ i ], i );
|
|
|
|
R_MakeSkyVec( skymaxs [ 0 ] [ i ], skymaxs [ 1 ] [ i ], i );
|
|
|
|
R_MakeSkyVec( skymaxs [ 0 ] [ i ], skymins [ 1 ] [ i ], i );
|
2010-10-22 08:13:03 +00:00
|
|
|
qglEnd();
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
qglPopMatrix();
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
void
|
|
|
|
R_SetSky ( char *name, float rotate, vec3_t axis )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
int i;
|
|
|
|
char pathname [ MAX_QPATH ];
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
strncpy( skyname, name, sizeof ( skyname ) - 1 );
|
2009-03-05 09:07:55 +00:00
|
|
|
skyrotate = rotate;
|
2010-10-22 08:13:03 +00:00
|
|
|
VectorCopy( axis, skyaxis );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
for ( i = 0; i < 6; i++ )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-25 12:55:59 +00:00
|
|
|
if ( qglColorTableEXT && gl_ext_palettedtexture->value )
|
|
|
|
{
|
|
|
|
Com_sprintf( pathname, sizeof ( pathname ), "env/%s%s.pcx", skyname, suf [ i ] );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Com_sprintf( pathname, sizeof ( pathname ), "env/%s%s.tga", skyname, suf [ i ] );
|
|
|
|
}
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 09:12:38 +00:00
|
|
|
sky_images [ i ] = R_FindImage( pathname, it_sky );
|
2009-03-05 09:07:55 +00:00
|
|
|
|
2010-10-22 08:13:03 +00:00
|
|
|
if ( !sky_images [ i ] )
|
2009-03-05 09:07:55 +00:00
|
|
|
{
|
2010-10-22 08:13:03 +00:00
|
|
|
sky_images [ i ] = r_notexture;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
2010-10-22 08:13:03 +00:00
|
|
|
|
|
|
|
sky_min = 1.0 / 512;
|
|
|
|
sky_max = 511.0 / 512;
|
2009-03-05 09:07:55 +00:00
|
|
|
}
|
|
|
|
}
|
2009-03-05 13:08:47 +00:00
|
|
|
|