mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-25 13:21:36 +00:00
Initial checkin of OpenGL renderer
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
f64029bbc8
commit
8aa0eee611
22 changed files with 27620 additions and 0 deletions
949
engine/gl/LTFACE.C
Normal file
949
engine/gl/LTFACE.C
Normal file
|
@ -0,0 +1,949 @@
|
|||
#include "bothdefs.h"
|
||||
|
||||
#if defined(GLQUAKE) || (!defined(GLQUAKE) && !defined(SWQUAKE))
|
||||
|
||||
#ifdef RUNTIMELIGHTING
|
||||
#if defined(GLQUAKE)
|
||||
#include "quakedef.h"
|
||||
|
||||
|
||||
extern model_t *lightmodel;
|
||||
#define bsptexinfo(i) (*i)
|
||||
#define dsurfedges lightmodel->surfedges
|
||||
#define dvertexes lightmodel->vertexes
|
||||
#define dedges lightmodel->edges
|
||||
#define texinfo_t mtexinfo_t
|
||||
#define Q_PI M_PI
|
||||
#define Error Host_Error
|
||||
#define byte qbyte
|
||||
|
||||
#define dfaces lightmodel->surfaces
|
||||
#define dplanes lightmodel->planes
|
||||
#define dface_t msurface_t
|
||||
#define dvertex_t mvertex_t
|
||||
#define point position
|
||||
|
||||
#define side flags & SURF_PLANEBACK
|
||||
|
||||
#define scaledist 1
|
||||
#define rangescale 0.5
|
||||
#define extrasamples 1
|
||||
#define scalecos 0.5
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct mentity_s {
|
||||
vec3_t origin;
|
||||
float light;
|
||||
float angle;
|
||||
float cone;
|
||||
int style;
|
||||
vec3_t colour;
|
||||
char classname[64];
|
||||
char target[64];
|
||||
char targetname[64];
|
||||
|
||||
struct mentity_s *targetent;
|
||||
} mentity_t;
|
||||
|
||||
static mentity_t entities[8192];
|
||||
static int num_entities;
|
||||
|
||||
#define bsp_origin vec3_origin
|
||||
|
||||
/*
|
||||
============
|
||||
CastRay
|
||||
|
||||
Returns the distance between the points, or -1 if blocked
|
||||
=============
|
||||
*/
|
||||
vec_t CastRay (vec3_t p1, vec3_t p2)
|
||||
{
|
||||
trace_t trace;
|
||||
vec3_t move;
|
||||
hull_t *hull;
|
||||
|
||||
hull = &lightmodel->hulls[0];
|
||||
memset (&trace, 0, sizeof(trace));
|
||||
if (!hull->funcs.RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, p1, p2, &trace))
|
||||
return -1;
|
||||
|
||||
VectorSubtract(p1, p2, move);
|
||||
return VectorLength(move);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void ParseEpair (mentity_t *mapent, char *key, char *value)
|
||||
{
|
||||
double vec[3];
|
||||
|
||||
if (!strcmp(key, "classname"))
|
||||
strcpy(mapent->classname, value);
|
||||
|
||||
else if (!strcmp(key, "target"))
|
||||
strcpy(mapent->target, value);
|
||||
|
||||
else if (!strcmp(key, "targetname"))
|
||||
strcpy(mapent->targetname, value);
|
||||
|
||||
else if (!strcmp(key, "light") || !strcmp(key, "_light"))
|
||||
mapent->light = atoi(value);
|
||||
|
||||
else if (!strcmp(key, "style") || !strcmp(key, "_style"))
|
||||
mapent->style = atoi(value);
|
||||
|
||||
else if (!strcmp(key, "angle") || !strcmp(key, "_angle"))
|
||||
mapent->angle = atof(value);
|
||||
|
||||
else if (!strcmp(key, "cone") || !strcmp(key, "_cone"))
|
||||
mapent->cone = atof(value);
|
||||
|
||||
else if (!strcmp(key, "origin"))
|
||||
{
|
||||
sscanf (value, "%lf %lf %lf", &vec[0], &vec[1], &vec[2]);
|
||||
mapent->origin[0]=vec[0];
|
||||
mapent->origin[1]=vec[1];
|
||||
mapent->origin[2]=vec[2];
|
||||
}
|
||||
|
||||
else if (!strcmp(key, "colour") || !strcmp(key, "color") || !strcmp(key, "_colour") || !strcmp(key, "_color"))
|
||||
{
|
||||
sscanf (value, "%lf %lf %lf", &vec[0], &vec[1], &vec[2]);
|
||||
mapent->colour[0]=vec[0];
|
||||
mapent->colour[1]=vec[1];
|
||||
mapent->colour[2]=vec[2];
|
||||
}
|
||||
}
|
||||
|
||||
void LightLoadEntities(char *entstring)
|
||||
{
|
||||
#define DEFAULTLIGHTLEVEL 300
|
||||
mentity_t *mapent;
|
||||
char key[1024];
|
||||
int i;
|
||||
int switchedstyle=32;
|
||||
num_entities = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
entstring = COM_Parse(entstring);
|
||||
if (!entstring || !*com_token)
|
||||
break;
|
||||
if (strcmp(com_token, "{"))
|
||||
Host_Error("token wasn't an open brace\n");
|
||||
|
||||
mapent = &entities[num_entities];
|
||||
memset(mapent, 0, sizeof(*mapent));
|
||||
mapent->colour[0] = 0;
|
||||
mapent->colour[1] = 0;
|
||||
mapent->colour[2] = 0;
|
||||
while(1)
|
||||
{
|
||||
entstring = COM_Parse(entstring);
|
||||
if (!strcmp(com_token, "}"))
|
||||
break;
|
||||
strcpy(key, com_token);
|
||||
entstring = COM_Parse(entstring);
|
||||
ParseEpair(mapent, key, com_token);
|
||||
}
|
||||
if (!mapent->colour[0] && !mapent->colour[1] && !mapent->colour[2])
|
||||
{
|
||||
int cont;
|
||||
vec3_t v;
|
||||
hull_t *hull = &lightmodel->hulls[0];
|
||||
v[0] = mapent->origin[0];
|
||||
v[1] = mapent->origin[1];
|
||||
cont=0;
|
||||
for (i = 0; i < 256; i+=16)
|
||||
{
|
||||
v[2] = mapent->origin[2]-i;
|
||||
cont = hull->funcs.HullPointContents (hull, v);
|
||||
if (cont & (FTECONTENTS_LAVA | FTECONTENTS_SLIME | FTECONTENTS_SOLID))
|
||||
break;
|
||||
}
|
||||
if (cont & FTECONTENTS_LAVA)
|
||||
{
|
||||
mapent->colour[0] = 1;
|
||||
mapent->colour[1] = i/256.0;
|
||||
mapent->colour[2] = i/256.0;
|
||||
}
|
||||
else if (cont & FTECONTENTS_SLIME)
|
||||
{
|
||||
mapent->colour[0] = 0.5+0.5*i/256.0;
|
||||
mapent->colour[1] = 1;
|
||||
mapent->colour[2] = 0.5+0.5*i/256.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mapent->style == 9) //hmm..
|
||||
{
|
||||
mapent->colour[1] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!strncmp(mapent->classname, "light_torch_small_walltorch", 12))
|
||||
{
|
||||
mapent->colour[0] = 1;
|
||||
mapent->colour[1] = 0.7;
|
||||
mapent->colour[2] = 0.7;
|
||||
}
|
||||
else
|
||||
{
|
||||
mapent->colour[0] = 1;
|
||||
mapent->colour[1] = 1;
|
||||
if (strncmp(mapent->classname, "light_fluoro", 12))
|
||||
mapent->colour[2] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mapent->light && !strncmp (mapent->classname, "light", 5))
|
||||
mapent->light = DEFAULTLIGHTLEVEL;
|
||||
|
||||
if (*mapent->targetname && !mapent->style && !strcmp(mapent->classname, "light"))
|
||||
{
|
||||
for (i = 0; i <= num_entities; i++)
|
||||
{
|
||||
if (entities[i].style >= 32 && !strcmp(entities[i].targetname, mapent->targetname))
|
||||
{
|
||||
mapent->style = entities[i].style;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == num_entities)
|
||||
mapent->style = switchedstyle++;
|
||||
}
|
||||
|
||||
|
||||
num_entities++;
|
||||
}
|
||||
|
||||
for (mapent = entities; mapent < &entities[num_entities]; mapent++)
|
||||
{
|
||||
if (*mapent->target)
|
||||
{
|
||||
for (i = 0; i < num_entities; i++)
|
||||
{
|
||||
if (mapent == &entities[i])
|
||||
continue;
|
||||
|
||||
if (!strcmp(mapent->target, entities[i].targetname))
|
||||
{
|
||||
mapent->targetent = &entities[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#define mentity_t entity_t
|
||||
#define UTILITY
|
||||
#include "light.h"
|
||||
|
||||
#define bsptexinfo(i) texinfo[i]
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
CastRay
|
||||
|
||||
Returns the distance between the points, or -1 if blocked
|
||||
=============
|
||||
*/
|
||||
vec_t CastRay (vec3_t p1, vec3_t p2)
|
||||
{
|
||||
int i;
|
||||
vec_t t;
|
||||
qboolean trace;
|
||||
|
||||
trace = TestLine (p1, p2);
|
||||
|
||||
if (!trace)
|
||||
return -1; // ray was blocked
|
||||
|
||||
t = 0;
|
||||
for (i=0 ; i< 3 ; i++)
|
||||
t += (p2[i]-p1[i]) * (p2[i]-p1[i]);
|
||||
|
||||
if (t < 1)
|
||||
t = 1; // don't blow up...
|
||||
return sqrt(t);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
SAMPLE POINT DETERMINATION
|
||||
|
||||
void SetupBlock (dface_t *f) Returns with surfpt[] set
|
||||
|
||||
This is a little tricky because the lightmap covers more area than the face.
|
||||
If done in the straightforward fashion, some of the
|
||||
sample points will be inside walls or on the other side of walls, causing
|
||||
false shadows and light bleeds.
|
||||
|
||||
To solve this, I only consider a sample point valid if a line can be drawn
|
||||
between it and the exact midpoint of the face. If invalid, it is adjusted
|
||||
towards the center until it is valid.
|
||||
|
||||
(this doesn't completely work)
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
#define SINGLEMAP (18*18*4)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t lightmaps[MAXLIGHTMAPS][SINGLEMAP];
|
||||
vec3_t lightnorm[MAXLIGHTMAPS][SINGLEMAP];
|
||||
int numlightstyles;
|
||||
vec_t *light;
|
||||
vec_t facedist;
|
||||
vec3_t facenormal;
|
||||
|
||||
int numsurfpt;
|
||||
vec3_t surfpt[SINGLEMAP];
|
||||
|
||||
vec3_t texorg;
|
||||
vec3_t worldtotex[2]; // s = (world - texorg) . worldtotex[0]
|
||||
vec3_t textoworld[2]; // world = texorg + s * textoworld[0]
|
||||
|
||||
vec_t exactmins[2], exactmaxs[2];
|
||||
|
||||
int texmins[2], texsize[2];
|
||||
int lightstyles[256];
|
||||
int surfnum;
|
||||
dface_t *face;
|
||||
} llightinfo_t;
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
CalcFaceVectors
|
||||
|
||||
Fills in texorg, worldtotex. and textoworld
|
||||
================
|
||||
*/
|
||||
static void LightCalcFaceVectors (llightinfo_t *l)
|
||||
{
|
||||
texinfo_t *tex;
|
||||
int i, j;
|
||||
vec3_t texnormal;
|
||||
float distscale;
|
||||
vec_t dist, len;
|
||||
|
||||
tex = &bsptexinfo(l->face->texinfo);
|
||||
|
||||
// convert from float to vec_t
|
||||
for (i=0 ; i<2 ; i++)
|
||||
for (j=0 ; j<3 ; j++)
|
||||
l->worldtotex[i][j] = tex->vecs[i][j];
|
||||
|
||||
// calculate a normal to the texture axis. points can be moved along this
|
||||
// without changing their S/T
|
||||
texnormal[0] = tex->vecs[1][1]*tex->vecs[0][2]
|
||||
- tex->vecs[1][2]*tex->vecs[0][1];
|
||||
texnormal[1] = tex->vecs[1][2]*tex->vecs[0][0]
|
||||
- tex->vecs[1][0]*tex->vecs[0][2];
|
||||
texnormal[2] = tex->vecs[1][0]*tex->vecs[0][1]
|
||||
- tex->vecs[1][1]*tex->vecs[0][0];
|
||||
VectorNormalize (texnormal);
|
||||
|
||||
// flip it towards plane normal
|
||||
distscale = DotProduct (texnormal, l->facenormal);
|
||||
if (!distscale)
|
||||
Error ("Texture axis perpendicular to face");
|
||||
if (distscale < 0)
|
||||
{
|
||||
distscale = -distscale;
|
||||
VectorSubtract (vec3_origin, texnormal, texnormal);
|
||||
}
|
||||
|
||||
// distscale is the ratio of the distance along the texture normal to
|
||||
// the distance along the plane normal
|
||||
distscale = 1/distscale;
|
||||
|
||||
for (i=0 ; i<2 ; i++)
|
||||
{
|
||||
len = VectorLength (l->worldtotex[i]);
|
||||
dist = DotProduct (l->worldtotex[i], l->facenormal);
|
||||
dist *= distscale;
|
||||
VectorMA (l->worldtotex[i], -dist, texnormal, l->textoworld[i]);
|
||||
VectorScale (l->textoworld[i], (1/len)*(1/len), l->textoworld[i]);
|
||||
}
|
||||
|
||||
|
||||
// calculate texorg on the texture plane
|
||||
for (i=0 ; i<3 ; i++)
|
||||
l->texorg[i] = -tex->vecs[0][3]* l->textoworld[0][i] - tex->vecs[1][3] * l->textoworld[1][i];
|
||||
|
||||
// project back to the face plane
|
||||
dist = DotProduct (l->texorg, l->facenormal) - l->facedist - 1;
|
||||
dist *= distscale;
|
||||
VectorMA (l->texorg, -dist, texnormal, l->texorg);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CalcFaceExtents
|
||||
|
||||
Fills in s->texmins[] and s->texsize[]
|
||||
also sets exactmins[] and exactmaxs[]
|
||||
================
|
||||
*/
|
||||
static void LightCalcFaceExtents (llightinfo_t *l)
|
||||
{
|
||||
dface_t *s;
|
||||
vec_t mins[2], maxs[2], val;
|
||||
int i,j, e;
|
||||
dvertex_t *v;
|
||||
texinfo_t *tex;
|
||||
|
||||
s = l->face;
|
||||
|
||||
mins[0] = mins[1] = 999999;
|
||||
maxs[0] = maxs[1] = -99999;
|
||||
|
||||
tex = &bsptexinfo(s->texinfo);
|
||||
|
||||
for (i=0 ; i<s->numedges ; i++)
|
||||
{
|
||||
e = dsurfedges[s->firstedge+i];
|
||||
if (e >= 0)
|
||||
v = dvertexes + dedges[e].v[0];
|
||||
else
|
||||
v = dvertexes + dedges[-e].v[1];
|
||||
|
||||
for (j=0 ; j<2 ; j++)
|
||||
{
|
||||
val = v->point[0] * tex->vecs[j][0] +
|
||||
v->point[1] * tex->vecs[j][1] +
|
||||
v->point[2] * tex->vecs[j][2] +
|
||||
tex->vecs[j][3];
|
||||
if (val < mins[j])
|
||||
mins[j] = val;
|
||||
if (val > maxs[j])
|
||||
maxs[j] = val;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0 ; i<2 ; i++)
|
||||
{
|
||||
l->exactmins[i] = mins[i];
|
||||
l->exactmaxs[i] = maxs[i];
|
||||
|
||||
mins[i] = floor(mins[i]/16);
|
||||
maxs[i] = ceil(maxs[i]/16);
|
||||
|
||||
l->texmins[i] = mins[i];
|
||||
l->texsize[i] = maxs[i] - mins[i];
|
||||
if (l->texsize[i] > 17)
|
||||
Error ("Bad surface extents");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CalcPoints
|
||||
|
||||
For each texture aligned grid point, back project onto the plane
|
||||
to get the world xyz value of the sample point
|
||||
=================
|
||||
*/
|
||||
int c_bad;
|
||||
static void LightCalcPoints (llightinfo_t *l)
|
||||
{
|
||||
int i;
|
||||
int s, t, j;
|
||||
int w, h, step;
|
||||
vec_t starts, startt, us, ut;
|
||||
vec_t *surf;
|
||||
vec_t mids, midt;
|
||||
vec3_t facemid, move;
|
||||
|
||||
//
|
||||
// fill in surforg
|
||||
// the points are biased towards the center of the surface
|
||||
// to help avoid edge cases just inside walls
|
||||
//
|
||||
surf = l->surfpt[0];
|
||||
mids = (l->exactmaxs[0] + l->exactmins[0])/2;
|
||||
midt = (l->exactmaxs[1] + l->exactmins[1])/2;
|
||||
|
||||
for (j=0 ; j<3 ; j++)
|
||||
facemid[j] = l->texorg[j] + l->textoworld[0][j]*mids + l->textoworld[1][j]*midt;
|
||||
|
||||
if (extrasamples)
|
||||
{ // extra filtering
|
||||
h = (l->texsize[1]+1)*2;
|
||||
w = (l->texsize[0]+1)*2;
|
||||
starts = (l->texmins[0]-0.5)*16;
|
||||
startt = (l->texmins[1]-0.5)*16;
|
||||
step = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = l->texsize[1]+1;
|
||||
w = l->texsize[0]+1;
|
||||
starts = l->texmins[0]*16;
|
||||
startt = l->texmins[1]*16;
|
||||
step = 16;
|
||||
}
|
||||
|
||||
l->numsurfpt = w * h;
|
||||
for (t=0 ; t<h ; t++)
|
||||
{
|
||||
for (s=0 ; s<w ; s++, surf+=3)
|
||||
{
|
||||
us = starts + s*step;
|
||||
ut = startt + t*step;
|
||||
|
||||
// if a line can be traced from surf to facemid, the point is good
|
||||
for (i=0 ; i<6 ; i++)
|
||||
{
|
||||
// calculate texture point
|
||||
for (j=0 ; j<3 ; j++)
|
||||
surf[j] = l->texorg[j] + l->textoworld[0][j]*us
|
||||
+ l->textoworld[1][j]*ut;
|
||||
|
||||
if (CastRay (facemid, surf) != -1)
|
||||
break; // got it
|
||||
if (i & 1)
|
||||
{
|
||||
if (us > mids)
|
||||
{
|
||||
us -= 8;
|
||||
if (us < mids)
|
||||
us = mids;
|
||||
}
|
||||
else
|
||||
{
|
||||
us += 8;
|
||||
if (us > mids)
|
||||
us = mids;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ut > midt)
|
||||
{
|
||||
ut -= 8;
|
||||
if (ut < midt)
|
||||
ut = midt;
|
||||
}
|
||||
else
|
||||
{
|
||||
ut += 8;
|
||||
if (ut > midt)
|
||||
ut = midt;
|
||||
}
|
||||
}
|
||||
|
||||
// move surf 8 pixels towards the center
|
||||
VectorSubtract (facemid, surf, move);
|
||||
VectorNormalize (move);
|
||||
VectorMA (surf, 8, move, surf);
|
||||
}
|
||||
if (i == 2)
|
||||
c_bad++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
FACE LIGHTING
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
int c_culldistplane, c_proper;
|
||||
|
||||
/*
|
||||
================
|
||||
SingleLightFace
|
||||
================
|
||||
*/
|
||||
static void SingleLightFace (mentity_t *light, llightinfo_t *l)
|
||||
{
|
||||
vec_t dist;
|
||||
vec3_t incoming;
|
||||
vec_t angle;
|
||||
vec_t add;
|
||||
vec_t *surf;
|
||||
qboolean hit;
|
||||
int mapnum;
|
||||
int size;
|
||||
int c, i;
|
||||
vec3_t rel;
|
||||
vec3_t spotvec;
|
||||
vec_t falloff;
|
||||
vec3_t *lightsamp;
|
||||
vec3_t *norms;
|
||||
|
||||
VectorSubtract (light->origin, bsp_origin, rel);
|
||||
dist = scaledist * (DotProduct (rel, l->facenormal) - l->facedist);
|
||||
|
||||
// don't bother with lights behind the surface
|
||||
if (dist <= 0)
|
||||
return;
|
||||
|
||||
// don't bother with light too far away
|
||||
if (dist > light->light)
|
||||
{
|
||||
c_culldistplane++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (light->targetent)
|
||||
{
|
||||
VectorSubtract (light->targetent->origin, light->origin, spotvec);
|
||||
VectorNormalize (spotvec);
|
||||
if (!light->angle)
|
||||
falloff = -cos(20*Q_PI/180);
|
||||
else
|
||||
falloff = -cos(light->angle/2*Q_PI/180);
|
||||
}
|
||||
else
|
||||
falloff = 0; // shut up compiler warnings
|
||||
|
||||
mapnum = 0;
|
||||
for (mapnum=0 ; mapnum<l->numlightstyles ; mapnum++)
|
||||
if (l->lightstyles[mapnum] == light->style)
|
||||
break;
|
||||
|
||||
lightsamp = l->lightmaps[mapnum];
|
||||
norms = l->lightnorm[mapnum];
|
||||
if (mapnum == l->numlightstyles)
|
||||
{ // init a new light map
|
||||
if (mapnum == MAXLIGHTMAPS)
|
||||
{
|
||||
printf ("WARNING: Too many light styles on a face\n");
|
||||
return;
|
||||
}
|
||||
size = (l->texsize[1]+1)*(l->texsize[0]+1);
|
||||
for (i=0 ; i<size ; i++)
|
||||
{
|
||||
lightsamp[i][0] = 0;
|
||||
lightsamp[i][1] = 0;
|
||||
lightsamp[i][2] = 0;
|
||||
norms[i][0] = 0;
|
||||
norms[i][1] = 0;
|
||||
norms[i][2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// check it for real
|
||||
//
|
||||
hit = false;
|
||||
c_proper++;
|
||||
|
||||
surf = l->surfpt[0];
|
||||
for (c=0 ; c<l->numsurfpt ; c++, surf+=3)
|
||||
{
|
||||
dist = CastRay(light->origin, surf)*scaledist;
|
||||
if (dist < 0)
|
||||
continue; // light doesn't reach
|
||||
|
||||
VectorSubtract (light->origin, surf, incoming);
|
||||
VectorNormalize (incoming);
|
||||
if (light->targetent)
|
||||
{ // spotlight cutoff
|
||||
if (DotProduct (spotvec, incoming) > falloff)
|
||||
continue;
|
||||
}
|
||||
angle = DotProduct (incoming, l->facenormal);
|
||||
|
||||
angle = (1.0-scalecos) + scalecos*angle;
|
||||
add = light->light - dist;
|
||||
add *= angle;
|
||||
if (add < 0)
|
||||
continue;
|
||||
|
||||
lightsamp[c][0] += add*light->colour[0];
|
||||
lightsamp[c][1] += add*light->colour[1];
|
||||
lightsamp[c][2] += add*light->colour[2];
|
||||
|
||||
norms[c][0] += add * incoming[0]; //Quake doesn't make sence some times.
|
||||
norms[c][1] -= add * incoming[1];
|
||||
norms[c][2] -= add * incoming[2];
|
||||
|
||||
if (add > 1) // ignore real tiny lights
|
||||
hit = true;
|
||||
}
|
||||
|
||||
if (mapnum == l->numlightstyles && hit)
|
||||
{
|
||||
l->lightstyles[mapnum] = light->style;
|
||||
l->numlightstyles++; // the style has some real data now
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
FixMinlight
|
||||
============
|
||||
*/
|
||||
static void FixMinlight (llightinfo_t *l)
|
||||
{
|
||||
int i, j;
|
||||
float minlight;
|
||||
|
||||
minlight = 0;
|
||||
|
||||
// if minlight is set, there must be a style 0 light map
|
||||
if (!minlight)
|
||||
return;
|
||||
|
||||
for (i=0 ; i< l->numlightstyles ; i++)
|
||||
{
|
||||
if (l->lightstyles[i] == 0)
|
||||
break;
|
||||
}
|
||||
if (i == l->numlightstyles)
|
||||
{
|
||||
if (l->numlightstyles == MAXLIGHTMAPS)
|
||||
return; // oh well..
|
||||
for (j=0 ; j<l->numsurfpt ; j++)
|
||||
{
|
||||
l->lightmaps[i][j][0] = minlight;
|
||||
l->lightmaps[i][j][1] = minlight;
|
||||
l->lightmaps[i][j][2] = minlight;
|
||||
}
|
||||
l->lightstyles[i] = 0;
|
||||
l->numlightstyles++;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j=0 ; j<l->numsurfpt ; j++)
|
||||
{
|
||||
if ( l->lightmaps[i][j][0] < minlight)
|
||||
l->lightmaps[i][j][0] = minlight;
|
||||
if ( l->lightmaps[i][j][1] < minlight)
|
||||
l->lightmaps[i][j][1] = minlight;
|
||||
if ( l->lightmaps[i][j][2] < minlight)
|
||||
l->lightmaps[i][j][2] = minlight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
LightFace
|
||||
============
|
||||
*/
|
||||
void LightFace (int surfnum)
|
||||
{
|
||||
dface_t *f;
|
||||
llightinfo_t l;
|
||||
int s, t;
|
||||
int i,j,c,ch;
|
||||
vec_t total, mean;
|
||||
int size;
|
||||
int lightmapwidth, lightmapsize;
|
||||
#ifdef UTILITY
|
||||
byte *out;
|
||||
#endif
|
||||
byte *rgbout;
|
||||
byte *dulout;
|
||||
vec3_t *light, *norm;
|
||||
vec3_t wnorm, temp;
|
||||
int w, h;
|
||||
|
||||
extern byte *runningrgblightdatabase;
|
||||
extern byte *runninglightnormbase;
|
||||
|
||||
f = dfaces + surfnum;
|
||||
|
||||
//
|
||||
// some surfaces don't need lightmaps
|
||||
//
|
||||
for (j=0 ; j<MAXLIGHTMAPS ; j++)
|
||||
f->styles[j] = 255;
|
||||
|
||||
if ( bsptexinfo(f->texinfo).flags & TEX_SPECIAL)
|
||||
{ // non-lit texture
|
||||
#ifdef UTILITY
|
||||
f->lightofs = -1;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef UTILITY
|
||||
if (!f->samples)
|
||||
return;
|
||||
#endif
|
||||
|
||||
memset (&l, 0, sizeof(l));
|
||||
l.surfnum = surfnum;
|
||||
l.face = f;
|
||||
|
||||
//
|
||||
// rotate plane
|
||||
//
|
||||
#ifndef UTILITY
|
||||
VectorCopy (f->plane->normal, l.facenormal);
|
||||
l.facedist = f->plane->dist;
|
||||
#else
|
||||
VectorCopy (dplanes[f->planenum].normal, l.facenormal);
|
||||
l.facedist = dplanes[f->planenum].dist;
|
||||
#endif
|
||||
if (f->side)
|
||||
{
|
||||
VectorSubtract (vec3_origin, l.facenormal, l.facenormal);
|
||||
l.facedist = -l.facedist;
|
||||
}
|
||||
|
||||
|
||||
|
||||
LightCalcFaceVectors (&l);
|
||||
LightCalcFaceExtents (&l);
|
||||
LightCalcPoints (&l);
|
||||
|
||||
lightmapwidth = l.texsize[0]+1;
|
||||
|
||||
size = lightmapwidth*(l.texsize[1]+1);
|
||||
if (size > SINGLEMAP)
|
||||
Error ("Bad lightmap size");
|
||||
|
||||
for (i=0 ; i<MAXLIGHTMAPS ; i++)
|
||||
l.lightstyles[i] = 255;
|
||||
|
||||
//
|
||||
// cast all lights
|
||||
//
|
||||
l.numlightstyles = 0;
|
||||
for (i=0 ; i<num_entities ; i++)
|
||||
{
|
||||
if (entities[i].light)
|
||||
SingleLightFace (&entities[i], &l);
|
||||
}
|
||||
|
||||
FixMinlight (&l);
|
||||
|
||||
if (!l.numlightstyles)
|
||||
{ // no light hitting it
|
||||
#ifdef UTILITY
|
||||
f->lightofs = -1;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// save out the values
|
||||
//
|
||||
for (i=0 ; i <MAXLIGHTMAPS ; i++)
|
||||
f->styles[i] = l.lightstyles[i];
|
||||
|
||||
lightmapsize = size*l.numlightstyles;
|
||||
|
||||
#ifdef UTILITY
|
||||
if (runningrgblightdatabase)
|
||||
{
|
||||
out = GetFakeFileSpace(&f->lightofs, size);
|
||||
rgbout = runningrgblightdatabase + f->lightofs*3;
|
||||
dulout = runninglightnormbase + f->lightofs*3;
|
||||
}
|
||||
else
|
||||
{
|
||||
out = GetFileSpace (&f->lightofs, lightmapsize);
|
||||
|
||||
rgbout = GetRGBFileSpace (f->lightofs, lightmapsize);
|
||||
dulout = GetNormFileSpace (f->lightofs, lightmapsize);
|
||||
}
|
||||
#else
|
||||
rgbout = f->samples;
|
||||
if (lightmodel->deluxdata)
|
||||
dulout = f->samples - lightmodel->lightdata + lightmodel->deluxdata;
|
||||
else
|
||||
dulout = NULL;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// extra filtering
|
||||
h = (l.texsize[1]+1)*2;
|
||||
w = (l.texsize[0]+1)*2;
|
||||
|
||||
for (i=0 ; i< l.numlightstyles ; i++)
|
||||
{
|
||||
if (l.lightstyles[i] == 0xff)
|
||||
Error ("Wrote empty lightmap");
|
||||
light = l.lightmaps[i];
|
||||
norm = l.lightnorm[i];
|
||||
c = 0;
|
||||
for (t=0 ; t<=l.texsize[1] ; t++)
|
||||
{
|
||||
for (s=0 ; s<=l.texsize[0] ; s++, c++)
|
||||
{
|
||||
mean = 0;
|
||||
|
||||
for (ch = 0; ch < 3; ch++)
|
||||
{
|
||||
if (extrasamples)
|
||||
{ // filtered sample
|
||||
total = light[t*2*w+s*2][ch] + light[t*2*w+s*2+1][ch]
|
||||
+ light[(t*2+1)*w+s*2][ch] + light[(t*2+1)*w+s*2+1][ch];
|
||||
total *= 0.25;
|
||||
|
||||
wnorm[ch] = norm[t*2*w+s*2][ch] + norm[t*2*w+s*2+1][ch]
|
||||
+ norm[(t*2+1)*w+s*2][ch] + norm[(t*2+1)*w+s*2+1][ch];
|
||||
}
|
||||
else
|
||||
{
|
||||
total = light[c][ch];
|
||||
wnorm[ch] = norm[c][ch];
|
||||
}
|
||||
total *= rangescale; // scale before clamping
|
||||
#ifdef UTILITY
|
||||
if (total > *out) //sorry - for qw
|
||||
total = *out;
|
||||
#else
|
||||
if (total > *rgbout) //sorry - for qw
|
||||
total = *rgbout;
|
||||
#endif
|
||||
if (total < 0)
|
||||
Error ("light < 0");
|
||||
|
||||
*rgbout++ = total;
|
||||
mean += total;
|
||||
}
|
||||
#ifdef UTILITY
|
||||
*out++ = mean/3;
|
||||
#endif
|
||||
|
||||
if (dulout)
|
||||
{
|
||||
temp[0] = DotProduct(wnorm, bsptexinfo(f->texinfo).vecs[0]);
|
||||
temp[1] = DotProduct(wnorm, bsptexinfo(f->texinfo).vecs[1]);
|
||||
temp[2] = DotProduct(wnorm, l.facenormal);
|
||||
VectorNormalize(temp);
|
||||
*dulout++ = (temp[0]+1)/2 * 255;
|
||||
*dulout++ = (temp[1]+1)/2 * 255;
|
||||
*dulout++ = (temp[2]+1)/2 * 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
2476
engine/gl/gl_alias.c
Normal file
2476
engine/gl/gl_alias.c
Normal file
File diff suppressed because it is too large
Load diff
489
engine/gl/gl_backend.c
Normal file
489
engine/gl/gl_backend.c
Normal file
|
@ -0,0 +1,489 @@
|
|||
#include "quakedef.h"
|
||||
#include "glquake.h"
|
||||
#include "shader.h"
|
||||
|
||||
#ifdef RGLQUAKE
|
||||
|
||||
|
||||
#define MAX_MESH_VERTS 8192
|
||||
|
||||
//we don't support multitexturing yet.
|
||||
|
||||
|
||||
static float tempstarray[MAX_MESH_VERTS*3];
|
||||
static vec4_t tempxyzarray[MAX_MESH_VERTS];
|
||||
|
||||
shader_t nullshader, wallbumpshader, modelbumpshader;
|
||||
#define frand() (rand()&32767)* (1.0/32767)
|
||||
|
||||
#define FTABLE_SIZE 1024
|
||||
#define FTABLE_CLAMP(x) (((int)((x)*FTABLE_SIZE) & (FTABLE_SIZE-1)))
|
||||
#define FTABLE_EVALUATE(table,x) (table ? table[FTABLE_CLAMP(x)] : frand())//*((x)-floor(x)))
|
||||
|
||||
static float r_sintable[FTABLE_SIZE];
|
||||
static float r_triangletable[FTABLE_SIZE];
|
||||
static float r_squaretable[FTABLE_SIZE];
|
||||
static float r_sawtoothtable[FTABLE_SIZE];
|
||||
static float r_inversesawtoothtable[FTABLE_SIZE];
|
||||
|
||||
void GLR_MeshInit(void)
|
||||
{
|
||||
int i;
|
||||
double t;
|
||||
for ( i = 0; i < FTABLE_SIZE; i++ )
|
||||
{
|
||||
t = (double)i / (double)FTABLE_SIZE;
|
||||
|
||||
r_sintable[i] = sin ( t * M_PI*2 );
|
||||
|
||||
if (t < 0.25)
|
||||
r_triangletable[i] = t * 4.0;
|
||||
else if (t < 0.75)
|
||||
r_triangletable[i] = 2 - 4.0 * t;
|
||||
else
|
||||
r_triangletable[i] = (t - 0.75) * 4.0 - 1.0;
|
||||
|
||||
if (t < 0.5)
|
||||
r_squaretable[i] = 1.0f;
|
||||
else
|
||||
r_squaretable[i] = -1.0f;
|
||||
|
||||
r_sawtoothtable[i] = t;
|
||||
r_inversesawtoothtable[i] = 1.0 - t;
|
||||
}
|
||||
|
||||
{
|
||||
nullshader.numdeforms = 0;//1;
|
||||
nullshader.deforms[0].type = DEFORMV_WAVE;
|
||||
nullshader.deforms[0].args[0] = 10;
|
||||
nullshader.deforms[0].func.type = SHADER_FUNC_SIN;
|
||||
nullshader.deforms[0].func.args[1] = 1;
|
||||
nullshader.deforms[0].func.args[3] = 10;
|
||||
|
||||
nullshader.pass[0].texturetype = GL_TEXTURE_2D;
|
||||
nullshader.pass[0].envmode = GL_MODULATE;
|
||||
nullshader.pass[0].blendsrc = GL_SRC_ALPHA;
|
||||
nullshader.pass[0].blenddst = GL_ONE_MINUS_SRC_ALPHA;
|
||||
|
||||
nullshader.pass[1].flags |= SHADER_PASS_BLEND;
|
||||
nullshader.pass[1].tcgen = TC_GEN_LIGHTMAP;
|
||||
nullshader.pass[1].blendsrc = GL_SRC_ALPHA;
|
||||
nullshader.pass[1].blenddst = GL_ONE_MINUS_SRC_ALPHA;
|
||||
nullshader.pass[1].texturetype = GL_TEXTURE_2D;
|
||||
}
|
||||
|
||||
{
|
||||
modelbumpshader.numpasses = 3;
|
||||
|
||||
if (1)
|
||||
modelbumpshader.pass[0].mergedpasses = 4;
|
||||
else
|
||||
modelbumpshader.pass[0].mergedpasses = 2;
|
||||
modelbumpshader.pass[2].mergedpasses = 1;
|
||||
|
||||
modelbumpshader.pass[0].tcgen = TC_GEN_BASE;
|
||||
modelbumpshader.pass[0].envmode = GL_COMBINE_ARB;
|
||||
modelbumpshader.pass[0].combinesrc0 = GL_TEXTURE;
|
||||
modelbumpshader.pass[0].combinemode = GL_REPLACE;
|
||||
modelbumpshader.pass[0].blendsrc = GL_SRC_ALPHA;
|
||||
modelbumpshader.pass[0].blenddst = GL_ONE_MINUS_SRC_ALPHA;
|
||||
modelbumpshader.pass[0].anim_frames[0] = 0;//bumpmap
|
||||
modelbumpshader.pass[0].texturetype = GL_TEXTURE_2D;
|
||||
|
||||
modelbumpshader.pass[1].tcgen = TC_GEN_DOTPRODUCT;
|
||||
modelbumpshader.pass[1].envmode = GL_COMBINE_ARB;
|
||||
modelbumpshader.pass[1].combinesrc0 = GL_TEXTURE;
|
||||
modelbumpshader.pass[1].combinesrc1 = GL_PREVIOUS_ARB;
|
||||
modelbumpshader.pass[1].combinemode = GL_DOT3_RGB_ARB;
|
||||
modelbumpshader.pass[1].anim_frames[0] = 0;//delux
|
||||
modelbumpshader.pass[1].texturetype = GL_TEXTURE_2D;
|
||||
|
||||
modelbumpshader.pass[2].flags |= SHADER_PASS_BLEND;
|
||||
modelbumpshader.pass[2].tcgen = TC_GEN_BASE;
|
||||
modelbumpshader.pass[2].envmode = GL_MODULATE;
|
||||
modelbumpshader.pass[2].blendsrc = GL_DST_COLOR;
|
||||
modelbumpshader.pass[2].blenddst = GL_ZERO;
|
||||
modelbumpshader.pass[2].anim_frames[0] = 0;//texture
|
||||
modelbumpshader.pass[2].texturetype = GL_TEXTURE_2D;
|
||||
|
||||
//gl_combine states that we need to use a textures.
|
||||
modelbumpshader.pass[3].tcgen = TC_GEN_BASE; //multiply by colors
|
||||
modelbumpshader.pass[3].envmode = GL_COMBINE_ARB;
|
||||
modelbumpshader.pass[3].combinesrc0 = GL_PREVIOUS_ARB;
|
||||
modelbumpshader.pass[3].combinesrc1 = GL_PRIMARY_COLOR_ARB;
|
||||
modelbumpshader.pass[3].combinemode = GL_MODULATE;
|
||||
modelbumpshader.pass[3].anim_frames[0] = 1; //any, has to be present
|
||||
modelbumpshader.pass[3].texturetype = GL_TEXTURE_2D;
|
||||
}
|
||||
|
||||
{
|
||||
wallbumpshader.numpasses = 4;
|
||||
|
||||
if (1)
|
||||
wallbumpshader.pass[0].mergedpasses = 4;
|
||||
else
|
||||
wallbumpshader.pass[0].mergedpasses = 2;
|
||||
wallbumpshader.pass[2].mergedpasses = 2;
|
||||
|
||||
wallbumpshader.pass[0].tcgen = TC_GEN_BASE;
|
||||
wallbumpshader.pass[0].envmode = GL_COMBINE_ARB;
|
||||
wallbumpshader.pass[0].combinesrc0 = GL_TEXTURE;
|
||||
wallbumpshader.pass[0].combinemode = GL_REPLACE;
|
||||
wallbumpshader.pass[0].anim_frames[0] = 0;//bumpmap
|
||||
wallbumpshader.pass[0].blendsrc = GL_SRC_ALPHA;
|
||||
wallbumpshader.pass[0].blenddst = GL_ONE_MINUS_SRC_ALPHA;
|
||||
wallbumpshader.pass[0].texturetype = GL_TEXTURE_2D;
|
||||
|
||||
wallbumpshader.pass[1].tcgen = TC_GEN_LIGHTMAP;
|
||||
wallbumpshader.pass[1].envmode = GL_COMBINE_ARB;
|
||||
wallbumpshader.pass[1].combinesrc0 = GL_TEXTURE;
|
||||
wallbumpshader.pass[1].combinesrc1 = GL_PREVIOUS_ARB;
|
||||
wallbumpshader.pass[1].combinemode = GL_DOT3_RGB_ARB;
|
||||
wallbumpshader.pass[1].anim_frames[0] = 0;//delux
|
||||
wallbumpshader.pass[1].texturetype = GL_TEXTURE_2D;
|
||||
|
||||
wallbumpshader.pass[2].flags |= SHADER_PASS_BLEND;
|
||||
wallbumpshader.pass[2].tcgen = TC_GEN_BASE;
|
||||
wallbumpshader.pass[2].envmode = GL_MODULATE;
|
||||
wallbumpshader.pass[2].blendsrc = GL_DST_COLOR;
|
||||
wallbumpshader.pass[2].blenddst = GL_ZERO;
|
||||
wallbumpshader.pass[2].anim_frames[0] = 0;//texture
|
||||
wallbumpshader.pass[2].texturetype = GL_TEXTURE_2D;
|
||||
|
||||
wallbumpshader.pass[3].tcgen = TC_GEN_LIGHTMAP;
|
||||
wallbumpshader.pass[3].envmode = GL_BLEND;
|
||||
wallbumpshader.pass[3].anim_frames[0] = 0;//lightmap
|
||||
wallbumpshader.pass[3].texturetype = GL_TEXTURE_2D;
|
||||
}
|
||||
}
|
||||
|
||||
static float *R_TableForFunc ( unsigned int func )
|
||||
{
|
||||
switch (func)
|
||||
{
|
||||
case SHADER_FUNC_SIN:
|
||||
return r_sintable;
|
||||
|
||||
case SHADER_FUNC_TRIANGLE:
|
||||
return r_triangletable;
|
||||
|
||||
case SHADER_FUNC_SQUARE:
|
||||
return r_squaretable;
|
||||
|
||||
case SHADER_FUNC_SAWTOOTH:
|
||||
return r_sawtoothtable;
|
||||
|
||||
case SHADER_FUNC_INVERSESAWTOOTH:
|
||||
return r_inversesawtoothtable;
|
||||
}
|
||||
|
||||
// assume noise
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void MakeDeforms(shader_t *shader, vec4_t *out, vec4_t *in, int number)
|
||||
{
|
||||
float *table;
|
||||
int d, j;
|
||||
float args[4], deflect;
|
||||
deformv_t *dfrm = shader->deforms;
|
||||
|
||||
for (d = 0; d < shader->numdeforms; d++, dfrm++)
|
||||
{
|
||||
switch(dfrm->type)
|
||||
{
|
||||
case DEFORMV_WAVE:
|
||||
args[0] = dfrm->func.args[0];
|
||||
args[1] = dfrm->func.args[1];
|
||||
args[3] = dfrm->func.args[2] + dfrm->func.args[3] * realtime;
|
||||
table = R_TableForFunc ( dfrm->func.type );
|
||||
|
||||
for ( j = 0; j < number; j++ ) {
|
||||
deflect = dfrm->args[0] * (in[j][0]+in[j][1]+in[j][2]) + args[3];
|
||||
deflect = sin(deflect)/*FTABLE_EVALUATE ( table, deflect )*/ * args[1] + args[0];
|
||||
|
||||
out[j][0] = in[j][0]+deflect;
|
||||
out[j][1] = in[j][1]+deflect;
|
||||
out[j][2] = in[j][2]+deflect;
|
||||
|
||||
// Deflect vertex along its normal by wave amount
|
||||
// VectorMA ( out[j], deflect, normalsArray[j], in[j] );
|
||||
}
|
||||
break;
|
||||
case DEFORMV_MOVE:
|
||||
table = R_TableForFunc ( dfrm->func.type );
|
||||
deflect = dfrm->func.args[2] + realtime * dfrm->func.args[3];
|
||||
deflect = FTABLE_EVALUATE (table, deflect) * dfrm->func.args[1] + dfrm->func.args[0];
|
||||
|
||||
for ( j = 0; j < number; j++ )
|
||||
VectorMA ( out[j], deflect, dfrm->args, in[j] );
|
||||
break;
|
||||
default:
|
||||
Sys_Error("Bad deform type %i\n", dfrm->type);
|
||||
}
|
||||
|
||||
in = out;
|
||||
}
|
||||
}
|
||||
|
||||
static void Mesh_DeformTextureCoords(mesh_t *mesh, shaderpass_t *pass)
|
||||
{
|
||||
int d;
|
||||
tcmod_t *tcmod = pass->tcmod;
|
||||
float *in, *out;
|
||||
switch(pass->tcgen)
|
||||
{
|
||||
case TC_GEN_DOTPRODUCT: //take normals, use the dotproduct and produce texture coords for bumpmapping
|
||||
{
|
||||
out = tempstarray;
|
||||
in = (float*)mesh->normals_array;
|
||||
|
||||
for (d = 0; d < mesh->numvertexes; d++)
|
||||
{
|
||||
out[d*3+0] = DotProduct((in+d*3), mesh->lightaxis[0]);
|
||||
out[d*3+1] = DotProduct((in+d*3), mesh->lightaxis[1]);
|
||||
out[d*3+2] = DotProduct((in+d*3), mesh->lightaxis[2]);
|
||||
}
|
||||
glTexCoordPointer(3, GL_FLOAT, 0, out);
|
||||
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
}
|
||||
return;
|
||||
case TC_GEN_LIGHTMAP:
|
||||
in = (float*)mesh->lmst_array;
|
||||
if (in)
|
||||
break; //fallthrought
|
||||
case TC_GEN_BASE:
|
||||
in = (float*)mesh->st_array;
|
||||
break;
|
||||
default:
|
||||
Sys_Error("Mesh_DeformTextureCoords: Bad TC_GEN type\n");
|
||||
return;
|
||||
}
|
||||
/*
|
||||
for (d = 0; d < pass->numtcmods; d++, dfrm++)
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, in);
|
||||
}
|
||||
|
||||
static void Mesh_SetShaderpassState ( shaderpass_t *pass, qboolean mtex )
|
||||
{
|
||||
if ( (mtex && (pass->blendmode != GL_REPLACE)) || (pass->flags & SHADER_PASS_BLEND) )
|
||||
{
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (pass->blendsrc, pass->blenddst);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable (GL_BLEND);
|
||||
}
|
||||
|
||||
if (pass->flags & SHADER_PASS_ALPHAFUNC)
|
||||
{
|
||||
glEnable (GL_ALPHA_TEST);
|
||||
|
||||
if (pass->alphafunc == SHADER_ALPHA_GT0)
|
||||
{
|
||||
glAlphaFunc (GL_GREATER, 0);
|
||||
}
|
||||
else if (pass->alphafunc == SHADER_ALPHA_LT128)
|
||||
{
|
||||
glAlphaFunc (GL_LESS, 0.5f);
|
||||
}
|
||||
else if (pass->alphafunc == SHADER_ALPHA_GE128)
|
||||
{
|
||||
glAlphaFunc (GL_GEQUAL, 0.5f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// glDisable (GL_ALPHA_TEST);
|
||||
}
|
||||
|
||||
// glDepthFunc (pass->depthfunc);
|
||||
|
||||
if (pass->flags & SHADER_PASS_DEPTHWRITE)
|
||||
{
|
||||
glDepthMask (GL_TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// glDepthMask (GL_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void Mesh_DrawPass(shaderpass_t *pass, mesh_t *mesh)
|
||||
{
|
||||
Mesh_SetShaderpassState(pass, false);
|
||||
if (pass->mergedpasses>1 && gl_mtexarbable)
|
||||
{
|
||||
int p;
|
||||
// Mesh_DrawPass(pass+2,mesh);
|
||||
// return;
|
||||
for (p = 0; p < pass->mergedpasses; p++)
|
||||
{
|
||||
qglActiveTextureARB(GL_TEXTURE0_ARB+p);
|
||||
qglClientActiveTextureARB(GL_TEXTURE0_ARB+p);
|
||||
GL_BindType(pass[p].texturetype, pass[p].anim_frames[0]);
|
||||
glEnable(pass[p].texturetype);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, pass[p].envmode);
|
||||
if (pass[p].envmode == GL_COMBINE_ARB)
|
||||
{
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, pass[p].combinesrc0);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, pass[p].combinesrc1);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, pass[p].combinemode);
|
||||
}
|
||||
|
||||
Mesh_DeformTextureCoords(mesh, pass+p);
|
||||
}
|
||||
glDrawElements(GL_TRIANGLES, mesh->numindexes, GL_UNSIGNED_INT, mesh->indexes);
|
||||
for (p = pass->mergedpasses-1; p >= 0; p--)
|
||||
{
|
||||
qglActiveTextureARB(GL_TEXTURE0_ARB+p);
|
||||
qglClientActiveTextureARB(GL_TEXTURE0_ARB+p);
|
||||
glDisable(pass[p].texturetype);
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Mesh_DeformTextureCoords(mesh, pass);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, pass->envmode);
|
||||
|
||||
GL_Bind(pass->anim_frames[0]);
|
||||
if (pass->texturetype != GL_TEXTURE_2D)
|
||||
{
|
||||
glDisable(pass->texturetype);
|
||||
glEnable(pass->texturetype);
|
||||
}
|
||||
glDrawElements(GL_TRIANGLES, mesh->numindexes, GL_UNSIGNED_INT, mesh->indexes);
|
||||
|
||||
if (pass->texturetype != GL_TEXTURE_2D)
|
||||
{
|
||||
glDisable(pass->texturetype);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GL_DrawMesh(mesh_t *mesh, shader_t *shader, int texturenum, int lmtexturenum)
|
||||
{
|
||||
int i;
|
||||
if (!shader)
|
||||
{
|
||||
shader = &nullshader;
|
||||
shader->pass[0].anim_frames[0] = texturenum;
|
||||
shader->pass[0].mergedpasses=1;
|
||||
|
||||
if (lmtexturenum && !texturenum)
|
||||
{
|
||||
shader->pass[0].anim_frames[0] = lmtexturenum;
|
||||
shader->numpasses = 1;
|
||||
shader->pass[0].flags |= SHADER_PASS_BLEND;
|
||||
}
|
||||
else if (lmtexturenum)
|
||||
{
|
||||
shader->numpasses = 2;
|
||||
shader->pass[1].anim_frames[0] = lmtexturenum;//lmtexture;
|
||||
shader->pass[0].flags &= ~SHADER_PASS_BLEND;
|
||||
}
|
||||
else
|
||||
{
|
||||
shader->pass[0].flags &= ~SHADER_PASS_BLEND;
|
||||
shader->numpasses = 1;
|
||||
}
|
||||
|
||||
shader->pass[0].texturetype = GL_TEXTURE_2D;
|
||||
}
|
||||
if (!shader->numdeforms)
|
||||
glVertexPointer(3, GL_FLOAT, 16, mesh->xyz_array);
|
||||
else
|
||||
{
|
||||
MakeDeforms(shader, tempxyzarray, mesh->xyz_array, mesh->numvertexes);
|
||||
glVertexPointer(3, GL_FLOAT, 16, tempxyzarray);
|
||||
}
|
||||
if (mesh->normals_array && glNormalPointer)
|
||||
{
|
||||
glNormalPointer(GL_FLOAT, 0, mesh->normals_array);
|
||||
glEnableClientState( GL_NORMAL_ARRAY );
|
||||
}
|
||||
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
if (mesh->colors_array && glColorPointer)
|
||||
{
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, 0, mesh->colors_array);
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
}
|
||||
|
||||
for (i =0 ; i < shader->numpasses; i+=shader->pass[i].mergedpasses)
|
||||
Mesh_DrawPass(shader->pass+i, mesh);
|
||||
|
||||
glDisableClientState( GL_VERTEX_ARRAY );
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
glDisableClientState( GL_NORMAL_ARRAY );
|
||||
|
||||
/* //show normals
|
||||
if (mesh->normals_array)
|
||||
{
|
||||
glColor3f(1,1,1);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBegin(GL_LINES);
|
||||
for (i = 0; i < mesh->numvertexes; i++)
|
||||
{
|
||||
glVertex3f( mesh->xyz_array[i][0],
|
||||
mesh->xyz_array[i][1],
|
||||
mesh->xyz_array[i][2]);
|
||||
|
||||
glVertex3f( mesh->xyz_array[i][0] + mesh->normals_array[i][0],
|
||||
mesh->xyz_array[i][1] + mesh->normals_array[i][1],
|
||||
mesh->xyz_array[i][2] + mesh->normals_array[i][2]);
|
||||
}
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void GL_DrawMeshBump(mesh_t *mesh, int texturenum, int lmtexturenum, int bumpnum, int deluxnum)
|
||||
{
|
||||
shader_t *shader;
|
||||
extern int normalisationCubeMap;
|
||||
|
||||
if (lmtexturenum)
|
||||
{
|
||||
shader = &wallbumpshader;
|
||||
shader->pass[3].anim_frames[0] = lmtexturenum;
|
||||
}
|
||||
else
|
||||
shader = &modelbumpshader;
|
||||
|
||||
shader->pass[0].anim_frames[0] = bumpnum;
|
||||
if (deluxnum)
|
||||
{
|
||||
shader->pass[1].anim_frames[0] = deluxnum;
|
||||
shader->pass[1].tcgen = TC_GEN_LIGHTMAP;
|
||||
shader->pass[1].texturetype = GL_TEXTURE_2D;
|
||||
}
|
||||
else
|
||||
{
|
||||
shader->pass[1].anim_frames[0] = normalisationCubeMap;
|
||||
shader->pass[1].tcgen = TC_GEN_DOTPRODUCT;
|
||||
shader->pass[1].texturetype = GL_TEXTURE_CUBE_MAP_ARB;
|
||||
}
|
||||
shader->pass[2].anim_frames[0] = texturenum;
|
||||
|
||||
// mesh->colors_array=NULL; //don't bother coloring it.
|
||||
|
||||
GL_DrawMesh(mesh, shader, 0, 0);
|
||||
}
|
||||
|
||||
#endif
|
3005
engine/gl/gl_draw.c
Normal file
3005
engine/gl/gl_draw.c
Normal file
File diff suppressed because it is too large
Load diff
649
engine/gl/gl_hlmdl.c
Normal file
649
engine/gl/gl_hlmdl.c
Normal file
|
@ -0,0 +1,649 @@
|
|||
#include "bothdefs.h"
|
||||
|
||||
#ifdef HALFLIFEMODELS
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "glquake.h"
|
||||
/*
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
Half-Life Model Renderer (Experimental) Copyright (C) 2001 James 'Ender' Brown [ender@quakesrc.org] 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. fromquake.h -
|
||||
|
||||
render.c - apart from calculations (mostly range checking or value conversion code is a mix of standard Quake 1
|
||||
meshing, and vertex deforms. The rendering loop uses standard Quake 1 drawing, after SetupBones deforms the vertex.
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
|
||||
|
||||
Also, please note that it won't do all hl models....
|
||||
Nor will it work 100%
|
||||
*/
|
||||
#include "model_hl.h"
|
||||
|
||||
void VectorTransform (const vec3_t in1, const float in2[3][4], vec3_t out);
|
||||
|
||||
void QuaternionGLMatrix(float x, float y, float z, float w, vec4_t *GLM)
|
||||
{
|
||||
GLM[0][0] = 1 - 2 * y * y - 2 * z * z;
|
||||
GLM[1][0] = 2 * x * y + 2 * w * z;
|
||||
GLM[2][0] = 2 * x * z - 2 * w * y;
|
||||
GLM[0][1] = 2 * x * y - 2 * w * z;
|
||||
GLM[1][1] = 1 - 2 * x * x - 2 * z * z;
|
||||
GLM[2][1] = 2 * y * z + 2 * w * x;
|
||||
GLM[0][2] = 2 * x * z + 2 * w * y;
|
||||
GLM[1][2] = 2 * y * z - 2 * w * x;
|
||||
GLM[2][2] = 1 - 2 * x * x - 2 * y * y;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================================================================================================================
|
||||
QuaternionGLAngle - Convert a GL angle to a quaternion matrix
|
||||
=======================================================================================================================
|
||||
*/
|
||||
void QuaternionGLAngle(const vec3_t angles, vec4_t quaternion)
|
||||
{
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
float yaw = angles[2] * 0.5;
|
||||
float pitch = angles[1] * 0.5;
|
||||
float roll = angles[0] * 0.5;
|
||||
float siny = sin(yaw);
|
||||
float cosy = cos(yaw);
|
||||
float sinp = sin(pitch);
|
||||
float cosp = cos(pitch);
|
||||
float sinr = sin(roll);
|
||||
float cosr = cos(roll);
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
|
||||
quaternion[0] = sinr * cosp * cosy - cosr * sinp * siny;
|
||||
quaternion[1] = cosr * sinp * cosy + sinr * cosp * siny;
|
||||
quaternion[2] = cosr * cosp * siny - sinr * sinp * cosy;
|
||||
quaternion[3] = cosr * cosp * cosy + sinr * sinp * siny;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
float transform_matrix[128][3][4]; /* Vertex transformation matrix */
|
||||
|
||||
void GL_Draw_HL_AliasFrame(short *order, vec3_t *transformed, float tex_w, float tex_h);
|
||||
|
||||
/*
|
||||
=======================================================================================================================
|
||||
Mod_LoadHLModel - read in the model's constituent parts
|
||||
=======================================================================================================================
|
||||
*/
|
||||
extern char loadname[];
|
||||
void Mod_LoadHLModel (model_t *mod, void *buffer)
|
||||
{
|
||||
/*~~*/
|
||||
int i;
|
||||
|
||||
hlmodelcache_t *model;
|
||||
hlmdl_header_t *header;
|
||||
hlmdl_tex_t *tex;
|
||||
hlmdl_bone_t *bones;
|
||||
hlmdl_bonecontroller_t *bonectls;
|
||||
|
||||
int start, end, total;
|
||||
/*~~*/
|
||||
|
||||
|
||||
//checksum the model
|
||||
|
||||
if (!strcmp(mod->name, "progs/player.mdl") ||
|
||||
!strcmp(mod->name, "progs/eyes.mdl")) {
|
||||
unsigned short crc;
|
||||
qbyte *p;
|
||||
int len;
|
||||
char st[40];
|
||||
|
||||
CRC_Init(&crc);
|
||||
for (len = com_filesize, p = buffer; len; len--, p++)
|
||||
CRC_ProcessByte(&crc, *p);
|
||||
|
||||
sprintf(st, "%d", (int) crc);
|
||||
Info_SetValueForKey (cls.userinfo,
|
||||
!strcmp(mod->name, "progs/player.mdl") ? pmodel_name : emodel_name,
|
||||
st, MAX_INFO_STRING);
|
||||
|
||||
if (cls.state >= ca_connected) {
|
||||
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
|
||||
sprintf(st, "setinfo %s %d",
|
||||
!strcmp(mod->name, "progs/player.mdl") ? pmodel_name : emodel_name,
|
||||
(int)crc);
|
||||
SZ_Print (&cls.netchan.message, st);
|
||||
}
|
||||
}
|
||||
|
||||
start = Hunk_LowMark ();
|
||||
|
||||
|
||||
//load the model into hunk
|
||||
model = Hunk_Alloc(sizeof(hlmodelcache_t));
|
||||
|
||||
header = Hunk_Alloc(com_filesize);
|
||||
memcpy(header, buffer, com_filesize);
|
||||
|
||||
if (header->version != 10)
|
||||
Host_EndGame("Cannot load model %s - unknown version %i\n", mod->name, header->version);
|
||||
|
||||
tex = (hlmdl_tex_t *) ((qbyte *) header + header->textures);
|
||||
bones = (hlmdl_bone_t *) ((qbyte *) header + header->boneindex);
|
||||
bonectls = (hlmdl_bonecontroller_t *) ((qbyte *) header + header->controllerindex);
|
||||
|
||||
|
||||
/* won't work - doesn't know exact sizes.
|
||||
|
||||
header = Hunk_Alloc(sizeof(hlmdl_header_t));
|
||||
memcpy(header, (hlmdl_header_t *) buffer, sizeof(hlmdl_header_t));
|
||||
|
||||
tex = Hunk_Alloc(sizeof(hlmdl_tex_t)*header->numtextures);
|
||||
memcpy(tex, (hlmdl_tex_t *) buffer, sizeof(hlmdl_tex_t)*header->numtextures);
|
||||
|
||||
bones = Hunk_Alloc(sizeof(hlmdl_bone_t)*header->numtextures);
|
||||
memcpy(bones, (hlmdl_bone_t *) buffer, sizeof(hlmdl_bone_t)*header->numbones);
|
||||
|
||||
bonectls = Hunk_Alloc(sizeof(hlmdl_bonecontroller_t)*header->numcontrollers);
|
||||
memcpy(bonectls, (hlmdl_bonecontroller_t *) buffer, sizeof(hlmdl_bonecontroller_t)*header->numcontrollers);
|
||||
*/
|
||||
|
||||
model->header = (char *)header - (char *)model;
|
||||
model->textures = (char *)tex - (char *)model;
|
||||
model->bones = (char *)bones - (char *)model;
|
||||
model->bonectls = (char *)bonectls - (char *)model;
|
||||
|
||||
for(i = 0; i < header->numtextures; i++)
|
||||
{
|
||||
tex[i].i = GL_LoadTexture8Pal24("", tex[i].w, tex[i].h, (qbyte *) header + tex[i].i, (qbyte *) header + tex[i].w * tex[i].h + tex[i].i, true, false);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// move the complete, relocatable alias model to the cache
|
||||
//
|
||||
end = Hunk_LowMark ();
|
||||
total = end - start;
|
||||
|
||||
mod->type = mod_halflife;
|
||||
|
||||
Cache_Alloc (&mod->cache, total, loadname);
|
||||
if (!mod->cache.data)
|
||||
return;
|
||||
memcpy (mod->cache.data, model, total);
|
||||
|
||||
Hunk_FreeToLowMark (start);
|
||||
}
|
||||
|
||||
/*
|
||||
=======================================================================================================================
|
||||
HL_CurSequence - return the current sequence
|
||||
=======================================================================================================================
|
||||
*/
|
||||
int HL_CurSequence(hlmodel_t model)
|
||||
{
|
||||
return model.sequence;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================================================================================================================
|
||||
HL_NewSequence - animation control (just some range checking really)
|
||||
=======================================================================================================================
|
||||
*/
|
||||
int HL_NewSequence(hlmodel_t *model, int _inew)
|
||||
{
|
||||
if(_inew < 0)
|
||||
_inew = model->header->numseq - 1;
|
||||
else if(_inew >= model->header->numseq)
|
||||
_inew = 0;
|
||||
|
||||
model->sequence = _inew;
|
||||
model->frame = 0;
|
||||
{
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
hlmdl_sequencelist_t *pseqdesc;
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
|
||||
if(_inew == 0)
|
||||
{
|
||||
pseqdesc = (hlmdl_sequencelist_t *) ((qbyte *) model->header + model->header->seqindex) + model->sequence;
|
||||
}
|
||||
else
|
||||
{
|
||||
pseqdesc = (hlmdl_sequencelist_t *) ((qbyte *) model->header + model->header->seqindex) + model->sequence;
|
||||
}
|
||||
|
||||
Sys_Printf("Current Sequence: %s\n", pseqdesc->name);
|
||||
}
|
||||
|
||||
return model->sequence;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================================================================================================================
|
||||
HL_SetController - control where the model is facing (upper body usually)
|
||||
=======================================================================================================================
|
||||
*/
|
||||
void HL_SetController(hlmodel_t *model, int num, float value)
|
||||
{
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
int real, limit;
|
||||
hlmdl_bonecontroller_t *control = (hlmdl_bonecontroller_t *)
|
||||
((qbyte *) model->header + model->header->controllerindex);
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
|
||||
if(num >= model->header->numcontrollers) return;
|
||||
|
||||
if(num == 4)
|
||||
{
|
||||
limit = 64;
|
||||
}
|
||||
else
|
||||
{
|
||||
limit = 255;
|
||||
}
|
||||
|
||||
if(control->type & (0x0008 | 0x0010 | 0x0020))
|
||||
{
|
||||
if(control->end < control->start) value = -value;
|
||||
|
||||
if(control->start + 359.0 >= control->end)
|
||||
{
|
||||
if(value > ((control->start + control->end) / 2.0) + 180) value = value - 360;
|
||||
if(value < ((control->start + control->end) / 2.0) - 180) value = value + 360;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(value > 360)
|
||||
value = value - (int) (value / 360.0) * 360.0;
|
||||
else if(value < 0)
|
||||
value = value + (int) ((value / -360.0) + 1) * 360.0;
|
||||
}
|
||||
}
|
||||
|
||||
real = limit * (value - control[num].start) / (control[num].end - control[num].start);
|
||||
if(real < 0) real = 0;
|
||||
if(real > limit) real = limit;
|
||||
model->controller[num] = real;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================================================================================================================
|
||||
HL_CalculateBones - calculate bone positions - quaternion+vector in one function
|
||||
=======================================================================================================================
|
||||
*/
|
||||
void HL_CalculateBones
|
||||
(
|
||||
int offset,
|
||||
int frame,
|
||||
vec4_t adjust,
|
||||
hlmdl_bone_t *bone,
|
||||
hlmdl_anim_t *animation,
|
||||
float *destination
|
||||
)
|
||||
{
|
||||
/*~~~~~~~~~~*/
|
||||
int i;
|
||||
vec3_t angle;
|
||||
/*~~~~~~~~~~*/
|
||||
|
||||
/* For each vector */
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
/*~~~~~~~~~~~~~~~*/
|
||||
int o = i + offset; /* Take the value offset - allows quaternion & vector in one function */
|
||||
/*~~~~~~~~~~~~~~~*/
|
||||
|
||||
angle[i] = bone->value[o]; /* Take the bone value */
|
||||
|
||||
if(animation->offset[o] != 0)
|
||||
{
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
int tempframe = frame;
|
||||
hlmdl_animvalue_t *animvalue = (hlmdl_animvalue_t *) ((qbyte *) animation + animation->offset[o]);
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
|
||||
/* find values including the required frame */
|
||||
while(animvalue->num.total <= tempframe)
|
||||
{
|
||||
tempframe -= animvalue->num.total;
|
||||
animvalue += animvalue->num.valid + 1;
|
||||
}
|
||||
if(animvalue->num.valid > tempframe)
|
||||
{
|
||||
if(animvalue->num.valid > (tempframe + 1))
|
||||
angle[i] += animvalue[tempframe + 1].value * 1; // + 0 * animvalue[tempframe + 2].value * bone->scale[o];
|
||||
else
|
||||
angle[i] = animvalue[animvalue->num.valid].value;
|
||||
angle[i] = bone->value[o] + angle[i] * bone->scale[o];
|
||||
}
|
||||
else
|
||||
{
|
||||
if(animvalue->num.total <= tempframe + 1)
|
||||
{
|
||||
angle[i] +=
|
||||
(animvalue[animvalue->num.valid].value * 1 +
|
||||
0 * animvalue[animvalue->num.valid + 2].value) *
|
||||
bone->scale[o];
|
||||
}
|
||||
else
|
||||
{
|
||||
angle[i] += animvalue[animvalue->num.valid].value * bone->scale[o];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(bone->bonecontroller[o] != -1) { /* Add the programmable offset. */
|
||||
angle[i] += adjust[bone->bonecontroller[o]];
|
||||
}
|
||||
}
|
||||
|
||||
if(offset < 3)
|
||||
{
|
||||
VectorCopy(angle, destination); /* Just a standard vector */
|
||||
}
|
||||
else
|
||||
{
|
||||
QuaternionGLAngle(angle, destination); /* A quaternion */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=======================================================================================================================
|
||||
HL_CalcBoneAdj - Calculate the adjustment values for the programmable controllers
|
||||
=======================================================================================================================
|
||||
*/
|
||||
void HL_CalcBoneAdj(hlmodel_t *model)
|
||||
{
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
int i;
|
||||
float value;
|
||||
hlmdl_bonecontroller_t *control = (hlmdl_bonecontroller_t *)
|
||||
((qbyte *) model->header + model->header->controllerindex);
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
|
||||
for(i = 0; i < model->header->numcontrollers; i++)
|
||||
{
|
||||
/*~~~~~~~~~~~~~~~~~~~~~*/
|
||||
int j = control[i].index;
|
||||
/*~~~~~~~~~~~~~~~~~~~~~*/
|
||||
|
||||
if(control[i].type & 0x8000)
|
||||
{
|
||||
value = model->controller[j] * (360.0 / 256.0) + control[i].start;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = model->controller[j] / 255.0;
|
||||
if(value < 0)
|
||||
value = 0;
|
||||
else if(value > 1.0)
|
||||
value = 1.0;
|
||||
value = (1.0 - value) * control[i].start + value * control[i].end;
|
||||
}
|
||||
|
||||
/* Rotational controllers need their values converted */
|
||||
if(control[i].type >= 0x0008 && control[i].type <= 0x0020)
|
||||
model->adjust[i] = M_PI * value / 180;
|
||||
else
|
||||
model->adjust[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=======================================================================================================================
|
||||
HL_SetupBones - determine where vertex should be using bone movements
|
||||
=======================================================================================================================
|
||||
*/
|
||||
void HL_SetupBones(hlmodel_t *model)
|
||||
{
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
int i;
|
||||
float matrix[3][4];
|
||||
static vec3_t positions[128];
|
||||
static vec4_t quaternions[128];
|
||||
hlmdl_sequencelist_t *sequence = (hlmdl_sequencelist_t *) ((qbyte *) model->header + model->header->seqindex) +
|
||||
model->sequence;
|
||||
hlmdl_sequencedata_t *sequencedata = (hlmdl_sequencedata_t *)
|
||||
((qbyte *) model->header + model->header->seqgroups) +
|
||||
sequence->seqindex;
|
||||
hlmdl_anim_t *animation = (hlmdl_anim_t *)
|
||||
((qbyte *) model->header + sequencedata->data + sequence->index);
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
|
||||
HL_CalcBoneAdj(model); /* Deal with programmable controllers */
|
||||
|
||||
if(sequence->motiontype & 0x0001) positions[sequence->motionbone][0] = 0.0;
|
||||
if(sequence->motiontype & 0x0002) positions[sequence->motionbone][1] = 0.0;
|
||||
if(sequence->motiontype & 0x0004) positions[sequence->motionbone][2] = 0.0;
|
||||
|
||||
/* Sys_Printf("Frame: %i\n", model->frame); */
|
||||
for(i = 0; i < model->header->numbones; i++)
|
||||
{
|
||||
/*
|
||||
* There are two vector offsets in the structure. The first seems to be the
|
||||
* positions of the bones, the second the quats of the bone matrix itself. We
|
||||
* convert it inside the routine - Inconsistant, but hey.. so's the whole model
|
||||
* format.
|
||||
*/
|
||||
HL_CalculateBones(0, model->frame, model->adjust, model->bones + i, animation + i, positions[i]);
|
||||
HL_CalculateBones(3, model->frame, model->adjust, model->bones + i, animation + i, quaternions[i]);
|
||||
|
||||
/* FIXME: Blend the bones and make them cry :) */
|
||||
QuaternionGLMatrix(quaternions[i][0], quaternions[i][1], quaternions[i][2], quaternions[i][3], matrix);
|
||||
matrix[0][3] = positions[i][0];
|
||||
matrix[1][3] = positions[i][1];
|
||||
matrix[2][3] = positions[i][2];
|
||||
|
||||
/* If we have a parent, take the addition. Otherwise just copy the values */
|
||||
if(model->bones[i].parent>=0)
|
||||
{
|
||||
R_ConcatTransforms(transform_matrix[model->bones[i].parent], matrix, transform_matrix[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(transform_matrix[i], matrix, 12 * sizeof(float));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=======================================================================================================================
|
||||
R_Draw_HL_AliasModel - main drawing function
|
||||
=======================================================================================================================
|
||||
*/
|
||||
void R_DrawHLModel(entity_t *curent)
|
||||
{
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
hlmodelcache_t *modelc = Mod_Extradata(curent->model);
|
||||
hlmodel_t model;
|
||||
int b, m, v;
|
||||
short *skins;
|
||||
hlmdl_sequencelist_t *sequence;
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
|
||||
//general model
|
||||
model.header = (hlmdl_header_t *) ((char *)modelc + modelc->header);
|
||||
model.textures = (hlmdl_tex_t *) ((char *)modelc + modelc->textures);
|
||||
model.bones = (hlmdl_bone_t *) ((char *)modelc + modelc->bones);
|
||||
model.bonectls = (hlmdl_bonecontroller_t *) ((char *)modelc + modelc->bonectls);
|
||||
|
||||
//specific to entity
|
||||
model.sequence = curent->frame;
|
||||
model.frame = 0;
|
||||
model.frametime = 0;
|
||||
|
||||
HL_NewSequence(&model, curent->frame);
|
||||
|
||||
skins = (short *) ((qbyte *) model.header + model.header->skins);
|
||||
sequence = (hlmdl_sequencelist_t *) ((qbyte *) model.header + model.header->seqindex) +
|
||||
model.sequence;
|
||||
|
||||
model.controller[0] = 127;
|
||||
model.controller[1] = 127;
|
||||
model.controller[2] = 127;
|
||||
model.controller[3] = 127;
|
||||
model.controller[4] = 0;//sin(cl.time)*127+127;
|
||||
|
||||
model.frametime += (cl.time - cl.lerpents[curent->keynum].framechange)*sequence->timing;
|
||||
|
||||
if (model.frametime>=1)
|
||||
{
|
||||
model.frame += (int) model.frametime;
|
||||
model.frametime -= (int)model.frametime;
|
||||
}
|
||||
|
||||
if (!sequence->numframes)
|
||||
return;
|
||||
if(model.frame >= sequence->numframes)
|
||||
model.frame %= sequence->numframes;
|
||||
|
||||
if (sequence->motiontype)
|
||||
model.frame = sequence->numframes-1;
|
||||
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
if (curent->alpha<1)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// Con_Printf("%s %i\n", sequence->name, sequence->unknown1[0]);
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
{
|
||||
vec3_t difuse, ambient, ldir;
|
||||
cl.worldmodel->funcs.LightPointValues(curent->origin, difuse, ambient, ldir);
|
||||
glColor4f(difuse[0]/255+ambient[0]/255, difuse[1]/255+ambient[1]/255, difuse[2]/255+ambient[2]/255, curent->alpha);
|
||||
}
|
||||
|
||||
R_RotateForEntity (curent);
|
||||
|
||||
HL_SetupBones(&model); /* Setup the bones */
|
||||
|
||||
/* Manipulate each mesh directly */
|
||||
for(b = 0; b < model.header->numbodyparts; b++)
|
||||
{
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
hlmdl_bodypart_t *bodypart = (hlmdl_bodypart_t *) ((qbyte *) model.header + model.header->bodypartindex) +
|
||||
b;
|
||||
int bodyindex = (0 / bodypart->base) % bodypart->nummodels;
|
||||
hlmdl_model_t *amodel = (hlmdl_model_t *) ((qbyte *) model.header + bodypart->modelindex) + bodyindex;
|
||||
qbyte *bone = ((qbyte *) model.header + amodel->vertinfoindex);
|
||||
vec3_t *verts = (vec3_t *) ((qbyte *) model.header + amodel->vertindex);
|
||||
vec3_t transformed[2048];
|
||||
|
||||
// vec3_t *norms = (vec3_t *) ((qbyte *) model.header + amodel->unknown3[2]);
|
||||
// vec3_t transformednorms[2048];
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
|
||||
|
||||
for(v = 0; v < amodel->numverts; v++) // Transform per the matrix
|
||||
{
|
||||
VectorTransform(verts[v], transform_matrix[bone[v]], transformed[v]);
|
||||
// glVertex3fv(verts[v]);
|
||||
// glVertex3f( verts[v][0]+10*verts[v][0],
|
||||
// verts[v][1]+10*verts[v][1],
|
||||
// verts[v][2]+10*verts[v][2]);
|
||||
}
|
||||
|
||||
//Need to work out what we have!
|
||||
//raw data appears to be unit vectors
|
||||
//transformed gives some points on the skeleton.
|
||||
//what's also weird is that the meshes use these up!
|
||||
/* glDisable(GL_TEXTURE_2D);
|
||||
glBegin(GL_LINES);
|
||||
for(v = 0; v < amodel->unknown3[0]; v++) // Transform per the matrix
|
||||
{
|
||||
VectorTransform(norms[v], transform_matrix[bone[v]], transformednorms[v]);
|
||||
glVertex3fv(transformednorms[v]);
|
||||
glVertex3f( transformednorms[v][0]+10*transformednorms[v][0],
|
||||
transformednorms[v][1]+10*transformednorms[v][1],
|
||||
transformednorms[v][2]+10*transformednorms[v][2]);
|
||||
}
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
*/
|
||||
|
||||
|
||||
/* Draw each mesh */
|
||||
for(m = 0; m < amodel->nummesh; m++)
|
||||
{
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
hlmdl_mesh_t *mesh = (hlmdl_mesh_t *) ((qbyte *) model.header + amodel->meshindex) + m;
|
||||
float tex_w = 1.0f / model.textures[skins[mesh->skinindex]].w;
|
||||
float tex_h = 1.0f / model.textures[skins[mesh->skinindex]].h;
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
|
||||
GL_Bind(model.textures[skins[mesh->skinindex]].i);
|
||||
GL_Draw_HL_AliasFrame((short *) ((qbyte *) model.header + mesh->index), transformed, tex_w, tex_h);
|
||||
}
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
}
|
||||
|
||||
/*
|
||||
=======================================================================================================================
|
||||
GL_Draw_HL_AliasFrame - clip and draw all triangles
|
||||
=======================================================================================================================
|
||||
*/
|
||||
void GL_Draw_HL_AliasFrame(short *order, vec3_t *transformed, float tex_w, float tex_h)
|
||||
{
|
||||
/*~~~~~~~~~~*/
|
||||
int count = 0;
|
||||
/*~~~~~~~~~~*/
|
||||
|
||||
// int c_tris=0;
|
||||
// int c_verts=0;
|
||||
// int c_chains=0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
count = *order++; /* get the vertex count and primitive type */
|
||||
if(!count) break; /* done */
|
||||
|
||||
if(count < 0)
|
||||
{
|
||||
count = -count;
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
}
|
||||
// c_tris += count-2;
|
||||
// c_chains++;
|
||||
|
||||
do
|
||||
{
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
float *verts = transformed[order[0]];
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
|
||||
/* texture coordinates come from the draw list */
|
||||
glTexCoord2f(order[2] * tex_w, order[3] * tex_h);
|
||||
order += 4;
|
||||
|
||||
glVertex3fv(verts);
|
||||
// c_verts++;
|
||||
} while(--count);
|
||||
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
3005
engine/gl/gl_model.c
Normal file
3005
engine/gl/gl_model.c
Normal file
File diff suppressed because it is too large
Load diff
817
engine/gl/gl_model.h
Normal file
817
engine/gl/gl_model.h
Normal file
|
@ -0,0 +1,817 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __MODEL__
|
||||
#define __MODEL__
|
||||
|
||||
#include "modelgen.h"
|
||||
#include "spritegn.h"
|
||||
|
||||
struct hull_s;
|
||||
struct trace_s;
|
||||
struct edict_s;
|
||||
|
||||
typedef struct {
|
||||
qboolean (*RecursiveHullCheck) (struct hull_s *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, struct trace_s *trace);
|
||||
int (*HullPointContents) (struct hull_s *hull, vec3_t p); //return FTE contents
|
||||
} hullfuncs_t;
|
||||
|
||||
typedef struct {
|
||||
void (*FatPVS) (vec3_t org, qboolean add);
|
||||
qboolean (*EdictInFatPVS) (struct edict_s *edict);
|
||||
void (*FindTouchedLeafs_Q1) (struct edict_s *ent); //edict system as opposed to q2 game dll system.
|
||||
|
||||
void (*LightPointValues) (vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
|
||||
void (*StainNode) (struct mnode_s *node, float *parms);
|
||||
void (*MarkLights) (struct dlight_s *light, int bit, struct mnode_s *node);
|
||||
|
||||
qbyte *(*LeafPVS) (int num, struct model_s *model, qbyte *buffer);
|
||||
int (*LeafForPoint) (vec3_t point, struct model_s *model);
|
||||
} bspfuncs_t;
|
||||
|
||||
|
||||
typedef struct mesh_s
|
||||
{
|
||||
int numvertexes;
|
||||
vec4_t *xyz_array; //structure is used only at load.
|
||||
vec3_t *normals_array; //so what harm is there in doing this?
|
||||
vec2_t *st_array;
|
||||
vec2_t *lmst_array;
|
||||
byte_vec4_t *colors_array;
|
||||
|
||||
int numindexes;
|
||||
int *indexes;
|
||||
int *trneighbors;
|
||||
vec3_t *trnormals;
|
||||
|
||||
vec3_t mins, maxs;
|
||||
float radius;
|
||||
|
||||
vec3_t lightaxis[3];
|
||||
|
||||
unsigned int patchWidth;
|
||||
unsigned int patchHeight;
|
||||
} mesh_t;
|
||||
|
||||
|
||||
extern int gl_canbumpmap;
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
d*_t structures are on-disk representations
|
||||
m*_t structures are in-memory
|
||||
|
||||
*/
|
||||
|
||||
// entity effects
|
||||
|
||||
#define EF_BRIGHTFIELD 1
|
||||
#define EF_MUZZLEFLASH 2
|
||||
#define EF_BRIGHTLIGHT 4
|
||||
#define EF_DIMLIGHT 8
|
||||
#define EF_FLAG1 16
|
||||
#define EF_FLAG2 32
|
||||
#define EF_BLUE 64
|
||||
#define EF_RED 128
|
||||
|
||||
#define EF_NODRAW 0x80 //this is going to get complicated...
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
BRUSH MODELS
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// in memory representation
|
||||
//
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
typedef struct
|
||||
{
|
||||
vec3_t position;
|
||||
} mvertex_t;
|
||||
|
||||
#define SIDE_FRONT 0
|
||||
#define SIDE_BACK 1
|
||||
#define SIDE_ON 2
|
||||
|
||||
|
||||
// plane_t structure
|
||||
// !!! if this is changed, it must be changed in asm_i386.h too !!!
|
||||
typedef struct mplane_s
|
||||
{
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
qbyte type; // for texture axis selection and fast side tests
|
||||
qbyte signbits; // signx + signy<<1 + signz<<1
|
||||
qbyte pad[2];
|
||||
} mplane_t;
|
||||
|
||||
typedef struct texture_s
|
||||
{
|
||||
char name[64];
|
||||
unsigned width, height;
|
||||
|
||||
qbyte pixbytes;
|
||||
qbyte alphaed; //gl_blend needed on this surface.
|
||||
|
||||
int parttype;
|
||||
|
||||
int gl_texturenum;
|
||||
int gl_texturenumfb;
|
||||
int gl_texturenumbumpmap;
|
||||
struct msurface_s *texturechain; // for gl_texsort drawing
|
||||
int anim_total; // total tenths in sequence ( 0 = no)
|
||||
int anim_min, anim_max; // time for this frame min <=time< max
|
||||
struct texture_s *anim_next; // in the animation sequence
|
||||
struct texture_s *alternate_anims; // bmodels in frmae 1 use these
|
||||
unsigned offsets[MIPLEVELS]; // four mip maps stored
|
||||
} texture_t;
|
||||
|
||||
#define SURF_DRAWSKYBOX 1
|
||||
#define SURF_PLANEBACK 2
|
||||
#define SURF_DRAWSKY 4
|
||||
#define SURF_DRAWSPRITE 8
|
||||
#define SURF_DRAWTURB 0x10
|
||||
#define SURF_DRAWTILED 0x20
|
||||
#define SURF_DRAWBACKGROUND 0x40
|
||||
#define SURF_UNDERWATER 0x80
|
||||
#define SURF_DONTWARP 0x100
|
||||
#define SURF_BULLETEN 0x200
|
||||
#define SURF_DRAWALPHA 0x10000
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
typedef struct
|
||||
{
|
||||
unsigned short v[2];
|
||||
unsigned int cachededgeoffset;
|
||||
} medge_t;
|
||||
|
||||
typedef struct mtexinfo_s
|
||||
{
|
||||
float vecs[2][4];
|
||||
float mipadjust;
|
||||
texture_t *texture;
|
||||
int flags;
|
||||
|
||||
//it's a q2 thing.
|
||||
int numframes;
|
||||
struct mtexinfo_s *next;
|
||||
} mtexinfo_t;
|
||||
|
||||
#define VERTEXSIZE 7
|
||||
|
||||
typedef struct glpoly_s
|
||||
{
|
||||
struct glpoly_s *next;
|
||||
struct glpoly_s *chain;
|
||||
int numverts;
|
||||
int flags; // for SURF_UNDERWATER
|
||||
#ifdef SHADERS
|
||||
float texcenter[2]; //center of texture made by adveraging the tex coords
|
||||
#endif
|
||||
float verts[4][VERTEXSIZE]; // variable sized (xyz s1t1 s2t2)
|
||||
} glpoly_t;
|
||||
|
||||
typedef struct msurface_s
|
||||
{
|
||||
int visframe; // should be drawn when node is crossed
|
||||
int shadowframe;
|
||||
|
||||
mplane_t *plane;
|
||||
int flags;
|
||||
|
||||
int firstedge; // look up in model->surfedges[], negative numbers
|
||||
int numedges; // are backwards edges
|
||||
|
||||
#ifdef SWQUAKE
|
||||
struct surfcache_s *cachespots[MIPLEVELS];
|
||||
#endif
|
||||
struct msurface_s *nextalphasurface;
|
||||
|
||||
short texturemins[2];
|
||||
short extents[2];
|
||||
|
||||
int light_s, light_t; // gl lightmap coordinates
|
||||
|
||||
mesh_t *mesh;
|
||||
entity_t *ownerent;
|
||||
glpoly_t *polys; // multiple if warped
|
||||
vec3_t center; //adverage
|
||||
float radius; //max dist from center
|
||||
struct msurface_s *texturechain;
|
||||
|
||||
vec3_t normal;
|
||||
|
||||
mtexinfo_t *texinfo;
|
||||
|
||||
// lighting info
|
||||
int dlightframe;
|
||||
int dlightbits;
|
||||
|
||||
int lightmaptexturenum;
|
||||
qbyte styles[MAXLIGHTMAPS];
|
||||
int cached_light[MAXLIGHTMAPS]; // values currently used in lightmap
|
||||
qboolean cached_dlight; // true if dynamic light in cache
|
||||
#ifdef PEXT_LIGHTSTYLECOL
|
||||
qbyte cached_colour[MAXLIGHTMAPS];
|
||||
#endif
|
||||
#ifndef NOSTAINS
|
||||
qboolean stained;
|
||||
#endif
|
||||
qbyte *samples; // [numstyles*surfsize]
|
||||
} msurface_t;
|
||||
|
||||
typedef struct mnode_s
|
||||
{
|
||||
// common with leaf
|
||||
int contents; // 0, to differentiate from leafs
|
||||
int visframe; // node needs to be traversed if current
|
||||
int shadowframe;
|
||||
|
||||
float minmaxs[6]; // for bounding box culling
|
||||
|
||||
struct mnode_s *parent;
|
||||
|
||||
// node specific
|
||||
mplane_t *plane;
|
||||
struct mnode_s *children[2];
|
||||
#ifdef Q2BSPS
|
||||
int childnum[2];
|
||||
#endif
|
||||
|
||||
unsigned short firstsurface;
|
||||
unsigned short numsurfaces;
|
||||
} mnode_t;
|
||||
|
||||
|
||||
|
||||
typedef struct mleaf_s
|
||||
{
|
||||
// common with node
|
||||
int contents; // wil be a negative contents number
|
||||
int visframe; // node needs to be traversed if current
|
||||
int shadowframe;
|
||||
|
||||
float minmaxs[6]; // for bounding box culling
|
||||
|
||||
struct mnode_s *parent;
|
||||
|
||||
// leaf specific
|
||||
qbyte *compressed_vis;
|
||||
struct efrag_s *efrags;
|
||||
|
||||
msurface_t **firstmarksurface;
|
||||
int nummarksurfaces;
|
||||
int key; // BSP sequence number for leaf's contents
|
||||
qbyte ambient_sound_level[NUM_AMBIENTS];
|
||||
#ifdef Q2BSPS
|
||||
//it's a q2 thing
|
||||
int cluster;
|
||||
int area;
|
||||
unsigned short firstleafbrush;
|
||||
unsigned short numleafbrushes;
|
||||
|
||||
unsigned short firstleafface; //q3 addititions
|
||||
unsigned short numleaffaces;
|
||||
|
||||
unsigned short numleafpatches;
|
||||
unsigned short firstleafpatch;
|
||||
|
||||
struct mleaf_s *vischain;
|
||||
#endif
|
||||
} mleaf_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float mins[3], maxs[3];
|
||||
float origin[3];
|
||||
int headnode[MAX_MAP_HULLSM];
|
||||
int visleafs; // not including the solid leaf 0
|
||||
int firstface, numfaces;
|
||||
qboolean hullavailable[MAX_MAP_HULLSM];
|
||||
} mmodel_t;
|
||||
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_i386.h too !!!
|
||||
typedef struct hull_s
|
||||
{
|
||||
dclipnode_t *clipnodes;
|
||||
mplane_t *planes;
|
||||
int firstclipnode;
|
||||
int lastclipnode;
|
||||
vec3_t clip_mins;
|
||||
vec3_t clip_maxs;
|
||||
int available;
|
||||
|
||||
hullfuncs_t funcs;
|
||||
} hull_t;
|
||||
|
||||
|
||||
void Q1BSP_SetHullFuncs(hull_t *hull);
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
SPRITE MODELS
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
|
||||
// FIXME: shorten these?
|
||||
typedef struct mspriteframe_s
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
float up, down, left, right;
|
||||
int gl_texturenum;
|
||||
#ifdef SWQUAKE
|
||||
qbyte pixels[4];
|
||||
#endif
|
||||
} mspriteframe_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int numframes;
|
||||
float *intervals;
|
||||
mspriteframe_t *frames[1];
|
||||
} mspritegroup_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
spriteframetype_t type;
|
||||
mspriteframe_t *frameptr;
|
||||
} mspriteframedesc_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int type;
|
||||
int maxwidth;
|
||||
int maxheight;
|
||||
int numframes;
|
||||
float beamlength; // remove?
|
||||
void *cachespot; // remove?
|
||||
mspriteframedesc_t frames[1];
|
||||
} msprite_t;
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
ALIAS MODELS
|
||||
|
||||
Alias models are position independent, so the cache manager can move them.
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int s;
|
||||
int t;
|
||||
} mstvert_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#ifdef SWQUAKE
|
||||
aliasframetype_t type;
|
||||
#endif
|
||||
int firstpose;
|
||||
int numposes;
|
||||
float interval;
|
||||
dtrivertx_t bboxmin;
|
||||
dtrivertx_t bboxmax;
|
||||
|
||||
vec3_t scale;
|
||||
vec3_t scale_origin;
|
||||
|
||||
int frame;
|
||||
char name[16];
|
||||
} maliasframedesc_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
dtrivertx_t bboxmin;
|
||||
dtrivertx_t bboxmax;
|
||||
int frame;
|
||||
} maliasgroupframedesc_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int numframes;
|
||||
int intervals;
|
||||
maliasgroupframedesc_t frames[1];
|
||||
} maliasgroup_t;
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
typedef struct mtriangle_s {
|
||||
int xyz_index[3];
|
||||
int st_index[3];
|
||||
int neighbors[3];
|
||||
} mtriangle_t;
|
||||
|
||||
|
||||
#define MAX_SKINS 32
|
||||
typedef struct {
|
||||
int ident;
|
||||
int version;
|
||||
vec3_t scale;
|
||||
vec3_t scale_origin;
|
||||
float boundingradius;
|
||||
vec3_t eyeposition;
|
||||
int numskins;
|
||||
int skinwidth;
|
||||
int skinheight;
|
||||
int numverts;
|
||||
int numtris;
|
||||
int numframes;
|
||||
synctype_t synctype;
|
||||
int flags;
|
||||
float size;
|
||||
#ifdef SWQUAKE
|
||||
int model;
|
||||
int stverts;
|
||||
int skindesc;
|
||||
#endif
|
||||
int numposes;
|
||||
int poseverts;
|
||||
int posedata; // numposes*poseverts trivert_t
|
||||
|
||||
int baseposedata; //original verts for triangles to reference
|
||||
int triangles; //we need tri data for shadow volumes
|
||||
|
||||
int commands; // gl command list with embedded s/t
|
||||
int gl_texturenum[MAX_SKINS][4];
|
||||
int texels[MAX_SKINS];
|
||||
maliasframedesc_t frames[1]; // variable sized
|
||||
} aliashdr_t;
|
||||
|
||||
#define MAXALIASVERTS 2048
|
||||
#define ALIAS_Z_CLIP_PLANE 5
|
||||
#define MAXALIASFRAMES 256
|
||||
#define MAXALIASTRIS 2048
|
||||
extern aliashdr_t *pheader;
|
||||
extern mstvert_t stverts[MAXALIASVERTS*2];
|
||||
extern mtriangle_t triangles[MAXALIASTRIS];
|
||||
extern dtrivertx_t *poseverts[MAXALIASFRAMES];
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.MD2 triangle model file format
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
// LordHavoc: grabbed this from the Q2 utility source,
|
||||
// renamed a things to avoid conflicts
|
||||
|
||||
#define MD2IDALIASHEADER (('2'<<24)+('P'<<16)+('D'<<8)+'I')
|
||||
#define MD2ALIAS_VERSION 8
|
||||
|
||||
#define MD2MAX_TRIANGLES 4096
|
||||
#define MD2MAX_VERTS 2048
|
||||
#define MD2MAX_FRAMES 512
|
||||
#define MD2MAX_SKINS 32
|
||||
#define MD2MAX_SKINNAME 64
|
||||
// sanity checking size
|
||||
#define MD2MAX_SIZE (1024*4200)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short s;
|
||||
short t;
|
||||
} md2stvert_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short index_xyz[3];
|
||||
short index_st[3];
|
||||
} md2triangle_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
qbyte v[3]; // scaled qbyte to fit in frame mins/maxs
|
||||
qbyte lightnormalindex;
|
||||
} md2trivertx_t;
|
||||
|
||||
#define MD2TRIVERTX_V0 0
|
||||
#define MD2TRIVERTX_V1 1
|
||||
#define MD2TRIVERTX_V2 2
|
||||
#define MD2TRIVERTX_LNI 3
|
||||
#define MD2TRIVERTX_SIZE 4
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float scale[3]; // multiply qbyte verts by this
|
||||
float translate[3]; // then add this
|
||||
char name[16]; // frame name from grabbing
|
||||
md2trivertx_t verts[1]; // variable sized
|
||||
} md2frame_t;
|
||||
|
||||
|
||||
// the glcmd format:
|
||||
// a positive integer starts a tristrip command, followed by that many
|
||||
// vertex structures.
|
||||
// a negative integer starts a trifan command, followed by -x vertexes
|
||||
// a zero indicates the end of the command list.
|
||||
// a vertex consists of a floating point s, a floating point t,
|
||||
// and an integer vertex index.
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ident;
|
||||
int version;
|
||||
|
||||
int skinwidth;
|
||||
int skinheight;
|
||||
int framesize; // qbyte size of each frame
|
||||
|
||||
int num_skins;
|
||||
int num_xyz;
|
||||
int num_st; // greater than num_xyz for seams
|
||||
int num_tris;
|
||||
int num_glcmds; // dwords in strip/fan command list
|
||||
int num_frames;
|
||||
|
||||
int ofs_skins; // each skin is a MAX_SKINNAME string
|
||||
int ofs_st; // qbyte offset from start for stverts
|
||||
int ofs_tris; // offset for dtriangles
|
||||
int ofs_frames; // offset for first frame
|
||||
int ofs_glcmds;
|
||||
int ofs_end; // end of file
|
||||
|
||||
int gl_texturenum[MAX_SKINS];
|
||||
} md2_t;
|
||||
|
||||
#define ALIASTYPE_MDL 1
|
||||
#define ALIASTYPE_MD2 2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//===================================================================
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
qbyte ambient[3];
|
||||
qbyte diffuse[3];
|
||||
qbyte direction[2];
|
||||
} dq3gridlight_t;
|
||||
typedef struct {
|
||||
vec3_t gridBounds;
|
||||
vec3_t gridMins;
|
||||
vec3_t gridSize;
|
||||
int numlightgridelems;
|
||||
dq3gridlight_t lightgrid[1];
|
||||
} q3lightgridinfo_t;
|
||||
|
||||
|
||||
//
|
||||
// Whole model
|
||||
//
|
||||
|
||||
typedef enum {mod_brush, mod_sprite, mod_alias, mod_dummy, mod_halflife} modtype_t;
|
||||
typedef enum {fg_quake, fg_quake2, fg_quake3, fg_halflife, fg_new, fg_doom} fromgame_t; //useful when we have very similar model types. (eg quake/halflife bsps)
|
||||
|
||||
#define EF_ROCKET 1 // leave a trail
|
||||
#define EF_GRENADE 2 // leave a trail
|
||||
#define EF_GIB 4 // leave a trail
|
||||
#define EF_ROTATE 8 // rotate (bonus items)
|
||||
#define EF_TRACER 16 // green split trail
|
||||
#define EF_ZOMGIB 32 // small blood trail
|
||||
#define EF_TRACER2 64 // orange split trail + rotate
|
||||
#define EF_TRACER3 128 // purple trail
|
||||
|
||||
//hexen2.
|
||||
#define EF_FIREBALL 256 // Yellow transparent trail in all directions
|
||||
#define EF_ICE 512 // Blue-white transparent trail, with gravity
|
||||
#define EF_MIP_MAP 1024 // This model has mip-maps
|
||||
#define EF_SPIT 2048 // Black transparent trail with negative light
|
||||
#define EF_TRANSPARENT 4096 // Transparent sprite
|
||||
#define EF_SPELL 8192 // Vertical spray of particles
|
||||
#define EF_HOLEY 16384 // Solid model with color 0
|
||||
#define EF_SPECIAL_TRANS 32768 // Translucency through the particle table
|
||||
#define EF_FACE_VIEW 65536 // Poly Model always faces you
|
||||
#define EF_VORP_MISSILE 131072 // leave a trail at top and bottom of model
|
||||
#define EF_SET_STAFF 262144 // slowly move up and left/right
|
||||
#define EF_MAGICMISSILE 524288 // a trickle of blue/white particles with gravity
|
||||
#define EF_BONESHARD 1048576 // a trickle of brown particles with gravity
|
||||
#define EF_SCARAB 2097152 // white transparent particles with little gravity
|
||||
#define EF_ACIDBALL 4194304 // Green drippy acid shit
|
||||
#define EF_BLOODSHOT 8388608 // Blood rain shot trail
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
int numlinedefs;
|
||||
int numsidedefs;
|
||||
int numsectors;
|
||||
} doom;
|
||||
} specificmodeltype_t;
|
||||
|
||||
typedef struct model_s
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
qboolean needload; // bmodels and sprites don't cache normally
|
||||
|
||||
modtype_t type;
|
||||
fromgame_t fromgame;
|
||||
|
||||
int numframes;
|
||||
synctype_t synctype;
|
||||
|
||||
int flags;
|
||||
int particleeffect;
|
||||
qboolean particleengulphs;
|
||||
int particletrail;
|
||||
qboolean nodefaulttrail;
|
||||
|
||||
qboolean rgblighting; //.lit, halflife.
|
||||
|
||||
//
|
||||
// volume occupied by the model graphics
|
||||
//
|
||||
vec3_t mins, maxs;
|
||||
float radius;
|
||||
|
||||
//
|
||||
// solid volume for clipping
|
||||
//
|
||||
qboolean clipbox;
|
||||
vec3_t clipmins, clipmaxs;
|
||||
|
||||
//
|
||||
// brush model
|
||||
//
|
||||
int firstmodelsurface, nummodelsurfaces;
|
||||
|
||||
int numsubmodels;
|
||||
mmodel_t *submodels;
|
||||
|
||||
int numplanes;
|
||||
mplane_t *planes;
|
||||
|
||||
int numleafs; // number of visible leafs, not counting 0
|
||||
mleaf_t *leafs;
|
||||
|
||||
int numvertexes;
|
||||
mvertex_t *vertexes;
|
||||
|
||||
int numedges;
|
||||
medge_t *edges;
|
||||
|
||||
int numnodes;
|
||||
mnode_t *nodes;
|
||||
|
||||
int numtexinfo;
|
||||
mtexinfo_t *texinfo;
|
||||
|
||||
int numsurfaces;
|
||||
msurface_t *surfaces;
|
||||
|
||||
int numsurfedges;
|
||||
int *surfedges;
|
||||
|
||||
int numclipnodes;
|
||||
dclipnode_t *clipnodes;
|
||||
|
||||
int nummarksurfaces;
|
||||
msurface_t **marksurfaces;
|
||||
|
||||
hull_t hulls[MAX_MAP_HULLSM];
|
||||
|
||||
int numtextures;
|
||||
texture_t **textures;
|
||||
|
||||
qbyte *visdata;
|
||||
void *vis;
|
||||
qbyte *lightdata;
|
||||
qbyte *deluxdata;
|
||||
q3lightgridinfo_t *lightgrid;
|
||||
char *entities;
|
||||
|
||||
struct terrain_s *terrain;
|
||||
|
||||
unsigned checksum;
|
||||
unsigned checksum2;
|
||||
|
||||
|
||||
bspfuncs_t funcs;
|
||||
//
|
||||
// additional model data
|
||||
//
|
||||
cache_user_t cache; // only access through Mod_Extradata
|
||||
|
||||
} model_t;
|
||||
|
||||
//============================================================================
|
||||
/*
|
||||
void Mod_Init (void);
|
||||
void Mod_ClearAll (void);
|
||||
model_t *Mod_ForName (char *name, qboolean crash);
|
||||
model_t *Mod_FindName (char *name);
|
||||
void *Mod_Extradata (model_t *mod); // handles caching
|
||||
void Mod_TouchModel (char *name);
|
||||
|
||||
mleaf_t *Mod_PointInLeaf (float *p, model_t *model);
|
||||
qbyte *Mod_LeafPVS (mleaf_t *leaf, model_t *model);
|
||||
*/
|
||||
#endif // __MODEL__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef Q2BSPS
|
||||
|
||||
#ifdef __cplusplus
|
||||
//#pragma message (" c++ stinks")
|
||||
#else
|
||||
|
||||
void CM_Init(void);
|
||||
|
||||
qboolean CM_SetAreaPortalState (int portalnum, qboolean open);
|
||||
qboolean CM_HeadnodeVisible (int nodenum, qbyte *visbits);
|
||||
qboolean CM_AreasConnected (int area1, int area2);
|
||||
int CM_NumClusters (void);
|
||||
int CM_ClusterSize (void);
|
||||
int CM_LeafContents (int leafnum);
|
||||
int CM_LeafCluster (int leafnum);
|
||||
int CM_LeafArea (int leafnum);
|
||||
int CM_WriteAreaBits (qbyte *buffer, int area);
|
||||
int CM_PointLeafnum (vec3_t p);
|
||||
qbyte *CM_ClusterPVS (int cluster, qbyte *buffer);
|
||||
qbyte *CM_ClusterPHS (int cluster);
|
||||
int CM_BoxLeafnums (vec3_t mins, vec3_t maxs, int *list, int listsize, int *topnode);
|
||||
int CM_PointContents (vec3_t p, int headnode);
|
||||
struct trace_s CM_BoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int headnode, int brushmask);
|
||||
int CM_HeadnodeForBox (vec3_t mins, vec3_t maxs);
|
||||
struct trace_s CM_TransformedBoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int headnode, int brushmask, vec3_t origin, vec3_t angles);
|
||||
|
||||
void Mod_ParseInfoFromEntityLump(char *data);
|
||||
|
||||
qboolean CMQ2_SetAreaPortalState (int portalnum, qboolean open);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SWQUAKE
|
||||
typedef struct
|
||||
{
|
||||
aliasskintype_t type;
|
||||
void *pcachespot;
|
||||
int skin;
|
||||
} maliasskindesc_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int numskins;
|
||||
int intervals;
|
||||
maliasskindesc_t skindescs[1];
|
||||
} maliasskingroup_t;
|
||||
|
||||
#endif
|
||||
#endif //__MODEL__
|
||||
|
||||
|
||||
|
143
engine/gl/gl_ngraph.c
Normal file
143
engine/gl/gl_ngraph.c
Normal file
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// gl_ngraph.c
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "glquake.h"
|
||||
|
||||
extern qbyte *draw_chars; // 8*8 graphic characters
|
||||
|
||||
int netgraphtexture; // netgraph texture
|
||||
|
||||
#define NET_GRAPHHEIGHT 32
|
||||
|
||||
static qbyte ngraph_texels[NET_GRAPHHEIGHT][NET_TIMINGS];
|
||||
|
||||
static void R_LineGraph (int x, int h)
|
||||
{
|
||||
int i;
|
||||
int s;
|
||||
int color;
|
||||
|
||||
s = NET_GRAPHHEIGHT;
|
||||
|
||||
if (h == 10000)
|
||||
color = 0x6f; // yellow
|
||||
else if (h == 9999)
|
||||
color = 0x4f; // red
|
||||
else if (h == 9998)
|
||||
color = 0xd0; // blue
|
||||
else
|
||||
color = 0xfe; // white
|
||||
|
||||
if (h>s)
|
||||
h = s;
|
||||
|
||||
for (i=0 ; i<h ; i++)
|
||||
if (i & 1)
|
||||
ngraph_texels[NET_GRAPHHEIGHT - i - 1][x] = 0xff;
|
||||
else
|
||||
ngraph_texels[NET_GRAPHHEIGHT - i - 1][x] = (qbyte)color;
|
||||
|
||||
for ( ; i<s ; i++)
|
||||
ngraph_texels[NET_GRAPHHEIGHT - i - 1][x] = (qbyte)0xff;
|
||||
}
|
||||
|
||||
void Draw_CharToNetGraph (int x, int y, int num)
|
||||
{
|
||||
int row, col;
|
||||
qbyte *source;
|
||||
int drawline;
|
||||
int nx;
|
||||
|
||||
row = num>>4;
|
||||
col = num&15;
|
||||
source = draw_chars + (row<<10) + (col<<3);
|
||||
|
||||
for (drawline = 8; drawline; drawline--, y++)
|
||||
{
|
||||
for (nx=0 ; nx<8 ; nx++)
|
||||
if (source[nx] != 255)
|
||||
ngraph_texels[y][nx+x] = 0x60 + source[nx];
|
||||
source += 128;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
R_NetGraph
|
||||
==============
|
||||
*/
|
||||
void GLR_NetGraph (void)
|
||||
{
|
||||
int a, x, i, y;
|
||||
int lost;
|
||||
char st[80];
|
||||
unsigned ngraph_pixels[NET_GRAPHHEIGHT][NET_TIMINGS];
|
||||
|
||||
x = 0;
|
||||
lost = CL_CalcNet();
|
||||
for (a=0 ; a<NET_TIMINGS ; a++)
|
||||
{
|
||||
i = (cls.netchan.outgoing_sequence-a) & NET_TIMINGSMASK;
|
||||
R_LineGraph (NET_TIMINGS-1-a, packet_latency[i]);
|
||||
}
|
||||
|
||||
// now load the netgraph texture into gl and draw it
|
||||
for (y = 0; y < NET_GRAPHHEIGHT; y++)
|
||||
for (x = 0; x < NET_TIMINGS; x++)
|
||||
ngraph_pixels[y][x] = d_8to24rgbtable[ngraph_texels[y][x]];
|
||||
|
||||
x = ((vid.width - 320)>>1);
|
||||
x=-x;
|
||||
y = vid.height - sb_lines - 24 - NET_GRAPHHEIGHT - 1;
|
||||
|
||||
M_DrawTextBox (x, y, NET_TIMINGS/8, NET_GRAPHHEIGHT/8 + 1);
|
||||
y += 8;
|
||||
|
||||
sprintf(st, "%3i%% packet loss", lost);
|
||||
Draw_String(8, y, st);
|
||||
y += 8;
|
||||
|
||||
GL_Bind(netgraphtexture);
|
||||
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format,
|
||||
NET_TIMINGS, NET_GRAPHHEIGHT, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, ngraph_pixels);
|
||||
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
x = 8;
|
||||
glColor3f (1,1,1);
|
||||
glBegin (GL_QUADS);
|
||||
glTexCoord2f (0, 0);
|
||||
glVertex2f (x, y);
|
||||
glTexCoord2f (1, 0);
|
||||
glVertex2f (x+NET_TIMINGS, y);
|
||||
glTexCoord2f (1, 1);
|
||||
glVertex2f (x+NET_TIMINGS, y+NET_GRAPHHEIGHT);
|
||||
glTexCoord2f (0, 1);
|
||||
glVertex2f (x, y+NET_GRAPHHEIGHT);
|
||||
glEnd ();
|
||||
}
|
||||
|
2297
engine/gl/gl_ppl.c
Normal file
2297
engine/gl/gl_ppl.c
Normal file
File diff suppressed because it is too large
Load diff
926
engine/gl/gl_rlight.c
Normal file
926
engine/gl/gl_rlight.c
Normal file
|
@ -0,0 +1,926 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// r_light.c
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "glquake.h"
|
||||
|
||||
int r_dlightframecount;
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
R_AnimateLight
|
||||
==================
|
||||
*/
|
||||
void GLR_AnimateLight (void)
|
||||
{
|
||||
int i,j,k;
|
||||
|
||||
//
|
||||
// light animations
|
||||
// 'm' is normal light, 'a' is no light, 'z' is double bright
|
||||
i = (int)(cl.time*10);
|
||||
for (j=0 ; j<MAX_LIGHTSTYLES ; j++)
|
||||
{
|
||||
if (!cl_lightstyle[j].length)
|
||||
{
|
||||
d_lightstylevalue[j] = 256;
|
||||
continue;
|
||||
}
|
||||
k = i % cl_lightstyle[j].length;
|
||||
k = cl_lightstyle[j].map[k] - 'a';
|
||||
k = k*22;
|
||||
d_lightstylevalue[j] = k;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
DYNAMIC LIGHTS BLEND RENDERING
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
void AddLightBlend (float r, float g, float b, float a2)
|
||||
{
|
||||
float a;
|
||||
|
||||
v_blend[3] = a = v_blend[3] + a2*(1-v_blend[3]);
|
||||
|
||||
a2 = a2/a;
|
||||
|
||||
v_blend[0] = v_blend[1]*(1-a2) + r*a2;
|
||||
v_blend[1] = v_blend[1]*(1-a2) + g*a2;
|
||||
v_blend[2] = v_blend[2]*(1-a2) + b*a2;
|
||||
//Con_Printf("AddLightBlend(): %4.2f %4.2f %4.2f %4.6f\n", v_blend[0], v_blend[1], v_blend[2], v_blend[3]);
|
||||
}
|
||||
|
||||
float bubble_sintable[17], bubble_costable[17];
|
||||
|
||||
void R_InitBubble() {
|
||||
float a;
|
||||
int i;
|
||||
float *bub_sin, *bub_cos;
|
||||
|
||||
bub_sin = bubble_sintable;
|
||||
bub_cos = bubble_costable;
|
||||
|
||||
for (i=16 ; i>=0 ; i--)
|
||||
{
|
||||
a = i/16.0 * M_PI*2;
|
||||
*bub_sin++ = sin(a);
|
||||
*bub_cos++ = cos(a);
|
||||
}
|
||||
}
|
||||
|
||||
void R_RenderDlight (dlight_t *light)
|
||||
{
|
||||
int i, j;
|
||||
// float a;
|
||||
vec3_t v;
|
||||
float rad;
|
||||
float *bub_sin, *bub_cos;
|
||||
|
||||
bub_sin = bubble_sintable;
|
||||
bub_cos = bubble_costable;
|
||||
rad = light->radius * 0.35;
|
||||
|
||||
VectorSubtract (light->origin, r_origin, v);
|
||||
if (Length (v) < rad)
|
||||
{ // view is inside the dlight
|
||||
AddLightBlend (1, 0.5, 0, light->radius * 0.0003);
|
||||
return;
|
||||
}
|
||||
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
// glColor3f (0.2,0.1,0.0);
|
||||
// glColor3f (0.2,0.1,0.05); // changed dimlight effect
|
||||
glColor4f (light->color[0]*2, light->color[1]*2, light->color[2]*2,
|
||||
1);//light->color[3]);
|
||||
for (i=0 ; i<3 ; i++)
|
||||
v[i] = light->origin[i] - vpn[i]*rad/1.5;
|
||||
glVertex3fv (v);
|
||||
glColor3f (0,0,0);
|
||||
for (i=16 ; i>=0 ; i--)
|
||||
{
|
||||
// a = i/16.0 * M_PI*2;
|
||||
for (j=0 ; j<3 ; j++)
|
||||
v[j] = light->origin[j] + (vright[j]*(*bub_cos) +
|
||||
+ vup[j]*(*bub_sin)) * rad;
|
||||
bub_sin++;
|
||||
bub_cos++;
|
||||
glVertex3fv (v);
|
||||
}
|
||||
glEnd ();
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_RenderDlights
|
||||
=============
|
||||
*/
|
||||
void R_RenderDlights (void)
|
||||
{
|
||||
int i;
|
||||
dlight_t *l;
|
||||
|
||||
if (!r_flashblend.value)
|
||||
return;
|
||||
|
||||
// r_dlightframecount = r_framecount + 1; // because the count hasn't
|
||||
// advanced yet for this frame
|
||||
glDepthMask (0);
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
glShadeModel (GL_SMOOTH);
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (GL_ONE, GL_ONE);
|
||||
|
||||
l = cl_dlights;
|
||||
for (i=0 ; i<MAX_DLIGHTS ; i++, l++)
|
||||
{
|
||||
if (l->die < cl.time || !l->radius)
|
||||
continue;
|
||||
R_RenderDlight (l);
|
||||
}
|
||||
|
||||
glColor3f (1,1,1);
|
||||
glDisable (GL_BLEND);
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDepthMask (1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
DYNAMIC LIGHTS
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
=============
|
||||
R_MarkLights
|
||||
=============
|
||||
*/
|
||||
/*void GLR_MarkLights (dlight_t *light, int bit, mnode_t *node)
|
||||
{
|
||||
mplane_t *splitplane;
|
||||
float dist;
|
||||
msurface_t *surf;
|
||||
int i;
|
||||
|
||||
if (node->contents < 0)
|
||||
return;
|
||||
|
||||
splitplane = node->plane;
|
||||
dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist;
|
||||
|
||||
if (dist > light->radius)
|
||||
{
|
||||
GLR_MarkLights (light, bit, node->children[0]);
|
||||
return;
|
||||
}
|
||||
if (dist < -light->radius)
|
||||
{
|
||||
GLR_MarkLights (light, bit, node->children[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
// mark the polygons
|
||||
surf = cl.worldmodel->surfaces + node->firstsurface;
|
||||
for (i=0 ; i<node->numsurfaces ; i++, surf++)
|
||||
{
|
||||
if (surf->dlightframe != r_dlightframecount)
|
||||
{
|
||||
surf->dlightbits = 0;
|
||||
surf->dlightframe = r_dlightframecount;
|
||||
}
|
||||
surf->dlightbits |= bit;
|
||||
}
|
||||
|
||||
GLR_MarkLights (light, bit, node->children[0]);
|
||||
GLR_MarkLights (light, bit, node->children[1]);
|
||||
}*/
|
||||
/*void Q2BSP_MarkLights (dlight_t *light, int bit, mnode_t *node)
|
||||
{
|
||||
mplane_t *splitplane;
|
||||
float dist;
|
||||
msurface_t *surf;
|
||||
int i;
|
||||
|
||||
if (node->contents != -1)
|
||||
return;
|
||||
|
||||
splitplane = node->plane;
|
||||
dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist;
|
||||
|
||||
if (dist > light->radius)
|
||||
{
|
||||
Q2BSP_MarkLights (light, bit, node->children[0]);
|
||||
return;
|
||||
}
|
||||
if (dist < -light->radius)
|
||||
{
|
||||
Q2BSP_MarkLights (light, bit, node->children[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
// mark the polygons
|
||||
surf = cl.worldmodel->surfaces + node->firstsurface;
|
||||
for (i=0 ; i<node->numsurfaces ; i++, surf++)
|
||||
{
|
||||
if (surf->dlightframe != r_dlightframecount)
|
||||
{
|
||||
surf->dlightbits = 0;
|
||||
surf->dlightframe = r_dlightframecount;
|
||||
}
|
||||
surf->dlightbits |= bit;
|
||||
}
|
||||
|
||||
Q2BSP_MarkLights (light, bit, node->children[0]);
|
||||
Q2BSP_MarkLights (light, bit, node->children[1]);
|
||||
}*/
|
||||
|
||||
void GLR_MarkQ3Lights (dlight_t *light, int bit, mnode_t *node)
|
||||
{
|
||||
mplane_t *splitplane;
|
||||
float dist;
|
||||
msurface_t *surf;
|
||||
int i;
|
||||
|
||||
return; //we need to get the texinfos right first.
|
||||
|
||||
/*
|
||||
//mark all
|
||||
for (surf = cl.worldmodel->surfaces, i = 0; i < cl.worldmodel->numsurfaces; i++, surf++)
|
||||
{
|
||||
if (surf->dlightframe != r_dlightframecount)
|
||||
{
|
||||
surf->dlightbits = 0;
|
||||
surf->dlightframe = r_dlightframecount;
|
||||
}
|
||||
surf->dlightbits |= bit;
|
||||
}
|
||||
return;
|
||||
*/
|
||||
if (node->contents != -1)
|
||||
{
|
||||
msurface_t **mark;
|
||||
mleaf_t *leaf;
|
||||
|
||||
// mark the polygons
|
||||
leaf = (mleaf_t *)node;
|
||||
mark = leaf->firstmarksurface;
|
||||
for (i=0 ; i<leaf->nummarksurfaces ; i++, surf++)
|
||||
{
|
||||
surf = *mark++;
|
||||
if (surf->dlightframe != r_dlightframecount)
|
||||
{
|
||||
surf->dlightbits = 0;
|
||||
surf->dlightframe = r_dlightframecount;
|
||||
}
|
||||
surf->dlightbits |= bit;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
splitplane = node->plane;
|
||||
dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist;
|
||||
|
||||
if (dist > light->radius)
|
||||
{
|
||||
GLR_MarkQ3Lights (light, bit, node->children[0]);
|
||||
return;
|
||||
}
|
||||
if (dist < -light->radius)
|
||||
{
|
||||
GLR_MarkQ3Lights (light, bit, node->children[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
GLR_MarkQ3Lights (light, bit, node->children[0]);
|
||||
GLR_MarkQ3Lights (light, bit, node->children[1]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
R_PushDlights
|
||||
=============
|
||||
*/
|
||||
void GLR_PushDlights (void)
|
||||
{
|
||||
int i;
|
||||
dlight_t *l;
|
||||
|
||||
r_dlightframecount = r_framecount + 1; // because the count hasn't
|
||||
// advanced yet for this frame
|
||||
|
||||
if (!r_dynamic.value)
|
||||
return;
|
||||
|
||||
// if (!cl.worldmodel->nodes)
|
||||
// return;
|
||||
|
||||
|
||||
l = cl_dlights;
|
||||
for (i=0 ; i<MAX_DLIGHTS ; i++, l++)
|
||||
{
|
||||
if (l->die < cl.time || !l->radius)
|
||||
continue;
|
||||
cl.worldmodel->funcs.MarkLights( l, 1<<i, cl.worldmodel->nodes );
|
||||
}
|
||||
|
||||
/*
|
||||
if (cl.worldmodel->fromgame == fg_quake3)
|
||||
{
|
||||
for (i=0 ; i<MAX_DLIGHTS ; i++, l++)
|
||||
{
|
||||
if (l->die < cl.time || !l->radius)
|
||||
continue;
|
||||
GLR_MarkQ3Lights ( l, 1<<i, cl.worldmodel->nodes );
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (cl.worldmodel->fromgame == fg_quake2)
|
||||
{
|
||||
for (i=0 ; i<MAX_DLIGHTS ; i++, l++)
|
||||
{
|
||||
if (l->die < cl.time || !l->radius)
|
||||
continue;
|
||||
GLR_MarkQ2Lights ( l, 1<<i, cl.worldmodel->nodes );
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (i=0 ; i<MAX_DLIGHTS ; i++, l++)
|
||||
{
|
||||
if (l->die < cl.time || !l->radius)
|
||||
continue;
|
||||
GLR_MarkLights ( l, 1<<i, cl.worldmodel->nodes );
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
LIGHT SAMPLING
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
mplane_t *lightplane;
|
||||
vec3_t lightspot;
|
||||
|
||||
void GLQ3_LightGrid(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir)
|
||||
{
|
||||
q3lightgridinfo_t *lg = (q3lightgridinfo_t *)cl.worldmodel->lightgrid;
|
||||
int index[4];
|
||||
int vi[3];
|
||||
int i, j;
|
||||
float t[8], direction_uv[3];
|
||||
vec3_t vf, vf2;
|
||||
vec3_t ambient, diffuse;
|
||||
|
||||
res_dir[0] = 1;
|
||||
res_dir[1] = 1;
|
||||
res_dir[2] = 0.1;
|
||||
|
||||
if (!lg)
|
||||
{
|
||||
res_ambient[0] = 255;
|
||||
res_ambient[1] = 255;
|
||||
res_ambient[2] = 255;
|
||||
return;
|
||||
}
|
||||
|
||||
//If in doubt, steal someone else's code...
|
||||
//Thanks QFusion.
|
||||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
vf[i] = (point[i] - lg->gridMins[i]) / lg->gridSize[i];
|
||||
vi[i] = (int)vf[i];
|
||||
vf[i] = vf[i] - floor(vf[i]);
|
||||
vf2[i] = 1.0f - vf[i];
|
||||
}
|
||||
|
||||
index[0] = vi[2]*lg->gridBounds[3] + vi[1]*lg->gridBounds[0] + vi[0];
|
||||
index[1] = index[0] + lg->gridBounds[0];
|
||||
index[2] = index[0] + lg->gridBounds[3];
|
||||
index[3] = index[2] + lg->gridBounds[0];
|
||||
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
if ( index[i] < 0 || index[i] >= (lg->numlightgridelems-1) )
|
||||
{
|
||||
res_ambient[0] = 255; //out of the map
|
||||
res_ambient[1] = 255;
|
||||
res_ambient[2] = 255;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
t[0] = vf2[0] * vf2[1] * vf2[2];
|
||||
t[1] = vf[0] * vf2[1] * vf2[2];
|
||||
t[2] = vf2[0] * vf[1] * vf2[2];
|
||||
t[3] = vf[0] * vf[1] * vf2[2];
|
||||
t[4] = vf2[0] * vf2[1] * vf[2];
|
||||
t[5] = vf[0] * vf2[1] * vf[2];
|
||||
t[6] = vf2[0] * vf[1] * vf[2];
|
||||
t[7] = vf[0] * vf[1] * vf[2];
|
||||
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
ambient[j] = 0;
|
||||
diffuse[j] = 0;
|
||||
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
ambient[j] += t[i*2] * lg->lightgrid[ index[i] ].ambient[j];
|
||||
ambient[j] += t[i*2+1] * lg->lightgrid[ index[i] + 1 ].ambient[j];
|
||||
|
||||
diffuse[j] += t[i*2] * lg->lightgrid[ index[i] ].diffuse[j];
|
||||
diffuse[j] += t[i*2+1] * lg->lightgrid[ index[i] + 1 ].diffuse[j];
|
||||
}
|
||||
}
|
||||
|
||||
for ( j = 0; j < 2; j++ )
|
||||
{
|
||||
direction_uv[j] = 0;
|
||||
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
direction_uv[j] += t[i*2] * lg->lightgrid[ index[i] ].direction[j];
|
||||
direction_uv[j] += t[i*2+1] * lg->lightgrid[ index[i] + 1 ].direction[j];
|
||||
}
|
||||
|
||||
direction_uv[j] = anglemod ( direction_uv[j] );
|
||||
}
|
||||
|
||||
VectorCopy(ambient, res_ambient);
|
||||
if (res_diffuse)
|
||||
VectorCopy(diffuse, res_diffuse);
|
||||
if (res_dir)
|
||||
{
|
||||
vec3_t right, left;
|
||||
direction_uv[2] = 0;
|
||||
AngleVectors(direction_uv, res_dir, right, left);
|
||||
}
|
||||
}
|
||||
|
||||
int GLRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
|
||||
{
|
||||
int r;
|
||||
float front, back, frac;
|
||||
int side;
|
||||
mplane_t *plane;
|
||||
vec3_t mid;
|
||||
msurface_t *surf;
|
||||
int s, t, ds, dt;
|
||||
int i;
|
||||
mtexinfo_t *tex;
|
||||
qbyte *lightmap;
|
||||
unsigned scale;
|
||||
int maps;
|
||||
|
||||
if (cl.worldmodel->fromgame == fg_quake2)
|
||||
{
|
||||
if (node->contents != -1)
|
||||
return -1; // solid
|
||||
}
|
||||
else if (node->contents < 0)
|
||||
return -1; // didn't hit anything
|
||||
|
||||
// calculate mid point
|
||||
|
||||
// FIXME: optimize for axial
|
||||
plane = node->plane;
|
||||
front = DotProduct (start, plane->normal) - plane->dist;
|
||||
back = DotProduct (end, plane->normal) - plane->dist;
|
||||
side = front < 0;
|
||||
|
||||
if ( (back < 0) == side)
|
||||
return GLRecursiveLightPoint (node->children[side], start, end);
|
||||
|
||||
frac = front / (front-back);
|
||||
mid[0] = start[0] + (end[0] - start[0])*frac;
|
||||
mid[1] = start[1] + (end[1] - start[1])*frac;
|
||||
mid[2] = start[2] + (end[2] - start[2])*frac;
|
||||
|
||||
// go down front side
|
||||
r = GLRecursiveLightPoint (node->children[side], start, mid);
|
||||
if (r >= 0)
|
||||
return r; // hit something
|
||||
|
||||
if ( (back < 0) == side )
|
||||
return -1; // didn't hit anuthing
|
||||
|
||||
// check for impact on this node
|
||||
VectorCopy (mid, lightspot);
|
||||
lightplane = plane;
|
||||
|
||||
surf = cl.worldmodel->surfaces + node->firstsurface;
|
||||
for (i=0 ; i<node->numsurfaces ; i++, surf++)
|
||||
{
|
||||
if (surf->flags & SURF_DRAWTILED)
|
||||
continue; // no lightmaps
|
||||
|
||||
tex = surf->texinfo;
|
||||
|
||||
s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3];
|
||||
t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3];;
|
||||
|
||||
if (s < surf->texturemins[0] ||
|
||||
t < surf->texturemins[1])
|
||||
continue;
|
||||
|
||||
ds = s - surf->texturemins[0];
|
||||
dt = t - surf->texturemins[1];
|
||||
|
||||
if ( ds > surf->extents[0] || dt > surf->extents[1] )
|
||||
continue;
|
||||
|
||||
if (!surf->samples)
|
||||
return 0;
|
||||
|
||||
ds >>= 4;
|
||||
dt >>= 4;
|
||||
|
||||
lightmap = surf->samples;
|
||||
r = 0;
|
||||
if (lightmap)
|
||||
{
|
||||
if (cl.worldmodel->rgblighting)
|
||||
{
|
||||
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3;
|
||||
|
||||
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
|
||||
maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]];
|
||||
r += (lightmap[0]+lightmap[1]+lightmap[2]) * scale / 3;
|
||||
lightmap += ((surf->extents[0]>>4)+1) *
|
||||
((surf->extents[1]>>4)+1)*3;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
lightmap += dt * ((surf->extents[0]>>4)+1) + ds;
|
||||
|
||||
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
|
||||
maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]];
|
||||
r += *lightmap * scale;
|
||||
lightmap += ((surf->extents[0]>>4)+1) *
|
||||
((surf->extents[1]>>4)+1);
|
||||
}
|
||||
}
|
||||
|
||||
r >>= 8;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// go down back side
|
||||
return GLRecursiveLightPoint (node->children[!side], mid, end);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int GLR_LightPoint (vec3_t p)
|
||||
{
|
||||
vec3_t end;
|
||||
int r;
|
||||
|
||||
if (r_refdef.flags & 1)
|
||||
return 255;
|
||||
|
||||
if (!cl.worldmodel || !cl.worldmodel->lightdata)
|
||||
return 255;
|
||||
|
||||
if (cl.worldmodel->fromgame == fg_quake3)
|
||||
{
|
||||
GLQ3_LightGrid(p, NULL, end, NULL);
|
||||
return (end[0] + end[1] + end[2])/3;
|
||||
}
|
||||
|
||||
end[0] = p[0];
|
||||
end[1] = p[1];
|
||||
end[2] = p[2] - 2048;
|
||||
|
||||
r = GLRecursiveLightPoint (cl.worldmodel->nodes, p, end);
|
||||
|
||||
if (r == -1)
|
||||
r = 0;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef PEXT_LIGHTSTYLECOL
|
||||
|
||||
float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
|
||||
{
|
||||
static float l[6];
|
||||
float *r;
|
||||
float front, back, frac;
|
||||
int side;
|
||||
mplane_t *plane;
|
||||
vec3_t mid;
|
||||
msurface_t *surf;
|
||||
int s, t, ds, dt;
|
||||
int i;
|
||||
mtexinfo_t *tex;
|
||||
qbyte *lightmap, *deluxmap;
|
||||
float scale;
|
||||
int maps;
|
||||
|
||||
if (cl.worldmodel->fromgame == fg_quake2)
|
||||
{
|
||||
if (node->contents != -1)
|
||||
return NULL; // solid
|
||||
}
|
||||
else if (node->contents < 0)
|
||||
return NULL; // didn't hit anything
|
||||
|
||||
// calculate mid point
|
||||
|
||||
// FIXME: optimize for axial
|
||||
plane = node->plane;
|
||||
front = DotProduct (start, plane->normal) - plane->dist;
|
||||
back = DotProduct (end, plane->normal) - plane->dist;
|
||||
side = front < 0;
|
||||
|
||||
if ( (back < 0) == side)
|
||||
return GLRecursiveLightPoint3C (node->children[side], start, end);
|
||||
|
||||
frac = front / (front-back);
|
||||
mid[0] = start[0] + (end[0] - start[0])*frac;
|
||||
mid[1] = start[1] + (end[1] - start[1])*frac;
|
||||
mid[2] = start[2] + (end[2] - start[2])*frac;
|
||||
|
||||
// go down front side
|
||||
r = GLRecursiveLightPoint3C (node->children[side], start, mid);
|
||||
if (r && r[0]+r[1]+r[2] >= 0)
|
||||
return r; // hit something
|
||||
|
||||
if ( (back < 0) == side )
|
||||
return NULL; // didn't hit anuthing
|
||||
|
||||
// check for impact on this node
|
||||
VectorCopy (mid, lightspot);
|
||||
lightplane = plane;
|
||||
|
||||
surf = cl.worldmodel->surfaces + node->firstsurface;
|
||||
for (i=0 ; i<node->numsurfaces ; i++, surf++)
|
||||
{
|
||||
if (surf->flags & SURF_DRAWTILED)
|
||||
continue; // no lightmaps
|
||||
|
||||
tex = surf->texinfo;
|
||||
|
||||
s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3];
|
||||
t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3];
|
||||
|
||||
if (s < surf->texturemins[0] ||
|
||||
t < surf->texturemins[1])
|
||||
continue;
|
||||
|
||||
ds = s - surf->texturemins[0];
|
||||
dt = t - surf->texturemins[1];
|
||||
|
||||
if ( ds > surf->extents[0] || dt > surf->extents[1] )
|
||||
continue;
|
||||
|
||||
if (!surf->samples)
|
||||
{
|
||||
l[0]=0;l[1]=0;l[2]=0;
|
||||
l[3]=0;l[4]=1;l[5]=1;
|
||||
return l;
|
||||
}
|
||||
|
||||
ds >>= 4;
|
||||
dt >>= 4;
|
||||
|
||||
lightmap = surf->samples;
|
||||
l[0]=0;l[1]=0;l[2]=0;
|
||||
l[3]=0;l[4]=0;l[5]=0;
|
||||
if (lightmap)
|
||||
{
|
||||
if (cl.worldmodel->deluxdata)
|
||||
{
|
||||
if (cl.worldmodel->rgblighting)
|
||||
{
|
||||
deluxmap = surf->samples - cl.worldmodel->lightdata + cl.worldmodel->deluxdata;
|
||||
|
||||
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3;
|
||||
deluxmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3;
|
||||
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
|
||||
maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]]/256.0f;
|
||||
|
||||
if (cl_lightstyle[surf->styles[maps]].colour & 1)
|
||||
l[0] += lightmap[0] * scale;
|
||||
if (cl_lightstyle[surf->styles[maps]].colour & 2)
|
||||
l[1] += lightmap[1] * scale;
|
||||
if (cl_lightstyle[surf->styles[maps]].colour & 4)
|
||||
l[2] += lightmap[2] * scale;
|
||||
|
||||
l[3] += (deluxmap[0]-127)*scale;
|
||||
l[4] += (deluxmap[1]-127)*scale;
|
||||
l[5] += (deluxmap[2]-127)*scale;
|
||||
|
||||
lightmap += ((surf->extents[0]>>4)+1) *
|
||||
((surf->extents[1]>>4)+1) * 3;
|
||||
deluxmap += ((surf->extents[0]>>4)+1) *
|
||||
((surf->extents[1]>>4)+1) * 3;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
deluxmap = (surf->samples - cl.worldmodel->lightdata)*3 + cl.worldmodel->deluxdata;
|
||||
|
||||
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds);
|
||||
deluxmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3;
|
||||
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
|
||||
maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]]/256.0f;
|
||||
|
||||
if (cl_lightstyle[surf->styles[maps]].colour & 1)
|
||||
l[0] += *lightmap * scale;
|
||||
if (cl_lightstyle[surf->styles[maps]].colour & 2)
|
||||
l[1] += *lightmap * scale;
|
||||
if (cl_lightstyle[surf->styles[maps]].colour & 4)
|
||||
l[2] += *lightmap * scale;
|
||||
|
||||
l[3] += deluxmap[0]*scale;
|
||||
l[4] += deluxmap[1]*scale;
|
||||
l[5] += deluxmap[2]*scale;
|
||||
|
||||
lightmap += ((surf->extents[0]>>4)+1) *
|
||||
((surf->extents[1]>>4)+1);
|
||||
deluxmap += ((surf->extents[0]>>4)+1) *
|
||||
((surf->extents[1]>>4)+1) * 3;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cl.worldmodel->rgblighting)
|
||||
{
|
||||
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3;
|
||||
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
|
||||
maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]]/256.0f;
|
||||
|
||||
if (cl_lightstyle[surf->styles[maps]].colour & 1)
|
||||
l[0] += lightmap[0] * scale;
|
||||
if (cl_lightstyle[surf->styles[maps]].colour & 2)
|
||||
l[1] += lightmap[1] * scale;
|
||||
if (cl_lightstyle[surf->styles[maps]].colour & 4)
|
||||
l[2] += lightmap[2] * scale;
|
||||
|
||||
lightmap += ((surf->extents[0]>>4)+1) *
|
||||
((surf->extents[1]>>4)+1) * 3;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds);
|
||||
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
|
||||
maps++)
|
||||
{
|
||||
scale = d_lightstylevalue[surf->styles[maps]]/256.0f;
|
||||
|
||||
if (cl_lightstyle[surf->styles[maps]].colour & 1)
|
||||
l[0] += *lightmap * scale;
|
||||
if (cl_lightstyle[surf->styles[maps]].colour & 2)
|
||||
l[1] += *lightmap * scale;
|
||||
if (cl_lightstyle[surf->styles[maps]].colour & 4)
|
||||
l[2] += *lightmap * scale;
|
||||
|
||||
lightmap += ((surf->extents[0]>>4)+1) *
|
||||
((surf->extents[1]>>4)+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
// go down back side
|
||||
return GLRecursiveLightPoint3C (node->children[!side], mid, end);
|
||||
}
|
||||
|
||||
float *GLR_LightPoint3C (vec3_t p)
|
||||
{
|
||||
static vec3_t l = {255, 255, 255};
|
||||
static vec3_t nl = {0, 0, 0};
|
||||
float *r;
|
||||
vec3_t end;
|
||||
|
||||
if (!cl.worldmodel->lightdata)
|
||||
{
|
||||
return l;
|
||||
}
|
||||
|
||||
if (cl.worldmodel->fromgame == fg_quake3)
|
||||
return nl;
|
||||
|
||||
if (cl.worldmodel->fromgame == fg_doom)
|
||||
return nl;
|
||||
|
||||
end[0] = p[0];
|
||||
end[1] = p[1];
|
||||
end[2] = p[2] - 2048;
|
||||
|
||||
r = GLRecursiveLightPoint3C (cl.worldmodel->nodes, p, end);
|
||||
|
||||
if (r == NULL)
|
||||
return nl;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void GLQ1BSP_LightPointValues(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir)
|
||||
{
|
||||
vec3_t end;
|
||||
float *r;
|
||||
|
||||
end[0] = point[0];
|
||||
end[1] = point[1];
|
||||
end[2] = point[2] - 2048;
|
||||
|
||||
r = GLRecursiveLightPoint3C(cl.worldmodel->nodes, point, end);
|
||||
if (r == NULL)
|
||||
{
|
||||
res_diffuse[0] = 0;
|
||||
res_diffuse[1] = 0;
|
||||
res_diffuse[2] = 0;
|
||||
|
||||
res_ambient[0] = 0;
|
||||
res_ambient[1] = 0;
|
||||
res_ambient[2] = 0;
|
||||
|
||||
res_dir[0] = 0;
|
||||
res_dir[1] = 1;
|
||||
res_dir[2] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
res_diffuse[0] = r[0];
|
||||
res_diffuse[1] = r[1];
|
||||
res_diffuse[2] = r[2];
|
||||
|
||||
res_ambient[0] = r[0];
|
||||
res_ambient[1] = r[1];
|
||||
res_ambient[2] = r[2];
|
||||
|
||||
res_dir[0] = r[3];
|
||||
res_dir[1] = r[4];
|
||||
res_dir[2] = -r[5];
|
||||
VectorNormalize(res_dir);
|
||||
|
||||
if (!res_dir[0] && !res_dir[1] && !res_dir[2])
|
||||
res_dir[1] = res_dir[2] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
1607
engine/gl/gl_rmain.c
Normal file
1607
engine/gl/gl_rmain.c
Normal file
File diff suppressed because it is too large
Load diff
940
engine/gl/gl_rmisc.c
Normal file
940
engine/gl/gl_rmisc.c
Normal file
|
@ -0,0 +1,940 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// r_misc.c
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "glquake.h"
|
||||
|
||||
#ifdef WATERLAYERS
|
||||
cvar_t r_waterlayers = {"r_waterlayers","3"};
|
||||
#endif
|
||||
|
||||
cvar_t gl_skyboxname = {"r_skybox", ""};
|
||||
|
||||
extern void R_InitBubble();
|
||||
|
||||
/*
|
||||
==================
|
||||
R_InitTextures
|
||||
==================
|
||||
*
|
||||
void GLR_InitTextures (void)
|
||||
{
|
||||
int x,y, m;
|
||||
qbyte *dest;
|
||||
|
||||
// create a simple checkerboard texture for the default
|
||||
r_notexture_mip = Hunk_AllocName (sizeof(texture_t) + 16*16+8*8+4*4+2*2, "notexture");
|
||||
|
||||
r_notexture_mip->width = r_notexture_mip->height = 16;
|
||||
r_notexture_mip->offsets[0] = sizeof(texture_t);
|
||||
r_notexture_mip->offsets[1] = r_notexture_mip->offsets[0] + 16*16;
|
||||
r_notexture_mip->offsets[2] = r_notexture_mip->offsets[1] + 8*8;
|
||||
r_notexture_mip->offsets[3] = r_notexture_mip->offsets[2] + 4*4;
|
||||
|
||||
for (m=0 ; m<4 ; m++)
|
||||
{
|
||||
dest = (qbyte *)r_notexture_mip + r_notexture_mip->offsets[m];
|
||||
for (y=0 ; y< (16>>m) ; y++)
|
||||
for (x=0 ; x< (16>>m) ; x++)
|
||||
{
|
||||
if ( (y< (8>>m) ) ^ (x< (8>>m) ) )
|
||||
*dest++ = 0;
|
||||
else
|
||||
*dest++ = 0xff;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
//we could go for nice smooth round particles... but then we would loose a little bit of the chaotic nature of the particles.
|
||||
static qbyte dottexture[8][8] =
|
||||
{
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,1,1,0,0,0},
|
||||
{0,0,1,1,1,1,0,0},
|
||||
{0,1,1,1,1,1,1,0},
|
||||
{0,1,1,1,1,1,1,0},
|
||||
{0,0,1,1,1,1,0,0},
|
||||
{0,0,0,1,1,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
};
|
||||
static qbyte exptexture[16][16] =
|
||||
{
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0},
|
||||
{0,0,0,1,1,1,1,1,3,1,1,2,1,0,0,0},
|
||||
{0,0,0,1,1,1,1,4,4,4,5,4,2,1,1,0},
|
||||
{0,0,1,1,6,5,5,8,6,8,3,6,3,2,1,0},
|
||||
{0,0,1,5,6,7,5,6,8,8,8,3,3,1,0,0},
|
||||
{0,0,0,1,6,8,9,9,9,9,4,6,3,1,0,0},
|
||||
{0,0,2,1,7,7,9,9,9,9,5,3,1,0,0,0},
|
||||
{0,0,2,4,6,8,9,9,9,9,8,6,1,0,0,0},
|
||||
{0,0,2,2,3,5,6,8,9,8,8,4,4,1,0,0},
|
||||
{0,0,1,2,4,1,8,7,8,8,6,5,4,1,0,0},
|
||||
{0,1,1,1,7,8,1,6,7,5,4,7,1,0,0,0},
|
||||
{0,1,2,1,1,5,1,3,4,3,1,1,0,0,0,0},
|
||||
{0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
};
|
||||
void R_InitParticleTexture (void)
|
||||
{
|
||||
int x,y;
|
||||
qbyte data[16*16][4];
|
||||
|
||||
//
|
||||
// particle texture
|
||||
//
|
||||
particletexture = texture_extension_number++;
|
||||
GL_Bind(particletexture);
|
||||
|
||||
for (x=0 ; x<8 ; x++)
|
||||
{
|
||||
for (y=0 ; y<8 ; y++)
|
||||
{
|
||||
data[y*8+x][0] = 255;
|
||||
data[y*8+x][1] = 255;
|
||||
data[y*8+x][2] = 255;
|
||||
data[y*8+x][3] = dottexture[x][y]*255;
|
||||
}
|
||||
}
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
|
||||
|
||||
|
||||
explosiontexture = texture_extension_number++;
|
||||
GL_Bind(explosiontexture);
|
||||
|
||||
for (x=0 ; x<16 ; x++)
|
||||
{
|
||||
for (y=0 ; y<16 ; y++)
|
||||
{
|
||||
data[y*16+x][0] = 255;
|
||||
data[y*16+x][1] = 255;
|
||||
data[y*16+x][2] = 255;
|
||||
data[y*16+x][3] = exptexture[x][y]*255/9.0;
|
||||
}
|
||||
}
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_Envmap_f
|
||||
|
||||
Grab six views for environment mapping tests
|
||||
===============
|
||||
*/
|
||||
void R_Envmap_f (void)
|
||||
{
|
||||
qbyte buffer[256*256*4];
|
||||
|
||||
glDrawBuffer (GL_FRONT);
|
||||
glReadBuffer (GL_FRONT);
|
||||
envmap = true;
|
||||
|
||||
r_refdef.vrect.x = 0;
|
||||
r_refdef.vrect.y = 0;
|
||||
r_refdef.vrect.width = 256;
|
||||
r_refdef.vrect.height = 256;
|
||||
|
||||
r_refdef.viewangles[0] = 0;
|
||||
r_refdef.viewangles[1] = 0;
|
||||
r_refdef.viewangles[2] = 0;
|
||||
GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
|
||||
R_RenderView ();
|
||||
glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
||||
COM_WriteFile ("env0.rgb", buffer, sizeof(buffer));
|
||||
|
||||
r_refdef.viewangles[1] = 90;
|
||||
GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
|
||||
R_RenderView ();
|
||||
glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
||||
COM_WriteFile ("env1.rgb", buffer, sizeof(buffer));
|
||||
|
||||
r_refdef.viewangles[1] = 180;
|
||||
GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
|
||||
R_RenderView ();
|
||||
glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
||||
COM_WriteFile ("env2.rgb", buffer, sizeof(buffer));
|
||||
|
||||
r_refdef.viewangles[1] = 270;
|
||||
GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
|
||||
R_RenderView ();
|
||||
glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
||||
COM_WriteFile ("env3.rgb", buffer, sizeof(buffer));
|
||||
|
||||
r_refdef.viewangles[0] = -90;
|
||||
r_refdef.viewangles[1] = 0;
|
||||
GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
|
||||
R_RenderView ();
|
||||
glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
||||
COM_WriteFile ("env4.rgb", buffer, sizeof(buffer));
|
||||
|
||||
r_refdef.viewangles[0] = 90;
|
||||
r_refdef.viewangles[1] = 0;
|
||||
GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
|
||||
R_RenderView ();
|
||||
glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
||||
COM_WriteFile ("env5.rgb", buffer, sizeof(buffer));
|
||||
|
||||
envmap = false;
|
||||
glDrawBuffer (GL_BACK);
|
||||
glReadBuffer (GL_BACK);
|
||||
GL_EndRendering ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
qboolean GenerateNormalisationCubeMap()
|
||||
{
|
||||
unsigned char data[32*32*3];
|
||||
|
||||
//some useful variables
|
||||
int size=32;
|
||||
float offset=0.5f;
|
||||
float halfSize=16.0f;
|
||||
vec3_t tempVector;
|
||||
unsigned char * bytePtr;
|
||||
|
||||
int i, j;
|
||||
|
||||
//positive x
|
||||
bytePtr=data;
|
||||
|
||||
for(j=0; j<size; j++)
|
||||
{
|
||||
for(i=0; i<size; i++)
|
||||
{
|
||||
tempVector[0] = halfSize;
|
||||
tempVector[1] = -(j+offset-halfSize);
|
||||
tempVector[2] = -(i+offset-halfSize);
|
||||
|
||||
VectorNormalize(tempVector);
|
||||
|
||||
bytePtr[0]=(unsigned char)((tempVector[0]/2 + 0.5)*255);
|
||||
bytePtr[1]=(unsigned char)((tempVector[1]/2 + 0.5)*255);
|
||||
bytePtr[2]=(unsigned char)((tempVector[2]/2 + 0.5)*255);
|
||||
|
||||
bytePtr+=3;
|
||||
}
|
||||
}
|
||||
glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
|
||||
0, GL_RGBA8, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
//negative x
|
||||
bytePtr=data;
|
||||
|
||||
for(j=0; j<size; j++)
|
||||
{
|
||||
for(i=0; i<size; i++)
|
||||
{
|
||||
tempVector[0] = (-halfSize);
|
||||
tempVector[1] = (-(j+offset-halfSize));
|
||||
tempVector[2] = ((i+offset-halfSize));
|
||||
|
||||
VectorNormalize(tempVector);
|
||||
|
||||
bytePtr[0]=(unsigned char)((tempVector[0]/2 + 0.5)*255);
|
||||
bytePtr[1]=(unsigned char)((tempVector[1]/2 + 0.5)*255);
|
||||
bytePtr[2]=(unsigned char)((tempVector[2]/2 + 0.5)*255);
|
||||
|
||||
bytePtr+=3;
|
||||
}
|
||||
}
|
||||
glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
|
||||
0, GL_RGBA8, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
//positive y
|
||||
bytePtr=data;
|
||||
|
||||
for(j=0; j<size; j++)
|
||||
{
|
||||
for(i=0; i<size; i++)
|
||||
{
|
||||
tempVector[0] = (i+offset-halfSize);
|
||||
tempVector[1] = (halfSize);
|
||||
tempVector[2] = ((j+offset-halfSize));
|
||||
|
||||
VectorNormalize(tempVector);
|
||||
|
||||
bytePtr[0]=(unsigned char)((tempVector[0]/2 + 0.5)*255);
|
||||
bytePtr[1]=(unsigned char)((tempVector[1]/2 + 0.5)*255);
|
||||
bytePtr[2]=(unsigned char)((tempVector[2]/2 + 0.5)*255);
|
||||
|
||||
bytePtr+=3;
|
||||
}
|
||||
}
|
||||
glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
|
||||
0, GL_RGBA8, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
//negative y
|
||||
bytePtr=data;
|
||||
|
||||
for(j=0; j<size; j++)
|
||||
{
|
||||
for(i=0; i<size; i++)
|
||||
{
|
||||
tempVector[0] = (i+offset-halfSize);
|
||||
tempVector[1] = (-halfSize);
|
||||
tempVector[2] = (-(j+offset-halfSize));
|
||||
|
||||
VectorNormalize(tempVector);
|
||||
|
||||
bytePtr[0]=(unsigned char)((tempVector[0]/2 + 0.5)*255);
|
||||
bytePtr[1]=(unsigned char)((tempVector[1]/2 + 0.5)*255);
|
||||
bytePtr[2]=(unsigned char)((tempVector[2]/2 + 0.5)*255);
|
||||
|
||||
bytePtr+=3;
|
||||
}
|
||||
}
|
||||
glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
|
||||
0, GL_RGBA8, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
//positive z
|
||||
bytePtr=data;
|
||||
|
||||
for(j=0; j<size; j++)
|
||||
{
|
||||
for(i=0; i<size; i++)
|
||||
{
|
||||
tempVector[0] = (i+offset-halfSize);
|
||||
tempVector[1] = (-(j+offset-halfSize));
|
||||
tempVector[2] = (halfSize);
|
||||
|
||||
VectorNormalize(tempVector);
|
||||
|
||||
bytePtr[0]=(unsigned char)((tempVector[0]/2 + 0.5)*255);
|
||||
bytePtr[1]=(unsigned char)((tempVector[1]/2 + 0.5)*255);
|
||||
bytePtr[2]=(unsigned char)((tempVector[2]/2 + 0.5)*255);
|
||||
|
||||
bytePtr+=3;
|
||||
}
|
||||
}
|
||||
glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
|
||||
0, GL_RGBA8, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
//negative z
|
||||
bytePtr=data;
|
||||
|
||||
for(j=0; j<size; j++)
|
||||
{
|
||||
for(i=0; i<size; i++)
|
||||
{
|
||||
tempVector[0] = (-(i+offset-halfSize));
|
||||
tempVector[1] = (-(j+offset-halfSize));
|
||||
tempVector[2] = (-halfSize);
|
||||
|
||||
VectorNormalize(tempVector);
|
||||
|
||||
bytePtr[0]=(unsigned char)((tempVector[0]/2 + 0.5)*255);
|
||||
bytePtr[1]=(unsigned char)((tempVector[1]/2 + 0.5)*255);
|
||||
bytePtr[2]=(unsigned char)((tempVector[2]/2 + 0.5)*255);
|
||||
|
||||
bytePtr+=3;
|
||||
}
|
||||
}
|
||||
glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
|
||||
0, GL_RGBA8, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int normalisationCubeMap;
|
||||
/*
|
||||
===============
|
||||
R_Init
|
||||
===============
|
||||
*/
|
||||
void GLR_ReInit (void)
|
||||
{
|
||||
extern int gl_bumpmappingpossible;
|
||||
R_InitParticleTexture ();
|
||||
|
||||
#ifdef GLTEST
|
||||
Test_Init ();
|
||||
#endif
|
||||
|
||||
netgraphtexture = texture_extension_number;
|
||||
texture_extension_number++;
|
||||
|
||||
playertextures = texture_extension_number;
|
||||
texture_extension_number += MAX_CLIENTS;
|
||||
|
||||
if (gl_bumpmappingpossible)
|
||||
{
|
||||
//Create normalisation cube map
|
||||
normalisationCubeMap = texture_extension_number++;
|
||||
GL_BindType(GL_TEXTURE_CUBE_MAP_ARB, normalisationCubeMap);
|
||||
GenerateNormalisationCubeMap();
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
else
|
||||
normalisationCubeMap = 0;
|
||||
|
||||
}
|
||||
/*
|
||||
typedef struct
|
||||
{
|
||||
long offset; // Position of the entry in WAD
|
||||
long dsize; // Size of the entry in WAD file
|
||||
long size; // Size of the entry in memory
|
||||
char type; // type of entry
|
||||
char cmprs; // Compression. 0 if none.
|
||||
short dummy; // Not used
|
||||
char name[16]; // we use only first 8
|
||||
} wad2entry_t;
|
||||
typedef struct
|
||||
{
|
||||
char magic[4]; //should be WAD2
|
||||
long num; //number of entries
|
||||
long offset; //location of directory
|
||||
} wad2_t;
|
||||
void R_MakeTexWad_f(void)
|
||||
{
|
||||
miptex_t dummymip = {"", 0, 0, {0, 0, 0, 0}};
|
||||
wad2_t wad2 = {"WAD2",0,0};
|
||||
wad2entry_t entry[2048];
|
||||
int entries = 0, i;
|
||||
FILE *f;
|
||||
char base[128];
|
||||
char *texname;
|
||||
// qbyte b;
|
||||
float scale;
|
||||
int width, height;
|
||||
|
||||
qbyte *buf, *outmip;
|
||||
qbyte *mip, *stack;
|
||||
|
||||
// WIN32_FIND_DATA fd;
|
||||
// HANDLE h;
|
||||
|
||||
scale = atof(Cmd_Argv(2));
|
||||
if (!scale)
|
||||
scale = 2;
|
||||
|
||||
// h = FindFirstFile(va("%s/textures/*.tga", com_gamedir), &fd);
|
||||
if (!shader)
|
||||
return;
|
||||
mip = BZ_Malloc(1024*1024);
|
||||
// initbuf = BZ_Malloc(1024*1024*4);
|
||||
stack = BZ_Malloc(1024*1024*4+1024);
|
||||
f=fopen(va("%s/shadrtex.wad", com_gamedir), "wb");
|
||||
fwrite(&wad2, 1, sizeof(wad2_t), f);
|
||||
|
||||
for (shad = shader; shad; shad=shad->next)
|
||||
{
|
||||
texname = shad->editorname;
|
||||
if (!*texname)
|
||||
continue;
|
||||
COM_StripExtension(shad->name, base);
|
||||
base[15]=0;
|
||||
for (i =0; i < entries; i++)
|
||||
if (!strcmp(entry[entries].name, base))
|
||||
break;
|
||||
if (i != entries)
|
||||
{
|
||||
Con_Printf("Skipped %s - duplicated shrunken name\n", texname);
|
||||
continue;
|
||||
}
|
||||
entry[entries].offset = ftell(f);
|
||||
entry[entries].dsize = entry[entries].size = 0;
|
||||
entry[entries].type = TYP_MIPTEX;
|
||||
entry[entries].cmprs = 0;
|
||||
entry[entries].dummy = 0;
|
||||
strcpy(entry[entries].name, base);
|
||||
|
||||
strcpy(dummymip.name, base);
|
||||
|
||||
{
|
||||
|
||||
qbyte *data;
|
||||
int h;
|
||||
float x, xi;
|
||||
float y, yi;
|
||||
|
||||
char *path[] ={
|
||||
"%s",
|
||||
"override/%s.tga",
|
||||
"override/%s.pcx",
|
||||
"%s.tga",
|
||||
"progs/%s"};
|
||||
for (h = 0, buf=NULL; h < sizeof(path)/sizeof(char *); h++)
|
||||
{
|
||||
buf = COM_LoadStackFile(va(path[h], texname), stack, 1024*1024*4+1024);
|
||||
if (buf)
|
||||
break;
|
||||
}
|
||||
if (!buf)
|
||||
{
|
||||
Con_Printf("Failed to find texture \"%s\"\n", texname);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
data = ReadTargaFile(buf, com_filesize, &width, &height, false);
|
||||
if (!data)
|
||||
{
|
||||
BZ_Free(data);
|
||||
Con_Printf("Skipped %s - file type not supported (bad bpp?)\n", texname);
|
||||
continue;
|
||||
}
|
||||
|
||||
dummymip.width = (int)(width/scale) & ~0xf;
|
||||
dummymip.height = (int)(height/scale) & ~0xf;
|
||||
if (dummymip.width<=0)
|
||||
dummymip.width=16;
|
||||
if (dummymip.height<=0)
|
||||
dummymip.height=16;
|
||||
|
||||
dummymip.offsets[0] = sizeof(dummymip);
|
||||
dummymip.offsets[1] = dummymip.offsets[0]+dummymip.width*dummymip.height;
|
||||
dummymip.offsets[2] = dummymip.offsets[1]+dummymip.width/2*dummymip.height/2;
|
||||
dummymip.offsets[3] = dummymip.offsets[2]+dummymip.width/4*dummymip.height/4;
|
||||
entry[entries].dsize = entry[entries].size = dummymip.offsets[3]+dummymip.width/8*dummymip.height/8;
|
||||
|
||||
xi = (float)width/dummymip.width;
|
||||
yi = (float)height/dummymip.height;
|
||||
|
||||
|
||||
fwrite(&dummymip, 1, sizeof(dummymip), f);
|
||||
outmip=mip;
|
||||
for (outmip=mip, y = 0; y < height; y+=yi)
|
||||
for (x = 0; x < width; x+=xi)
|
||||
{
|
||||
*outmip++ = GetPalette( data[(int)(x+y*width)*4+0],
|
||||
data[(int)(x+y*width)*4+1],
|
||||
data[(int)(x+y*width)*4+2]);
|
||||
}
|
||||
fwrite(mip, dummymip.width, dummymip.height, f);
|
||||
for (outmip=mip, y = 0; y < height; y+=yi*2)
|
||||
for (x = 0; x < width; x+=xi*2)
|
||||
{
|
||||
*outmip++ = GetPalette( data[(int)(x+y*width)*4+0],
|
||||
data[(int)(x+y*width)*4+1],
|
||||
data[(int)(x+y*width)*4+2]);
|
||||
}
|
||||
fwrite(mip, dummymip.width/2, dummymip.height/2, f);
|
||||
for (outmip=mip, y = 0; y < height; y+=yi*4)
|
||||
for (x = 0; x < width; x+=xi*4)
|
||||
{
|
||||
*outmip++ = GetPalette( data[(int)(x+y*width)*4+0],
|
||||
data[(int)(x+y*width)*4+1],
|
||||
data[(int)(x+y*width)*4+2]);
|
||||
}
|
||||
fwrite(mip, dummymip.width/4, dummymip.height/4, f);
|
||||
for (outmip=mip, y = 0; y < height; y+=yi*8)
|
||||
for (x = 0; x < width; x+=xi*8)
|
||||
{
|
||||
*outmip++ = GetPalette( data[(int)(x+y*width)*4+0],
|
||||
data[(int)(x+y*width)*4+1],
|
||||
data[(int)(x+y*width)*4+2]);
|
||||
}
|
||||
fwrite(mip, dummymip.width/8, dummymip.height/8, f);
|
||||
|
||||
BZ_Free(data);
|
||||
}
|
||||
entries++;
|
||||
Con_Printf("Added %s\n", base);
|
||||
GLSCR_UpdateScreen();
|
||||
}
|
||||
|
||||
wad2.offset = ftell(f);
|
||||
wad2.num = entries;
|
||||
fwrite(entry, entries, sizeof(wad2entry_t), f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
fwrite(&wad2, 1, sizeof(wad2_t), f);
|
||||
fclose(f);
|
||||
|
||||
|
||||
BZ_Free(mip);
|
||||
// BZ_Free(initbuf);
|
||||
BZ_Free(stack);
|
||||
|
||||
Con_Printf("Written %i mips to textures.wad\n", entries);
|
||||
}
|
||||
*/
|
||||
void GLR_TimeRefresh_f (void);
|
||||
|
||||
extern cvar_t gl_bump;
|
||||
extern cvar_t r_stains, r_stainfadetime, r_stainfadeammount;
|
||||
|
||||
void GLR_DeInit (void)
|
||||
{
|
||||
Cmd_RemoveCommand ("timerefresh");
|
||||
Cmd_RemoveCommand ("envmap");
|
||||
Cmd_RemoveCommand ("pointfile");
|
||||
|
||||
Cmd_RemoveCommand ("makewad");
|
||||
|
||||
GLDraw_DeInit();
|
||||
|
||||
GLSurf_DeInit();
|
||||
}
|
||||
|
||||
void GLR_Init (void)
|
||||
{
|
||||
Cmd_AddRemCommand ("timerefresh", GLR_TimeRefresh_f);
|
||||
Cmd_AddRemCommand ("envmap", R_Envmap_f);
|
||||
Cmd_AddRemCommand ("pointfile", R_ReadPointFile_f);
|
||||
|
||||
// Cmd_AddRemCommand ("makewad", R_MakeTexWad_f);
|
||||
|
||||
R_InitBubble();
|
||||
|
||||
GLR_ReInit();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_TranslatePlayerSkin
|
||||
|
||||
Translates a skin texture by the per-player color lookup
|
||||
===============
|
||||
*/
|
||||
void R_TranslatePlayerSkin (int playernum)
|
||||
{
|
||||
int top, bottom;
|
||||
qbyte translate[256];
|
||||
unsigned translate32[256];
|
||||
int i, j;
|
||||
qbyte *original;
|
||||
unsigned pixels[512*256], *out;
|
||||
unsigned scaled_width, scaled_height;
|
||||
int inwidth, inheight;
|
||||
int tinwidth, tinheight;
|
||||
qbyte *inrow;
|
||||
unsigned frac, fracstep;
|
||||
player_info_t *player;
|
||||
extern qbyte *player_8bit_texels/*[320*200]*/;
|
||||
char s[512];
|
||||
|
||||
GL_DisableMultitexture();
|
||||
|
||||
player = &cl.players[playernum];
|
||||
if (!player->name[0])
|
||||
return;
|
||||
|
||||
strcpy(s, Info_ValueForKey(player->userinfo, "skin"));
|
||||
COM_StripExtension(s, s);
|
||||
if (player->skin && !stricmp(s, player->skin->name))
|
||||
player->skin = NULL;
|
||||
|
||||
if (player->_topcolor != player->topcolor ||
|
||||
player->_bottomcolor != player->bottomcolor || !player->skin) {
|
||||
player->_topcolor = player->topcolor;
|
||||
player->_bottomcolor = player->bottomcolor;
|
||||
|
||||
top = player->topcolor;
|
||||
bottom = player->bottomcolor;
|
||||
top = (top < 0) ? 0 : ((top > 13) ? 13 : top);
|
||||
bottom = (bottom < 0) ? 0 : ((bottom > 13) ? 13 : bottom);
|
||||
top *= 16;
|
||||
bottom *= 16;
|
||||
|
||||
for (i=0 ; i<256 ; i++)
|
||||
translate[i] = i;
|
||||
|
||||
for (i=0 ; i<16 ; i++)
|
||||
{
|
||||
if (top < 128) // the artists made some backwards ranges. sigh.
|
||||
translate[TOP_RANGE+i] = top+i;
|
||||
else
|
||||
translate[TOP_RANGE+i] = top+15-i;
|
||||
|
||||
if (bottom < 128)
|
||||
translate[BOTTOM_RANGE+i] = bottom+i;
|
||||
else
|
||||
translate[BOTTOM_RANGE+i] = bottom+15-i;
|
||||
}
|
||||
|
||||
//
|
||||
// locate the original skin pixels
|
||||
//
|
||||
// real model width
|
||||
tinwidth = 296;
|
||||
tinheight = 194;
|
||||
|
||||
if (!player->skin)
|
||||
Skin_Find(player);
|
||||
if ((original = Skin_Cache8(player->skin)) != NULL) {
|
||||
//skin data width
|
||||
inwidth = player->skin->width;
|
||||
inheight = player->skin->height;
|
||||
} else {
|
||||
original = player_8bit_texels;
|
||||
inwidth = 296;
|
||||
inheight = 194;
|
||||
}
|
||||
//tinwidth = 251&~3;
|
||||
//tinheight = 194&~3;
|
||||
//tinwidth = 319&~3;
|
||||
//tinheight = 199&~3;
|
||||
|
||||
if (!original) //can't.
|
||||
return;
|
||||
|
||||
|
||||
// because this happens during gameplay, do it fast
|
||||
// instead of sending it through gl_upload 8
|
||||
GL_Bind(playertextures + playernum);
|
||||
|
||||
#if 0
|
||||
s = 320*200;
|
||||
qbyte translated[320*200];
|
||||
|
||||
for (i=0 ; i<s ; i+=4)
|
||||
{
|
||||
translated[i] = translate[original[i]];
|
||||
translated[i+1] = translate[original[i+1]];
|
||||
translated[i+2] = translate[original[i+2]];
|
||||
translated[i+3] = translate[original[i+3]];
|
||||
}
|
||||
|
||||
|
||||
// don't mipmap these, because it takes too long
|
||||
GL_Upload8 (translated, paliashdr->skinwidth, paliashdr->skinheight,
|
||||
false, false, true);
|
||||
#endif
|
||||
|
||||
scaled_width = gl_max_size.value < 512 ? gl_max_size.value : 512;
|
||||
scaled_height = gl_max_size.value < 256 ? gl_max_size.value : 256;
|
||||
// allow users to crunch sizes down even more if they want
|
||||
scaled_width >>= (int)gl_playermip.value;
|
||||
scaled_height >>= (int)gl_playermip.value;
|
||||
|
||||
if (scaled_width < 8)
|
||||
scaled_width = 8;
|
||||
if (scaled_height < 8)
|
||||
scaled_height = 8;
|
||||
#ifdef GL_USE8BITTEX
|
||||
#ifdef GL_EXT_paletted_texture
|
||||
if (GLVID_Is8bit())
|
||||
{// 8bit texture upload
|
||||
qbyte *out2;
|
||||
|
||||
out2 = (qbyte *)pixels;
|
||||
memset(pixels, 0, sizeof(pixels));
|
||||
fracstep = tinwidth*0x10000/scaled_width;
|
||||
for (i=0 ; i<scaled_height ; i++, out2 += scaled_width)
|
||||
{
|
||||
inrow = original + inwidth*(i*tinheight/scaled_height);
|
||||
frac = fracstep >> 1;
|
||||
for (j=0 ; j<scaled_width ; j+=4)
|
||||
{
|
||||
out2[j] = translate[inrow[frac>>16]];
|
||||
frac += fracstep;
|
||||
out2[j+1] = translate[inrow[frac>>16]];
|
||||
frac += fracstep;
|
||||
out2[j+2] = translate[inrow[frac>>16]];
|
||||
frac += fracstep;
|
||||
out2[j+3] = translate[inrow[frac>>16]];
|
||||
frac += fracstep;
|
||||
}
|
||||
}
|
||||
|
||||
GL_Upload8_EXT ((qbyte *)pixels, scaled_width, scaled_height, false, false);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef Q2BSP
|
||||
if (cls.q2server)
|
||||
{
|
||||
extern unsigned char d_q28to24table[768];
|
||||
for (i=0 ; i<256 ; i++)
|
||||
{
|
||||
translate32[i] = d_q28to24table[i*3] |
|
||||
(d_q28to24table[i*3+1]<<8) |
|
||||
(d_q28to24table[i*3+2]<<16) |
|
||||
255<<24;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
for (i=0 ; i<256 ; i++)
|
||||
translate32[i] = d_8to24rgbtable[translate[i]];
|
||||
|
||||
out = pixels;
|
||||
memset(pixels, 0, sizeof(pixels));
|
||||
fracstep = tinwidth*0x10000/scaled_width;
|
||||
for (i=0 ; i<scaled_height ; i++, out += scaled_width)
|
||||
{
|
||||
inrow = original + inwidth*(i*tinheight/scaled_height);
|
||||
frac = fracstep >> 1;
|
||||
for (j=0 ; j<scaled_width ; j+=4)
|
||||
{
|
||||
out[j] = translate32[inrow[frac>>16]];
|
||||
frac += fracstep;
|
||||
out[j+1] = translate32[inrow[frac>>16]];
|
||||
frac += fracstep;
|
||||
out[j+2] = translate32[inrow[frac>>16]];
|
||||
frac += fracstep;
|
||||
out[j+3] = translate32[inrow[frac>>16]];
|
||||
frac += fracstep;
|
||||
}
|
||||
}
|
||||
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format,
|
||||
scaled_width, scaled_height, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_NewMap
|
||||
===============
|
||||
*/
|
||||
void GLR_NewMap (void)
|
||||
{
|
||||
extern cvar_t host_mapname;
|
||||
int i;
|
||||
/*
|
||||
if (cl.worldmodel->fromgame == fg_quake3 && cls.netchan.remote_address.type != NA_LOOPBACK)
|
||||
{
|
||||
if (!cls.allow_cheats)
|
||||
{
|
||||
CL_Disconnect();
|
||||
Host_EndGame("\n\nThe quake3 map implementation is still experimental and contains many bugs that could be considered cheats. Therefore, the engine is handicapped to quake3 maps only when hosting - it's single player only.\n\nYou can allow it on the server by activating cheats, at which point this check will be ignored\n");
|
||||
return;
|
||||
}
|
||||
// Cbuf_AddText("disconnect\n", RESTRICT_LOCAL);
|
||||
}
|
||||
*/
|
||||
|
||||
for (i=0 ; i<256 ; i++)
|
||||
d_lightstylevalue[i] = 264; // normal light value
|
||||
|
||||
memset (&r_worldentity, 0, sizeof(r_worldentity));
|
||||
r_worldentity.model = cl.worldmodel;
|
||||
|
||||
Cvar_Set(&host_mapname, cl.worldmodel->name);
|
||||
|
||||
// clear out efrags in case the level hasn't been reloaded
|
||||
// FIXME: is this one short?
|
||||
for (i=0 ; i<cl.worldmodel->numleafs ; i++)
|
||||
cl.worldmodel->leafs[i].efrags = NULL;
|
||||
|
||||
r_viewleaf = NULL;
|
||||
r_viewcluster = -1;
|
||||
r_oldviewcluster = 0;
|
||||
r_viewcluster2 = -1;
|
||||
R_ClearParticles ();
|
||||
GLR_WipeStains();
|
||||
|
||||
GL_BuildLightmaps ();
|
||||
|
||||
// identify sky texture
|
||||
if (cl.worldmodel->fromgame != fg_quake2 && cl.worldmodel->fromgame != fg_quake3)
|
||||
{
|
||||
skytexturenum = -1;
|
||||
mirrortexturenum = -1;
|
||||
}
|
||||
for (i=0 ; i<cl.worldmodel->numtextures ; i++)
|
||||
{
|
||||
if (!cl.worldmodel->textures[i])
|
||||
continue;
|
||||
if (!Q_strncmp(cl.worldmodel->textures[i]->name,"sky",3) )
|
||||
skytexturenum = i;
|
||||
if (!Q_strncmp(cl.worldmodel->textures[i]->name,"window02_1",10) )
|
||||
mirrortexturenum = i;
|
||||
cl.worldmodel->textures[i]->texturechain = NULL;
|
||||
}
|
||||
|
||||
//#ifdef QUAKE2
|
||||
R_LoadSkys ();
|
||||
//#endif
|
||||
|
||||
UI_Reset();
|
||||
}
|
||||
|
||||
void GLR_PreNewMap(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
R_TimeRefresh_f
|
||||
|
||||
For program optimization
|
||||
====================
|
||||
*/
|
||||
void GLR_TimeRefresh_f (void)
|
||||
{
|
||||
int i;
|
||||
float start, stop, time;
|
||||
|
||||
glDrawBuffer (GL_FRONT);
|
||||
glFinish ();
|
||||
|
||||
start = Sys_DoubleTime ();
|
||||
for (i=0 ; i<128 ; i++)
|
||||
{
|
||||
r_refdef.viewangles[1] = i/128.0*360.0;
|
||||
R_RenderView ();
|
||||
}
|
||||
|
||||
glFinish ();
|
||||
stop = Sys_DoubleTime ();
|
||||
time = stop-start;
|
||||
Con_Printf ("%f seconds (%f fps)\n", time, 128/time);
|
||||
|
||||
glDrawBuffer (GL_BACK);
|
||||
GL_EndRendering ();
|
||||
}
|
||||
|
||||
#ifndef SWQUAKE
|
||||
void D_FlushCaches (void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
3510
engine/gl/gl_rsurf.c
Normal file
3510
engine/gl/gl_rsurf.c
Normal file
File diff suppressed because it is too large
Load diff
239
engine/gl/gl_screen.c
Normal file
239
engine/gl/gl_screen.c
Normal file
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
// screen.c -- master for refresh, status bar, console, chat, notify, etc
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "glquake.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
void GLSCR_UpdateScreen (void);
|
||||
|
||||
|
||||
extern qboolean scr_drawdialog;
|
||||
|
||||
extern cvar_t gl_triplebuffer;
|
||||
extern cvar_t scr_fov;
|
||||
|
||||
extern qboolean scr_initialized;
|
||||
extern float oldsbar;
|
||||
extern qboolean scr_drawloading;
|
||||
|
||||
extern float oldfov;
|
||||
|
||||
|
||||
extern int scr_chatmode;
|
||||
extern cvar_t scr_chatmodecvar;
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
SCR_UpdateScreen
|
||||
|
||||
This is called every frame, and can also be called explicitly to flush
|
||||
text to the screen.
|
||||
|
||||
WARNING: be very careful calling this from elsewhere, because the refresh
|
||||
needs almost the entire 256k of stack space!
|
||||
==================
|
||||
*/
|
||||
|
||||
void GLSCR_UpdateScreen (void)
|
||||
{
|
||||
extern cvar_t gl_2dscale;
|
||||
static float old2dscale=1;
|
||||
int uimenu;
|
||||
#ifdef TEXTEDITOR
|
||||
extern qboolean editormodal, editoractive;
|
||||
#endif
|
||||
if (block_drawing)
|
||||
return;
|
||||
|
||||
if (gl_2dscale.modified)
|
||||
{
|
||||
gl_2dscale.modified=false;
|
||||
if (gl_2dscale.value < 0) //lower would be wrong
|
||||
Cvar_Set(&gl_2dscale, "0");
|
||||
if (gl_2dscale.value > 2) //anything higher is unreadable.
|
||||
Cvar_Set(&gl_2dscale, "2");
|
||||
|
||||
old2dscale = gl_2dscale.value;
|
||||
vid.width = vid.conwidth = (glwidth - 320) * gl_2dscale.value + 320;
|
||||
vid.height = vid.conheight = (glheight - 240) * gl_2dscale.value + 240;
|
||||
|
||||
vid.recalc_refdef = true;
|
||||
Con_CheckResize();
|
||||
}
|
||||
|
||||
vid.numpages = 2 + gl_triplebuffer.value;
|
||||
|
||||
scr_copytop = 0;
|
||||
scr_copyeverything = 0;
|
||||
|
||||
if (scr_disabled_for_loading)
|
||||
{
|
||||
/* if (Sys_DoubleTime() - scr_disabled_time > 60 || key_dest != key_game)
|
||||
{
|
||||
scr_disabled_for_loading = false;
|
||||
Con_Printf ("load failed.\n");
|
||||
}
|
||||
else
|
||||
*/ {
|
||||
GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
|
||||
SCR_DrawLoading ();
|
||||
GL_EndRendering ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!scr_initialized || !con_initialized)
|
||||
return; // not initialized yet
|
||||
|
||||
uimenu = UI_MenuState();
|
||||
|
||||
|
||||
if (oldsbar != cl_sbar.value) {
|
||||
oldsbar = cl_sbar.value;
|
||||
vid.recalc_refdef = true;
|
||||
}
|
||||
|
||||
GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
|
||||
|
||||
#ifdef TEXTEDITOR
|
||||
if (editormodal)
|
||||
{
|
||||
Editor_Draw();
|
||||
GLV_UpdatePalette ();
|
||||
#if defined(_WIN32) && defined(RGLQUAKE)
|
||||
Media_RecordFrame();
|
||||
#endif
|
||||
GLR_BrightenScreen();
|
||||
GL_EndRendering ();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (Media_ShowFilm())
|
||||
{
|
||||
M_Draw(0);
|
||||
GLV_UpdatePalette ();
|
||||
#if defined(_WIN32) && defined(RGLQUAKE)
|
||||
Media_RecordFrame();
|
||||
#endif
|
||||
GLR_BrightenScreen();
|
||||
GL_EndRendering ();
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// determine size of refresh window
|
||||
//
|
||||
if (oldfov != scr_fov.value)
|
||||
{
|
||||
oldfov = scr_fov.value;
|
||||
vid.recalc_refdef = true;
|
||||
}
|
||||
|
||||
if (scr_chatmode != scr_chatmodecvar.value)
|
||||
vid.recalc_refdef = true;
|
||||
|
||||
if (vid.recalc_refdef || scr_viewsize.modified)
|
||||
SCR_CalcRefdef ();
|
||||
|
||||
//
|
||||
// do 3D refresh drawing, and then update the screen
|
||||
//
|
||||
SCR_SetUpToDrawConsole ();
|
||||
if (cl.worldmodel && uimenu != 1)
|
||||
V_RenderView ();
|
||||
|
||||
GL_Set2D ();
|
||||
|
||||
//
|
||||
// draw any areas not covered by the refresh
|
||||
//
|
||||
SCR_TileClear ();
|
||||
|
||||
if (r_netgraph.value)
|
||||
GLR_NetGraph ();
|
||||
|
||||
if (scr_drawdialog)
|
||||
{
|
||||
Sbar_Draw ();
|
||||
Draw_FadeScreen ();
|
||||
SCR_DrawNotifyString ();
|
||||
scr_copyeverything = true;
|
||||
}
|
||||
else if (scr_drawloading)
|
||||
{
|
||||
SCR_DrawLoading ();
|
||||
Sbar_Draw ();
|
||||
}
|
||||
else if (cl.intermission == 1 && key_dest == key_game)
|
||||
{
|
||||
Sbar_IntermissionOverlay ();
|
||||
M_Draw (uimenu);
|
||||
}
|
||||
else if (cl.intermission == 2 && key_dest == key_game)
|
||||
{
|
||||
Sbar_FinaleOverlay ();
|
||||
SCR_CheckDrawCenterString ();
|
||||
}
|
||||
else
|
||||
{
|
||||
Draw_Crosshair();
|
||||
|
||||
SCR_DrawRam ();
|
||||
SCR_DrawNet ();
|
||||
SCR_DrawFPS ();
|
||||
SCR_DrawTurtle ();
|
||||
SCR_DrawPause ();
|
||||
SCR_CheckDrawCenterString ();
|
||||
Sbar_Draw ();
|
||||
glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||
#ifdef TEXTEDITOR
|
||||
if (editoractive)
|
||||
Editor_Draw();
|
||||
#endif
|
||||
M_Draw (uimenu);
|
||||
SCR_DrawConsole (false);
|
||||
}
|
||||
|
||||
GLR_BrightenScreen();
|
||||
|
||||
GLV_UpdatePalette ();
|
||||
#if defined(_WIN32) && defined(RGLQUAKE)
|
||||
Media_RecordFrame();
|
||||
#endif
|
||||
GL_EndRendering ();
|
||||
}
|
||||
|
||||
|
||||
char *GLVID_GetRGBInfo(int prepadbytes, int *truewidth, int *trueheight)
|
||||
{ //returns a BZ_Malloced array
|
||||
qbyte *ret = BZ_Malloc(prepadbytes + glwidth*glheight*3);
|
||||
|
||||
glReadPixels (glx, gly, glwidth, glheight, GL_RGB, GL_UNSIGNED_BYTE, ret + prepadbytes);
|
||||
|
||||
*truewidth = glwidth;
|
||||
*trueheight = glheight;
|
||||
|
||||
return ret;
|
||||
}
|
369
engine/gl/gl_vidcommon.c
Normal file
369
engine/gl/gl_vidcommon.c
Normal file
|
@ -0,0 +1,369 @@
|
|||
#include "quakedef.h"
|
||||
#include "glquake.h"
|
||||
|
||||
//standard 1.1 opengl calls
|
||||
void (APIENTRY *qglAlphaFunc) (GLenum func, GLclampf ref);
|
||||
void (APIENTRY *qglBegin) (GLenum mode);
|
||||
void (APIENTRY *qglBlendFunc) (GLenum sfactor, GLenum dfactor);
|
||||
void (APIENTRY *qglClear) (GLbitfield mask);
|
||||
void (APIENTRY *qglClearColor) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
|
||||
void (APIENTRY *qglClearDepth) (GLclampd depth);
|
||||
void (APIENTRY *qglClearStencil) (GLint s);
|
||||
void (APIENTRY *qglColor3f) (GLfloat red, GLfloat green, GLfloat blue);
|
||||
void (APIENTRY *qglColor3ub) (GLubyte red, GLubyte green, GLubyte blue);
|
||||
void (APIENTRY *qglColor4f) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
void (APIENTRY *qglColor4fv) (const GLfloat *v);
|
||||
void (APIENTRY *qglColor4ub) (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
|
||||
void (APIENTRY *qglColor4ubv) (const GLubyte *v);
|
||||
void (APIENTRY *qglColorMask) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
|
||||
void (APIENTRY *qglCullFace) (GLenum mode);
|
||||
void (APIENTRY *qglDepthFunc) (GLenum func);
|
||||
void (APIENTRY *qglDepthMask) (GLboolean flag);
|
||||
void (APIENTRY *qglDepthRange) (GLclampd zNear, GLclampd zFar);
|
||||
void (APIENTRY *qglDisable) (GLenum cap);
|
||||
void (APIENTRY *qglDrawBuffer) (GLenum mode);
|
||||
void (APIENTRY *qglDrawPixels) (GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
void (APIENTRY *qglEnable) (GLenum cap);
|
||||
void (APIENTRY *qglEnd) (void);
|
||||
void (APIENTRY *qglFinish) (void);
|
||||
void (APIENTRY *qglFlush) (void);
|
||||
void (APIENTRY *qglFrustum) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
|
||||
void (APIENTRY *qglGetFloatv) (GLenum pname, GLfloat *params);
|
||||
void (APIENTRY *qglGetIntegerv) (GLenum pname, GLint *params);
|
||||
const GLubyte * (APIENTRY *qglGetString) (GLenum name);
|
||||
void (APIENTRY *qglHint) (GLenum target, GLenum mode);
|
||||
void (APIENTRY *qglLoadIdentity) (void);
|
||||
void (APIENTRY *qglLoadMatrixf) (const GLfloat *m);
|
||||
void (APIENTRY *qglNormal3f) (GLfloat nx, GLfloat ny, GLfloat nz);
|
||||
void (APIENTRY *qglNormal3fv) (const GLfloat *v);
|
||||
void (APIENTRY *qglMatrixMode) (GLenum mode);
|
||||
void (APIENTRY *qglMultMatrixf) (const GLfloat *m);
|
||||
void (APIENTRY *qglOrtho) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
|
||||
void (APIENTRY *qglPolygonMode) (GLenum face, GLenum mode);
|
||||
void (APIENTRY *qglPopMatrix) (void);
|
||||
void (APIENTRY *qglPushMatrix) (void);
|
||||
void (APIENTRY *qglReadBuffer) (GLenum mode);
|
||||
void (APIENTRY *qglReadPixels) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
|
||||
void (APIENTRY *qglRotatef) (GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
|
||||
void (APIENTRY *qglScalef) (GLfloat x, GLfloat y, GLfloat z);
|
||||
void (APIENTRY *qglShadeModel) (GLenum mode);
|
||||
void (APIENTRY *qglTexCoord1f) (GLfloat s);
|
||||
void (APIENTRY *qglTexCoord2f) (GLfloat s, GLfloat t);
|
||||
void (APIENTRY *qglTexCoord2fv) (const GLfloat *v);
|
||||
void (APIENTRY *qglTexEnvf) (GLenum target, GLenum pname, GLfloat param);
|
||||
void (APIENTRY *qglTexEnvi) (GLenum target, GLenum pname, GLint param);
|
||||
void (APIENTRY *qglTexGeni) (GLenum coord, GLenum pname, GLint param);
|
||||
void (APIENTRY *qglTexImage2D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
void (APIENTRY *qglTexParameteri) (GLenum target, GLenum pname, GLint param);
|
||||
void (APIENTRY *qglTexParameterf) (GLenum target, GLenum pname, GLfloat param);
|
||||
void (APIENTRY *qglTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
void (APIENTRY *qglTranslatef) (GLfloat x, GLfloat y, GLfloat z);
|
||||
void (APIENTRY *qglVertex2f) (GLfloat x, GLfloat y);
|
||||
void (APIENTRY *qglVertex3f) (GLfloat x, GLfloat y, GLfloat z);
|
||||
void (APIENTRY *qglVertex3fv) (const GLfloat *v);
|
||||
void (APIENTRY *qglViewport) (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
void (APIENTRY *qglGetTexLevelParameteriv) (GLenum target, GLint level, GLenum pname, GLint *params);
|
||||
|
||||
void (APIENTRY *qglDrawElements) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
|
||||
void (APIENTRY *qglVertexPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
void (APIENTRY *qglNormalPointer) (GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
void (APIENTRY *qglTexCoordPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
void (APIENTRY *qglColorPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
void (APIENTRY *qglDisableClientState) (GLenum array);
|
||||
void (APIENTRY *qglEnableClientState) (GLenum array);
|
||||
|
||||
|
||||
void (APIENTRY *qglStencilOp) (GLenum fail, GLenum zfail, GLenum zpass);
|
||||
void (APIENTRY *qglStencilFunc) (GLenum func, GLint ref, GLuint mask);
|
||||
void (APIENTRY *qglPushAttrib) (GLbitfield mask);
|
||||
void (APIENTRY *qglPopAttrib) (void);
|
||||
|
||||
|
||||
|
||||
|
||||
//extensions
|
||||
//arb multitexture
|
||||
qlpSelTexFUNC qglActiveTextureARB;
|
||||
qlpSelTexFUNC qglClientActiveTextureARB;
|
||||
qlpMTex3FUNC qglMultiTexCoord3fARB;
|
||||
qlpMTex2FUNC qglMultiTexCoord2fARB;
|
||||
|
||||
//generic multitexture
|
||||
lpMTexFUNC qglMTexCoord2fSGIS;
|
||||
lpSelTexFUNC qglSelectTextureSGIS;
|
||||
int mtexid0;
|
||||
int mtexid1;
|
||||
|
||||
//ati_truform
|
||||
PFNGLPNTRIANGLESIATIPROC qglPNTrianglesiATI;
|
||||
PFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI;
|
||||
|
||||
//stencil shadowing
|
||||
void (APIENTRY *qglStencilOpSeparateATI) (GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
|
||||
PFNGLACTIVESTENCILFACEEXTPROC qglActiveStencilFaceEXT;
|
||||
|
||||
//quick hack that made quake work on both 1 and 1.1 gl implementations.
|
||||
BINDTEXFUNCPTR bindTexFunc;
|
||||
|
||||
|
||||
qboolean gl_ext_stencil_wrap;
|
||||
int gl_mtexarbable=0; //max texture units
|
||||
qboolean gl_mtexable = false;
|
||||
qboolean gl_compressable=false;
|
||||
int gl_bumpmappingpossible;
|
||||
|
||||
|
||||
|
||||
|
||||
//int texture_mode = GL_NEAREST;
|
||||
//int texture_mode = GL_NEAREST_MIPMAP_NEAREST;
|
||||
//int texture_mode = GL_NEAREST_MIPMAP_LINEAR;
|
||||
int texture_mode = GL_LINEAR;
|
||||
//int texture_mode = GL_LINEAR_MIPMAP_NEAREST;
|
||||
//int texture_mode = GL_LINEAR_MIPMAP_LINEAR;
|
||||
|
||||
int texture_extension_number = 1;
|
||||
|
||||
#define fieldvector(name) QC_RegisterFieldVar(svprogfuncs, ev_vector, #name, (int)&((edict_t*)0)->v.name - (int)&((edict_t*)0)->v, -1)
|
||||
#define getglcore getglfunction
|
||||
#define getglext(name) getglfunction(name)
|
||||
void GL_CheckExtensions (void *(*getglfunction) (char *name))
|
||||
{
|
||||
extern cvar_t gl_bump;
|
||||
qboolean support_GL_ARB_texture_env_combine, support_GL_ARB_texture_env_dot3, support_GL_ARB_texture_cube_map;
|
||||
|
||||
|
||||
//multitexture
|
||||
gl_mtexable = false;
|
||||
gl_mtexarbable = 0;
|
||||
qglActiveTextureARB = NULL;
|
||||
qglMultiTexCoord2fARB = NULL;
|
||||
qglMultiTexCoord3fARB = NULL;
|
||||
qglMTexCoord2fSGIS = NULL;
|
||||
qglSelectTextureSGIS = NULL;
|
||||
mtexid0 = 0;
|
||||
mtexid1 = 0;
|
||||
|
||||
//none of them bumpmapping possabilities.
|
||||
gl_bumpmappingpossible = false;
|
||||
|
||||
//no GL_EXT_stencil_wrap
|
||||
gl_ext_stencil_wrap = false;
|
||||
|
||||
//no GL_ATI_separate_stencil
|
||||
qglStencilOpSeparateATI = NULL;
|
||||
|
||||
//no GL_EXT_stencil_two_side
|
||||
qglActiveStencilFaceEXT = NULL;
|
||||
|
||||
//no GL_ARB_texture_compression
|
||||
gl_compressable = false;
|
||||
|
||||
//no truform. sorry.
|
||||
qglPNTrianglesfATI = NULL;
|
||||
qglPNTrianglesiATI = NULL;
|
||||
|
||||
if (strstr(gl_extensions, "GL_ARB_multitexture") && !COM_CheckParm("-noamtex"))
|
||||
{ //ARB multitexture is the popular choice.
|
||||
Con_SafePrintf("ARB Multitexture extensions found. Use -noamtex to disable.\n");
|
||||
qglActiveTextureARB = (void *) getglext("glActiveTextureARB");
|
||||
qglClientActiveTextureARB = (void *) getglext("glClientActiveTextureARB");
|
||||
qglMultiTexCoord2fARB = (void *) getglext("glMultiTexCoord2fARB");
|
||||
qglMultiTexCoord3fARB = (void *) getglext("glMultiTexCoord3fARB");
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_mtexarbable);
|
||||
gl_mtexable = true;
|
||||
|
||||
qglMTexCoord2fSGIS = qglMultiTexCoord2fARB;
|
||||
qglSelectTextureSGIS = qglActiveTextureARB;
|
||||
|
||||
mtexid0 = GL_TEXTURE0_ARB;
|
||||
mtexid1 = GL_TEXTURE1_ARB;
|
||||
|
||||
if (!qglActiveTextureARB || !qglClientActiveTextureARB || !qglMultiTexCoord2fARB || !qglMultiTexCoord3fARB)
|
||||
{
|
||||
qglActiveTextureARB = NULL;
|
||||
qglMultiTexCoord2fARB = NULL;
|
||||
qglMultiTexCoord3fARB = NULL;
|
||||
qglMTexCoord2fSGIS = NULL;
|
||||
qglSelectTextureSGIS = NULL;
|
||||
gl_mtexable=false;
|
||||
gl_mtexarbable = false;
|
||||
}
|
||||
|
||||
}
|
||||
else if (strstr(gl_extensions, "GL_SGIS_multitexture") && !COM_CheckParm("-nomtex"))
|
||||
{ //SGIS multitexture, limited in many ways but basic functionality is identical to ARB
|
||||
Con_SafePrintf("Multitexture extensions found.\n");
|
||||
qglMTexCoord2fSGIS = (void *) getglext("glMTexCoord2fSGIS");
|
||||
qglSelectTextureSGIS = (void *) getglext("glSelectTextureSGIS");
|
||||
gl_mtexable = true;
|
||||
|
||||
mtexid0 = GL_TEXTURE0_SGIS;
|
||||
mtexid1 = GL_TEXTURE1_SGIS;
|
||||
}
|
||||
|
||||
if (strstr(gl_extensions, "GL_EXT_stencil_wrap"))
|
||||
gl_ext_stencil_wrap = true;
|
||||
|
||||
if (strstr(gl_extensions, "GL_ATI_separate_stencil"))
|
||||
qglStencilOpSeparateATI = (void *) getglext("glStencilOpSeparateATI");
|
||||
if (strstr(gl_extensions, "GL_EXT_stencil_two_side"))
|
||||
qglActiveStencilFaceEXT = (void *) getglext("glActiveStencilFaceEXT");
|
||||
|
||||
if (strstr(gl_extensions, "GL_ARB_texture_compression"))
|
||||
{
|
||||
qglCompressedTexImage2DARB = (void *)getglext("glCompressedTexImage2DARB");
|
||||
qglGetCompressedTexImageARB = (void *)getglext("glGetCompressedTexImageARB");
|
||||
|
||||
if (!qglCompressedTexImage2DARB || !qglGetCompressedTexImageARB)
|
||||
{
|
||||
qglCompressedTexImage2DARB = NULL;
|
||||
qglGetCompressedTexImageARB = NULL;
|
||||
}
|
||||
else
|
||||
gl_compressable = true;
|
||||
}
|
||||
|
||||
if (strstr(gl_extensions, "GL_ATI_pn_triangles"))
|
||||
{
|
||||
qglPNTrianglesfATI = (void *)getglext("glPNTrianglesfATI");
|
||||
qglPNTrianglesiATI = (void *)getglext("glPNTrianglesiATI");
|
||||
}
|
||||
|
||||
if (strstr(gl_extensions, "GL_EXT_texture_object"))
|
||||
{
|
||||
bindTexFunc = (void *)getglext("glBindTextureEXT");
|
||||
if (!bindTexFunc) //grrr
|
||||
bindTexFunc = (void *)getglext("glBindTexture");
|
||||
}
|
||||
|
||||
support_GL_ARB_texture_env_combine = !!strstr(gl_extensions, "GL_ARB_texture_env_combine");
|
||||
support_GL_ARB_texture_env_dot3 = !!strstr(gl_extensions, "GL_ARB_texture_env_dot3");
|
||||
support_GL_ARB_texture_cube_map = !!strstr(gl_extensions, "GL_ARB_texture_cube_map");
|
||||
|
||||
if (gl_mtexarbable && support_GL_ARB_texture_cube_map && support_GL_ARB_texture_env_combine && support_GL_ARB_texture_env_dot3 && !COM_CheckParm("-nobump") && gl_bump.value)
|
||||
gl_bumpmappingpossible = true;
|
||||
}
|
||||
|
||||
//the vid routines have initialised a window, and now they are giving us a reference to some of of GetProcAddress to get pointers to the funcs.
|
||||
void GL_Init(void *(*getglfunction) (char *name))
|
||||
{
|
||||
qglAlphaFunc = (void *)getglcore("glAlphaFunc");
|
||||
qglBegin = (void *)getglcore("glBegin");
|
||||
qglBlendFunc = (void *)getglcore("glBlendFunc");
|
||||
bindTexFunc = (void *)getglcore("glBindTexture"); //for compleateness
|
||||
qglClear = (void *)getglcore("glClear");
|
||||
qglClearColor = (void *)getglcore("glClearColor");
|
||||
qglClearDepth = (void *)getglcore("glClearDepth");
|
||||
qglClearStencil = (void *)getglcore("glClearStencil");
|
||||
qglColor3f = (void *)getglcore("glColor3f");
|
||||
qglColor3ub = (void *)getglcore("glColor3ub");
|
||||
qglColor4f = (void *)getglcore("glColor4f");
|
||||
qglColor4fv = (void *)getglcore("glColor4fv");
|
||||
qglColor4ub = (void *)getglcore("glColor4ub");
|
||||
qglColor4ubv = (void *)getglcore("glColor4ubv");
|
||||
qglColorMask = (void *)getglcore("glColorMask");
|
||||
qglCullFace = (void *)getglcore("glCullFace");
|
||||
qglDepthFunc = (void *)getglcore("glDepthFunc");
|
||||
qglDepthMask = (void *)getglcore("glDepthMask");
|
||||
qglDepthRange = (void *)getglcore("glDepthRange");
|
||||
qglDisable = (void *)getglcore("glDisable");
|
||||
qglDrawBuffer = (void *)getglcore("glDrawBuffer");
|
||||
qglDrawPixels = (void *)getglcore("glDrawPixels");
|
||||
qglEnable = (void *)getglcore("glEnable");
|
||||
qglEnd = (void *)getglcore("glEnd");
|
||||
qglFinish = (void *)getglcore("glFinish");
|
||||
qglFlush = (void *)getglcore("glFlush");
|
||||
qglFrustum = (void *)getglcore("glFrustum");
|
||||
qglGetFloatv = (void *)getglcore("glGetFloatv");
|
||||
qglGetIntegerv = (void *)getglcore("glGetIntegerv");
|
||||
qglGetString = (void *)getglcore("glGetString");
|
||||
qglGetTexLevelParameteriv = (void *)getglcore("glGetTexLevelParameteriv");
|
||||
qglHint = (void *)getglcore("glHint");
|
||||
qglLoadIdentity = (void *)getglcore("glLoadIdentity");
|
||||
qglLoadMatrixf = (void *)getglcore("glLoadMatrixf");
|
||||
qglNormal3f = (void *)getglcore("glNormal3f");
|
||||
qglNormal3fv = (void *)getglcore("glNormal3fv");
|
||||
qglMatrixMode = (void *)getglcore("glMatrixMode");
|
||||
qglMultMatrixf = (void *)getglcore("glMultMatrixf");
|
||||
qglOrtho = (void *)getglcore("glOrtho");
|
||||
qglPolygonMode = (void *)getglcore("glPolygonMode");
|
||||
qglPopMatrix = (void *)getglcore("glPopMatrix");
|
||||
qglPushMatrix = (void *)getglcore("glPushMatrix");
|
||||
qglReadBuffer = (void *)getglcore("glReadBuffer");
|
||||
qglReadPixels = (void *)getglcore("glReadPixels");
|
||||
qglRotatef = (void *)getglcore("glRotatef");
|
||||
qglScalef = (void *)getglcore("glScalef");
|
||||
qglShadeModel = (void *)getglcore("glShadeModel");
|
||||
qglTexCoord1f = (void *)getglcore("glTexCoord1f");
|
||||
qglTexCoord2f = (void *)getglcore("glTexCoord2f");
|
||||
qglTexCoord2fv = (void *)getglcore("glTexCoord2fv");
|
||||
qglTexEnvf = (void *)getglcore("glTexEnvf");
|
||||
qglTexEnvi = (void *)getglcore("glTexEnvi");
|
||||
qglTexGeni = (void *)getglcore("glTexGeni");
|
||||
qglTexImage2D = (void *)getglcore("glTexImage2D");
|
||||
qglTexParameteri = (void *)getglcore("glTexParameteri");
|
||||
qglTexParameterf = (void *)getglcore("glTexParameterf");
|
||||
qglTexSubImage2D = (void *)getglcore("glTexSubImage2D");
|
||||
qglTranslatef = (void *)getglcore("glTranslatef");
|
||||
qglVertex2f = (void *)getglcore("glVertex2f");
|
||||
qglVertex3f = (void *)getglcore("glVertex3f");
|
||||
qglVertex3fv = (void *)getglcore("glVertex3fv");
|
||||
qglViewport = (void *)getglcore("glViewport");
|
||||
|
||||
//fixme: make non-core?
|
||||
qglDrawElements = (void *)getglcore("glDrawElements");
|
||||
qglVertexPointer = (void *)getglcore("glVertexPointer");
|
||||
qglNormalPointer = (void *)getglcore("glNormalPointer");
|
||||
qglTexCoordPointer = (void *)getglcore("glTexCoordPointer");
|
||||
qglColorPointer = (void *)getglcore("glColorPointer");
|
||||
qglEnableClientState = (void *)getglcore("glEnableClientState");
|
||||
qglDisableClientState = (void *)getglcore("glDisableClientState");
|
||||
|
||||
//fixme: definatly make non-core
|
||||
qglStencilOp = (void *)getglcore("glStencilOp");
|
||||
qglStencilFunc = (void *)getglcore("glStencilFunc");
|
||||
qglPushAttrib = (void *)getglcore("glPushAttrib");
|
||||
qglPopAttrib = (void *)getglcore("glPopAttrib");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
gl_vendor = glGetString (GL_VENDOR);
|
||||
Con_SafePrintf ("GL_VENDOR: %s\n", gl_vendor);
|
||||
gl_renderer = glGetString (GL_RENDERER);
|
||||
Con_SafePrintf ("GL_RENDERER: %s\n", gl_renderer);
|
||||
|
||||
gl_version = glGetString (GL_VERSION);
|
||||
Con_SafePrintf ("GL_VERSION: %s\n", gl_version);
|
||||
gl_extensions = glGetString (GL_EXTENSIONS);
|
||||
Con_DPrintf ("GL_EXTENSIONS: %s\n", gl_extensions);
|
||||
|
||||
GL_CheckExtensions (getglfunction);
|
||||
|
||||
glClearColor (0,0,0,0); //clear to black so that it looks a little nicer on start.
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor (1,0,0,0);
|
||||
glCullFace(GL_FRONT);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glAlphaFunc(GL_GREATER, 0.666);
|
||||
|
||||
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
|
||||
glShadeModel (GL_FLAT);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
}
|
||||
|
||||
unsigned int d_8to24rgbtable[256];
|
899
engine/gl/gl_vidlinuxglx.c
Normal file
899
engine/gl/gl_vidlinuxglx.c
Normal file
|
@ -0,0 +1,899 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#ifndef __CYGWIN__
|
||||
#include <sys/vt.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "glquake.h"
|
||||
|
||||
#include <GL/glx.h>
|
||||
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/cursorfont.h>
|
||||
|
||||
#ifdef USE_DGA
|
||||
#include <X11/extensions/xf86dga.h>
|
||||
#endif
|
||||
|
||||
#define WITH_VMODE //undefine this if the following include fails.
|
||||
#ifdef WITH_VMODE
|
||||
#include <X11/extensions/xf86vmode.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define WARP_WIDTH 320
|
||||
#define WARP_HEIGHT 200
|
||||
|
||||
#ifdef SWQUAKE
|
||||
Display *vid_dpy = NULL;
|
||||
#else
|
||||
static Display *vid_dpy = NULL;
|
||||
#endif
|
||||
static Window vid_window;
|
||||
static GLXContext ctx = NULL;
|
||||
int scrnum;
|
||||
|
||||
|
||||
static float old_windowed_mouse = 0;
|
||||
|
||||
#define KEY_MASK (KeyPressMask | KeyReleaseMask)
|
||||
#define MOUSE_MASK (ButtonPressMask | ButtonReleaseMask | \
|
||||
PointerMotionMask)
|
||||
|
||||
#define X_MASK (KEY_MASK | MOUSE_MASK | FocusChangeMask | VisibilityChangeMask)
|
||||
|
||||
|
||||
#ifdef WITH_VMODE
|
||||
static qboolean vidmode_ext = false;
|
||||
static XF86VidModeModeInfo **vidmodes;
|
||||
static int num_vidmodes;
|
||||
static qboolean vidmode_active = false;
|
||||
#endif
|
||||
|
||||
extern cvar_t _windowed_mouse;
|
||||
|
||||
|
||||
#ifndef SWQUAKE
|
||||
cvar_t m_filter = {"m_filter", "0"};
|
||||
#ifdef IN_XFLIP
|
||||
cvar_t in_xflip = {"in_xflip", "0"};
|
||||
#endif
|
||||
|
||||
static float mouse_x, mouse_y;
|
||||
static float old_mouse_x, old_mouse_y;
|
||||
|
||||
#else
|
||||
|
||||
extern float mouse_x, mouse_y;
|
||||
extern float old_mouse_x, old_mouse_y;
|
||||
#endif
|
||||
|
||||
static int scr_width, scr_height;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
float gldepthmin, gldepthmax;
|
||||
|
||||
const char *gl_vendor;
|
||||
const char *gl_renderer;
|
||||
const char *gl_version;
|
||||
const char *gl_extensions;
|
||||
|
||||
qboolean is8bit = false;
|
||||
qboolean isPermedia = false;
|
||||
float vid_gamma = 1.0;
|
||||
qboolean mouseactive = false;
|
||||
qboolean has_focus = false;
|
||||
|
||||
int gl_canstencil;
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static void *gllibrary;
|
||||
|
||||
XVisualInfo* (*qglXChooseVisual) (Display *dpy, int screen, int *attribList);
|
||||
void (*qglXSwapBuffers) (Display *dpy, GLXDrawable drawable);
|
||||
Bool (*qglXMakeCurrent) (Display *dpy, GLXDrawable drawable, GLXContext ctx);
|
||||
GLXContext (*qglXCreateContext) (Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct);
|
||||
void (*qglXDestroyContext) (Display *dpy, GLXContext ctx);
|
||||
void *(*qglXGetProcAddress) (char *name);
|
||||
|
||||
void GLX_CloseLibrary(void)
|
||||
{
|
||||
dlclose(gllibrary);
|
||||
gllibrary = NULL;
|
||||
}
|
||||
|
||||
qboolean GLX_InitLibrary(char *driver)
|
||||
{
|
||||
if (driver && *driver)
|
||||
gllibrary = dlopen(driver, RTLD_LOCAL | RTLD_LAZY);
|
||||
else
|
||||
gllibrary = NULL;
|
||||
if (!gllibrary)
|
||||
gllibrary = dlopen("libGL.so", RTLD_LOCAL | RTLD_LAZY);
|
||||
if (!gllibrary)
|
||||
return false;
|
||||
|
||||
qglXChooseVisual = dlsym(gllibrary, "glXChooseVisual");
|
||||
qglXSwapBuffers = dlsym(gllibrary, "glXSwapBuffers");
|
||||
qglXMakeCurrent = dlsym(gllibrary, "glXMakeCurrent");
|
||||
qglXCreateContext = dlsym(gllibrary, "glXCreateContext");
|
||||
qglXDestroyContext = dlsym(gllibrary, "glXDestroyContext");
|
||||
qglXDestroyContext = dlsym(gllibrary, "glXDestroyContext");
|
||||
qglXGetProcAddress = dlsym(gllibrary, "glXGetProcAddress");
|
||||
if (!qglXGetProcAddress)
|
||||
qglXGetProcAddress = dlsym(gllibrary, "glXGetProcAddressARB");
|
||||
|
||||
if (!qglXSwapBuffers && !qglXDestroyContext && !qglXCreateContext && !qglXMakeCurrent && !qglXChooseVisual)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void *GLX_GetSymbol(char *name)
|
||||
{
|
||||
void *symb;
|
||||
if (qglXGetProcAddress)
|
||||
symb = qglXGetProcAddress(name);
|
||||
else
|
||||
symb = NULL;
|
||||
|
||||
if (!symb)
|
||||
symb = dlsym(gllibrary, name);
|
||||
return symb;
|
||||
}
|
||||
|
||||
|
||||
void GLD_BeginDirectRect (int x, int y, qbyte *pbitmap, int width, int height)
|
||||
{
|
||||
}
|
||||
|
||||
void GLD_EndDirectRect (int x, int y, int width, int height)
|
||||
{
|
||||
}
|
||||
|
||||
static int XLateKey(XKeyEvent *ev)
|
||||
{
|
||||
|
||||
int key;
|
||||
char buf[64];
|
||||
KeySym keysym;
|
||||
|
||||
key = 0;
|
||||
|
||||
XLookupString(ev, buf, sizeof buf, &keysym, 0);
|
||||
|
||||
switch(keysym)
|
||||
{
|
||||
case XK_KP_Page_Up:
|
||||
case XK_Page_Up: key = K_PGUP; break;
|
||||
|
||||
case XK_KP_Page_Down:
|
||||
case XK_Page_Down: key = K_PGDN; break;
|
||||
|
||||
case XK_KP_Home:
|
||||
case XK_Home: key = K_HOME; break;
|
||||
|
||||
case XK_KP_End:
|
||||
case XK_End: key = K_END; break;
|
||||
|
||||
case XK_KP_Left:
|
||||
case XK_Left: key = K_LEFTARROW; break;
|
||||
|
||||
case XK_KP_Right:
|
||||
case XK_Right: key = K_RIGHTARROW; break;
|
||||
|
||||
case XK_KP_Down:
|
||||
case XK_Down: key = K_DOWNARROW; break;
|
||||
|
||||
case XK_KP_Up:
|
||||
case XK_Up: key = K_UPARROW; break;
|
||||
|
||||
case XK_Escape: key = K_ESCAPE; break;
|
||||
|
||||
case XK_KP_Enter:
|
||||
case XK_Return: key = K_ENTER; break;
|
||||
|
||||
case XK_Tab: key = K_TAB; break;
|
||||
|
||||
case XK_F1: key = K_F1; break;
|
||||
|
||||
case XK_F2: key = K_F2; break;
|
||||
|
||||
case XK_F3: key = K_F3; break;
|
||||
|
||||
case XK_F4: key = K_F4; break;
|
||||
|
||||
case XK_F5: key = K_F5; break;
|
||||
|
||||
case XK_F6: key = K_F6; break;
|
||||
|
||||
case XK_F7: key = K_F7; break;
|
||||
|
||||
case XK_F8: key = K_F8; break;
|
||||
|
||||
case XK_F9: key = K_F9; break;
|
||||
|
||||
case XK_F10: key = K_F10; break;
|
||||
|
||||
case XK_F11: key = K_F11; break;
|
||||
|
||||
case XK_F12: key = K_F12; break;
|
||||
|
||||
case XK_BackSpace: key = K_BACKSPACE; break;
|
||||
|
||||
case XK_KP_Delete:
|
||||
case XK_Delete: key = K_DEL; break;
|
||||
|
||||
case XK_Pause: key = K_PAUSE; break;
|
||||
|
||||
case XK_Shift_L:
|
||||
case XK_Shift_R: key = K_SHIFT; break;
|
||||
|
||||
case XK_Execute:
|
||||
case XK_Control_L:
|
||||
case XK_Control_R: key = K_CTRL; break;
|
||||
|
||||
case XK_Alt_L:
|
||||
case XK_Meta_L:
|
||||
case XK_Alt_R:
|
||||
case XK_Meta_R: key = K_ALT; break;
|
||||
|
||||
case XK_KP_Begin: key = '5'; break;
|
||||
|
||||
case XK_KP_Insert:
|
||||
case XK_Insert:key = K_INS; break;
|
||||
|
||||
case XK_KP_Multiply: key = '*'; break;
|
||||
case XK_KP_Add: key = '+'; break;
|
||||
case XK_KP_Subtract: key = '-'; break;
|
||||
case XK_KP_Divide: key = '/'; break;
|
||||
|
||||
#if 0
|
||||
case 0x021: key = '1';break;/* [!] */
|
||||
case 0x040: key = '2';break;/* [@] */
|
||||
case 0x023: key = '3';break;/* [#] */
|
||||
case 0x024: key = '4';break;/* [$] */
|
||||
case 0x025: key = '5';break;/* [%] */
|
||||
case 0x05e: key = '6';break;/* [^] */
|
||||
case 0x026: key = '7';break;/* [&] */
|
||||
case 0x02a: key = '8';break;/* [*] */
|
||||
case 0x028: key = '9';;break;/* [(] */
|
||||
case 0x029: key = '0';break;/* [)] */
|
||||
case 0x05f: key = '-';break;/* [_] */
|
||||
case 0x02b: key = '=';break;/* [+] */
|
||||
case 0x07c: key = '\'';break;/* [|] */
|
||||
case 0x07d: key = '[';break;/* [}] */
|
||||
case 0x07b: key = ']';break;/* [{] */
|
||||
case 0x022: key = '\'';break;/* ["] */
|
||||
case 0x03a: key = ';';break;/* [:] */
|
||||
case 0x03f: key = '/';break;/* [?] */
|
||||
case 0x03e: key = '.';break;/* [>] */
|
||||
case 0x03c: key = ',';break;/* [<] */
|
||||
#endif
|
||||
|
||||
default:
|
||||
key = *(unsigned char*)buf;
|
||||
if (key >= 'A' && key <= 'Z')
|
||||
key = key - 'A' + 'a';
|
||||
break;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static void install_grabs(void)
|
||||
{
|
||||
XGrabPointer(vid_dpy, vid_window,
|
||||
True,
|
||||
0,
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
vid_window,
|
||||
None,
|
||||
CurrentTime);
|
||||
|
||||
#ifdef USE_DGA
|
||||
XF86DGADirectVideo(vid_dpy, DefaultScreen(vid_dpy), XF86DGADirectMouse);
|
||||
dgamouse = 1;
|
||||
#else
|
||||
XWarpPointer(vid_dpy, None, vid_window,
|
||||
0, 0, 0, 0,
|
||||
vid.width / 2, vid.height / 2);
|
||||
#endif
|
||||
|
||||
// XSync(vid_dpy, True);
|
||||
}
|
||||
|
||||
static void uninstall_grabs(void)
|
||||
{
|
||||
#ifdef USE_DGA
|
||||
XF86DGADirectVideo(vid_dpy, DefaultScreen(vid_dpy), 0);
|
||||
dgamouse = 0;
|
||||
#endif
|
||||
|
||||
XUngrabPointer(vid_dpy, CurrentTime);
|
||||
|
||||
// XSync(vid_dpy, True);
|
||||
}
|
||||
|
||||
static void GetEvent(void)
|
||||
{
|
||||
XEvent event;
|
||||
int b;
|
||||
qboolean wantwindowed;
|
||||
|
||||
if (!vid_dpy)
|
||||
return;
|
||||
|
||||
XNextEvent(vid_dpy, &event);
|
||||
|
||||
switch (event.type) {
|
||||
case KeyPress:
|
||||
case KeyRelease:
|
||||
Key_Event(XLateKey(&event.xkey), event.type == KeyPress);
|
||||
break;
|
||||
|
||||
case MotionNotify:
|
||||
#ifdef USE_DGA
|
||||
if (dgamouse && old_windowed_mouse)
|
||||
{
|
||||
mouse_x = event.xmotion.x_root;
|
||||
mouse_y = event.xmotion.y_root;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (old_windowed_mouse)
|
||||
{
|
||||
mouse_x = (float) ((int)event.xmotion.x - (int)(vid.width/2));
|
||||
mouse_y = (float) ((int)event.xmotion.y - (int)(vid.height/2));
|
||||
|
||||
/* move the mouse to the window center again */
|
||||
XSelectInput(vid_dpy, vid_window, X_MASK & ~PointerMotionMask);
|
||||
XWarpPointer(vid_dpy, None, vid_window, 0, 0, 0, 0,
|
||||
(vid.width/2), (vid.height/2));
|
||||
XSelectInput(vid_dpy, vid_window, X_MASK);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ButtonPress:
|
||||
b=-1;
|
||||
if (event.xbutton.button == 1)
|
||||
b = 0;
|
||||
else if (event.xbutton.button == 2)
|
||||
b = 2;
|
||||
else if (event.xbutton.button == 3)
|
||||
b = 1;
|
||||
if (b>=0)
|
||||
Key_Event(K_MOUSE1 + b, true);
|
||||
break;
|
||||
|
||||
case ButtonRelease:
|
||||
b=-1;
|
||||
if (event.xbutton.button == 1)
|
||||
b = 0;
|
||||
else if (event.xbutton.button == 2)
|
||||
b = 2;
|
||||
else if (event.xbutton.button == 3)
|
||||
b = 1;
|
||||
if (b>=0)
|
||||
Key_Event(K_MOUSE1 + b, false);
|
||||
break;
|
||||
|
||||
case FocusIn:
|
||||
has_focus = true;
|
||||
break;
|
||||
case FocusOut:
|
||||
has_focus = false;
|
||||
break;
|
||||
}
|
||||
|
||||
wantwindowed = !!_windowed_mouse.value;
|
||||
if (!has_focus)
|
||||
wantwindowed = false;
|
||||
if (key_dest == key_console)
|
||||
wantwindowed = false;
|
||||
|
||||
if (old_windowed_mouse != wantwindowed)
|
||||
{
|
||||
old_windowed_mouse = wantwindowed;
|
||||
|
||||
if (!wantwindowed)
|
||||
{
|
||||
/* ungrab the pointer */
|
||||
uninstall_grabs();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* grab the pointer */
|
||||
install_grabs();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GLVID_Shutdown(void)
|
||||
{
|
||||
printf("GLVID_Shutdown");
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
XUngrabKeyboard(vid_dpy, CurrentTime);
|
||||
if (old_windowed_mouse)
|
||||
uninstall_grabs();
|
||||
|
||||
qglXDestroyContext(vid_dpy, ctx);
|
||||
if (vid_window)
|
||||
XDestroyWindow(vid_dpy, vid_window);
|
||||
#ifdef WITH_VMODE
|
||||
if (vid_dpy) {
|
||||
if (vidmode_active)
|
||||
XF86VidModeSwitchToMode(vid_dpy, scrnum, vidmodes[0]);
|
||||
vidmode_active = false;
|
||||
}
|
||||
#endif
|
||||
// XCloseDisplay(vid_dpy);
|
||||
// vid_dpy = NULL;
|
||||
vid_window = (Window)NULL;
|
||||
}
|
||||
|
||||
void GLVID_DeInit(void) //FIXME:....
|
||||
{
|
||||
GLVID_Shutdown();
|
||||
}
|
||||
|
||||
|
||||
void signal_handler(int sig)
|
||||
{
|
||||
printf("Received signal %d, exiting...\n", sig);
|
||||
Sys_Quit();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void InitSig(void)
|
||||
{
|
||||
signal(SIGHUP, signal_handler);
|
||||
signal(SIGINT, signal_handler);
|
||||
signal(SIGQUIT, signal_handler);
|
||||
signal(SIGILL, signal_handler);
|
||||
signal(SIGTRAP, signal_handler);
|
||||
#ifndef __CYGWIN__
|
||||
signal(SIGIOT, signal_handler);
|
||||
#endif
|
||||
signal(SIGBUS, signal_handler);
|
||||
signal(SIGFPE, signal_handler);
|
||||
signal(SIGSEGV, signal_handler);
|
||||
signal(SIGTERM, signal_handler);
|
||||
}
|
||||
|
||||
static Cursor CreateNullCursor(Display *display, Window root)
|
||||
{
|
||||
Pixmap cursormask;
|
||||
XGCValues xgc;
|
||||
GC gc;
|
||||
XColor dummycolour;
|
||||
Cursor cursor;
|
||||
|
||||
cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
|
||||
xgc.function = GXclear;
|
||||
gc = XCreateGC(display, cursormask, GCFunction, &xgc);
|
||||
XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
|
||||
dummycolour.pixel = 0;
|
||||
dummycolour.red = 0;
|
||||
dummycolour.flags = 04;
|
||||
cursor = XCreatePixmapCursor(display, cursormask, cursormask,
|
||||
&dummycolour,&dummycolour, 0,0);
|
||||
XFreePixmap(display,cursormask);
|
||||
XFreeGC(display,gc);
|
||||
return cursor;
|
||||
}
|
||||
|
||||
void GLVID_ShiftPalette(unsigned char *p)
|
||||
{
|
||||
// VID_SetPalette(p);
|
||||
}
|
||||
|
||||
void GLVID_SetPalette (unsigned char *palette)
|
||||
{
|
||||
qbyte *pal;
|
||||
unsigned r,g,b;
|
||||
unsigned v;
|
||||
unsigned short i;
|
||||
unsigned *table;
|
||||
unsigned *table2;
|
||||
extern qbyte gammatable[256];
|
||||
|
||||
//
|
||||
// 8 8 8 encoding
|
||||
//
|
||||
Con_Printf("Converting 8to24\n");
|
||||
|
||||
pal = palette;
|
||||
table = d_8to24rgbtable;
|
||||
table2 = d_8to24bgrtable;
|
||||
for (i=0 ; i<256 ; i++)
|
||||
{
|
||||
r = gammatable[pal[0]];
|
||||
g = gammatable[pal[1]];
|
||||
b = gammatable[pal[2]];
|
||||
pal += 3;
|
||||
|
||||
// v = (255<<24) + (r<<16) + (g<<8) + (b<<0);
|
||||
// v = (255<<0) + (r<<8) + (g<<16) + (b<<24);
|
||||
v = (255<<24) + (r<<0) + (g<<8) + (b<<16);
|
||||
*table++ = v;
|
||||
*table2++ = (255<<24) + (r<<16) + (g<<8) + (b<<0);
|
||||
}
|
||||
d_8to24bgrtable[255] &= 0xffffff; // 255 is transparent
|
||||
d_8to24rgbtable[255] &= 0xffffff; // 255 is transparent
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
GL_BeginRendering
|
||||
|
||||
=================
|
||||
*/
|
||||
void GL_BeginRendering (int *x, int *y, int *width, int *height)
|
||||
{
|
||||
*x = *y = 0;
|
||||
*width = scr_width;
|
||||
*height = scr_height;
|
||||
|
||||
// if (!wglMakeCurrent( maindc, baseRC ))
|
||||
// Sys_Error ("wglMakeCurrent failed");
|
||||
|
||||
// glViewport (*x, *y, *width, *height);
|
||||
}
|
||||
|
||||
|
||||
void GL_EndRendering (void)
|
||||
{
|
||||
//return;
|
||||
glFlush();
|
||||
qglXSwapBuffers(vid_dpy, vid_window);
|
||||
}
|
||||
|
||||
qboolean GLVID_Is8bit(void)
|
||||
{
|
||||
return is8bit;
|
||||
}
|
||||
|
||||
qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
|
||||
{
|
||||
int i;
|
||||
int attrib[] = {
|
||||
GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_DOUBLEBUFFER,
|
||||
GLX_DEPTH_SIZE, 1,
|
||||
None
|
||||
};
|
||||
char gldir[MAX_OSPATH];
|
||||
XSetWindowAttributes attr;
|
||||
unsigned long mask;
|
||||
Window root;
|
||||
XVisualInfo *visinfo;
|
||||
|
||||
#ifdef WITH_VMODE
|
||||
qboolean fullscreen = false;
|
||||
int MajorVersion, MinorVersion, actualWidth, actualHeight;
|
||||
|
||||
if (info->fullscreen)
|
||||
fullscreen = true;
|
||||
#endif
|
||||
|
||||
|
||||
S_Startup();
|
||||
|
||||
GLX_InitLibrary(info->glrenderer);
|
||||
|
||||
vid.maxwarpwidth = WARP_WIDTH;
|
||||
vid.maxwarpheight = WARP_HEIGHT;
|
||||
vid.colormap = host_colormap;
|
||||
|
||||
// interpret command-line params
|
||||
|
||||
// set vid parameters
|
||||
if ((i = COM_CheckParm("-conwidth")) != 0)
|
||||
vid.conwidth = Q_atoi(com_argv[i+1]);
|
||||
else
|
||||
vid.conwidth = 640;
|
||||
|
||||
vid.conwidth &= ~7; // make it a multiple of eight
|
||||
|
||||
if (vid.conwidth < 320)
|
||||
vid.conwidth = 320;
|
||||
|
||||
// pick a conheight that matches with correct aspect
|
||||
vid.conheight = vid.conwidth*3 / 4;
|
||||
|
||||
if ((i = COM_CheckParm("-conheight")) != 0)
|
||||
vid.conheight = Q_atoi(com_argv[i+1]);
|
||||
if (vid.conheight < 200)
|
||||
vid.conheight = 200;
|
||||
if (!vid_dpy)
|
||||
vid_dpy = XOpenDisplay(NULL);
|
||||
if (!vid_dpy)
|
||||
{
|
||||
Sys_Error("Error couldn't open the X display\n");
|
||||
}
|
||||
|
||||
scrnum = DefaultScreen(vid_dpy);
|
||||
root = RootWindow(vid_dpy, scrnum);
|
||||
|
||||
#ifdef WITH_VMODE //find out if it's supported on this pc.
|
||||
MajorVersion = MinorVersion = 0;
|
||||
if (!XF86VidModeQueryVersion(vid_dpy, &MajorVersion, &MinorVersion))
|
||||
{
|
||||
vidmode_ext = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf("Using XF86-VidModeExtension Ver. %d.%d\n", MajorVersion, MinorVersion);
|
||||
vidmode_ext = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
visinfo = qglXChooseVisual(vid_dpy, scrnum, attrib);
|
||||
if (!visinfo)
|
||||
{
|
||||
Sys_Error("qkHack: Error couldn't get an RGB, Double-buffered, Depth visual\n");
|
||||
}
|
||||
|
||||
#ifdef WITH_VMODE
|
||||
if (vidmode_ext)
|
||||
{
|
||||
int best_fit, best_dist, dist, x, y;
|
||||
|
||||
XF86VidModeGetAllModeLines(vid_dpy, scrnum, &num_vidmodes, &vidmodes);
|
||||
// Are we going fullscreen? If so, let's change video mode
|
||||
if (fullscreen)
|
||||
{
|
||||
best_dist = 9999999;
|
||||
best_fit = -1;
|
||||
|
||||
for (i = 0; i < num_vidmodes; i++)
|
||||
{
|
||||
if (info->width > vidmodes[i]->hdisplay ||
|
||||
info->height > vidmodes[i]->vdisplay)
|
||||
continue;
|
||||
|
||||
x = info->width - vidmodes[i]->hdisplay;
|
||||
y = info->height - vidmodes[i]->vdisplay;
|
||||
dist = (x * x) + (y * y);
|
||||
if (dist < best_dist)
|
||||
{
|
||||
best_dist = dist;
|
||||
best_fit = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (best_fit != -1 && (!best_dist || COM_CheckParm("-fullscreen")))
|
||||
{
|
||||
actualWidth = vidmodes[best_fit]->hdisplay;
|
||||
actualHeight = vidmodes[best_fit]->vdisplay;
|
||||
// change to the mode
|
||||
XF86VidModeSwitchToMode(vid_dpy, scrnum, vidmodes[best_fit]);
|
||||
vidmode_active = true;
|
||||
// Move the viewport to top left
|
||||
XF86VidModeSetViewPort(vid_dpy, scrnum, 0, 0);
|
||||
|
||||
}
|
||||
else
|
||||
fullscreen = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* window attributes */
|
||||
attr.background_pixel = 0;
|
||||
attr.border_pixel = 0;
|
||||
attr.colormap = XCreateColormap(vid_dpy, root, visinfo->visual, AllocNone);
|
||||
attr.event_mask = X_MASK;
|
||||
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
|
||||
|
||||
#ifdef WITH_VMODE //get rid of borders
|
||||
// fullscreen
|
||||
if (vidmode_active) {
|
||||
mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore |
|
||||
CWEventMask | CWOverrideRedirect;
|
||||
attr.override_redirect = True;
|
||||
attr.backing_store = NotUseful;
|
||||
attr.save_under = False;
|
||||
}
|
||||
#endif
|
||||
|
||||
has_focus = false;
|
||||
vid_window = XCreateWindow(vid_dpy, root, 0, 0, info->width, info->height,
|
||||
0, visinfo->depth, InputOutput,
|
||||
visinfo->visual, mask, &attr);
|
||||
XMapWindow(vid_dpy, vid_window);
|
||||
|
||||
XMoveWindow(vid_dpy, vid_window, 0, 0);
|
||||
#ifdef WITH_VMODE
|
||||
if (vidmode_active) {
|
||||
XRaiseWindow(vid_dpy, vid_window);
|
||||
XWarpPointer(vid_dpy, None, vid_window, 0, 0, 0, 0, 0, 0);
|
||||
XFlush(vid_dpy);
|
||||
// Move the viewport to top left
|
||||
XF86VidModeSetViewPort(vid_dpy, scrnum, 0, 0);
|
||||
}
|
||||
#endif
|
||||
XStoreName(vid_dpy, vid_window, "GLX QuakeWorld Cient");
|
||||
|
||||
//hide the cursor.
|
||||
XDefineCursor(vid_dpy, vid_window, CreateNullCursor(vid_dpy, vid_window));
|
||||
|
||||
XFlush(vid_dpy);
|
||||
|
||||
ctx = qglXCreateContext(vid_dpy, visinfo, NULL, True);
|
||||
|
||||
qglXMakeCurrent(vid_dpy, vid_window, ctx);
|
||||
|
||||
scr_width = info->width;
|
||||
scr_height = info->height;
|
||||
|
||||
if (vid.conheight > info->height)
|
||||
vid.conheight = info->height;
|
||||
if (vid.conwidth > info->width)
|
||||
vid.conwidth = info->width;
|
||||
vid.width = vid.conwidth;
|
||||
vid.height = vid.conheight;
|
||||
|
||||
vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0);
|
||||
vid.numpages = 2;
|
||||
|
||||
InitSig(); // trap evil signals
|
||||
|
||||
GL_Init(&GLX_GetSymbol);
|
||||
|
||||
sprintf (gldir, "%s/glquake", com_gamedir);
|
||||
Sys_mkdir (gldir);
|
||||
|
||||
VID_SetPalette(palette);
|
||||
|
||||
Con_SafePrintf ("Video mode %dx%d initialized.\n", info->width, info->height);
|
||||
|
||||
vid.recalc_refdef = 1; // force a surface cache flush
|
||||
|
||||
if (Cvar_Get("vidx_grabkeyboard", "0", 0, "Additional video options")->value)
|
||||
XGrabKeyboard(vid_dpy, vid_window,
|
||||
False,
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
CurrentTime);
|
||||
else
|
||||
XSetInputFocus(vid_dpy, vid_window, RevertToParent, CurrentTime);
|
||||
XRaiseWindow(vid_dpy, vid_window);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef SWQUAKE
|
||||
void GLSys_SendKeyEvents(void)
|
||||
#else
|
||||
void Sys_SendKeyEvents(void)
|
||||
#endif
|
||||
{
|
||||
if (vid_dpy && vid_window) {
|
||||
while (XPending(vid_dpy))
|
||||
GetEvent();
|
||||
}
|
||||
}
|
||||
|
||||
void Force_CenterView_f (void)
|
||||
{
|
||||
cl.viewangles[0][PITCH] = 0;
|
||||
}
|
||||
|
||||
#ifndef SWQUAKE
|
||||
void IN_Init(void)
|
||||
{
|
||||
#ifdef IN_XFLIP
|
||||
Cvar_Register (&in_xflip, "Input variables");
|
||||
#endif
|
||||
}
|
||||
|
||||
void IN_Shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Commands
|
||||
===========
|
||||
*/
|
||||
void IN_Commands (void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Move
|
||||
===========
|
||||
*/
|
||||
void IN_MouseMove (usercmd_t *cmd, int pnum)
|
||||
{
|
||||
if (m_filter.value)
|
||||
{
|
||||
mouse_x = (mouse_x + old_mouse_x) * 0.5;
|
||||
mouse_y = (mouse_y + old_mouse_y) * 0.5;
|
||||
}
|
||||
old_mouse_x = mouse_x;
|
||||
old_mouse_y = mouse_y;
|
||||
|
||||
mouse_x *= sensitivity.value;
|
||||
mouse_y *= sensitivity.value;
|
||||
|
||||
#ifdef IN_XFLIP
|
||||
if(in_xflip.value) mouse_x *= -1;
|
||||
#endif
|
||||
|
||||
// add mouse X/Y movement to cmd
|
||||
if ( (in_strafe.state[pnum] & 1) || (lookstrafe.value && (in_mlook.state[pnum] & 1) ))
|
||||
cmd->sidemove += m_side.value * mouse_x;
|
||||
else
|
||||
cl.viewangles[pnum][YAW] -= m_yaw.value * mouse_x;
|
||||
|
||||
if (in_mlook.state[pnum] & 1)
|
||||
V_StopPitchDrift (pnum);
|
||||
|
||||
if ( (in_mlook.state[pnum] & 1) && !(in_strafe.state[pnum] & 1))
|
||||
{
|
||||
cl.viewangles[pnum][PITCH] += m_pitch.value * mouse_y;
|
||||
CL_ClampPitch(pnum);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((in_strafe.state[pnum] & 1) && noclip_anglehack)
|
||||
cmd->upmove -= m_forward.value * mouse_y;
|
||||
else
|
||||
cmd->forwardmove -= m_forward.value * mouse_y;
|
||||
}
|
||||
mouse_x = mouse_y = 0.0;
|
||||
}
|
||||
|
||||
void IN_Move (usercmd_t *cmd, int pnum)
|
||||
{
|
||||
IN_MouseMove(cmd, pnum);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void GLVID_UnlockBuffer() {}
|
||||
void GLVID_LockBuffer() {}
|
||||
|
||||
int GLVID_ForceUnlockedAndReturnState (void) {return 0;}
|
||||
void GLVID_ForceLockState (int lk) {}
|
||||
void GLVID_HandlePause (qboolean pause) {}
|
1283
engine/gl/gl_vidnt.c
Normal file
1283
engine/gl/gl_vidnt.c
Normal file
File diff suppressed because it is too large
Load diff
956
engine/gl/gl_warp.c
Normal file
956
engine/gl/gl_warp.c
Normal file
|
@ -0,0 +1,956 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// gl_warp.c -- sky and water polygons
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "glquake.h"
|
||||
|
||||
extern model_t *loadmodel;
|
||||
|
||||
int skytexturenum;
|
||||
|
||||
int solidskytexture;
|
||||
int alphaskytexture;
|
||||
float speedscale; // for top sky and bottom sky
|
||||
|
||||
qboolean usingskybox;
|
||||
|
||||
msurface_t *warpface;
|
||||
|
||||
extern cvar_t gl_skyboxname;
|
||||
extern cvar_t gl_waterripples;
|
||||
char loadedskybox[256];
|
||||
|
||||
void R_DrawSkyBox (msurface_t *s);
|
||||
void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs)
|
||||
{
|
||||
int i, j;
|
||||
float *v;
|
||||
|
||||
mins[0] = mins[1] = mins[2] = 9999;
|
||||
maxs[0] = maxs[1] = maxs[2] = -9999;
|
||||
v = verts;
|
||||
for (i=0 ; i<numverts ; i++)
|
||||
for (j=0 ; j<3 ; j++, v++)
|
||||
{
|
||||
if (*v < mins[j])
|
||||
mins[j] = *v;
|
||||
if (*v > maxs[j])
|
||||
maxs[j] = *v;
|
||||
}
|
||||
}
|
||||
|
||||
void SubdividePolygon (int numverts, float *verts, float dividesize)
|
||||
{
|
||||
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;
|
||||
|
||||
if (numverts > 60 || numverts <= 0)
|
||||
Sys_Error ("numverts = %i", numverts);
|
||||
|
||||
BoundPoly (numverts, verts, mins, maxs);
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
m = (mins[i] + maxs[i]) * 0.5;
|
||||
m = dividesize * floor (m/dividesize + 0.5);
|
||||
if (maxs[i] - m < 8)
|
||||
continue;
|
||||
if (m - mins[i] < 8)
|
||||
continue;
|
||||
|
||||
// cut it
|
||||
v = verts + i;
|
||||
for (j=0 ; j<numverts ; j++, v+= 3)
|
||||
dist[j] = *v - m;
|
||||
|
||||
// wrap cases
|
||||
dist[j] = dist[0];
|
||||
v-=i;
|
||||
VectorCopy (verts, v);
|
||||
|
||||
f = b = 0;
|
||||
v = verts;
|
||||
for (j=0 ; j<numverts ; j++, v+= 3)
|
||||
{
|
||||
if (dist[j] >= 0)
|
||||
{
|
||||
VectorCopy (v, front[f]);
|
||||
f++;
|
||||
}
|
||||
if (dist[j] <= 0)
|
||||
{
|
||||
VectorCopy (v, back[b]);
|
||||
b++;
|
||||
}
|
||||
if (dist[j] == 0 || dist[j+1] == 0)
|
||||
continue;
|
||||
if ( (dist[j] > 0) != (dist[j+1] > 0) )
|
||||
{
|
||||
// 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]);
|
||||
f++;
|
||||
b++;
|
||||
}
|
||||
}
|
||||
|
||||
SubdividePolygon (f, front[0], dividesize);
|
||||
SubdividePolygon (b, back[0], dividesize);
|
||||
return;
|
||||
}
|
||||
|
||||
poly = Hunk_AllocName (sizeof(glpoly_t) + (numverts-4) * VERTEXSIZE*sizeof(float), "subpoly");
|
||||
poly->next = warpface->polys;
|
||||
warpface->polys = poly;
|
||||
poly->numverts = numverts;
|
||||
for (i=0 ; i<numverts ; i++, verts+= 3)
|
||||
{
|
||||
VectorCopy (verts, poly->verts[i]);
|
||||
s = DotProduct (verts, warpface->texinfo->vecs[0]);
|
||||
t = DotProduct (verts, warpface->texinfo->vecs[1]);
|
||||
poly->verts[i][3] = s;
|
||||
poly->verts[i][4] = t;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
GL_SubdivideSurface
|
||||
|
||||
Breaks a polygon up along axial 64 unit
|
||||
boundaries so that turbulent and sky warps
|
||||
can be done reasonably.
|
||||
================
|
||||
*/
|
||||
void GL_SubdivideSurface (msurface_t *fa, float dividesize)
|
||||
{
|
||||
vec3_t verts[64];
|
||||
int numverts;
|
||||
int i;
|
||||
int lindex;
|
||||
float *vec;
|
||||
|
||||
warpface = fa;
|
||||
|
||||
//
|
||||
// convert edges back to a normal polygon
|
||||
//
|
||||
numverts = 0;
|
||||
for (i=0 ; i<fa->numedges ; i++)
|
||||
{
|
||||
lindex = loadmodel->surfedges[fa->firstedge + i];
|
||||
|
||||
if (lindex > 0)
|
||||
vec = loadmodel->vertexes[loadmodel->edges[lindex].v[0]].position;
|
||||
else
|
||||
vec = loadmodel->vertexes[loadmodel->edges[-lindex].v[1]].position;
|
||||
VectorCopy (vec, verts[numverts]);
|
||||
numverts++;
|
||||
|
||||
if(numverts >= 64)
|
||||
{
|
||||
Con_Printf("Too many verts on surface\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SubdividePolygon (numverts, verts[0], dividesize);
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
||||
|
||||
|
||||
// speed up sin calculations - Ed
|
||||
float turbsin[] =
|
||||
{
|
||||
#include "gl_warp_sin.h"
|
||||
};
|
||||
#define TURBSCALE (256.0 / (2 * M_PI))
|
||||
|
||||
/*
|
||||
=============
|
||||
EmitWaterPolys
|
||||
|
||||
Does a water warp on the pre-fragmented glpoly_t chain
|
||||
=============
|
||||
*/
|
||||
void EmitWaterPolys (msurface_t *fa)
|
||||
{
|
||||
glpoly_t *p;
|
||||
float *v;
|
||||
int i;
|
||||
float s, t, os, ot;
|
||||
|
||||
#ifdef WATERLAYERS
|
||||
extern cvar_t r_waterlayers;
|
||||
|
||||
|
||||
if (gl_waterripples.value)
|
||||
{
|
||||
float f = 10;
|
||||
|
||||
glEnable(GL_AUTO_NORMAL);
|
||||
for (p=fa->polys ; p ; p=p->next)
|
||||
{
|
||||
glBegin (GL_POLYGON);
|
||||
for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
|
||||
{
|
||||
os = v[3];
|
||||
ot = v[4];
|
||||
|
||||
s = os + turbsin[(int)((ot*0.125+realtime) * TURBSCALE) & 255];
|
||||
s *= (1.0/64);
|
||||
|
||||
t = ot + turbsin[(int)((os*0.125+realtime) * TURBSCALE) & 255];
|
||||
t *= (1.0/64);
|
||||
|
||||
glNormal3f(fa->plane->normal[0] + (sin(realtime+v[0]/f+v[1]/f))/4, fa->plane->normal[1] +(sin(realtime-v[1]/f))/4, fa->plane->normal[2] + (sin(realtime+v[2]/f))/4);
|
||||
glTexCoord2f (s, t);
|
||||
glVertex3fv (v);
|
||||
}
|
||||
glEnd ();
|
||||
}
|
||||
glDisable(GL_AUTO_NORMAL);
|
||||
}
|
||||
else if (r_waterlayers.value>=1)
|
||||
{
|
||||
float a, stm, ttm;
|
||||
int l;
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glEnable(GL_BLEND); //to ensure.
|
||||
for (a=r_wateralphaval,l = 0; l < r_waterlayers.value; l++,a=a*4/6)
|
||||
{
|
||||
glColor4f(1, 1, 1, a);
|
||||
stm =cos(l)/10;
|
||||
ttm =sin(l)/10;
|
||||
for (p=fa->polys ; p ; p=p->next)
|
||||
{
|
||||
glBegin (GL_POLYGON);
|
||||
for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
|
||||
{
|
||||
os = v[3]/(l*0.5+0.2);
|
||||
ot = v[4]/(l*0.5+0.2);
|
||||
|
||||
s = os + turbsin[(int)((ot*0.125+cl.time+l*8) * TURBSCALE) & 255];//*r_watersurfacewarp.value;
|
||||
s *= (1.0/64);
|
||||
|
||||
t = ot + turbsin[(int)((os*0.125+cl.time+l*8) * TURBSCALE) & 255];//*r_watersurfacewarp.value;
|
||||
t *= (1.0/64);
|
||||
|
||||
glTexCoord2f (s+cl.time*stm, t+cl.time*ttm);
|
||||
glVertex3fv (v);
|
||||
}
|
||||
glEnd ();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
for (p=fa->polys ; p ; p=p->next)
|
||||
{
|
||||
glBegin (GL_POLYGON);
|
||||
for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
|
||||
{
|
||||
os = v[3];
|
||||
ot = v[4];
|
||||
|
||||
s = os + turbsin[(int)((ot*0.125+realtime) * TURBSCALE) & 255];
|
||||
s *= (1.0/64);
|
||||
|
||||
t = ot + turbsin[(int)((os*0.125+realtime) * TURBSCALE) & 255];
|
||||
t *= (1.0/64);
|
||||
|
||||
glTexCoord2f (s, t);
|
||||
glVertex3fv (v);
|
||||
}
|
||||
glEnd ();
|
||||
}
|
||||
#ifdef WATERLAYERS
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
EmitSkyPolys
|
||||
=============
|
||||
*/
|
||||
void EmitSkyPolys (msurface_t *fa)
|
||||
{
|
||||
glpoly_t *p;
|
||||
float *v;
|
||||
int i;
|
||||
float s, t;
|
||||
vec3_t dir;
|
||||
float length;
|
||||
|
||||
for (p=fa->polys ; p ; p=p->next)
|
||||
{
|
||||
glBegin (GL_POLYGON);
|
||||
for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
|
||||
{
|
||||
VectorSubtract (v, r_origin, dir);
|
||||
dir[2] *= 3; // flatten the sphere
|
||||
|
||||
length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2];
|
||||
length = sqrt (length);
|
||||
length = 6*63/length;
|
||||
|
||||
dir[0] *= length;
|
||||
dir[1] *= length;
|
||||
|
||||
s = (speedscale + dir[0]) * (1.0/128);
|
||||
t = (speedscale + dir[1]) * (1.0/128);
|
||||
|
||||
glTexCoord2f (s, t);
|
||||
glVertex3fv (v);
|
||||
}
|
||||
glEnd ();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
EmitBothSkyLayers
|
||||
|
||||
Does a sky warp on the pre-fragmented glpoly_t chain
|
||||
This will be called for brushmodels, the world
|
||||
will have them chained together.
|
||||
===============
|
||||
*/
|
||||
void EmitBothSkyLayers (msurface_t *fa)
|
||||
{
|
||||
GL_DisableMultitexture();
|
||||
|
||||
GL_Bind (solidskytexture);
|
||||
speedscale = realtime*8;
|
||||
speedscale -= (int)speedscale & ~127 ;
|
||||
|
||||
EmitSkyPolys (fa);
|
||||
|
||||
glEnable (GL_BLEND);
|
||||
GL_Bind (alphaskytexture);
|
||||
speedscale = realtime*16;
|
||||
speedscale -= (int)speedscale & ~127 ;
|
||||
|
||||
EmitSkyPolys (fa);
|
||||
|
||||
glDisable (GL_BLEND);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_DrawSkyChain
|
||||
=================
|
||||
*/
|
||||
void R_DrawSkyBoxChain (msurface_t *s);
|
||||
void R_DrawSkyChain (msurface_t *s)
|
||||
{
|
||||
msurface_t *fa;
|
||||
|
||||
if (usingskybox)
|
||||
{
|
||||
R_DrawSkyBoxChain(s);
|
||||
return;
|
||||
}
|
||||
|
||||
GL_DisableMultitexture();
|
||||
|
||||
// used when gl_texsort is on
|
||||
GL_Bind(solidskytexture);
|
||||
speedscale = realtime*8;
|
||||
speedscale -= (int)speedscale & ~127 ;
|
||||
|
||||
for (fa=s ; fa ; fa=fa->texturechain)
|
||||
EmitSkyPolys (fa);
|
||||
|
||||
glEnable (GL_BLEND);
|
||||
GL_Bind (alphaskytexture);
|
||||
speedscale = realtime*16;
|
||||
speedscale -= (int)speedscale & ~127 ;
|
||||
|
||||
for (fa=s ; fa ; fa=fa->texturechain)
|
||||
EmitSkyPolys (fa);
|
||||
|
||||
glDisable (GL_BLEND);
|
||||
}
|
||||
|
||||
/*
|
||||
=================================================================
|
||||
|
||||
Quake 2 environment sky
|
||||
|
||||
=================================================================
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
R_LoadSkys
|
||||
==================
|
||||
*/
|
||||
static char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
|
||||
int skyboxtex[6];
|
||||
void R_LoadSkys (void)
|
||||
{
|
||||
int i;
|
||||
char name[64];
|
||||
|
||||
for (i=0 ; i<6 ; i++)
|
||||
{
|
||||
sprintf (name, "env/%s%s.tga", gl_skyboxname.string, suf[i]);
|
||||
|
||||
skyboxtex[i] = Mod_LoadHiResTexture(name, false, false);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
Q_strncpyz(loadedskybox, gl_skyboxname.string, sizeof(loadedskybox));
|
||||
gl_skyboxname.modified = false;
|
||||
}
|
||||
|
||||
|
||||
qboolean GLR_CheckSky()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
void GLR_SetSky(char *name, float rotate, vec3_t axis)
|
||||
{
|
||||
if (*name)
|
||||
Cvar_Set(&gl_skyboxname, name);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// 1 = s, 2 = t, 3 = 2048
|
||||
int st_to_vec[6][3] =
|
||||
{
|
||||
{3,-1,2},
|
||||
{-3,1,2},
|
||||
|
||||
{1,3,2},
|
||||
{-1,-3,2},
|
||||
|
||||
{-2,-1,3}, // 0 degrees yaw, look straight up
|
||||
{2,-1,-3} // look straight down
|
||||
|
||||
// {-1,2,3},
|
||||
// {1,2,-3}
|
||||
};
|
||||
|
||||
// s = [0]/[2], t = [1]/[2]
|
||||
int vec_to_st[6][3] =
|
||||
{
|
||||
{-2,3,1},
|
||||
{2,3,-1},
|
||||
|
||||
{1,3,2},
|
||||
{-1,3,-2},
|
||||
|
||||
{-2,-1,3},
|
||||
{-2,1,-3}
|
||||
|
||||
// {-1,2,3},
|
||||
// {1,2,-3}
|
||||
};
|
||||
|
||||
float skymins[2][6], skymaxs[2][6];
|
||||
|
||||
void DrawSkyPolygon (int nump, vec3_t vecs)
|
||||
{
|
||||
int i,j;
|
||||
vec3_t v, av;
|
||||
float s, t, dv;
|
||||
int axis;
|
||||
float *vp;
|
||||
|
||||
c_sky++;
|
||||
#if 0
|
||||
glBegin (GL_POLYGON);
|
||||
for (i=0 ; i<nump ; i++, vecs+=3)
|
||||
{
|
||||
VectorAdd(vecs, r_origin, v);
|
||||
glVertex3fv (v);
|
||||
}
|
||||
glEnd();
|
||||
return;
|
||||
#endif
|
||||
// decide which face it maps to
|
||||
VectorCopy (vec3_origin, v);
|
||||
for (i=0, vp=vecs ; i<nump ; i++, vp+=3)
|
||||
{
|
||||
VectorAdd (vp, v, v);
|
||||
}
|
||||
av[0] = fabs(v[0]);
|
||||
av[1] = fabs(v[1]);
|
||||
av[2] = fabs(v[2]);
|
||||
if (av[0] > av[1] && av[0] > av[2])
|
||||
{
|
||||
if (v[0] < 0)
|
||||
axis = 1;
|
||||
else
|
||||
axis = 0;
|
||||
}
|
||||
else if (av[1] > av[2] && av[1] > av[0])
|
||||
{
|
||||
if (v[1] < 0)
|
||||
axis = 3;
|
||||
else
|
||||
axis = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (v[2] < 0)
|
||||
axis = 5;
|
||||
else
|
||||
axis = 4;
|
||||
}
|
||||
|
||||
// project new texture coords
|
||||
for (i=0 ; i<nump ; i++, vecs+=3)
|
||||
{
|
||||
j = vec_to_st[axis][2];
|
||||
if (j > 0)
|
||||
dv = vecs[j - 1];
|
||||
else
|
||||
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;
|
||||
else
|
||||
s = vecs[j-1] / dv;
|
||||
j = vec_to_st[axis][1];
|
||||
if (j < 0)
|
||||
t = -vecs[-j -1] / dv;
|
||||
else
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_CLIP_VERTS 64
|
||||
void ClipSkyPolygon (int nump, vec3_t vecs, int stage)
|
||||
{
|
||||
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)
|
||||
Sys_Error ("ClipSkyPolygon: MAX_CLIP_VERTS");
|
||||
if (stage == 6)
|
||||
{ // fully clipped, so draw it
|
||||
DrawSkyPolygon (nump, vecs);
|
||||
return;
|
||||
}
|
||||
|
||||
front = back = false;
|
||||
norm = skyclip[stage];
|
||||
for (i=0, v = vecs ; i<nump ; i++, v+=3)
|
||||
{
|
||||
d = DotProduct (v, norm);
|
||||
if (d > ON_EPSILON)
|
||||
{
|
||||
front = true;
|
||||
sides[i] = SIDE_FRONT;
|
||||
}
|
||||
else if (d < -ON_EPSILON)
|
||||
{
|
||||
back = true;
|
||||
sides[i] = SIDE_BACK;
|
||||
}
|
||||
else
|
||||
sides[i] = SIDE_ON;
|
||||
dists[i] = d;
|
||||
}
|
||||
|
||||
if (!front || !back)
|
||||
{ // not clipped
|
||||
ClipSkyPolygon (nump, vecs, stage+1);
|
||||
return;
|
||||
}
|
||||
|
||||
// clip it
|
||||
sides[i] = sides[0];
|
||||
dists[i] = dists[0];
|
||||
VectorCopy (vecs, (vecs+(i*3)) );
|
||||
newc[0] = newc[1] = 0;
|
||||
|
||||
for (i=0, v = vecs ; i<nump ; i++, v+=3)
|
||||
{
|
||||
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])
|
||||
continue;
|
||||
|
||||
d = dists[i] / (dists[i] - dists[i+1]);
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
e = v[j] + d*(v[j+3] - v[j]);
|
||||
newv[0][newc[0]][j] = e;
|
||||
newv[1][newc[1]][j] = e;
|
||||
}
|
||||
newc[0]++;
|
||||
newc[1]++;
|
||||
}
|
||||
|
||||
// continue
|
||||
ClipSkyPolygon (newc[0], newv[0][0], stage+1);
|
||||
ClipSkyPolygon (newc[1], newv[1][0], stage+1);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_DrawSkyChain
|
||||
=================
|
||||
*/
|
||||
void R_DrawSkyBoxChain (msurface_t *s)
|
||||
{
|
||||
msurface_t *fa;
|
||||
|
||||
int i;
|
||||
vec3_t verts[MAX_CLIP_VERTS];
|
||||
glpoly_t *p;
|
||||
|
||||
c_sky = 0;
|
||||
// GL_Bind(solidskytexture);
|
||||
|
||||
// calculate vertex values for sky box
|
||||
|
||||
for (fa=s ; fa ; fa=fa->texturechain)
|
||||
{
|
||||
for (p=fa->polys ; p ; p=p->next)
|
||||
{
|
||||
for (i=0 ; i<p->numverts ; i++)
|
||||
{
|
||||
VectorSubtract (p->verts[i], r_origin, verts[i]);
|
||||
}
|
||||
ClipSkyPolygon (p->numverts, verts[0], 0);
|
||||
}
|
||||
}
|
||||
|
||||
R_DrawSkyBox (s);
|
||||
|
||||
glColorMask(0, 0, 0, 0);
|
||||
for (fa=s ; fa ; fa=fa->texturechain)
|
||||
{
|
||||
for (p=fa->polys ; p ; p=p->next)
|
||||
{
|
||||
glBegin(GL_POLYGON);
|
||||
for (i = 0; i < p->numverts; i++)
|
||||
glVertex3fv(p->verts[i]);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
glColorMask(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
void R_AddSkySurface (msurface_t *fa)
|
||||
{
|
||||
int i;
|
||||
vec3_t verts[MAX_CLIP_VERTS];
|
||||
glpoly_t *p;
|
||||
|
||||
// calculate vertex values for sky box
|
||||
for (p=fa->polys ; p ; p=p->next)
|
||||
{
|
||||
for (i=0 ; i<p->numverts ; i++)
|
||||
{
|
||||
VectorSubtract (p->verts[i], r_origin, verts[i]);
|
||||
}
|
||||
ClipSkyPolygon (p->numverts, verts[0], 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
R_ClearSkyBox
|
||||
==============
|
||||
*/
|
||||
void R_ClearSkyBox (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!cl.worldmodel) //allow skyboxes on non quake1 maps. (expect them even)
|
||||
{
|
||||
usingskybox = false;
|
||||
return;
|
||||
}
|
||||
if (gl_skyboxname.modified)
|
||||
R_LoadSkys();
|
||||
|
||||
if (!skyboxtex[0] || !skyboxtex[1] || !skyboxtex[2] || !skyboxtex[3] || !skyboxtex[4] || !skyboxtex[5])
|
||||
{
|
||||
usingskybox = false;
|
||||
return;
|
||||
}
|
||||
|
||||
usingskybox = true;
|
||||
|
||||
for (i=0 ; i<6 ; i++)
|
||||
{
|
||||
skymins[0][i] = skymins[1][i] = 9999;
|
||||
skymaxs[0][i] = skymaxs[1][i] = -9999;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MakeSkyVec (float s, float t, int axis)
|
||||
{
|
||||
vec3_t v, b;
|
||||
int j, k;
|
||||
|
||||
b[0] = s*2300;
|
||||
b[1] = t*2300;
|
||||
b[2] = 2300;
|
||||
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
k = st_to_vec[axis][j];
|
||||
if (k < 0)
|
||||
v[j] = -b[-k - 1];
|
||||
else
|
||||
v[j] = b[k - 1];
|
||||
v[j] += r_origin[j];
|
||||
}
|
||||
|
||||
// avoid bilerp seam
|
||||
s = (s+1)*0.5;
|
||||
t = (t+1)*0.5;
|
||||
|
||||
if (s < 1.0/512)
|
||||
s = 1.0/512;
|
||||
else if (s > 511.0/512)
|
||||
s = 511.0/512;
|
||||
if (t < 1.0/512)
|
||||
t = 1.0/512;
|
||||
else if (t > 511.0/512)
|
||||
t = 511.0/512;
|
||||
|
||||
t = 1.0 - t;
|
||||
glTexCoord2f (s, t);
|
||||
glVertex3fv (v);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
R_DrawSkyBox
|
||||
==============
|
||||
*/
|
||||
int skytexorder[6] = {0,2,1,3,4,5};
|
||||
void R_DrawSkyBox (msurface_t *s)
|
||||
{
|
||||
msurface_t *fa;
|
||||
glpoly_t *poly;
|
||||
int i;
|
||||
|
||||
if (!usingskybox)
|
||||
return;
|
||||
|
||||
#if 0
|
||||
glEnable (GL_BLEND);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glColor4f (1,1,1,0.5);
|
||||
glDisable (GL_DEPTH_TEST);
|
||||
#endif
|
||||
for (i=0 ; i<6 ; i++)
|
||||
{
|
||||
if (skymins[0][i] >= skymaxs[0][i]
|
||||
|| skymins[1][i] >= skymaxs[1][i])
|
||||
continue;
|
||||
|
||||
GL_Bind (skyboxtex[skytexorder[i]]);
|
||||
#if 0
|
||||
skymins[0][i] = -1;
|
||||
skymins[1][i] = -1;
|
||||
skymaxs[0][i] = 1;
|
||||
skymaxs[1][i] = 1;
|
||||
#endif
|
||||
glBegin (GL_QUADS);
|
||||
MakeSkyVec (skymins[0][i], skymins[1][i], i);
|
||||
MakeSkyVec (skymins[0][i], skymaxs[1][i], i);
|
||||
MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i);
|
||||
MakeSkyVec (skymaxs[0][i], skymins[1][i], i);
|
||||
glEnd ();
|
||||
}
|
||||
#if 0
|
||||
glDisable (GL_BLEND);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
glColor4f (1,1,1,0.5);
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
#endif
|
||||
|
||||
if (!cls.allow_skyboxes && s) //allow a little extra fps.
|
||||
{
|
||||
glColorMask(0, 0, 0, 0); //depth only.
|
||||
for (fa = s; fa; fa = fa->texturechain)
|
||||
{
|
||||
for (poly = fa->polys; poly; poly = poly->next)
|
||||
{
|
||||
glBegin (GL_POLYGON);
|
||||
for (i = 0; i < poly->numverts; i++)
|
||||
glVertex3fv (&poly->verts[0][0]+i*VERTEXSIZE);
|
||||
glEnd ();
|
||||
}
|
||||
}
|
||||
glColorMask(1, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===============================================================
|
||||
|
||||
/*
|
||||
=============
|
||||
R_InitSky
|
||||
|
||||
A sky texture is 256*128, with the right side being a masked overlay
|
||||
==============
|
||||
*/
|
||||
void GLR_InitSky (texture_t *mt)
|
||||
{
|
||||
int i, j, p;
|
||||
qbyte *src;
|
||||
unsigned trans[128*128];
|
||||
unsigned transpix;
|
||||
int r, g, b;
|
||||
unsigned *rgba;
|
||||
char name[MAX_QPATH];
|
||||
|
||||
src = (qbyte *)mt + mt->offsets[0];
|
||||
|
||||
// make an average value for the back to avoid
|
||||
// a fringe on the top level
|
||||
|
||||
r = g = b = 0;
|
||||
for (i=0 ; i<128 ; i++)
|
||||
for (j=0 ; j<128 ; j++)
|
||||
{
|
||||
p = src[i*256 + j + 128];
|
||||
rgba = &d_8to24rgbtable[p];
|
||||
trans[(i*128) + j] = *rgba;
|
||||
r += ((qbyte *)rgba)[0];
|
||||
g += ((qbyte *)rgba)[1];
|
||||
b += ((qbyte *)rgba)[2];
|
||||
}
|
||||
|
||||
((qbyte *)&transpix)[0] = r/(128*128);
|
||||
((qbyte *)&transpix)[1] = g/(128*128);
|
||||
((qbyte *)&transpix)[2] = b/(128*128);
|
||||
((qbyte *)&transpix)[3] = 0;
|
||||
|
||||
sprintf(name, "%s_solid", mt->name);
|
||||
strlwr(name);
|
||||
solidskytexture = Mod_LoadReplacementTexture(name, true, false);
|
||||
if (!solidskytexture)
|
||||
solidskytexture = GL_LoadTexture32(name, 128, 128, trans, true, false);
|
||||
/*
|
||||
if (!solidskytexture)
|
||||
solidskytexture = texture_extension_number++;
|
||||
|
||||
GL_Bind (solidskytexture );
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
*/
|
||||
|
||||
for (i=0 ; i<128 ; i++)
|
||||
for (j=0 ; j<128 ; j++)
|
||||
{
|
||||
p = src[i*256 + j];
|
||||
if (p == 0)
|
||||
trans[(i*128) + j] = transpix;
|
||||
else
|
||||
trans[(i*128) + j] = d_8to24rgbtable[p];
|
||||
}
|
||||
|
||||
sprintf(name, "%s_trans", mt->name);
|
||||
strlwr(name);
|
||||
alphaskytexture = Mod_LoadReplacementTexture(name, true, true);
|
||||
if (!alphaskytexture)
|
||||
alphaskytexture = GL_LoadTexture32(name, 128, 128, trans, true, true);
|
||||
/*
|
||||
if (!alphaskytexture)
|
||||
alphaskytexture = texture_extension_number++;
|
||||
GL_Bind(alphaskytexture);
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
*/
|
||||
}
|
51
engine/gl/gl_warp_sin.h
Normal file
51
engine/gl/gl_warp_sin.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
0, 0.19633, 0.392541, 0.588517, 0.784137, 0.979285, 1.17384, 1.3677,
|
||||
1.56072, 1.75281, 1.94384, 2.1337, 2.32228, 2.50945, 2.69512, 2.87916,
|
||||
3.06147, 3.24193, 3.42044, 3.59689, 3.77117, 3.94319, 4.11282, 4.27998,
|
||||
4.44456, 4.60647, 4.76559, 4.92185, 5.07515, 5.22538, 5.37247, 5.51632,
|
||||
5.65685, 5.79398, 5.92761, 6.05767, 6.18408, 6.30677, 6.42566, 6.54068,
|
||||
6.65176, 6.75883, 6.86183, 6.9607, 7.05537, 7.14579, 7.23191, 7.31368,
|
||||
7.39104, 7.46394, 7.53235, 7.59623, 7.65552, 7.71021, 7.76025, 7.80562,
|
||||
7.84628, 7.88222, 7.91341, 7.93984, 7.96148, 7.97832, 7.99036, 7.99759,
|
||||
8, 7.99759, 7.99036, 7.97832, 7.96148, 7.93984, 7.91341, 7.88222,
|
||||
7.84628, 7.80562, 7.76025, 7.71021, 7.65552, 7.59623, 7.53235, 7.46394,
|
||||
7.39104, 7.31368, 7.23191, 7.14579, 7.05537, 6.9607, 6.86183, 6.75883,
|
||||
6.65176, 6.54068, 6.42566, 6.30677, 6.18408, 6.05767, 5.92761, 5.79398,
|
||||
5.65685, 5.51632, 5.37247, 5.22538, 5.07515, 4.92185, 4.76559, 4.60647,
|
||||
4.44456, 4.27998, 4.11282, 3.94319, 3.77117, 3.59689, 3.42044, 3.24193,
|
||||
3.06147, 2.87916, 2.69512, 2.50945, 2.32228, 2.1337, 1.94384, 1.75281,
|
||||
1.56072, 1.3677, 1.17384, 0.979285, 0.784137, 0.588517, 0.392541, 0.19633,
|
||||
9.79717e-16, -0.19633, -0.392541, -0.588517, -0.784137, -0.979285, -1.17384, -1.3677,
|
||||
-1.56072, -1.75281, -1.94384, -2.1337, -2.32228, -2.50945, -2.69512, -2.87916,
|
||||
-3.06147, -3.24193, -3.42044, -3.59689, -3.77117, -3.94319, -4.11282, -4.27998,
|
||||
-4.44456, -4.60647, -4.76559, -4.92185, -5.07515, -5.22538, -5.37247, -5.51632,
|
||||
-5.65685, -5.79398, -5.92761, -6.05767, -6.18408, -6.30677, -6.42566, -6.54068,
|
||||
-6.65176, -6.75883, -6.86183, -6.9607, -7.05537, -7.14579, -7.23191, -7.31368,
|
||||
-7.39104, -7.46394, -7.53235, -7.59623, -7.65552, -7.71021, -7.76025, -7.80562,
|
||||
-7.84628, -7.88222, -7.91341, -7.93984, -7.96148, -7.97832, -7.99036, -7.99759,
|
||||
-8, -7.99759, -7.99036, -7.97832, -7.96148, -7.93984, -7.91341, -7.88222,
|
||||
-7.84628, -7.80562, -7.76025, -7.71021, -7.65552, -7.59623, -7.53235, -7.46394,
|
||||
-7.39104, -7.31368, -7.23191, -7.14579, -7.05537, -6.9607, -6.86183, -6.75883,
|
||||
-6.65176, -6.54068, -6.42566, -6.30677, -6.18408, -6.05767, -5.92761, -5.79398,
|
||||
-5.65685, -5.51632, -5.37247, -5.22538, -5.07515, -4.92185, -4.76559, -4.60647,
|
||||
-4.44456, -4.27998, -4.11282, -3.94319, -3.77117, -3.59689, -3.42044, -3.24193,
|
||||
-3.06147, -2.87916, -2.69512, -2.50945, -2.32228, -2.1337, -1.94384, -1.75281,
|
||||
-1.56072, -1.3677, -1.17384, -0.979285, -0.784137, -0.588517, -0.392541, -0.19633,
|
1993
engine/gl/glmod_doom.c
Normal file
1993
engine/gl/glmod_doom.c
Normal file
File diff suppressed because it is too large
Load diff
813
engine/gl/glquake.h
Normal file
813
engine/gl/glquake.h
Normal file
|
@ -0,0 +1,813 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// disable data conversion warnings
|
||||
#ifdef MSVCDISABLEWARNINGS
|
||||
#pragma warning(disable : 4244) // MIPS
|
||||
#pragma warning(disable : 4136) // X86
|
||||
#pragma warning(disable : 4051) // ALPHA
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#ifndef APIENTRY
|
||||
#define APIENTRY
|
||||
#endif
|
||||
|
||||
typedef qbyte pal77[128][128];
|
||||
pal77 *pal777to8;
|
||||
|
||||
void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs);
|
||||
qboolean BoundsIntersect (vec3_t mins1, vec3_t maxs1, vec3_t mins2, vec3_t maxs2);
|
||||
void ClearBounds (vec3_t mins, vec3_t maxs);
|
||||
|
||||
#ifdef RGLQUAKE
|
||||
#include <GL/gl.h>
|
||||
//#include <GL/glu.h>
|
||||
#include "glsupp.h"
|
||||
|
||||
|
||||
|
||||
void GL_BeginRendering (int *x, int *y, int *width, int *height);
|
||||
void GL_EndRendering (void);
|
||||
|
||||
void R_EmitSkyEffectTris(model_t *mod, msurface_t *fa);
|
||||
void GLR_BrightenScreen (void);
|
||||
void GLR_NetGraph (void);
|
||||
void GLR_DrawAlphaSurfaces (void);
|
||||
void GL_FlushSkinCache(void);
|
||||
void GL_GAliasFlushSkinCache(void);
|
||||
|
||||
|
||||
// Function prototypes for the Texture Object Extension routines
|
||||
typedef GLboolean (APIENTRY *ARETEXRESFUNCPTR)(GLsizei, const GLuint *,
|
||||
const GLboolean *);
|
||||
typedef void (APIENTRY *BINDTEXFUNCPTR)(GLenum, GLuint);
|
||||
typedef void (APIENTRY *DELTEXFUNCPTR)(GLsizei, const GLuint *);
|
||||
typedef void (APIENTRY *GENTEXFUNCPTR)(GLsizei, GLuint *);
|
||||
typedef GLboolean (APIENTRY *ISTEXFUNCPTR)(GLuint);
|
||||
typedef void (APIENTRY *PRIORTEXFUNCPTR)(GLsizei, const GLuint *,
|
||||
const GLclampf *);
|
||||
typedef void (APIENTRY *TEXSUBIMAGEPTR)(int, int, int, int, int, int, int, int, void *);
|
||||
|
||||
extern BINDTEXFUNCPTR bindTexFunc;
|
||||
extern DELTEXFUNCPTR delTexFunc;
|
||||
extern TEXSUBIMAGEPTR TexSubImage2DFunc;
|
||||
extern void (APIENTRY *qglStencilOpSeparateATI) (GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
|
||||
extern PFNGLCOMPRESSEDTEXIMAGE2DARBPROC qglCompressedTexImage2DARB;
|
||||
extern PFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImageARB;
|
||||
extern PFNGLPNTRIANGLESIATIPROC qglPNTrianglesiATI;
|
||||
extern PFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI;
|
||||
|
||||
extern int texture_extension_number;
|
||||
extern int texture_mode;
|
||||
|
||||
extern float gldepthmin, gldepthmax;
|
||||
|
||||
void GL_Upload32 (char *name, unsigned *data, int width, int height, qboolean mipmap, qboolean alpha); //name was added for texture compression output
|
||||
void GL_Upload8 (qbyte *data, int width, int height, qboolean mipmap, qboolean alpha);
|
||||
#ifdef GL_EXT_paletted_texture
|
||||
void GL_Upload8_EXT (qbyte *data, int width, int height, qboolean mipmap, qboolean alpha);
|
||||
#endif
|
||||
int GL_LoadTexture (char *identifier, int width, int height, qbyte *data, qboolean mipmap, qboolean alpha);
|
||||
int GL_LoadTexture8Bump (char *identifier, int width, int height, unsigned char *data, qboolean mipmap);
|
||||
int GL_LoadTexture8Pal24 (char *identifier, int width, int height, qbyte *data, qbyte *palette24, qboolean mipmap, qboolean alpha);
|
||||
int GL_LoadTexture32 (char *identifier, int width, int height, unsigned *data, qboolean mipmap, qboolean alpha);
|
||||
int GL_LoadCompressed(char *name);
|
||||
int GL_FindTexture (char *identifier);
|
||||
|
||||
int GL_LoadTextureFB (char *identifier, int width, int height, qbyte *data, qboolean mipmap, qboolean alpha);
|
||||
void GL_Upload8Pal24 (qbyte *data, qbyte *pal, int width, int height, qboolean mipmap, qboolean alpha);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x, y, z;
|
||||
float s, t;
|
||||
float r, g, b;
|
||||
} glvert_t;
|
||||
|
||||
extern glvert_t glv;
|
||||
|
||||
extern int glx, gly, glwidth, glheight;
|
||||
|
||||
#endif
|
||||
|
||||
// r_local.h -- private refresh defs
|
||||
|
||||
#define ALIAS_BASE_SIZE_RATIO (1.0 / 11.0)
|
||||
// normalizing factor so player model works out to about
|
||||
// 1 pixel per triangle
|
||||
#define MAX_LBM_HEIGHT 480
|
||||
|
||||
#define TILE_SIZE 128 // size of textures generated by R_GenTiledSurf
|
||||
|
||||
#define SKYSHIFT 7
|
||||
#define SKYSIZE (1 << SKYSHIFT)
|
||||
#define SKYMASK (SKYSIZE - 1)
|
||||
|
||||
#define BACKFACE_EPSILON 0.01
|
||||
|
||||
|
||||
void R_TimeRefresh_f (void);
|
||||
void R_ReadPointFile_f (void);
|
||||
texture_t *SWR_TextureAnimation (texture_t *base);
|
||||
texture_t *GLR_TextureAnimation (texture_t *base);
|
||||
|
||||
#include "particles.h"
|
||||
|
||||
//====================================================
|
||||
|
||||
|
||||
extern entity_t r_worldentity;
|
||||
extern qboolean r_cache_thrash; // compatability
|
||||
extern vec3_t modelorg, r_entorigin;
|
||||
extern entity_t *currententity;
|
||||
extern int r_visframecount; // ??? what difs?
|
||||
extern int r_framecount;
|
||||
extern mplane_t frustum[4];
|
||||
extern int c_brush_polys, c_alias_polys;
|
||||
|
||||
extern float r_wateralphaval;
|
||||
|
||||
//
|
||||
// view origin
|
||||
//
|
||||
extern vec3_t vup;
|
||||
extern vec3_t vpn;
|
||||
extern vec3_t vright;
|
||||
extern vec3_t r_origin;
|
||||
|
||||
//
|
||||
// screen size info
|
||||
//
|
||||
extern refdef_t r_refdef;
|
||||
extern mleaf_t *r_viewleaf, *r_oldviewleaf;
|
||||
extern mleaf_t *r_viewleaf2, *r_oldviewleaf2;
|
||||
extern int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2; //q2
|
||||
extern texture_t *r_notexture_mip;
|
||||
extern int d_lightstylevalue[256]; // 8.8 fraction of base light value
|
||||
|
||||
extern qboolean envmap;
|
||||
extern int currenttexture;
|
||||
extern int particletexture;
|
||||
extern int explosiontexture;
|
||||
extern int netgraphtexture; // netgraph texture
|
||||
extern int playertextures;
|
||||
|
||||
extern int skytexturenum; // index in cl.loadmodel, not gl texture object
|
||||
|
||||
extern int gl_lightmap_format;
|
||||
extern int gl_solid_format;
|
||||
extern int gl_alpha_format;
|
||||
|
||||
extern int mirrortexturenum; // quake texturenum, not gltexturenum
|
||||
extern qboolean mirror;
|
||||
extern mplane_t *mirror_plane;
|
||||
|
||||
extern float r_world_matrix[16];
|
||||
|
||||
extern const char *gl_vendor;
|
||||
extern const char *gl_renderer;
|
||||
extern const char *gl_version;
|
||||
extern const char *gl_extensions;
|
||||
|
||||
void R_TranslatePlayerSkin (int playernum);
|
||||
void GL_Bind (int texnum);
|
||||
void GL_BindType (int type, int texnum);
|
||||
|
||||
#if defined(RGLQUAKE)
|
||||
// Multitexture
|
||||
#define GL_TEXTURE0_SGIS 0x835E
|
||||
#define GL_TEXTURE1_SGIS 0x835F
|
||||
|
||||
typedef void (APIENTRY *lpMTexFUNC) (GLenum en, GLfloat f1, GLfloat f2);
|
||||
typedef void (APIENTRY *lpSelTexFUNC) (GLenum en);
|
||||
extern lpMTexFUNC qglMTexCoord2fSGIS;
|
||||
extern lpSelTexFUNC qglSelectTextureSGIS;
|
||||
|
||||
extern int gl_canstencil;
|
||||
extern PFNGLACTIVESTENCILFACEEXTPROC qglActiveStencilFaceEXT;
|
||||
|
||||
extern lpMTexFUNC qglMTexCoord2fSGIS;
|
||||
extern lpSelTexFUNC qglSelectTextureSGIS;
|
||||
|
||||
|
||||
extern qboolean gl_ext_stencil_wrap;
|
||||
extern int gl_mtexarbable; //max texture units
|
||||
extern qboolean gl_mtexable;
|
||||
extern qboolean gl_compressable;
|
||||
|
||||
extern int mtexid0;
|
||||
extern int mtexid1;
|
||||
|
||||
extern qboolean gl_mtexable;
|
||||
|
||||
void GL_DisableMultitexture(void);
|
||||
void GL_EnableMultitexture(void);
|
||||
|
||||
//
|
||||
// gl_warp.c
|
||||
//
|
||||
void GL_SubdivideSurface (msurface_t *fa, float dividesize);
|
||||
void EmitBothSkyLayers (msurface_t *fa);
|
||||
void EmitWaterPolys (msurface_t *fa);
|
||||
void EmitSkyPolys (msurface_t *fa);
|
||||
void R_DrawSkyChain (msurface_t *s);
|
||||
|
||||
void R_ClearSkyBox (void);
|
||||
void R_AddSkySurface (msurface_t *fa);
|
||||
|
||||
//
|
||||
// gl_draw.c
|
||||
//
|
||||
int GL_LoadPicTexture (qpic_t *pic);
|
||||
void GL_Set2D (void);
|
||||
|
||||
//
|
||||
// gl_rmain.c
|
||||
//
|
||||
qboolean R_CullBox (vec3_t mins, vec3_t maxs);
|
||||
void R_RotateForEntity (entity_t *e);
|
||||
void R_DrawAliasModel (entity_t *e);
|
||||
|
||||
//gl_alias.c
|
||||
void R_DrawGAliasModel (entity_t *e);
|
||||
void R_DrawGAliasShadowVolume(entity_t *e, vec3_t lightpos, float radius);
|
||||
void R_DrawGAliasModelLighting (entity_t *e);
|
||||
|
||||
//misc model formats
|
||||
void R_DrawAlias3Model (entity_t *ent);
|
||||
void R_DrawHLModel(entity_t *curent);
|
||||
void R_DrawGroupModel (entity_t *ent);
|
||||
|
||||
//typedef float m3by3_t[3][3];
|
||||
//int GetTag(model_t *mod, char *tagname, int frame, float **org, m3by3_t **ang);
|
||||
|
||||
//
|
||||
// gl_rlight.c
|
||||
//
|
||||
void GLR_MarkLights (dlight_t *light, int bit, mnode_t *node);
|
||||
void GLR_MarkQ2Lights (dlight_t *light, int bit, mnode_t *node);
|
||||
void GLR_AnimateLight (void);
|
||||
void R_RenderDlights (void);
|
||||
int GLR_LightPoint (vec3_t p);
|
||||
|
||||
void GLQ3_LightGrid(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_lightdir);
|
||||
|
||||
//
|
||||
// gl_rsurf.c
|
||||
//
|
||||
void R_DrawBrushModel (entity_t *e);
|
||||
void R_DrawWorld (void);
|
||||
void GL_BuildLightmaps (void);
|
||||
|
||||
void GL_LoadShaders(void);
|
||||
int Mod_LoadReplacementTexture(char *name, qboolean mipmap, qboolean alpha);
|
||||
int Mod_LoadHiResTexture(char *name, qboolean mipmap, qboolean alpha);
|
||||
int Mod_LoadBumpmapTexture(char *name);
|
||||
|
||||
#define LMBLOCK_WIDTH 128
|
||||
#define LMBLOCK_HEIGHT 128
|
||||
typedef struct glRect_s {
|
||||
unsigned char l,t,w,h;
|
||||
} glRect_t;
|
||||
typedef char stmap;
|
||||
typedef struct {
|
||||
glpoly_t *polys;
|
||||
qboolean modified;
|
||||
qboolean deluxmodified;
|
||||
glRect_t rectchange;
|
||||
glRect_t deluxrectchange;
|
||||
int allocated[LMBLOCK_WIDTH];
|
||||
qbyte lightmaps[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT];
|
||||
qbyte deluxmaps[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //fixme: make seperate structure for easy disabling with less memory usage.
|
||||
stmap stainmaps[3*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //rgb no a. added to lightmap for added (hopefully) speed.
|
||||
} lightmapinfo_t;
|
||||
|
||||
//gl_ppl.c
|
||||
void PPL_DrawWorld (void);
|
||||
void RotateLightVector(vec3_t angles, vec3_t origin, vec3_t lightpoint, vec3_t result);
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// gl_refrag.c
|
||||
//
|
||||
void R_StoreEfrags (efrag_t **ppefrag);
|
||||
|
||||
|
||||
//
|
||||
// gl_ngraph.c
|
||||
//
|
||||
void R_NetGraph (void);
|
||||
|
||||
|
||||
#if defined(RGLQUAKE)
|
||||
|
||||
extern void (APIENTRY *qglAccum) (GLenum op, GLfloat value);
|
||||
extern void (APIENTRY *qglAlphaFunc) (GLenum func, GLclampf ref);
|
||||
extern GLboolean (APIENTRY *qglAreTexturesResident) (GLsizei n, const GLuint *textures, GLboolean *residences);
|
||||
extern void (APIENTRY *qglArrayElement) (GLint i);
|
||||
extern void (APIENTRY *qglBegin) (GLenum mode);
|
||||
extern void (APIENTRY *qglBindTexture) (GLenum target, GLuint texture);
|
||||
extern void (APIENTRY *qglBitmap) (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap);
|
||||
extern void (APIENTRY *qglBlendFunc) (GLenum sfactor, GLenum dfactor);
|
||||
extern void (APIENTRY *qglCallList) (GLuint list);
|
||||
extern void (APIENTRY *qglCallLists) (GLsizei n, GLenum type, const GLvoid *lists);
|
||||
extern void (APIENTRY *qglClear) (GLbitfield mask);
|
||||
extern void (APIENTRY *qglClearAccum) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
extern void (APIENTRY *qglClearColor) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
|
||||
extern void (APIENTRY *qglClearDepth) (GLclampd depth);
|
||||
extern void (APIENTRY *qglClearIndex) (GLfloat c);
|
||||
extern void (APIENTRY *qglClearStencil) (GLint s);
|
||||
extern void (APIENTRY *qglClipPlane) (GLenum plane, const GLdouble *equation);
|
||||
extern void (APIENTRY *qglColor3b) (GLbyte red, GLbyte green, GLbyte blue);
|
||||
extern void (APIENTRY *qglColor3bv) (const GLbyte *v);
|
||||
extern void (APIENTRY *qglColor3d) (GLdouble red, GLdouble green, GLdouble blue);
|
||||
extern void (APIENTRY *qglColor3dv) (const GLdouble *v);
|
||||
extern void (APIENTRY *qglColor3f) (GLfloat red, GLfloat green, GLfloat blue);
|
||||
extern void (APIENTRY *qglColor3fv) (const GLfloat *v);
|
||||
extern void (APIENTRY *qglColor3i) (GLint red, GLint green, GLint blue);
|
||||
extern void (APIENTRY *qglColor3iv) (const GLint *v);
|
||||
extern void (APIENTRY *qglColor3s) (GLshort red, GLshort green, GLshort blue);
|
||||
extern void (APIENTRY *qglColor3sv) (const GLshort *v);
|
||||
extern void (APIENTRY *qglColor3ub) (GLubyte red, GLubyte green, GLubyte blue);
|
||||
extern void (APIENTRY *qglColor3ubv) (const GLubyte *v);
|
||||
extern void (APIENTRY *qglColor3ui) (GLuint red, GLuint green, GLuint blue);
|
||||
extern void (APIENTRY *qglColor3uiv) (const GLuint *v);
|
||||
extern void (APIENTRY *qglColor3us) (GLushort red, GLushort green, GLushort blue);
|
||||
extern void (APIENTRY *qglColor3usv) (const GLushort *v);
|
||||
extern void (APIENTRY *qglColor4b) (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha);
|
||||
extern void (APIENTRY *qglColor4bv) (const GLbyte *v);
|
||||
extern void (APIENTRY *qglColor4d) (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha);
|
||||
extern void (APIENTRY *qglColor4dv) (const GLdouble *v);
|
||||
extern void (APIENTRY *qglColor4f) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
extern void (APIENTRY *qglColor4fv) (const GLfloat *v);
|
||||
extern void (APIENTRY *qglColor4i) (GLint red, GLint green, GLint blue, GLint alpha);
|
||||
extern void (APIENTRY *qglColor4iv) (const GLint *v);
|
||||
extern void (APIENTRY *qglColor4s) (GLshort red, GLshort green, GLshort blue, GLshort alpha);
|
||||
extern void (APIENTRY *qglColor4sv) (const GLshort *v);
|
||||
extern void (APIENTRY *qglColor4ub) (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
|
||||
extern void (APIENTRY *qglColor4ubv) (const GLubyte *v);
|
||||
extern void (APIENTRY *qglColor4ui) (GLuint red, GLuint green, GLuint blue, GLuint alpha);
|
||||
extern void (APIENTRY *qglColor4uiv) (const GLuint *v);
|
||||
extern void (APIENTRY *qglColor4us) (GLushort red, GLushort green, GLushort blue, GLushort alpha);
|
||||
extern void (APIENTRY *qglColor4usv) (const GLushort *v);
|
||||
extern void (APIENTRY *qglColorMask) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
|
||||
extern void (APIENTRY *qglColorMaterial) (GLenum face, GLenum mode);
|
||||
extern void (APIENTRY *qglColorPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
extern void (APIENTRY *qglCopyPixels) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type);
|
||||
extern void (APIENTRY *qglCopyTexImage1D) (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border);
|
||||
extern void (APIENTRY *qglCopyTexImage2D) (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
|
||||
extern void (APIENTRY *qglCopyTexSubImage1D) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
|
||||
extern void (APIENTRY *qglCopyTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
extern void (APIENTRY *qglCullFace) (GLenum mode);
|
||||
extern void (APIENTRY *qglDeleteLists) (GLuint list, GLsizei range);
|
||||
extern void (APIENTRY *qglDeleteTextures) (GLsizei n, const GLuint *textures);
|
||||
extern void (APIENTRY *qglDepthFunc) (GLenum func);
|
||||
extern void (APIENTRY *qglDepthMask) (GLboolean flag);
|
||||
extern void (APIENTRY *qglDepthRange) (GLclampd zNear, GLclampd zFar);
|
||||
extern void (APIENTRY *qglDisable) (GLenum cap);
|
||||
extern void (APIENTRY *qglDisableClientState) (GLenum array);
|
||||
extern void (APIENTRY *qglDrawArrays) (GLenum mode, GLint first, GLsizei count);
|
||||
extern void (APIENTRY *qglDrawBuffer) (GLenum mode);
|
||||
extern void (APIENTRY *qglDrawElements) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
|
||||
extern void (APIENTRY *qglDrawPixels) (GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
extern void (APIENTRY *qglEdgeFlag) (GLboolean flag);
|
||||
extern void (APIENTRY *qglEdgeFlagPointer) (GLsizei stride, const GLvoid *pointer);
|
||||
extern void (APIENTRY *qglEdgeFlagv) (const GLboolean *flag);
|
||||
extern void (APIENTRY *qglEnable) (GLenum cap);
|
||||
extern void (APIENTRY *qglEnableClientState) (GLenum array);
|
||||
extern void (APIENTRY *qglEnd) (void);
|
||||
extern void (APIENTRY *qglEndList) (void);
|
||||
extern void (APIENTRY *qglEvalCoord1d) (GLdouble u);
|
||||
extern void (APIENTRY *qglEvalCoord1dv) (const GLdouble *u);
|
||||
extern void (APIENTRY *qglEvalCoord1f) (GLfloat u);
|
||||
extern void (APIENTRY *qglEvalCoord1fv) (const GLfloat *u);
|
||||
extern void (APIENTRY *qglEvalCoord2d) (GLdouble u, GLdouble v);
|
||||
extern void (APIENTRY *qglEvalCoord2dv) (const GLdouble *u);
|
||||
extern void (APIENTRY *qglEvalCoord2f) (GLfloat u, GLfloat v);
|
||||
extern void (APIENTRY *qglEvalCoord2fv) (const GLfloat *u);
|
||||
extern void (APIENTRY *qglEvalMesh1) (GLenum mode, GLint i1, GLint i2);
|
||||
extern void (APIENTRY *qglEvalMesh2) (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2);
|
||||
extern void (APIENTRY *qglEvalPoint1) (GLint i);
|
||||
extern void (APIENTRY *qglEvalPoint2) (GLint i, GLint j);
|
||||
extern void (APIENTRY *qglFeedbackBuffer) (GLsizei size, GLenum type, GLfloat *buffer);
|
||||
extern void (APIENTRY *qglFinish) (void);
|
||||
extern void (APIENTRY *qglFlush) (void);
|
||||
extern void (APIENTRY *qglFogf) (GLenum pname, GLfloat param);
|
||||
extern void (APIENTRY *qglFogfv) (GLenum pname, const GLfloat *params);
|
||||
extern void (APIENTRY *qglFogi) (GLenum pname, GLint param);
|
||||
extern void (APIENTRY *qglFogiv) (GLenum pname, const GLint *params);
|
||||
extern void (APIENTRY *qglFrontFace) (GLenum mode);
|
||||
extern void (APIENTRY *qglFrustum) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
|
||||
extern GLuint (APIENTRY *qglGenLists) (GLsizei range);
|
||||
extern void (APIENTRY *qglGenTextures) (GLsizei n, GLuint *textures);
|
||||
extern void (APIENTRY *qglGetBooleanv) (GLenum pname, GLboolean *params);
|
||||
extern void (APIENTRY *qglGetClipPlane) (GLenum plane, GLdouble *equation);
|
||||
extern void (APIENTRY *qglGetDoublev) (GLenum pname, GLdouble *params);
|
||||
extern GLenum (APIENTRY *qglGetError) (void);
|
||||
extern void (APIENTRY *qglGetFloatv) (GLenum pname, GLfloat *params);
|
||||
extern void (APIENTRY *qglGetIntegerv) (GLenum pname, GLint *params);
|
||||
extern void (APIENTRY *qglGetLightfv) (GLenum light, GLenum pname, GLfloat *params);
|
||||
extern void (APIENTRY *qglGetLightiv) (GLenum light, GLenum pname, GLint *params);
|
||||
extern void (APIENTRY *qglGetMapdv) (GLenum target, GLenum query, GLdouble *v);
|
||||
extern void (APIENTRY *qglGetMapfv) (GLenum target, GLenum query, GLfloat *v);
|
||||
extern void (APIENTRY *qglGetMapiv) (GLenum target, GLenum query, GLint *v);
|
||||
extern void (APIENTRY *qglGetMaterialfv) (GLenum face, GLenum pname, GLfloat *params);
|
||||
extern void (APIENTRY *qglGetMaterialiv) (GLenum face, GLenum pname, GLint *params);
|
||||
extern void (APIENTRY *qglGetPixelMapfv) (GLenum map, GLfloat *values);
|
||||
extern void (APIENTRY *qglGetPixelMapuiv) (GLenum map, GLuint *values);
|
||||
extern void (APIENTRY *qglGetPixelMapusv) (GLenum map, GLushort *values);
|
||||
extern void (APIENTRY *qglGetPointerv) (GLenum pname, GLvoid* *params);
|
||||
extern void (APIENTRY *qglGetPolygonStipple) (GLubyte *mask);
|
||||
extern const GLubyte * (APIENTRY *qglGetString) (GLenum name);
|
||||
extern void (APIENTRY *qglGetTexEnvfv) (GLenum target, GLenum pname, GLfloat *params);
|
||||
extern void (APIENTRY *qglGetTexEnviv) (GLenum target, GLenum pname, GLint *params);
|
||||
extern void (APIENTRY *qglGetTexGendv) (GLenum coord, GLenum pname, GLdouble *params);
|
||||
extern void (APIENTRY *qglGetTexGenfv) (GLenum coord, GLenum pname, GLfloat *params);
|
||||
extern void (APIENTRY *qglGetTexGeniv) (GLenum coord, GLenum pname, GLint *params);
|
||||
extern void (APIENTRY *qglGetTexImage) (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
|
||||
extern void (APIENTRY *qglGetTexLevelParameterfv) (GLenum target, GLint level, GLenum pname, GLfloat *params);
|
||||
extern void (APIENTRY *qglGetTexLevelParameteriv) (GLenum target, GLint level, GLenum pname, GLint *params);
|
||||
extern void (APIENTRY *qglGetTexParameterfv) (GLenum target, GLenum pname, GLfloat *params);
|
||||
extern void (APIENTRY *qglGetTexParameteriv) (GLenum target, GLenum pname, GLint *params);
|
||||
extern void (APIENTRY *qglHint) (GLenum target, GLenum mode);
|
||||
extern void (APIENTRY *qglIndexMask) (GLuint mask);
|
||||
extern void (APIENTRY *qglIndexPointer) (GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
extern void (APIENTRY *qglIndexd) (GLdouble c);
|
||||
extern void (APIENTRY *qglIndexdv) (const GLdouble *c);
|
||||
extern void (APIENTRY *qglIndexf) (GLfloat c);
|
||||
extern void (APIENTRY *qglIndexfv) (const GLfloat *c);
|
||||
extern void (APIENTRY *qglIndexi) (GLint c);
|
||||
extern void (APIENTRY *qglIndexiv) (const GLint *c);
|
||||
extern void (APIENTRY *qglIndexs) (GLshort c);
|
||||
extern void (APIENTRY *qglIndexsv) (const GLshort *c);
|
||||
extern void (APIENTRY *qglIndexub) (GLubyte c);
|
||||
extern void (APIENTRY *qglIndexubv) (const GLubyte *c);
|
||||
extern void (APIENTRY *qglInitNames) (void);
|
||||
extern void (APIENTRY *qglInterleavedArrays) (GLenum format, GLsizei stride, const GLvoid *pointer);
|
||||
extern GLboolean (APIENTRY *qglIsEnabled) (GLenum cap);
|
||||
extern GLboolean (APIENTRY *qglIsList) (GLuint list);
|
||||
extern GLboolean (APIENTRY *qglIsTexture) (GLuint texture);
|
||||
extern void (APIENTRY *qglLightModelf) (GLenum pname, GLfloat param);
|
||||
extern void (APIENTRY *qglLightModelfv) (GLenum pname, const GLfloat *params);
|
||||
extern void (APIENTRY *qglLightModeli) (GLenum pname, GLint param);
|
||||
extern void (APIENTRY *qglLightModeliv) (GLenum pname, const GLint *params);
|
||||
extern void (APIENTRY *qglLightf) (GLenum light, GLenum pname, GLfloat param);
|
||||
extern void (APIENTRY *qglLightfv) (GLenum light, GLenum pname, const GLfloat *params);
|
||||
extern void (APIENTRY *qglLighti) (GLenum light, GLenum pname, GLint param);
|
||||
extern void (APIENTRY *qglLightiv) (GLenum light, GLenum pname, const GLint *params);
|
||||
extern void (APIENTRY *qglLineStipple) (GLint factor, GLushort pattern);
|
||||
extern void (APIENTRY *qglLineWidth) (GLfloat width);
|
||||
extern void (APIENTRY *qglListBase) (GLuint base);
|
||||
extern void (APIENTRY *qglLoadIdentity) (void);
|
||||
extern void (APIENTRY *qglLoadMatrixd) (const GLdouble *m);
|
||||
extern void (APIENTRY *qglLoadMatrixf) (const GLfloat *m);
|
||||
extern void (APIENTRY *qglLoadName) (GLuint name);
|
||||
extern void (APIENTRY *qglLogicOp) (GLenum opcode);
|
||||
extern void (APIENTRY *qglMap1d) (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
|
||||
extern void (APIENTRY *qglMap1f) (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
|
||||
extern void (APIENTRY *qglMap2d) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
|
||||
extern void (APIENTRY *qglMap2f) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
|
||||
extern void (APIENTRY *qglMapGrid1d) (GLint un, GLdouble u1, GLdouble u2);
|
||||
extern void (APIENTRY *qglMapGrid1f) (GLint un, GLfloat u1, GLfloat u2);
|
||||
extern void (APIENTRY *qglMapGrid2d) (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2);
|
||||
extern void (APIENTRY *qglMapGrid2f) (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2);
|
||||
extern void (APIENTRY *qglMaterialf) (GLenum face, GLenum pname, GLfloat param);
|
||||
extern void (APIENTRY *qglMaterialfv) (GLenum face, GLenum pname, const GLfloat *params);
|
||||
extern void (APIENTRY *qglMateriali) (GLenum face, GLenum pname, GLint param);
|
||||
extern void (APIENTRY *qglMaterialiv) (GLenum face, GLenum pname, const GLint *params);
|
||||
extern void (APIENTRY *qglMatrixMode) (GLenum mode);
|
||||
extern void (APIENTRY *qglMultMatrixd) (const GLdouble *m);
|
||||
extern void (APIENTRY *qglMultMatrixf) (const GLfloat *m);
|
||||
extern void (APIENTRY *qglNewList) (GLuint list, GLenum mode);
|
||||
extern void (APIENTRY *qglNormal3b) (GLbyte nx, GLbyte ny, GLbyte nz);
|
||||
extern void (APIENTRY *qglNormal3bv) (const GLbyte *v);
|
||||
extern void (APIENTRY *qglNormal3d) (GLdouble nx, GLdouble ny, GLdouble nz);
|
||||
extern void (APIENTRY *qglNormal3dv) (const GLdouble *v);
|
||||
extern void (APIENTRY *qglNormal3f) (GLfloat nx, GLfloat ny, GLfloat nz);
|
||||
extern void (APIENTRY *qglNormal3fv) (const GLfloat *v);
|
||||
extern void (APIENTRY *qglNormal3i) (GLint nx, GLint ny, GLint nz);
|
||||
extern void (APIENTRY *qglNormal3iv) (const GLint *v);
|
||||
extern void (APIENTRY *qglNormal3s) (GLshort nx, GLshort ny, GLshort nz);
|
||||
extern void (APIENTRY *qglNormal3sv) (const GLshort *v);
|
||||
extern void (APIENTRY *qglNormalPointer) (GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
extern void (APIENTRY *qglOrtho) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
|
||||
extern void (APIENTRY *qglPassThrough) (GLfloat token);
|
||||
extern void (APIENTRY *qglPixelMapfv) (GLenum map, GLsizei mapsize, const GLfloat *values);
|
||||
extern void (APIENTRY *qglPixelMapuiv) (GLenum map, GLsizei mapsize, const GLuint *values);
|
||||
extern void (APIENTRY *qglPixelMapusv) (GLenum map, GLsizei mapsize, const GLushort *values);
|
||||
extern void (APIENTRY *qglPixelStoref) (GLenum pname, GLfloat param);
|
||||
extern void (APIENTRY *qglPixelStorei) (GLenum pname, GLint param);
|
||||
extern void (APIENTRY *qglPixelTransferf) (GLenum pname, GLfloat param);
|
||||
extern void (APIENTRY *qglPixelTransferi) (GLenum pname, GLint param);
|
||||
extern void (APIENTRY *qglPixelZoom) (GLfloat xfactor, GLfloat yfactor);
|
||||
extern void (APIENTRY *qglPointSize) (GLfloat size);
|
||||
extern void (APIENTRY *qglPolygonMode) (GLenum face, GLenum mode);
|
||||
extern void (APIENTRY *qglPolygonOffset) (GLfloat factor, GLfloat units);
|
||||
extern void (APIENTRY *qglPolygonStipple) (const GLubyte *mask);
|
||||
extern void (APIENTRY *qglPopAttrib) (void);
|
||||
extern void (APIENTRY *qglPopClientAttrib) (void);
|
||||
extern void (APIENTRY *qglPopMatrix) (void);
|
||||
extern void (APIENTRY *qglPopName) (void);
|
||||
extern void (APIENTRY *qglPrioritizeTextures) (GLsizei n, const GLuint *textures, const GLclampf *priorities);
|
||||
extern void (APIENTRY *qglPushAttrib) (GLbitfield mask);
|
||||
extern void (APIENTRY *qglPushClientAttrib) (GLbitfield mask);
|
||||
extern void (APIENTRY *qglPushMatrix) (void);
|
||||
extern void (APIENTRY *qglPushName) (GLuint name);
|
||||
extern void (APIENTRY *qglRasterPos2d) (GLdouble x, GLdouble y);
|
||||
extern void (APIENTRY *qglRasterPos2dv) (const GLdouble *v);
|
||||
extern void (APIENTRY *qglRasterPos2f) (GLfloat x, GLfloat y);
|
||||
extern void (APIENTRY *qglRasterPos2fv) (const GLfloat *v);
|
||||
extern void (APIENTRY *qglRasterPos2i) (GLint x, GLint y);
|
||||
extern void (APIENTRY *qglRasterPos2iv) (const GLint *v);
|
||||
extern void (APIENTRY *qglRasterPos2s) (GLshort x, GLshort y);
|
||||
extern void (APIENTRY *qglRasterPos2sv) (const GLshort *v);
|
||||
extern void (APIENTRY *qglRasterPos3d) (GLdouble x, GLdouble y, GLdouble z);
|
||||
extern void (APIENTRY *qglRasterPos3dv) (const GLdouble *v);
|
||||
extern void (APIENTRY *qglRasterPos3f) (GLfloat x, GLfloat y, GLfloat z);
|
||||
extern void (APIENTRY *qglRasterPos3fv) (const GLfloat *v);
|
||||
extern void (APIENTRY *qglRasterPos3i) (GLint x, GLint y, GLint z);
|
||||
extern void (APIENTRY *qglRasterPos3iv) (const GLint *v);
|
||||
extern void (APIENTRY *qglRasterPos3s) (GLshort x, GLshort y, GLshort z);
|
||||
extern void (APIENTRY *qglRasterPos3sv) (const GLshort *v);
|
||||
extern void (APIENTRY *qglRasterPos4d) (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
|
||||
extern void (APIENTRY *qglRasterPos4dv) (const GLdouble *v);
|
||||
extern void (APIENTRY *qglRasterPos4f) (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
extern void (APIENTRY *qglRasterPos4fv) (const GLfloat *v);
|
||||
extern void (APIENTRY *qglRasterPos4i) (GLint x, GLint y, GLint z, GLint w);
|
||||
extern void (APIENTRY *qglRasterPos4iv) (const GLint *v);
|
||||
extern void (APIENTRY *qglRasterPos4s) (GLshort x, GLshort y, GLshort z, GLshort w);
|
||||
extern void (APIENTRY *qglRasterPos4sv) (const GLshort *v);
|
||||
extern void (APIENTRY *qglReadBuffer) (GLenum mode);
|
||||
extern void (APIENTRY *qglReadPixels) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
|
||||
extern void (APIENTRY *qglRectd) (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2);
|
||||
extern void (APIENTRY *qglRectdv) (const GLdouble *v1, const GLdouble *v2);
|
||||
extern void (APIENTRY *qglRectf) (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
|
||||
extern void (APIENTRY *qglRectfv) (const GLfloat *v1, const GLfloat *v2);
|
||||
extern void (APIENTRY *qglRecti) (GLint x1, GLint y1, GLint x2, GLint y2);
|
||||
extern void (APIENTRY *qglRectiv) (const GLint *v1, const GLint *v2);
|
||||
extern void (APIENTRY *qglRects) (GLshort x1, GLshort y1, GLshort x2, GLshort y2);
|
||||
extern void (APIENTRY *qglRectsv) (const GLshort *v1, const GLshort *v2);
|
||||
extern GLint (APIENTRY *qglRenderMode) (GLenum mode);
|
||||
extern void (APIENTRY *qglRotated) (GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
|
||||
extern void (APIENTRY *qglRotatef) (GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
|
||||
extern void (APIENTRY *qglScaled) (GLdouble x, GLdouble y, GLdouble z);
|
||||
extern void (APIENTRY *qglScalef) (GLfloat x, GLfloat y, GLfloat z);
|
||||
extern void (APIENTRY *qglScissor) (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
extern void (APIENTRY *qglSelectBuffer) (GLsizei size, GLuint *buffer);
|
||||
extern void (APIENTRY *qglShadeModel) (GLenum mode);
|
||||
extern void (APIENTRY *qglStencilFunc) (GLenum func, GLint ref, GLuint mask);
|
||||
extern void (APIENTRY *qglStencilMask) (GLuint mask);
|
||||
extern void (APIENTRY *qglStencilOp) (GLenum fail, GLenum zfail, GLenum zpass);
|
||||
extern void (APIENTRY *qglTexCoord1d) (GLdouble s);
|
||||
extern void (APIENTRY *qglTexCoord1dv) (const GLdouble *v);
|
||||
extern void (APIENTRY *qglTexCoord1f) (GLfloat s);
|
||||
extern void (APIENTRY *qglTexCoord1fv) (const GLfloat *v);
|
||||
extern void (APIENTRY *qglTexCoord1i) (GLint s);
|
||||
extern void (APIENTRY *qglTexCoord1iv) (const GLint *v);
|
||||
extern void (APIENTRY *qglTexCoord1s) (GLshort s);
|
||||
extern void (APIENTRY *qglTexCoord1sv) (const GLshort *v);
|
||||
extern void (APIENTRY *qglTexCoord2d) (GLdouble s, GLdouble t);
|
||||
extern void (APIENTRY *qglTexCoord2dv) (const GLdouble *v);
|
||||
extern void (APIENTRY *qglTexCoord2f) (GLfloat s, GLfloat t);
|
||||
extern void (APIENTRY *qglTexCoord2fv) (const GLfloat *v);
|
||||
extern void (APIENTRY *qglTexCoord2i) (GLint s, GLint t);
|
||||
extern void (APIENTRY *qglTexCoord2iv) (const GLint *v);
|
||||
extern void (APIENTRY *qglTexCoord2s) (GLshort s, GLshort t);
|
||||
extern void (APIENTRY *qglTexCoord2sv) (const GLshort *v);
|
||||
extern void (APIENTRY *qglTexCoord3d) (GLdouble s, GLdouble t, GLdouble r);
|
||||
extern void (APIENTRY *qglTexCoord3dv) (const GLdouble *v);
|
||||
extern void (APIENTRY *qglTexCoord3f) (GLfloat s, GLfloat t, GLfloat r);
|
||||
extern void (APIENTRY *qglTexCoord3fv) (const GLfloat *v);
|
||||
extern void (APIENTRY *qglTexCoord3i) (GLint s, GLint t, GLint r);
|
||||
extern void (APIENTRY *qglTexCoord3iv) (const GLint *v);
|
||||
extern void (APIENTRY *qglTexCoord3s) (GLshort s, GLshort t, GLshort r);
|
||||
extern void (APIENTRY *qglTexCoord3sv) (const GLshort *v);
|
||||
extern void (APIENTRY *qglTexCoord4d) (GLdouble s, GLdouble t, GLdouble r, GLdouble q);
|
||||
extern void (APIENTRY *qglTexCoord4dv) (const GLdouble *v);
|
||||
extern void (APIENTRY *qglTexCoord4f) (GLfloat s, GLfloat t, GLfloat r, GLfloat q);
|
||||
extern void (APIENTRY *qglTexCoord4fv) (const GLfloat *v);
|
||||
extern void (APIENTRY *qglTexCoord4i) (GLint s, GLint t, GLint r, GLint q);
|
||||
extern void (APIENTRY *qglTexCoord4iv) (const GLint *v);
|
||||
extern void (APIENTRY *qglTexCoord4s) (GLshort s, GLshort t, GLshort r, GLshort q);
|
||||
extern void (APIENTRY *qglTexCoord4sv) (const GLshort *v);
|
||||
extern void (APIENTRY *qglTexCoordPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
extern void (APIENTRY *qglTexEnvf) (GLenum target, GLenum pname, GLfloat param);
|
||||
extern void (APIENTRY *qglTexEnvfv) (GLenum target, GLenum pname, const GLfloat *params);
|
||||
extern void (APIENTRY *qglTexEnvi) (GLenum target, GLenum pname, GLint param);
|
||||
extern void (APIENTRY *qglTexEnviv) (GLenum target, GLenum pname, const GLint *params);
|
||||
extern void (APIENTRY *qglTexGend) (GLenum coord, GLenum pname, GLdouble param);
|
||||
extern void (APIENTRY *qglTexGendv) (GLenum coord, GLenum pname, const GLdouble *params);
|
||||
extern void (APIENTRY *qglTexGenf) (GLenum coord, GLenum pname, GLfloat param);
|
||||
extern void (APIENTRY *qglTexGenfv) (GLenum coord, GLenum pname, const GLfloat *params);
|
||||
extern void (APIENTRY *qglTexGeni) (GLenum coord, GLenum pname, GLint param);
|
||||
extern void (APIENTRY *qglTexGeniv) (GLenum coord, GLenum pname, const GLint *params);
|
||||
extern void (APIENTRY *qglTexImage1D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
extern void (APIENTRY *qglTexImage2D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
extern void (APIENTRY *qglTexParameterf) (GLenum target, GLenum pname, GLfloat param);
|
||||
extern void (APIENTRY *qglTexParameterfv) (GLenum target, GLenum pname, const GLfloat *params);
|
||||
extern void (APIENTRY *qglTexParameteri) (GLenum target, GLenum pname, GLint param);
|
||||
extern void (APIENTRY *qglTexParameteriv) (GLenum target, GLenum pname, const GLint *params);
|
||||
extern void (APIENTRY *qglTexSubImage1D) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
extern void (APIENTRY *qglTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
extern void (APIENTRY *qglTranslated) (GLdouble x, GLdouble y, GLdouble z);
|
||||
extern void (APIENTRY *qglTranslatef) (GLfloat x, GLfloat y, GLfloat z);
|
||||
extern void (APIENTRY *qglVertex2d) (GLdouble x, GLdouble y);
|
||||
extern void (APIENTRY *qglVertex2dv) (const GLdouble *v);
|
||||
extern void (APIENTRY *qglVertex2f) (GLfloat x, GLfloat y);
|
||||
extern void (APIENTRY *qglVertex2fv) (const GLfloat *v);
|
||||
extern void (APIENTRY *qglVertex2i) (GLint x, GLint y);
|
||||
extern void (APIENTRY *qglVertex2iv) (const GLint *v);
|
||||
extern void (APIENTRY *qglVertex2s) (GLshort x, GLshort y);
|
||||
extern void (APIENTRY *qglVertex2sv) (const GLshort *v);
|
||||
extern void (APIENTRY *qglVertex3d) (GLdouble x, GLdouble y, GLdouble z);
|
||||
extern void (APIENTRY *qglVertex3dv) (const GLdouble *v);
|
||||
extern void (APIENTRY *qglVertex3f) (GLfloat x, GLfloat y, GLfloat z);
|
||||
extern void (APIENTRY *qglVertex3fv) (const GLfloat *v);
|
||||
extern void (APIENTRY *qglVertex3i) (GLint x, GLint y, GLint z);
|
||||
extern void (APIENTRY *qglVertex3iv) (const GLint *v);
|
||||
extern void (APIENTRY *qglVertex3s) (GLshort x, GLshort y, GLshort z);
|
||||
extern void (APIENTRY *qglVertex3sv) (const GLshort *v);
|
||||
extern void (APIENTRY *qglVertex4d) (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
|
||||
extern void (APIENTRY *qglVertex4dv) (const GLdouble *v);
|
||||
extern void (APIENTRY *qglVertex4f) (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
extern void (APIENTRY *qglVertex4fv) (const GLfloat *v);
|
||||
extern void (APIENTRY *qglVertex4i) (GLint x, GLint y, GLint z, GLint w);
|
||||
extern void (APIENTRY *qglVertex4iv) (const GLint *v);
|
||||
extern void (APIENTRY *qglVertex4s) (GLshort x, GLshort y, GLshort z, GLshort w);
|
||||
extern void (APIENTRY *qglVertex4sv) (const GLshort *v);
|
||||
extern void (APIENTRY *qglVertexPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
extern void (APIENTRY *qglViewport) (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
|
||||
#ifdef _WIN32
|
||||
extern BOOL (WINAPI *qwglCopyContext)(HGLRC, HGLRC, UINT);
|
||||
extern HGLRC (WINAPI *qwglCreateContext)(HDC);
|
||||
extern HGLRC (WINAPI *qwglCreateLayerContext)(HDC, int);
|
||||
extern BOOL (WINAPI *qwglDeleteContext)(HGLRC);
|
||||
extern HGLRC (WINAPI *qwglGetCurrentContext)(VOID);
|
||||
extern HDC (WINAPI *qwglGetCurrentDC)(VOID);
|
||||
extern PROC (WINAPI *qwglGetProcAddress)(LPCSTR);
|
||||
extern BOOL (WINAPI *qwglMakeCurrent)(HDC, HGLRC);
|
||||
extern BOOL (WINAPI *qSwapBuffers)(HDC);
|
||||
#endif
|
||||
|
||||
|
||||
#define glAlphaFunc qglAlphaFunc
|
||||
#define glBlendFunc qglBlendFunc
|
||||
#define glBegin qglBegin
|
||||
#define glColor3f qglColor3f
|
||||
#define glColor4f qglColor4f
|
||||
#define glColor4ub qglColor4ub
|
||||
#define glColor4ubv qglColor4ubv
|
||||
#define glColorMask qglColorMask
|
||||
#define glClearDepth qglClearDepth
|
||||
#define glClearStencil qglClearStencil
|
||||
#define glDisable qglDisable
|
||||
#define glEnable qglEnable
|
||||
#define glEnd qglEnd
|
||||
#define glFlush qglFlush
|
||||
#define glScalef qglScalef
|
||||
#define glTranslatef qglTranslatef
|
||||
#define glGetInteger qglGetInteger
|
||||
#define glTexCoord1f qglTexCoord1f
|
||||
#define glTexCoord2f qglTexCoord2f
|
||||
#define glTexCoord2fv qglTexCoord2fv
|
||||
#define glTexParameterf qglTexParameterf
|
||||
#define glNormal3f qglNormal3f
|
||||
#define glNormal3fv qglNormal3fv
|
||||
#define glTexParameteri qglTexParameteri
|
||||
#define glTexImage2D qglTexImage2D
|
||||
#define glMultMatrixf qglMultMatrixf
|
||||
#define glGetIntegerv qglGetIntegerv
|
||||
#define glTexEnvf qglTexEnvf
|
||||
#define glTexEnvi qglTexEnvi
|
||||
#define glTexGeni qglTexGeni
|
||||
#define glVertex2f qglVertex2f
|
||||
#define glVertex3f qglVertex3f
|
||||
#define glVertex3fv qglVertex3fv
|
||||
#define glCullFace qglCullFace
|
||||
#define glPushMatrix qglPushMatrix
|
||||
#define glPopMatrix qglPopMatrix
|
||||
#define glViewport qglViewport
|
||||
#define glRotatef qglRotatef
|
||||
#define glShadeModel qglShadeModel
|
||||
#define glDepthMask qglDepthMask
|
||||
#define glDepthFunc qglDepthFunc
|
||||
#define glClearColor qglClearColor
|
||||
#define glFinish qglFinish
|
||||
#define glClear qglClear
|
||||
#define glHint qglHint
|
||||
#define glDepthRange qglDepthRange
|
||||
#define glMatrixMode qglMatrixMode
|
||||
#define glOrtho qglOrtho
|
||||
#define glDrawBuffer qglDrawBuffer
|
||||
#define glTexSubImage2D qglTexSubImage2D
|
||||
#define glGetString qglGetString
|
||||
#define glPolygonMode qglPolygonMode
|
||||
#define glReadPixels qglReadPixels
|
||||
#define glLoadMatrixf qglLoadMatrixf
|
||||
#define glColor4fv qglColor4fv
|
||||
#define glFrustum qglFrustum
|
||||
#define glGetFloatv qglGetFloatv
|
||||
#define glReadBuffer qglReadBuffer
|
||||
#define glLoadIdentity qglLoadIdentity
|
||||
#define glGetTexLevelParameteriv qglGetTexLevelParameteriv
|
||||
|
||||
//vertex lists
|
||||
#define glTexCoordPointer qglTexCoordPointer
|
||||
#define glVertexPointer qglVertexPointer
|
||||
#define glNormalPointer qglNormalPointer
|
||||
#define glColorPointer qglColorPointer
|
||||
#define glDrawElements qglDrawElements
|
||||
#define glDisableClientState qglDisableClientState
|
||||
#define glEnableClientState qglEnableClientState
|
||||
|
||||
//stencil functions
|
||||
#define glStencilOp qglStencilOp
|
||||
#define glStencilFunc qglStencilFunc
|
||||
#define glPushAttrib qglPushAttrib
|
||||
#define glPopAttrib qglPopAttrib
|
||||
|
||||
void GL_Init(void *(*getglfunction) (char *name));
|
||||
|
||||
#endif
|
||||
|
||||
qbyte GetPalette(int red, int green, int blue);
|
||||
int Mod_ReadFlagsFromMD1(char *name, int md3version);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef SWQUAKE
|
||||
|
||||
|
||||
#define CYCLE 128 // turbulent cycle size
|
||||
extern int r_pixbytes;
|
||||
|
||||
#define WARP_WIDTH 320
|
||||
#define WARP_HEIGHT 200
|
||||
|
||||
|
||||
extern cvar_t r_drawflat;
|
||||
extern int d_spanpixcount;
|
||||
extern int r_framecount; // sequence # of current frame since Quake
|
||||
// started
|
||||
extern qboolean r_drawpolys; // 1 if driver wants clipped polygons
|
||||
// rather than a span list
|
||||
extern qboolean r_drawculledpolys; // 1 if driver wants clipped polygons that
|
||||
// have been culled by the edge list
|
||||
extern qboolean r_worldpolysbacktofront; // 1 if driver wants polygons
|
||||
// delivered back to front rather
|
||||
// than front to back
|
||||
extern qboolean r_recursiveaffinetriangles; // true if a driver wants to use
|
||||
// recursive triangular subdivison
|
||||
// and vertex drawing via
|
||||
// D_PolysetDrawFinalVerts() past
|
||||
// a certain distance (normally
|
||||
// only used by the software
|
||||
// driver)
|
||||
extern float r_aliasuvscale; // scale-up factor for screen u and v
|
||||
// on Alias vertices passed to driver
|
||||
extern int r_pixbytes;
|
||||
extern qboolean r_dowarp;
|
||||
|
||||
/*extern affinetridesc_t r_affinetridesc;
|
||||
extern spritedesc_t r_spritedesc;
|
||||
extern zpointdesc_t r_zpointdesc;
|
||||
extern polydesc_t r_polydesc;
|
||||
*/
|
||||
extern int d_con_indirect; // if 0, Quake will draw console directly
|
||||
// to vid.buffer; if 1, Quake will
|
||||
// draw console via D_DrawRect. Must be
|
||||
// defined by driver
|
||||
|
||||
extern vec3_t r_pright, r_pup, r_ppn;
|
||||
|
||||
|
||||
|
||||
|
||||
extern float xscaleshrink, yscaleshrink;
|
||||
#endif
|
204
engine/gl/glsupp.h
Normal file
204
engine/gl/glsupp.h
Normal file
|
@ -0,0 +1,204 @@
|
|||
//gl suppliment for Quake
|
||||
|
||||
//contains the extra things that would otherwise be found in glext.h
|
||||
|
||||
typedef void (APIENTRY *qlpMTex2FUNC) (GLenum, GLfloat, GLfloat);
|
||||
typedef void (APIENTRY *qlpMTex3FUNC) (GLenum, GLfloat, GLfloat, GLfloat);
|
||||
typedef void (APIENTRY *qlpSelTexFUNC) (GLenum);
|
||||
|
||||
extern qlpSelTexFUNC qglActiveTextureARB;
|
||||
extern qlpSelTexFUNC qglClientActiveTextureARB;
|
||||
extern qlpMTex3FUNC qglMultiTexCoord3fARB;
|
||||
extern qlpMTex2FUNC qglMultiTexCoord2fARB;
|
||||
|
||||
//This stuff is normally supplied in the <GL/glext.h> header file. I don't actually have one of them, so it's here instead.
|
||||
#if 0 //change to 1 if you do actually have the file in question.
|
||||
#include <GL/glext.h> //would be ideal.
|
||||
#else
|
||||
|
||||
|
||||
//#ifndef GL_VERSION_1_2
|
||||
#define GL_CLAMP_TO_EDGE 0x812F
|
||||
//#endif
|
||||
|
||||
|
||||
#ifndef GL_ARB_multitexture
|
||||
#define GL_ARB_multitexture 1
|
||||
#define GL_TEXTURE0_ARB 0x84C0
|
||||
#define GL_TEXTURE1_ARB 0x84C1
|
||||
#define GL_TEXTURE2_ARB 0x84C2
|
||||
#define GL_TEXTURE3_ARB 0x84C3
|
||||
#define GL_TEXTURE4_ARB 0x84C4
|
||||
#define GL_TEXTURE5_ARB 0x84C5
|
||||
#define GL_TEXTURE6_ARB 0x84C6
|
||||
#define GL_TEXTURE7_ARB 0x84C7
|
||||
#define GL_TEXTURE8_ARB 0x84C8
|
||||
#define GL_TEXTURE9_ARB 0x84C9
|
||||
#define GL_TEXTURE10_ARB 0x84CA
|
||||
#define GL_TEXTURE11_ARB 0x84CB
|
||||
#define GL_TEXTURE12_ARB 0x84CC
|
||||
#define GL_TEXTURE13_ARB 0x84CD
|
||||
#define GL_TEXTURE14_ARB 0x84CE
|
||||
#define GL_TEXTURE15_ARB 0x84CF
|
||||
#define GL_TEXTURE16_ARB 0x84D0
|
||||
#define GL_TEXTURE17_ARB 0x84D1
|
||||
#define GL_TEXTURE18_ARB 0x84D2
|
||||
#define GL_TEXTURE19_ARB 0x84D3
|
||||
#define GL_TEXTURE20_ARB 0x84D4
|
||||
#define GL_TEXTURE21_ARB 0x84D5
|
||||
#define GL_TEXTURE22_ARB 0x84D6
|
||||
#define GL_TEXTURE23_ARB 0x84D7
|
||||
#define GL_TEXTURE24_ARB 0x84D8
|
||||
#define GL_TEXTURE25_ARB 0x84D9
|
||||
#define GL_TEXTURE26_ARB 0x84DA
|
||||
#define GL_TEXTURE27_ARB 0x84DB
|
||||
#define GL_TEXTURE28_ARB 0x84DC
|
||||
#define GL_TEXTURE29_ARB 0x84DD
|
||||
#define GL_TEXTURE30_ARB 0x84DE
|
||||
#define GL_TEXTURE31_ARB 0x84DF
|
||||
#define GL_ACTIVE_TEXTURE_ARB 0x84E0
|
||||
#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1
|
||||
#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2
|
||||
#endif
|
||||
|
||||
#ifndef GL_ARB_texture_cube_map
|
||||
#define GL_ARB_texture_cube_map 1
|
||||
#define GL_NORMAL_MAP_ARB 0x8511
|
||||
#define GL_REFLECTION_MAP_ARB 0x8512
|
||||
#define GL_TEXTURE_CUBE_MAP_ARB 0x8513
|
||||
#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514
|
||||
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515
|
||||
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516
|
||||
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517
|
||||
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518
|
||||
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519
|
||||
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A
|
||||
#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B
|
||||
#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef GL_EXT_texture3D
|
||||
#define define GL_EXT_texture3D 1
|
||||
#define GL_PACK_SKIP_IMAGES 0x806B
|
||||
#define GL_PACK_SKIP_IMAGES_EXT 0x806B
|
||||
#define GL_PACK_IMAGE_HEIGHT 0x806C
|
||||
#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C
|
||||
#define GL_UNPACK_SKIP_IMAGES 0x806D
|
||||
#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D
|
||||
#define GL_UNPACK_IMAGE_HEIGHT 0x806E
|
||||
#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E
|
||||
#define GL_TEXTURE_3D 0x806F
|
||||
#define GL_TEXTURE_3D_EXT 0x806F
|
||||
#define GL_PROXY_TEXTURE_3D 0x8070
|
||||
#define GL_PROXY_TEXTURE_3D_EXT 0x8070
|
||||
#define GL_TEXTURE_DEPTH 0x8071
|
||||
#define GL_TEXTURE_DEPTH_EXT 0x8071
|
||||
#define GL_TEXTURE_WRAP_R 0x8072
|
||||
#define GL_TEXTURE_WRAP_R_EXT 0x8072
|
||||
#define GL_MAX_3D_TEXTURE_SIZE 0x8073
|
||||
#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//some of these were needed.
|
||||
//They were also not in the ones I could find on the web.
|
||||
#define GL_COMBINE_ARB 0x8570
|
||||
#define GL_COMBINE_RGB_ARB 0x8571
|
||||
#define GL_COMBINE_ALPHA_ARB 0x8572
|
||||
#define GL_SOURCE0_RGB_ARB 0x8580
|
||||
#define GL_SOURCE1_RGB_ARB 0x8581
|
||||
#define GL_SOURCE2_RGB_ARB 0x8582
|
||||
#define GL_SOURCE0_ALPHA_ARB 0x8588
|
||||
#define GL_SOURCE1_ALPHA_ARB 0x8589
|
||||
#define GL_SOURCE2_ALPHA_ARB 0x858A
|
||||
#define GL_OPERAND0_RGB_ARB 0x8590
|
||||
#define GL_OPERAND1_RGB_ARB 0x8591
|
||||
#define GL_OPERAND2_RGB_ARB 0x8592
|
||||
#define GL_OPERAND0_ALPHA_ARB 0x8598
|
||||
#define GL_OPERAND1_ALPHA_ARB 0x8599
|
||||
#define GL_OPERAND2_ALPHA_ARB 0x859A
|
||||
#define GL_RGB_SCALE_ARB 0x8573
|
||||
#define GL_ADD_SIGNED_ARB 0x8574
|
||||
#define GL_INTERPOLATE_ARB 0x8575
|
||||
#define GL_SUBTRACT_ARB 0x84E7
|
||||
#define GL_CONSTANT_ARB 0x8576
|
||||
#define GL_PRIMARY_COLOR_ARB 0x8577
|
||||
#define GL_PREVIOUS_ARB 0x8578
|
||||
#define GL_DOT3_RGB_ARB 0x86AE
|
||||
#define GL_DOT3_RGBA_ARB 0x86AF
|
||||
|
||||
|
||||
|
||||
/* GL_ARB_texture_compression */
|
||||
#ifndef GL_ARB_texture_compression
|
||||
#define GL_ARB_texture_compression 1
|
||||
|
||||
#define GL_COMPRESSED_ALPHA_ARB 0x84E9
|
||||
#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA
|
||||
#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB
|
||||
#define GL_COMPRESSED_INTENSITY_ARB 0x84EC
|
||||
#define GL_COMPRESSED_RGB_ARB 0x84ED
|
||||
#define GL_COMPRESSED_RGBA_ARB 0x84EE
|
||||
#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF
|
||||
#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0
|
||||
#define GL_TEXTURE_COMPRESSED_ARB 0x86A1
|
||||
#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2
|
||||
#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3
|
||||
|
||||
typedef void (APIENTRY *PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
|
||||
typedef void (APIENTRY *PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
|
||||
typedef void (APIENTRY *PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid* data);
|
||||
typedef void (APIENTRY *PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
|
||||
typedef void (APIENTRY *PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
|
||||
typedef void (APIENTRY *PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid* data);
|
||||
typedef void (APIENTRY *PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, const GLvoid* img);
|
||||
|
||||
#endif /* GL_ARB_texture_compression */
|
||||
|
||||
|
||||
#ifndef GL_ATI_pn_triangles //ati truform
|
||||
#define GL_PN_TRIANGLES_ATI 0x87F0
|
||||
#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1
|
||||
#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2
|
||||
#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3
|
||||
#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4
|
||||
#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5
|
||||
#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6
|
||||
#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7
|
||||
#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8
|
||||
|
||||
typedef void (APIENTRY *PFNGLPNTRIANGLESIATIPROC)(GLenum pname, GLint param);
|
||||
typedef void (APIENTRY *PFNGLPNTRIANGLESFATIPROC)(GLenum pname, GLfloat param);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef GL_EXT_stencil_two_side
|
||||
#define GL_EXT_stencil_two_side 1
|
||||
|
||||
#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910
|
||||
#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911
|
||||
|
||||
typedef void (APIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face);
|
||||
#endif
|
||||
|
||||
#ifndef GL_EXT_stencil_wrap
|
||||
#define GL_EXT_stencil_wrap 1
|
||||
#define GL_INCR_WRAP_EXT 0x8507
|
||||
#define GL_DECR_WRAP_EXT 0x8508
|
||||
#endif
|
||||
|
||||
#ifndef GL_EXT_texture_filter_anisotropic
|
||||
#define GL_EXT_texture_filter_anisotropic 1
|
||||
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
|
||||
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue