mirror of
https://git.code.sf.net/p/quake/nuq
synced 2024-11-24 21:12:07 +00:00
that's most of newtree's gl stuff ported over. Three bugs: wound up with
newtree's slow skys, some models are not getting lit, and dlights don't seem to be working :(
This commit is contained in:
parent
8538ec49d1
commit
8302413276
7 changed files with 1066 additions and 1693 deletions
|
@ -163,6 +163,7 @@ extern qboolean envmap;
|
|||
extern int currenttexture;
|
||||
extern int cnttextures[2];
|
||||
extern int particletexture;
|
||||
extern int netgraphtexture;
|
||||
extern int playertextures;
|
||||
|
||||
extern int skytexturenum; // index in cl.loadmodel, not gl texture object
|
||||
|
@ -178,8 +179,10 @@ extern cvar_t *r_lightmap;
|
|||
extern cvar_t *r_shadows;
|
||||
extern cvar_t *r_mirroralpha;
|
||||
extern cvar_t *r_wateralpha;
|
||||
extern cvar_t *r_waterripple;
|
||||
extern cvar_t *r_dynamic;
|
||||
extern cvar_t *r_novis;
|
||||
extern cvar_t *r_netgraph;
|
||||
|
||||
extern cvar_t *gl_clear;
|
||||
extern cvar_t *gl_cull;
|
||||
|
@ -200,6 +203,7 @@ extern cvar_t *gl_clear;
|
|||
extern cvar_t *gl_subdivide_size;
|
||||
extern cvar_t *gl_particles;
|
||||
extern cvar_t *gl_fires;
|
||||
extern cvar_t *gl_fb_models;
|
||||
|
||||
extern int gl_lightmap_format;
|
||||
extern int gl_solid_format;
|
||||
|
@ -208,6 +212,9 @@ extern int gl_alpha_format;
|
|||
extern cvar_t *gl_max_size;
|
||||
extern cvar_t *gl_playermip;
|
||||
|
||||
extern cvar_t *r_skyname;
|
||||
extern cvar_t *gl_skymultipass;
|
||||
|
||||
extern int mirrortexturenum; // quake texturenum, not gltexturenum
|
||||
extern qboolean mirror;
|
||||
extern qboolean lighthalf;
|
||||
|
@ -256,9 +263,13 @@ void EmitWaterPolys (msurface_t *fa);
|
|||
void EmitSkyPolys (msurface_t *fa);
|
||||
void EmitBothSkyLayers (msurface_t *fa);
|
||||
void R_DrawSkyChain (msurface_t *s);
|
||||
qboolean R_CullBox (vec3_t mins, vec3_t maxs);
|
||||
void R_LoadSkys (char *);
|
||||
void R_DrawSky (void);
|
||||
|
||||
void R_RotateForEntity (entity_t *e);
|
||||
|
||||
qboolean R_CullBox (vec3_t mins, vec3_t maxs);
|
||||
|
||||
void AddLightBlend (float, float, float, float);
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -476,8 +476,8 @@ void Draw_Init (void)
|
|||
draw_backtile = Draw_PicFromWad ("backtile");
|
||||
|
||||
// LordHavoc: call init code for other GL renderer modules;
|
||||
//XXXglrmain_init();
|
||||
//XXXglrsurf_init();
|
||||
glrmain_init();
|
||||
glrsurf_init();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1414,20 +1414,3 @@ static int GL_LoadPicTexture (qpic_t *pic)
|
|||
{
|
||||
return GL_LoadTexture ("", pic->width, pic->height, pic->data, false, true, 1);
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
|
||||
static GLenum oldtarget = TEXTURE0_SGIS;
|
||||
|
||||
void GL_SelectTexture (GLenum target)
|
||||
{
|
||||
if (!gl_mtexable)
|
||||
return;
|
||||
qglSelectTextureSGIS(target);
|
||||
if (target == oldtarget)
|
||||
return;
|
||||
cnttextures[oldtarget-TEXTURE0_SGIS] = currenttexture;
|
||||
currenttexture = cnttextures[target-TEXTURE0_SGIS];
|
||||
oldtarget = target;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
gl_rmain.c
|
||||
|
||||
@description@
|
||||
(description)
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
|
@ -30,13 +30,23 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "compat.h"
|
||||
#include "qargs.h"
|
||||
#include "console.h"
|
||||
#include "r_local.h"
|
||||
#include "view.h"
|
||||
#include "qdefs.h"
|
||||
#include "glquake.h"
|
||||
#include "client.h"
|
||||
#include "model.h"
|
||||
#include "render.h"
|
||||
#include "sys.h"
|
||||
#include "console.h"
|
||||
#include "chase.h"
|
||||
#include "view.h"
|
||||
#include "r_local.h"
|
||||
|
||||
entity_t r_worldentity;
|
||||
|
||||
|
@ -45,6 +55,10 @@ qboolean r_cache_thrash; // compatability
|
|||
vec3_t modelorg, r_entorigin;
|
||||
entity_t *currententity;
|
||||
|
||||
int currenttexture = -1; // to avoid unnecessary texture sets
|
||||
int cnttextures[2] = {-1, -1}; // cached
|
||||
|
||||
|
||||
int r_visframecount; // bumped when going to a new PVS
|
||||
int r_framecount; // used for dlight push checking
|
||||
|
||||
|
@ -54,9 +68,6 @@ int c_brush_polys, c_alias_polys;
|
|||
|
||||
qboolean envmap; // true during envmap command capture
|
||||
|
||||
int currenttexture = -1; // to avoid unnecessary texture sets
|
||||
|
||||
int cnttextures[2] = {-1, -1}; // cached
|
||||
|
||||
int particletexture; // little dot for particles
|
||||
int playertextures; // up to 16 color translated skins
|
||||
|
@ -83,8 +94,6 @@ refdef_t r_refdef;
|
|||
|
||||
mleaf_t *r_viewleaf, *r_oldviewleaf;
|
||||
|
||||
texture_t *r_notexture_mip;
|
||||
|
||||
int d_lightstylevalue[256]; // 8.8 fraction of base light value
|
||||
|
||||
|
||||
|
@ -99,10 +108,11 @@ cvar_t *r_lightmap;
|
|||
cvar_t *r_shadows;
|
||||
cvar_t *r_mirroralpha;
|
||||
cvar_t *r_wateralpha;
|
||||
cvar_t *r_waterripple;
|
||||
cvar_t *r_dynamic;
|
||||
cvar_t *r_novis;
|
||||
cvar_t *r_netgraph;
|
||||
|
||||
cvar_t *gl_finish;
|
||||
cvar_t *gl_clear;
|
||||
cvar_t *gl_cull;
|
||||
cvar_t *gl_texsort;
|
||||
|
@ -114,9 +124,65 @@ cvar_t *gl_playermip;
|
|||
cvar_t *gl_nocolors;
|
||||
cvar_t *gl_keeptjunctions;
|
||||
cvar_t *gl_reporttjunctions;
|
||||
cvar_t *gl_doubleeyes;
|
||||
cvar_t *gl_particles;
|
||||
cvar_t *gl_fires;
|
||||
|
||||
cvar_t *r_skyname;
|
||||
cvar_t *gl_skymultipass;
|
||||
|
||||
cvar_t *gl_fb_models;
|
||||
cvar_t *gl_fb_bmodels;
|
||||
|
||||
extern cvar_t *scr_fov;
|
||||
|
||||
extern byte gammatable[256];
|
||||
extern qboolean lighthalf;
|
||||
static float vid_gamma = 1.0;
|
||||
|
||||
// LordHavoc: place for gl_rmain setup code
|
||||
void glrmain_init()
|
||||
{
|
||||
};
|
||||
|
||||
/*
|
||||
GL_CheckGamma
|
||||
|
||||
More or less redesigned by LordHavoc
|
||||
*/
|
||||
void
|
||||
GL_CheckGamma (unsigned char *pal)
|
||||
{
|
||||
float inf;
|
||||
int i;
|
||||
|
||||
if ((i = COM_CheckParm("-gamma")) == 0) {
|
||||
if ((gl_renderer && strstr(gl_renderer, "Voodoo")) ||
|
||||
(gl_vendor && strstr(gl_vendor, "3Dfx")))
|
||||
vid_gamma = 1;
|
||||
else
|
||||
vid_gamma = 0.7; // default to 0.7 on non-3dfx hardware
|
||||
} else
|
||||
vid_gamma = atof(com_argv[i+1]);
|
||||
|
||||
// build the gamma table
|
||||
if (vid_gamma == 1)
|
||||
{
|
||||
// screw the math
|
||||
for (i = 0; i < 256; i++)
|
||||
gammatable[i] = i;
|
||||
} else {
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
inf = pow((i+1)/256.0, vid_gamma)*255 + 0.5;
|
||||
inf = bound(0, inf, 255);
|
||||
gammatable[i] = inf;
|
||||
}
|
||||
}
|
||||
|
||||
// correct the palette
|
||||
for (i = 0; i < 768; i++)
|
||||
pal[i] = gammatable[pal[i]];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -142,6 +208,7 @@ void R_RotateForEntity (entity_t *e)
|
|||
|
||||
glRotatef (e->angles[1], 0, 0, 1);
|
||||
glRotatef (-e->angles[0], 0, 1, 0);
|
||||
//ZOID: fixed z angle
|
||||
glRotatef (e->angles[2], 1, 0, 0);
|
||||
}
|
||||
|
||||
|
@ -158,7 +225,7 @@ void R_RotateForEntity (entity_t *e)
|
|||
R_GetSpriteFrame
|
||||
================
|
||||
*/
|
||||
mspriteframe_t *R_GetSpriteFrame (entity_t *currententity)
|
||||
static mspriteframe_t *R_GetSpriteFrame (entity_t *currententity)
|
||||
{
|
||||
msprite_t *psprite;
|
||||
mspritegroup_t *pspritegroup;
|
||||
|
@ -211,7 +278,7 @@ R_DrawSpriteModel
|
|||
|
||||
=================
|
||||
*/
|
||||
void R_DrawSpriteModel (entity_t *e)
|
||||
static void R_DrawSpriteModel (entity_t *e)
|
||||
{
|
||||
vec3_t point;
|
||||
mspriteframe_t *frame;
|
||||
|
@ -236,15 +303,19 @@ void R_DrawSpriteModel (entity_t *e)
|
|||
right = vright;
|
||||
}
|
||||
|
||||
glColor3f (1,1,1);
|
||||
|
||||
GL_DisableMultitexture();
|
||||
if (lighthalf)
|
||||
glColor4f(0.5,0.5,0.5,1);
|
||||
else
|
||||
glColor4f(1,1,1,1);
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, frame->gl_texturenum);
|
||||
|
||||
glEnable (GL_ALPHA_TEST);
|
||||
glBegin (GL_QUADS);
|
||||
|
||||
glEnable (GL_ALPHA_TEST);
|
||||
glBegin (GL_QUADS);
|
||||
|
||||
glTexCoord2f (0, 1);
|
||||
VectorMA (e->origin, frame->down, up, point);
|
||||
VectorMA (point, frame->left, right, point);
|
||||
|
@ -303,14 +374,14 @@ int lastposenum;
|
|||
GL_DrawAliasFrame
|
||||
=============
|
||||
*/
|
||||
void GL_DrawAliasFrame (aliashdr_t *paliashdr, int posenum)
|
||||
static void GL_DrawAliasFrame (aliashdr_t *paliashdr, int posenum, qboolean fb)
|
||||
{
|
||||
float l;
|
||||
trivertx_t *verts;
|
||||
int *order;
|
||||
int count;
|
||||
|
||||
lastposenum = posenum;
|
||||
|
||||
lastposenum = posenum;
|
||||
|
||||
verts = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata);
|
||||
verts += posenum * paliashdr->poseverts;
|
||||
|
@ -336,9 +407,20 @@ lastposenum = posenum;
|
|||
glTexCoord2f (((float *)order)[0], ((float *)order)[1]);
|
||||
order += 2;
|
||||
|
||||
// normals and vertexes come from the frame list
|
||||
l = shadedots[verts->lightnormalindex] * shadelight;
|
||||
glColor3f (l, l, l);
|
||||
if (fb) {
|
||||
glColor4f (1, 1, 1, 1);
|
||||
} else {
|
||||
// normals and vertexes come from the frame list
|
||||
l = shadedots[verts->lightnormalindex] * shadelight;
|
||||
|
||||
// LordHavoc: cleanup after Endy
|
||||
if (!lighthalf) {
|
||||
glColor4f(2 * l, 2 * l, 2 * l, 1);
|
||||
} else {
|
||||
glColor4f(l, l, l, 1);
|
||||
}
|
||||
}
|
||||
|
||||
glVertex3f (verts->v[0], verts->v[1], verts->v[2]);
|
||||
verts++;
|
||||
} while (--count);
|
||||
|
@ -355,7 +437,7 @@ GL_DrawAliasShadow
|
|||
*/
|
||||
extern vec3_t lightspot;
|
||||
|
||||
void GL_DrawAliasShadow (aliashdr_t *paliashdr, int posenum)
|
||||
static void GL_DrawAliasShadow (aliashdr_t *paliashdr, int posenum)
|
||||
{
|
||||
trivertx_t *verts;
|
||||
int *order;
|
||||
|
@ -418,7 +500,7 @@ R_SetupAliasFrame
|
|||
|
||||
=================
|
||||
*/
|
||||
void R_SetupAliasFrame (int frame, aliashdr_t *paliashdr)
|
||||
static void R_SetupAliasFrame (int frame, aliashdr_t *paliashdr, qboolean fb)
|
||||
{
|
||||
int pose, numposes;
|
||||
float interval;
|
||||
|
@ -438,18 +520,17 @@ void R_SetupAliasFrame (int frame, aliashdr_t *paliashdr)
|
|||
pose += (int)(cl.time / interval) % numposes;
|
||||
}
|
||||
|
||||
GL_DrawAliasFrame (paliashdr, pose);
|
||||
GL_DrawAliasFrame (paliashdr, pose, fb);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
R_DrawAliasModel
|
||||
|
||||
=================
|
||||
*/
|
||||
void R_DrawAliasModel (entity_t *e)
|
||||
static void R_DrawAliasModel (entity_t *e)
|
||||
{
|
||||
int i;
|
||||
int lnum;
|
||||
|
@ -469,7 +550,6 @@ void R_DrawAliasModel (entity_t *e)
|
|||
if (R_CullBox (mins, maxs))
|
||||
return;
|
||||
|
||||
|
||||
VectorCopy (currententity->origin, r_entorigin);
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
|
||||
|
@ -490,9 +570,10 @@ void R_DrawAliasModel (entity_t *e)
|
|||
VectorSubtract (currententity->origin,
|
||||
cl_dlights[lnum].origin,
|
||||
dist);
|
||||
add = cl_dlights[lnum].radius - Length(dist);
|
||||
add = (cl_dlights[lnum].radius * cl_dlights[lnum].radius * 8) / (Length(dist) * Length(dist)); // FIXME Deek
|
||||
|
||||
if (add > 0) {
|
||||
if (add > 0)
|
||||
{
|
||||
ambientlight += add;
|
||||
//ZOID models should be affected by dlights as well
|
||||
shadelight += add;
|
||||
|
@ -507,15 +588,16 @@ void R_DrawAliasModel (entity_t *e)
|
|||
shadelight = 192 - ambientlight;
|
||||
|
||||
// ZOID: never allow players to go totally black
|
||||
i = currententity - cl_entities;
|
||||
if (i >= 1 && i<=cl.maxclients /* && !strcmp (currententity->model->name, "progs/player.mdl") */)
|
||||
if (!strcmp(clmodel->name, "progs/player.mdl"))
|
||||
{
|
||||
if (ambientlight < 8)
|
||||
ambientlight = shadelight = 8;
|
||||
|
||||
// HACK HACK HACK -- no fullbright colors, so make torches full light
|
||||
if (!strcmp (clmodel->name, "progs/flame2.mdl")
|
||||
|| !strcmp (clmodel->name, "progs/flame.mdl") )
|
||||
} else if (!gl_fb_models->value && (
|
||||
!strcmp (clmodel->name, "progs/flame.mdl") ||
|
||||
!strcmp (clmodel->name, "progs/flame2.mdl"))) {
|
||||
// HACK HACK HACK -- no fullbright colors, so make torches full light
|
||||
ambientlight = shadelight = 256;
|
||||
}
|
||||
|
||||
shadedots = r_avertexnormal_dots[((int)(e->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
|
||||
shadelight = shadelight / 200.0;
|
||||
|
@ -537,16 +619,17 @@ void R_DrawAliasModel (entity_t *e)
|
|||
// draw all the triangles
|
||||
//
|
||||
|
||||
GL_DisableMultitexture();
|
||||
|
||||
glPushMatrix ();
|
||||
glPushMatrix ();
|
||||
R_RotateForEntity (e);
|
||||
|
||||
if (!strcmp (clmodel->name, "progs/eyes.mdl") && gl_doubleeyes->value) {
|
||||
if (!strcmp (clmodel->name, "progs/eyes.mdl") )
|
||||
{
|
||||
glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2] - (22 + 8));
|
||||
// double size of eyes, since they are really hard to see in gl
|
||||
// double size of eyes, since they are really hard to see in gl
|
||||
glScalef (paliashdr->scale[0]*2, paliashdr->scale[1]*2, paliashdr->scale[2]*2);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2]);
|
||||
glScalef (paliashdr->scale[0], paliashdr->scale[1], paliashdr->scale[2]);
|
||||
}
|
||||
|
@ -565,14 +648,25 @@ void R_DrawAliasModel (entity_t *e)
|
|||
|
||||
if (gl_smoothmodels->value)
|
||||
glShadeModel (GL_SMOOTH);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
if (gl_affinemodels->value)
|
||||
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
||||
|
||||
R_SetupAliasFrame (currententity->frame, paliashdr);
|
||||
R_SetupAliasFrame (currententity->frame, paliashdr, false);
|
||||
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
// This block is GL fullbright support for objects...
|
||||
if (clmodel->hasfullbrights && gl_fb_models->value &&
|
||||
paliashdr->gl_fb_texturenum[currententity->skinnum][anim]) {
|
||||
/*
|
||||
glEnable (GL_BLEND);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
*/
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, paliashdr->gl_fb_texturenum[currententity->skinnum][anim]);
|
||||
R_SetupAliasFrame (currententity->frame, paliashdr, true);
|
||||
|
||||
//glDisable (GL_BLEND);
|
||||
}
|
||||
|
||||
glShadeModel (GL_FLAT);
|
||||
if (gl_affinemodels->value)
|
||||
|
@ -585,12 +679,10 @@ void R_DrawAliasModel (entity_t *e)
|
|||
glPushMatrix ();
|
||||
R_RotateForEntity (e);
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
glEnable (GL_BLEND);
|
||||
glColor4f (0,0,0,0.5);
|
||||
GL_DrawAliasShadow (paliashdr, lastposenum);
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
glDisable (GL_BLEND);
|
||||
glColor4f (1,1,1,1);
|
||||
glColor4f (0.5, 0.5, 0.5, 1);
|
||||
glPopMatrix ();
|
||||
}
|
||||
|
||||
|
@ -603,46 +695,39 @@ void R_DrawAliasModel (entity_t *e)
|
|||
R_DrawEntitiesOnList
|
||||
=============
|
||||
*/
|
||||
void R_DrawEntitiesOnList (void)
|
||||
static void R_DrawEntitiesOnList (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!r_drawentities->value)
|
||||
return;
|
||||
|
||||
// draw sprites seperately, because of alpha blending
|
||||
// LordHavoc: split into 3 loops to simplify state changes
|
||||
for (i=0 ; i<cl_numvisedicts ; i++)
|
||||
{
|
||||
if (cl_visedicts[i]->model->type != mod_brush)
|
||||
continue;
|
||||
currententity = cl_visedicts[i];
|
||||
|
||||
switch (currententity->model->type)
|
||||
{
|
||||
case mod_alias:
|
||||
R_DrawAliasModel (currententity);
|
||||
break;
|
||||
|
||||
case mod_brush:
|
||||
R_DrawBrushModel (currententity);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
R_DrawBrushModel (currententity);
|
||||
}
|
||||
|
||||
for (i=0 ; i<cl_numvisedicts ; i++)
|
||||
{
|
||||
if (cl_visedicts[i]->model->type != mod_alias)
|
||||
continue;
|
||||
currententity = cl_visedicts[i];
|
||||
|
||||
switch (currententity->model->type)
|
||||
{
|
||||
case mod_sprite:
|
||||
R_DrawSpriteModel (currententity);
|
||||
break;
|
||||
case mod_brush:
|
||||
case mod_alias:
|
||||
break;
|
||||
}
|
||||
R_DrawAliasModel (currententity);
|
||||
}
|
||||
|
||||
for (i=0 ; i<cl_numvisedicts ; i++)
|
||||
{
|
||||
if (cl_visedicts[i]->model->type != mod_sprite)
|
||||
continue;
|
||||
currententity = cl_visedicts[i];
|
||||
|
||||
R_DrawSpriteModel (currententity);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -651,113 +736,25 @@ void R_DrawEntitiesOnList (void)
|
|||
R_DrawViewModel
|
||||
=============
|
||||
*/
|
||||
void R_DrawViewModel (void)
|
||||
static void R_DrawViewModel (void)
|
||||
{
|
||||
float ambient[4], diffuse[4];
|
||||
int j;
|
||||
int lnum;
|
||||
vec3_t dist;
|
||||
float add;
|
||||
dlight_t *dl;
|
||||
int ambientlight, shadelight;
|
||||
|
||||
if (!r_drawviewmodel->value)
|
||||
return;
|
||||
|
||||
if (chase_active->value)
|
||||
return;
|
||||
|
||||
if (envmap)
|
||||
return;
|
||||
|
||||
if (!r_drawentities->value)
|
||||
return;
|
||||
|
||||
if (cl.items & IT_INVISIBILITY)
|
||||
return;
|
||||
|
||||
if (cl.stats[STAT_HEALTH] <= 0)
|
||||
return;
|
||||
|
||||
currententity = &cl.viewent;
|
||||
if (!currententity->model)
|
||||
if (!r_drawviewmodel->value
|
||||
|| chase_active->value
|
||||
|| envmap
|
||||
|| !r_drawentities->value
|
||||
|| (cl.items & IT_INVISIBILITY)
|
||||
|| cl.stats[STAT_HEALTH] <= 0
|
||||
|| !currententity->model)
|
||||
return;
|
||||
|
||||
j = R_LightPoint (currententity->origin);
|
||||
|
||||
if (j < 24)
|
||||
j = 24; // allways give some light on gun
|
||||
ambientlight = j;
|
||||
shadelight = j;
|
||||
|
||||
// add dynamic lights
|
||||
for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++)
|
||||
{
|
||||
dl = &cl_dlights[lnum];
|
||||
if (!dl->radius)
|
||||
continue;
|
||||
if (!dl->radius)
|
||||
continue;
|
||||
if (dl->die < cl.time)
|
||||
continue;
|
||||
|
||||
VectorSubtract (currententity->origin, dl->origin, dist);
|
||||
add = dl->radius - Length(dist);
|
||||
if (add > 0)
|
||||
ambientlight += add;
|
||||
}
|
||||
|
||||
ambient[0] = ambient[1] = ambient[2] = ambient[3] = (float)ambientlight / 128;
|
||||
diffuse[0] = diffuse[1] = diffuse[2] = diffuse[3] = (float)shadelight / 128;
|
||||
|
||||
// hack the depth range to prevent view model from poking into walls
|
||||
glDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin));
|
||||
R_DrawAliasModel (currententity);
|
||||
glDepthRange (gldepthmin, gldepthmax);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
R_PolyBlend
|
||||
============
|
||||
*/
|
||||
void R_PolyBlend (void)
|
||||
{
|
||||
if (!gl_polyblend->value)
|
||||
return;
|
||||
if (!v_blend[3])
|
||||
return;
|
||||
|
||||
GL_DisableMultitexture();
|
||||
|
||||
glDisable (GL_ALPHA_TEST);
|
||||
glEnable (GL_BLEND);
|
||||
glDisable (GL_DEPTH_TEST);
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
|
||||
glLoadIdentity ();
|
||||
|
||||
glRotatef (-90, 1, 0, 0); // put Z going up
|
||||
glRotatef (90, 0, 0, 1); // put Z going up
|
||||
|
||||
glColor4fv (v_blend);
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
|
||||
glVertex3f (10, 100, 100);
|
||||
glVertex3f (10, -100, 100);
|
||||
glVertex3f (10, -100, -100);
|
||||
glVertex3f (10, 100, -100);
|
||||
glEnd ();
|
||||
|
||||
glDisable (GL_BLEND);
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
glEnable (GL_ALPHA_TEST);
|
||||
}
|
||||
|
||||
|
||||
int SignbitsForPlane (mplane_t *out)
|
||||
static int SignbitsForPlane (mplane_t *out)
|
||||
{
|
||||
int bits, j;
|
||||
|
||||
|
@ -773,7 +770,7 @@ int SignbitsForPlane (mplane_t *out)
|
|||
}
|
||||
|
||||
|
||||
void R_SetFrustum (void)
|
||||
static void R_SetFrustum (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -789,6 +786,7 @@ void R_SetFrustum (void)
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
// rotate VPN right by FOV_X/2 degrees
|
||||
RotatePointAroundVector( frustum[0].normal, vup, vpn, -(90-r_refdef.fov_x / 2 ) );
|
||||
// rotate VPN left by FOV_X/2 degrees
|
||||
|
@ -814,11 +812,11 @@ void R_SetFrustum (void)
|
|||
R_SetupFrame
|
||||
===============
|
||||
*/
|
||||
void R_SetupFrame (void)
|
||||
static void R_SetupFrame (void)
|
||||
{
|
||||
// don't allow cheats in multiplayer
|
||||
if (cl.maxclients > 1)
|
||||
Cvar_Set(r_fullbright, "0");
|
||||
r_fullbright->value = 0;
|
||||
r_lightmap->value = 0;
|
||||
|
||||
R_AnimateLight ();
|
||||
|
||||
|
@ -844,7 +842,7 @@ void R_SetupFrame (void)
|
|||
}
|
||||
|
||||
|
||||
void MYgluPerspective( GLdouble fovy, GLdouble aspect,
|
||||
static void MYgluPerspective( GLdouble fovy, GLdouble aspect,
|
||||
GLdouble zNear, GLdouble zFar )
|
||||
{
|
||||
GLdouble xmin, xmax, ymin, ymax;
|
||||
|
@ -864,7 +862,7 @@ void MYgluPerspective( GLdouble fovy, GLdouble aspect,
|
|||
R_SetupGL
|
||||
=============
|
||||
*/
|
||||
void R_SetupGL (void)
|
||||
static void R_SetupGL (void)
|
||||
{
|
||||
float screenaspect;
|
||||
extern int glwidth, glheight;
|
||||
|
@ -902,6 +900,9 @@ void R_SetupGL (void)
|
|||
glViewport (glx + x, gly + y2, w, h);
|
||||
screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height;
|
||||
// yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*180/M_PI;
|
||||
// yfov = (2.0 * tan (scr_fov->value/360*M_PI)) / screenaspect;
|
||||
// yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*(scr_fov->value*2)/M_PI;
|
||||
// MYgluPerspective (yfov, screenaspect, 4, 4096);
|
||||
MYgluPerspective (r_refdef.fov_y, screenaspect, 4, 4096);
|
||||
|
||||
if (mirror)
|
||||
|
@ -931,13 +932,15 @@ void R_SetupGL (void)
|
|||
// set drawing parms
|
||||
//
|
||||
if (gl_cull->value)
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable (GL_CULL_FACE);
|
||||
else
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable (GL_CULL_FACE);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable (GL_BLEND);
|
||||
glDisable (GL_ALPHA_TEST);
|
||||
glAlphaFunc (GL_GREATER, 0.5);
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glShadeModel (GL_SMOOTH);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -947,7 +950,7 @@ R_RenderScene
|
|||
r_refdef must be set before the first call
|
||||
================
|
||||
*/
|
||||
void R_RenderScene (void)
|
||||
static void R_RenderScene (void)
|
||||
{
|
||||
R_SetupFrame ();
|
||||
|
||||
|
@ -963,16 +966,9 @@ void R_RenderScene (void)
|
|||
|
||||
R_DrawEntitiesOnList ();
|
||||
|
||||
GL_DisableMultitexture();
|
||||
|
||||
R_RenderDlights ();
|
||||
|
||||
R_UpdateFires ();
|
||||
R_DrawParticles ();
|
||||
|
||||
#ifdef GLTEST
|
||||
Test_Draw ();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -981,32 +977,20 @@ void R_RenderScene (void)
|
|||
R_Clear
|
||||
=============
|
||||
*/
|
||||
void R_Clear (void)
|
||||
static void R_Clear (void)
|
||||
{
|
||||
if (r_mirroralpha->value != 1.0)
|
||||
{
|
||||
if (gl_clear->value)
|
||||
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
else
|
||||
glClear (GL_DEPTH_BUFFER_BIT);
|
||||
gldepthmin = 0;
|
||||
gldepthmax = 0.5;
|
||||
glDepthFunc (GL_LEQUAL);
|
||||
}
|
||||
if (gl_clear->value)
|
||||
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
else
|
||||
{
|
||||
if (gl_clear->value)
|
||||
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
else
|
||||
glClear (GL_DEPTH_BUFFER_BIT);
|
||||
gldepthmin = 0;
|
||||
gldepthmax = 1;
|
||||
glDepthFunc (GL_LEQUAL);
|
||||
}
|
||||
glClear (GL_DEPTH_BUFFER_BIT);
|
||||
gldepthmin = 0;
|
||||
gldepthmax = 1;
|
||||
glDepthFunc (GL_LEQUAL);
|
||||
|
||||
glDepthRange (gldepthmin, gldepthmax);
|
||||
}
|
||||
|
||||
#if 0 //!!! FIXME, Zoid, mirror is disabled for now
|
||||
/*
|
||||
=============
|
||||
R_Mirror
|
||||
|
@ -1048,13 +1032,13 @@ void R_Mirror (void)
|
|||
R_RenderScene ();
|
||||
R_DrawWaterSurfaces ();
|
||||
|
||||
|
||||
gldepthmin = 0;
|
||||
gldepthmax = 0.5;
|
||||
glDepthRange (gldepthmin, gldepthmax);
|
||||
glDepthFunc (GL_LEQUAL);
|
||||
|
||||
// blend on top
|
||||
glEnable (GL_BLEND);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
if (mirror_plane->normal[2])
|
||||
glScalef (1,-1,1);
|
||||
|
@ -1070,9 +1054,9 @@ void R_Mirror (void)
|
|||
for ( ; s ; s=s->texturechain)
|
||||
R_RenderBrushPoly (s);
|
||||
cl.worldmodel->textures[mirrortexturenum]->texturechain = NULL;
|
||||
glDisable (GL_BLEND);
|
||||
glColor4f (1,1,1,1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
================
|
||||
|
@ -1083,56 +1067,23 @@ r_refdef must be set before the first call
|
|||
*/
|
||||
void R_RenderView (void)
|
||||
{
|
||||
double time1=0, time2;
|
||||
|
||||
if (r_norefresh->value)
|
||||
return;
|
||||
|
||||
if (!r_worldentity.model || !cl.worldmodel)
|
||||
Sys_Error ("R_RenderView: NULL worldmodel");
|
||||
|
||||
if (r_speeds->value)
|
||||
{
|
||||
glFinish ();
|
||||
time1 = Sys_DoubleTime ();
|
||||
c_brush_polys = 0;
|
||||
c_alias_polys = 0;
|
||||
}
|
||||
// glFinish ();
|
||||
|
||||
mirror = false;
|
||||
|
||||
if (gl_finish->value)
|
||||
glFinish ();
|
||||
|
||||
R_Clear ();
|
||||
|
||||
// render normal view
|
||||
|
||||
/***** Experimental silly looking fog ******
|
||||
****** Use r_fullbright if you enable ******
|
||||
glFogi(GL_FOG_MODE, GL_LINEAR);
|
||||
glFogfv(GL_FOG_COLOR, colors);
|
||||
glFogf(GL_FOG_END, 512.0);
|
||||
glEnable(GL_FOG);
|
||||
********************************************/
|
||||
|
||||
R_RenderScene ();
|
||||
R_DrawViewModel ();
|
||||
R_DrawWaterSurfaces ();
|
||||
|
||||
// More fog right here :)
|
||||
// glDisable(GL_FOG);
|
||||
// End of all fog code...
|
||||
|
||||
// render mirror view
|
||||
R_Mirror ();
|
||||
|
||||
R_PolyBlend ();
|
||||
|
||||
if (r_speeds->value)
|
||||
{
|
||||
// glFinish ();
|
||||
time2 = Sys_DoubleTime ();
|
||||
Con_Printf ("%3i ms %4i wpoly %4i epoly\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys);
|
||||
}
|
||||
// R_Mirror ();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
gl_rmisc.c
|
||||
|
||||
@description@
|
||||
(description)
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
|
@ -30,11 +30,37 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "glquake.h"
|
||||
#include "client.h"
|
||||
#include "r_local.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "bspfile.h" // needed by: glquake.h
|
||||
#include "vid.h"
|
||||
#include "sys.h"
|
||||
#include "mathlib.h" // needed by: protocol.h, render.h, client.h,
|
||||
// modelgen.h, glmodel.h
|
||||
#include "wad.h"
|
||||
#include "draw.h"
|
||||
#include "cvar.h"
|
||||
#include "net.h" // needed by: client.h
|
||||
#include "protocol.h" // needed by: client.h
|
||||
#include "cmd.h"
|
||||
#include "sbar.h"
|
||||
#include "render.h" // needed by: client.h, gl_model.h, glquake.h
|
||||
#include "client.h" // need cls in this file
|
||||
#include "model.h" // needed by: glquake.h
|
||||
#include "console.h"
|
||||
#include "glquake.h"
|
||||
#include "r_local.h"
|
||||
|
||||
qboolean VID_Is8bit(void);
|
||||
void R_InitBubble();
|
||||
void R_FireColor_f(void);
|
||||
|
||||
cvar_t *gl_fires;
|
||||
qboolean allowskybox; // allow skyboxes? --KB
|
||||
|
||||
/*
|
||||
==================
|
||||
|
@ -175,16 +201,37 @@ void R_Envmap_f (void)
|
|||
GL_EndRendering ();
|
||||
}
|
||||
|
||||
/*
|
||||
R_LoadSky_f
|
||||
*/
|
||||
void
|
||||
R_LoadSky_f (void)
|
||||
{
|
||||
if (Cmd_Argc () != 2)
|
||||
{
|
||||
Con_Printf ("loadsky <name> : load a skybox\n");
|
||||
return;
|
||||
}
|
||||
|
||||
R_LoadSkys (Cmd_Argv(1));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
R_Init
|
||||
===============
|
||||
*/
|
||||
void R_Init (void)
|
||||
{
|
||||
{
|
||||
allowskybox = false; // server will decide if this is allowed --KB
|
||||
|
||||
Cmd_AddCommand ("timerefresh", R_TimeRefresh_f);
|
||||
Cmd_AddCommand ("envmap", R_Envmap_f);
|
||||
Cmd_AddCommand ("pointfile", R_ReadPointFile_f);
|
||||
Cmd_AddCommand ("pointfile", R_ReadPointFile_f);
|
||||
Cmd_AddCommand ("loadsky", R_LoadSky_f);
|
||||
|
||||
Cmd_AddCommand ("r_firecolor", R_FireColor_f);
|
||||
|
||||
r_norefresh = Cvar_Get("r_norefresh", "0", CVAR_NONE, "None");
|
||||
r_lightmap = Cvar_Get("r_lightmap", "0", CVAR_NONE, "None");
|
||||
|
@ -194,14 +241,15 @@ void R_Init (void)
|
|||
r_shadows = Cvar_Get("r_shadows", "0", CVAR_NONE, "None");
|
||||
r_mirroralpha = Cvar_Get("r_mirroralpha", "1", CVAR_NONE, "None");
|
||||
r_wateralpha = Cvar_Get("r_wateralpha", "1", CVAR_NONE, "None");
|
||||
r_waterripple = Cvar_Get ("r_waterripple", "0", CVAR_NONE, "None");
|
||||
r_dynamic = Cvar_Get("r_dynamic", "1", CVAR_NONE, "None");
|
||||
r_novis = Cvar_Get("r_novis", "0", CVAR_NONE, "None");
|
||||
r_speeds = Cvar_Get("r_speeds", "0", CVAR_NONE, "None");
|
||||
r_netgraph = Cvar_Get("r_netgraph", "0", CVAR_NONE, "None");
|
||||
|
||||
gl_finish = Cvar_Get("gl_finish", "0", CVAR_NONE, "None");
|
||||
gl_clear = Cvar_Get("gl_clear", "0", CVAR_NONE, "None");
|
||||
gl_texsort = Cvar_Get("gl_texsort", "1", CVAR_NONE, "None");
|
||||
|
||||
|
||||
if (gl_mtexable)
|
||||
Cvar_SetValue(gl_texsort, 0.0);
|
||||
|
||||
|
@ -209,7 +257,7 @@ void R_Init (void)
|
|||
gl_smoothmodels = Cvar_Get("gl_smoothmodels", "1", CVAR_NONE, "None");
|
||||
gl_affinemodels = Cvar_Get("gl_affinemodels", "0", CVAR_NONE, "None");
|
||||
gl_polyblend = Cvar_Get("gl_polyblend", "1", CVAR_NONE, "None");
|
||||
gl_flashblend = Cvar_Get("gl_flashblend", "1", CVAR_NONE, "None");
|
||||
gl_flashblend = Cvar_Get("gl_flashblend", "0", CVAR_NONE, "None");
|
||||
gl_playermip = Cvar_Get("gl_playermip", "0", CVAR_NONE, "None");
|
||||
gl_nocolors = Cvar_Get("gl_nocolors", "0", CVAR_NONE, "None");
|
||||
|
||||
|
@ -219,18 +267,23 @@ void R_Init (void)
|
|||
gl_particles = Cvar_Get ("gl_particles", "1", CVAR_ARCHIVE,
|
||||
"whether or not to draw particles");
|
||||
|
||||
gl_keeptjunctions = Cvar_Get("gl_keeptjunctions", "0", CVAR_NONE, "None");
|
||||
gl_fb_models = Cvar_Get ("gl_fb_models", "1", CVAR_ARCHIVE,
|
||||
"Toggles fullbright color support for models.. "
|
||||
"This is very handy, but costs me 2 FPS.. (=:]");
|
||||
|
||||
gl_keeptjunctions = Cvar_Get("gl_keeptjunctions", "1", CVAR_NONE, "None");
|
||||
gl_reporttjunctions = Cvar_Get("gl_reporttjunctions", "0", CVAR_NONE, "None");
|
||||
|
||||
r_skyname = Cvar_Get("r_skyname", "none", CVAR_NONE,
|
||||
"name of the current skybox");
|
||||
gl_skymultipass = Cvar_Get("gl_skymultipass", "1", CVAR_NONE,
|
||||
"controls wether the skydome is single or double pass");
|
||||
|
||||
gl_doubleeyes = Cvar_Get("gl_doubleeys", "1", CVAR_NONE, "None");
|
||||
|
||||
R_InitBubble();
|
||||
|
||||
R_InitParticles ();
|
||||
R_InitParticleTexture ();
|
||||
|
||||
#ifdef GLTEST
|
||||
Test_Init ();
|
||||
#endif
|
||||
|
||||
playertextures = texture_extension_number;
|
||||
texture_extension_number += 16;
|
||||
}
|
||||
|
@ -257,8 +310,6 @@ void R_TranslatePlayerSkin (int playernum)
|
|||
byte *inrow;
|
||||
unsigned frac, fracstep;
|
||||
|
||||
GL_DisableMultitexture();
|
||||
|
||||
top = cl.scores[playernum].colors & 0xf0;
|
||||
bottom = (cl.scores[playernum].colors &15)<<4;
|
||||
|
||||
|
@ -284,10 +335,10 @@ void R_TranslatePlayerSkin (int playernum)
|
|||
currententity = &cl_entities[1+playernum];
|
||||
model = currententity->model;
|
||||
if (!model)
|
||||
return; // player doesn't have a model yet
|
||||
return; // player doesn't have a model yet
|
||||
if (model->type != mod_alias)
|
||||
return; // only translate skins on alias models
|
||||
|
||||
|
||||
paliashdr = (aliashdr_t *)Mod_Extradata (model);
|
||||
s = paliashdr->skinwidth * paliashdr->skinheight;
|
||||
if (currententity->skinnum < 0 || currententity->skinnum >= paliashdr->numskins) {
|
||||
|
@ -297,13 +348,13 @@ void R_TranslatePlayerSkin (int playernum)
|
|||
original = (byte *)paliashdr + paliashdr->texels[currententity->skinnum];
|
||||
if (s & 3)
|
||||
Sys_Error ("R_TranslateSkin: s&3");
|
||||
|
||||
|
||||
inwidth = paliashdr->skinwidth;
|
||||
inheight = paliashdr->skinheight;
|
||||
|
||||
|
||||
// because this happens during gameplay, do it fast
|
||||
// instead of sending it through gl_upload 8
|
||||
glBindTexture (GL_TEXTURE_2D, playertextures + playernum);
|
||||
glBindTexture (GL_TEXTURE_2D, playertextures + playernum);
|
||||
|
||||
#if 0
|
||||
byte translated[320*200];
|
||||
|
@ -381,10 +432,8 @@ void R_TranslatePlayerSkin (int playernum)
|
|||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
R_NewMap
|
||||
|
@ -393,6 +442,7 @@ R_NewMap
|
|||
void R_NewMap (void)
|
||||
{
|
||||
int i;
|
||||
cvar_t *r_skyname;
|
||||
|
||||
for (i=0 ; i<256 ; i++)
|
||||
d_lightstylevalue[i] = 264; // normal light value
|
||||
|
@ -423,9 +473,11 @@ void R_NewMap (void)
|
|||
mirrortexturenum = i;
|
||||
cl.worldmodel->textures[i]->texturechain = NULL;
|
||||
}
|
||||
#ifdef QUAKE2
|
||||
R_LoadSkys ();
|
||||
#endif
|
||||
r_skyname = Cvar_FindVar ("r_skyname");
|
||||
if (r_skyname != NULL)
|
||||
R_LoadSkys (r_skyname->string);
|
||||
else
|
||||
R_LoadSkys ("none");
|
||||
}
|
||||
|
||||
|
||||
|
@ -436,28 +488,34 @@ R_TimeRefresh_f
|
|||
For program optimization
|
||||
====================
|
||||
*/
|
||||
// LordHavoc: improved appearance and accuracy of timerefresh
|
||||
void R_TimeRefresh_f (void)
|
||||
{
|
||||
int i;
|
||||
float start, stop, time;
|
||||
double start, stop, time;
|
||||
|
||||
glDrawBuffer (GL_FRONT);
|
||||
// glDrawBuffer (GL_FRONT);
|
||||
glFinish ();
|
||||
GL_EndRendering ();
|
||||
|
||||
start = Sys_DoubleTime ();
|
||||
for (i=0 ; i<128 ; i++)
|
||||
{
|
||||
GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
|
||||
r_refdef.viewangles[1] = i/128.0*360.0;
|
||||
R_RenderView ();
|
||||
glFinish ();
|
||||
GL_EndRendering ();
|
||||
}
|
||||
|
||||
glFinish ();
|
||||
// glFinish ();
|
||||
stop = Sys_DoubleTime ();
|
||||
time = stop-start;
|
||||
Con_Printf ("%f seconds (%f fps)\n", time, 128/time);
|
||||
|
||||
glDrawBuffer (GL_BACK);
|
||||
GL_EndRendering ();
|
||||
// glDrawBuffer (GL_BACK);
|
||||
// GL_EndRendering ();
|
||||
GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
|
||||
}
|
||||
|
||||
void D_FlushCaches (void)
|
||||
|
|
1289
source/gl_rsurf.c
1289
source/gl_rsurf.c
File diff suppressed because it is too large
Load diff
865
source/gl_warp.c
865
source/gl_warp.c
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
gl_warp.c
|
||||
|
||||
@description@
|
||||
sky and water polygons
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
|
@ -30,20 +30,38 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "qtypes.h"
|
||||
#include "console.h"
|
||||
#include "model.h"
|
||||
#include "quakefs.h"
|
||||
#include "glquake.h"
|
||||
#include "sys.h"
|
||||
#include "host.h"
|
||||
|
||||
extern double realtime;
|
||||
extern model_t *loadmodel;
|
||||
|
||||
int skytexturenum;
|
||||
extern int skytexturenum;
|
||||
extern qboolean lighthalf;
|
||||
|
||||
int solidskytexture;
|
||||
int alphaskytexture;
|
||||
float speedscale; // for top sky and bottom sky
|
||||
int solidskytexture;
|
||||
int alphaskytexture;
|
||||
float speedscale; // for top sky and bottom sky
|
||||
|
||||
// Set to true if a valid skybox is loaded --KB
|
||||
qboolean skyloaded = false;
|
||||
|
||||
msurface_t *warpface;
|
||||
|
||||
extern cvar_t *gl_subdivide_size;
|
||||
|
||||
void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs)
|
||||
{
|
||||
int i, j;
|
||||
|
@ -190,7 +208,7 @@ void GL_SubdivideSurface (msurface_t *fa)
|
|||
// speed up sin calculations - Ed
|
||||
float turbsin[] =
|
||||
{
|
||||
#include "gl_warp_sin.h"
|
||||
# include "gl_warp_sin.h"
|
||||
};
|
||||
#define TURBSCALE (256.0 / (2 * M_PI))
|
||||
|
||||
|
@ -207,7 +225,7 @@ void EmitWaterPolys (msurface_t *fa)
|
|||
float *v;
|
||||
int i;
|
||||
float s, t, os, ot;
|
||||
|
||||
vec3_t nv;
|
||||
|
||||
for (p=fa->polys ; p ; p=p->next)
|
||||
{
|
||||
|
@ -224,116 +242,20 @@ void EmitWaterPolys (msurface_t *fa)
|
|||
t *= (1.0/64);
|
||||
|
||||
glTexCoord2f (s, t);
|
||||
glVertex3fv (v);
|
||||
|
||||
VectorCopy (v, nv);
|
||||
nv[2] += r_waterripple->value
|
||||
* turbsin[(int)((v[3]*0.125+realtime) * TURBSCALE) & 255]
|
||||
* turbsin[(int)((v[4]*0.125+realtime) * TURBSCALE) & 255]
|
||||
* (1.0 / 64.0);
|
||||
|
||||
glVertex3fv (nv);
|
||||
}
|
||||
glEnd ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
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();
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, solidskytexture);
|
||||
speedscale = realtime*8;
|
||||
speedscale -= (int)speedscale & ~127 ;
|
||||
|
||||
EmitSkyPolys (fa);
|
||||
|
||||
glEnable (GL_BLEND);
|
||||
glBindTexture (GL_TEXTURE_2D, alphaskytexture);
|
||||
speedscale = realtime*16;
|
||||
speedscale -= (int)speedscale & ~127 ;
|
||||
|
||||
EmitSkyPolys (fa);
|
||||
|
||||
glDisable (GL_BLEND);
|
||||
}
|
||||
|
||||
#ifndef QUAKE2
|
||||
/*
|
||||
=================
|
||||
R_DrawSkyChain
|
||||
=================
|
||||
*/
|
||||
void R_DrawSkyChain (msurface_t *s)
|
||||
{
|
||||
msurface_t *fa;
|
||||
|
||||
GL_DisableMultitexture();
|
||||
|
||||
// used when gl_texsort is on
|
||||
glBindTexture (GL_TEXTURE_2D, solidskytexture);
|
||||
speedscale = realtime*8;
|
||||
speedscale -= (int)speedscale & ~127 ;
|
||||
|
||||
for (fa=s ; fa ; fa=fa->texturechain)
|
||||
EmitSkyPolys (fa);
|
||||
|
||||
glEnable (GL_BLEND);
|
||||
glBindTexture (GL_TEXTURE_2D, alphaskytexture);
|
||||
speedscale = realtime*16;
|
||||
speedscale -= (int)speedscale & ~127 ;
|
||||
|
||||
for (fa=s ; fa ; fa=fa->texturechain)
|
||||
EmitSkyPolys (fa);
|
||||
|
||||
glDisable (GL_BLEND);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
=================================================================
|
||||
|
||||
|
@ -342,107 +264,8 @@ void R_DrawSkyChain (msurface_t *s)
|
|||
=================================================================
|
||||
*/
|
||||
|
||||
#ifdef QUAKE2
|
||||
|
||||
|
||||
#define SKY_TEX 2000
|
||||
|
||||
/*
|
||||
=================================================================
|
||||
|
||||
PCX Loading
|
||||
|
||||
=================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char manufacturer;
|
||||
char version;
|
||||
char encoding;
|
||||
char bits_per_pixel;
|
||||
unsigned short xmin,ymin,xmax,ymax;
|
||||
unsigned short hres,vres;
|
||||
unsigned char palette[48];
|
||||
char reserved;
|
||||
char color_planes;
|
||||
unsigned short bytes_per_line;
|
||||
unsigned short palette_type;
|
||||
char filler[58];
|
||||
unsigned data; // unbounded
|
||||
} pcx_t;
|
||||
|
||||
byte *pcx_rgb;
|
||||
|
||||
/*
|
||||
============
|
||||
LoadPCX
|
||||
============
|
||||
*/
|
||||
void LoadPCX (FILE *f)
|
||||
{
|
||||
pcx_t *pcx, pcxbuf;
|
||||
byte palette[768];
|
||||
byte *pix;
|
||||
int x, y;
|
||||
int dataByte, runLength;
|
||||
int count;
|
||||
|
||||
//
|
||||
// parse the PCX file
|
||||
//
|
||||
fread (&pcxbuf, 1, sizeof(pcxbuf), f);
|
||||
|
||||
pcx = &pcxbuf;
|
||||
|
||||
if (pcx->manufacturer != 0x0a
|
||||
|| pcx->version != 5
|
||||
|| pcx->encoding != 1
|
||||
|| pcx->bits_per_pixel != 8
|
||||
|| pcx->xmax >= 320
|
||||
|| pcx->ymax >= 256)
|
||||
{
|
||||
Con_Printf ("Bad pcx file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// seek to palette
|
||||
fseek (f, -768, SEEK_END);
|
||||
fread (palette, 1, 768, f);
|
||||
|
||||
fseek (f, sizeof(pcxbuf) - 4, SEEK_SET);
|
||||
|
||||
count = (pcx->xmax+1) * (pcx->ymax+1);
|
||||
pcx_rgb = malloc( count * 4);
|
||||
|
||||
for (y=0 ; y<=pcx->ymax ; y++)
|
||||
{
|
||||
pix = pcx_rgb + 4*y*(pcx->xmax+1);
|
||||
for (x=0 ; x<=pcx->ymax ; )
|
||||
{
|
||||
dataByte = fgetc(f);
|
||||
|
||||
if((dataByte & 0xC0) == 0xC0)
|
||||
{
|
||||
runLength = dataByte & 0x3F;
|
||||
dataByte = fgetc(f);
|
||||
}
|
||||
else
|
||||
runLength = 1;
|
||||
|
||||
while(runLength-- > 0)
|
||||
{
|
||||
pix[0] = palette[dataByte*3];
|
||||
pix[1] = palette[dataByte*3+1];
|
||||
pix[2] = palette[dataByte*3+2];
|
||||
pix[3] = 255;
|
||||
pix += 4;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=========================================================
|
||||
|
||||
|
@ -496,6 +319,7 @@ void LoadTGA (FILE *fin)
|
|||
int columns, rows, numPixels;
|
||||
byte *pixbuf;
|
||||
int row, column;
|
||||
unsigned char red = 0, green = 0, blue = 0, alphabyte = 0;
|
||||
|
||||
targa_header.id_length = fgetc(fin);
|
||||
targa_header.colormap_type = fgetc(fin);
|
||||
|
@ -532,7 +356,6 @@ void LoadTGA (FILE *fin)
|
|||
for(row=rows-1; row>=0; row--) {
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
for(column=0; column<columns; column++) {
|
||||
unsigned char red,green,blue,alphabyte;
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
|
||||
|
@ -559,7 +382,7 @@ void LoadTGA (FILE *fin)
|
|||
}
|
||||
}
|
||||
else if (targa_header.image_type==10) { // Runlength encoded RGB images
|
||||
unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
|
||||
unsigned char packetHeader, packetSize, j;
|
||||
for(row=rows-1; row>=0; row--) {
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
for(column=0; column<columns; ) {
|
||||
|
@ -645,388 +468,241 @@ R_LoadSkys
|
|||
==================
|
||||
*/
|
||||
char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
|
||||
void R_LoadSkys (void)
|
||||
void R_LoadSkys (char * skyname)
|
||||
{
|
||||
int i;
|
||||
FILE *f;
|
||||
char name[64];
|
||||
|
||||
if (stricmp (skyname, "none") == 0)
|
||||
{
|
||||
skyloaded = false;
|
||||
return;
|
||||
}
|
||||
|
||||
skyloaded = true;
|
||||
for (i=0 ; i<6 ; i++)
|
||||
{
|
||||
glBindTexture (GL_TEXTURE_2D, SKY_TEX + i);
|
||||
sprintf (name, "gfx/env/bkgtst%s.tga", suf[i]);
|
||||
snprintf (name, sizeof(name),"env/%s%s.tga", skyname, suf[i]);
|
||||
COM_FOpenFile (name, &f);
|
||||
if (!f)
|
||||
{
|
||||
Con_Printf ("Couldn't load %s\n", name);
|
||||
Con_DPrintf ("Couldn't load %s\n", name);
|
||||
skyloaded = false;
|
||||
continue;
|
||||
}
|
||||
LoadTGA (f);
|
||||
// LoadPCX (f);
|
||||
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, targa_rgba);
|
||||
// glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, pcx_rgb);
|
||||
|
||||
free (targa_rgba);
|
||||
// free (pcx_rgb);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
if (!skyloaded)
|
||||
Con_Printf ("Unable to load skybox %s, using normal sky\n",
|
||||
skyname);
|
||||
}
|
||||
|
||||
|
||||
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] =
|
||||
void
|
||||
R_SkyBoxPolyVec(vec5_t v)
|
||||
{
|
||||
{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);
|
||||
// avoid interpolation seams
|
||||
// s = s * (254.0/256.0) + (1.0/256.0);
|
||||
// t = t * (254.0/256.0) + (1.0/256.0);
|
||||
glTexCoord2fv (v);
|
||||
glVertex3f (r_refdef.vieworg[0] + v[2],
|
||||
r_refdef.vieworg[1] + v[3],
|
||||
r_refdef.vieworg[2] + v[4]);
|
||||
}
|
||||
glEnd();
|
||||
return;
|
||||
#endif
|
||||
// decide which face it maps to
|
||||
VectorCopy (vec3_origin, v);
|
||||
for (i=0, vp=vecs ; i<nump ; i++, vp+=3)
|
||||
|
||||
#define ftc(x) (x * (254.0/256.0) + (1.0/256.0))
|
||||
|
||||
vec5_t skyvec[6][4] = {
|
||||
{
|
||||
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])
|
||||
// right
|
||||
{ftc(1), ftc(0), 1024, 1024, 1024},
|
||||
{ftc(1), ftc(1), 1024, 1024, -1024},
|
||||
{ftc(0), ftc(1), -1024, 1024, -1024},
|
||||
{ftc(0), ftc(0), -1024, 1024, 1024}
|
||||
},
|
||||
{
|
||||
if (v[0] < 0)
|
||||
axis = 1;
|
||||
else
|
||||
axis = 0;
|
||||
}
|
||||
else if (av[1] > av[2] && av[1] > av[0])
|
||||
// back
|
||||
{ftc(1), ftc(0), -1024, 1024, 1024},
|
||||
{ftc(1), ftc(1), -1024, 1024, -1024},
|
||||
{ftc(0), ftc(1), -1024, -1024, -1024},
|
||||
{ftc(0), ftc(0), -1024, -1024, 1024}
|
||||
},
|
||||
{
|
||||
if (v[1] < 0)
|
||||
axis = 3;
|
||||
else
|
||||
axis = 2;
|
||||
// left
|
||||
{ftc(1), ftc(0), -1024, -1024, 1024},
|
||||
{ftc(1), ftc(1), -1024, -1024, -1024},
|
||||
{ftc(0), ftc(1), 1024, -1024, -1024},
|
||||
{ftc(0), ftc(0), 1024, -1024, 1024}
|
||||
},
|
||||
{
|
||||
// front
|
||||
{ftc(1), ftc(0), 1024, -1024, 1024},
|
||||
{ftc(1), ftc(1), 1024, -1024, -1024},
|
||||
{ftc(0), ftc(1), 1024, 1024, -1024},
|
||||
{ftc(0), ftc(0), 1024, 1024, 1024}
|
||||
},
|
||||
{
|
||||
// up
|
||||
{ftc(1), ftc(0), 1024, -1024, 1024},
|
||||
{ftc(1), ftc(1), 1024, 1024, 1024},
|
||||
{ftc(0), ftc(1), -1024, 1024, 1024},
|
||||
{ftc(0), ftc(0), -1024, -1024, 1024}
|
||||
},
|
||||
{
|
||||
// down
|
||||
{ftc(1), ftc(0), 1024, 1024, -1024},
|
||||
{ftc(1), ftc(1), 1024, -1024, -1024},
|
||||
{ftc(0), ftc(1), -1024, -1024, -1024},
|
||||
{ftc(0), ftc(0), -1024, 1024, -1024}
|
||||
}
|
||||
};
|
||||
|
||||
#undef ftc
|
||||
|
||||
void
|
||||
R_DrawSkyBox (void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glDepthFunc (GL_ALWAYS);
|
||||
// glDisable (GL_BLEND);
|
||||
// glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glDepthRange (gldepthmax, gldepthmax);
|
||||
if (lighthalf)
|
||||
glColor3f(0.5,0.5,0.5);
|
||||
else
|
||||
glColor3f(1,1,1);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
if (v[2] < 0)
|
||||
axis = 5;
|
||||
else
|
||||
axis = 4;
|
||||
glBindTexture(GL_TEXTURE_2D, SKY_TEX + i);
|
||||
glBegin(GL_QUADS);
|
||||
for (j = 0; j < 4; j++)
|
||||
R_SkyBoxPolyVec(skyvec[i][j]);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// 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];
|
||||
|
||||
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_DrawSkyChain (msurface_t *s)
|
||||
{
|
||||
msurface_t *fa;
|
||||
|
||||
int i;
|
||||
vec3_t verts[MAX_CLIP_VERTS];
|
||||
glpoly_t *p;
|
||||
|
||||
c_sky = 0;
|
||||
glBindTexture (GL_TEXTURE_2D, 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);
|
||||
}
|
||||
}
|
||||
glColor3f (1,1,1);
|
||||
glDepthFunc (GL_LEQUAL);
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glDepthRange(gldepthmin, gldepthmax);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
R_ClearSkyBox
|
||||
==============
|
||||
*/
|
||||
void R_ClearSkyBox (void)
|
||||
vec3_t domescale;
|
||||
void
|
||||
R_DrawSkyLayer (float s)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0 ; i<6 ; i++)
|
||||
int a, b;
|
||||
float x, y, a1x, a1y, a2x, a2y;
|
||||
vec3_t v;
|
||||
|
||||
for (a = 0; a < 16; a++)
|
||||
{
|
||||
skymins[0][i] = skymins[1][i] = 9999;
|
||||
skymaxs[0][i] = skymaxs[1][i] = -9999;
|
||||
}
|
||||
}
|
||||
a1x = bubble_costable[a*2];
|
||||
a1y = -bubble_sintable[a*2];
|
||||
a2x = bubble_costable[(a+1)*2];
|
||||
a2y = -bubble_sintable[(a+1)*2];
|
||||
|
||||
glBegin (GL_TRIANGLE_STRIP);
|
||||
glTexCoord2f(0.5 + s * (1.0 / 128.0), 0.5 + s * (1.0 / 128.0));
|
||||
glVertex3f(r_refdef.vieworg[0],
|
||||
r_refdef.vieworg[1],
|
||||
r_refdef.vieworg[2]+domescale[2]);
|
||||
for (b = 1; b < 8; b++)
|
||||
{
|
||||
x = bubble_costable[b*2+16];
|
||||
y = -bubble_sintable[b*2+16];
|
||||
|
||||
void MakeSkyVec (float s, float t, int axis)
|
||||
{
|
||||
vec3_t v, b;
|
||||
int j, k;
|
||||
v[0] = a1x*x * domescale[0];
|
||||
v[1] = a1y*x * domescale[1];
|
||||
v[2] = y * domescale[2];
|
||||
glTexCoord2f((v[0] + s) * (1.0 / 128.0),
|
||||
(v[1] + s) * (1.0 / 128.0));
|
||||
glVertex3f(v[0] + r_refdef.vieworg[0],
|
||||
v[1] + r_refdef.vieworg[1],
|
||||
v[2] + r_refdef.vieworg[2]);
|
||||
|
||||
b[0] = s*2048;
|
||||
b[1] = t*2048;
|
||||
b[2] = 2048;
|
||||
|
||||
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 (void)
|
||||
{
|
||||
int i, j, k;
|
||||
vec3_t v;
|
||||
float s, t;
|
||||
|
||||
#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;
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, SKY_TEX+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);
|
||||
v[0] = a2x*x * domescale[0];
|
||||
v[1] = a2y*x * domescale[1];
|
||||
v[2] = y * domescale[2];
|
||||
glTexCoord2f((v[0] + s) * (1.0 / 128.0),
|
||||
(v[1] + s) * (1.0 / 128.0));
|
||||
glVertex3f(v[0] + r_refdef.vieworg[0],
|
||||
v[1] + r_refdef.vieworg[1],
|
||||
v[2] + r_refdef.vieworg[2]);
|
||||
}
|
||||
glTexCoord2f(0.5 + s * (1.0 / 128.0), 0.5 + s * (1.0 / 128.0));
|
||||
glVertex3f(r_refdef.vieworg[0],
|
||||
r_refdef.vieworg[1],
|
||||
r_refdef.vieworg[2]-domescale[2]);
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
void
|
||||
R_DrawSkyDome (void)
|
||||
{
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glDepthFunc (GL_ALWAYS);
|
||||
// glDisable (GL_BLEND);
|
||||
// glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDepthRange (gldepthmax, gldepthmax);
|
||||
glDisable (GL_BLEND);
|
||||
if (lighthalf)
|
||||
glColor3f(0.5,0.5,0.5);
|
||||
else
|
||||
glColor3f(1,1,1);
|
||||
|
||||
// base sky
|
||||
glBindTexture (GL_TEXTURE_2D, solidskytexture);
|
||||
domescale[0] = 512;
|
||||
domescale[1] = 512;
|
||||
domescale[2] = 128;
|
||||
speedscale = realtime*8;
|
||||
speedscale -= (int)speedscale & ~127;
|
||||
R_DrawSkyLayer (speedscale);
|
||||
glEnable (GL_BLEND);
|
||||
|
||||
// clouds
|
||||
if (gl_skymultipass->value) {
|
||||
glBindTexture (GL_TEXTURE_2D, alphaskytexture);
|
||||
domescale[0] = 512;
|
||||
domescale[1] = 512;
|
||||
domescale[2] = 128;
|
||||
speedscale = realtime*16;
|
||||
speedscale -= (int)speedscale & ~127;
|
||||
R_DrawSkyLayer (speedscale);
|
||||
}
|
||||
|
||||
// glDisable (GL_BLEND);
|
||||
glColor3f (1,1,1);
|
||||
glDepthFunc (GL_LEQUAL);
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glDepthRange (gldepthmin, gldepthmax);
|
||||
}
|
||||
|
||||
void
|
||||
R_DrawSky ( void )
|
||||
{
|
||||
if (skyloaded)
|
||||
R_DrawSkyBox();
|
||||
else
|
||||
R_DrawSkyDome();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===============================================================
|
||||
|
||||
|
@ -1095,3 +771,96 @@ void R_InitSky (texture_t *mt)
|
|||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
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 ();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_DrawSkyChain
|
||||
=================
|
||||
*/
|
||||
void R_DrawSkyChain (msurface_t *s)
|
||||
{
|
||||
msurface_t *fa;
|
||||
|
||||
// used when gl_texsort is on
|
||||
glBindTexture (GL_TEXTURE_2D, solidskytexture);
|
||||
speedscale = realtime*8;
|
||||
speedscale -= (int)speedscale & ~127 ;
|
||||
|
||||
for (fa=s ; fa ; fa=fa->texturechain)
|
||||
EmitSkyPolys (fa);
|
||||
|
||||
glEnable (GL_BLEND);
|
||||
glBindTexture (GL_TEXTURE_2D, alphaskytexture);
|
||||
speedscale = realtime*16;
|
||||
speedscale -= (int)speedscale & ~127 ;
|
||||
|
||||
for (fa=s ; fa ; fa=fa->texturechain)
|
||||
EmitSkyPolys (fa);
|
||||
|
||||
glDisable (GL_BLEND);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
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)
|
||||
{
|
||||
glBindTexture (GL_TEXTURE_2D, solidskytexture);
|
||||
speedscale = realtime*8;
|
||||
speedscale -= (int)speedscale & ~127 ;
|
||||
|
||||
EmitSkyPolys (fa);
|
||||
|
||||
glEnable (GL_BLEND);
|
||||
glBindTexture (GL_TEXTURE_2D, alphaskytexture);
|
||||
speedscale = realtime*16;
|
||||
speedscale -= (int)speedscale & ~127 ;
|
||||
|
||||
EmitSkyPolys (fa);
|
||||
|
||||
glDisable (GL_BLEND);
|
||||
}
|
||||
|
|
|
@ -705,7 +705,7 @@ void VID_Init(unsigned char *palette)
|
|||
snprintf(gldir, sizeof(gldir), "%s/glquake", com_gamedir);
|
||||
Sys_mkdir (gldir);
|
||||
|
||||
//XXXGL_CheckGamma (palette);
|
||||
GL_CheckGamma (palette);
|
||||
VID_SetPalette (palette);
|
||||
|
||||
// Check for 3DFX Extensions and initialize them.
|
||||
|
|
Loading…
Reference in a new issue