3
*************************************************************************
5
ArmageTron -- Just another Tron Lightcycle Game in 3D.
6
Copyright (C) 2000 Manuel Moos (manuel@moosnet.de)
8
**************************************************************************
10
This program is free software; you can redistribute it and/or
11
modify it under the terms of the GNU General Public License
12
as published by the Free Software Foundation; either version 2
13
of the License, or (at your option) any later version.
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License
21
along with this program; if not, write to the Free Software
22
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
***************************************************************************
28
//void se_FetchAndStoreSDLInput();
32
#include "tConfiguration.h"
36
static REAL sr_floorMirror_strength=.1;
37
static tSettingItem<REAL> f_m("FLOOR_MIRROR_INT",sr_floorMirror_strength);
39
#include "tEventQueue.h"
40
#include "uInputQueue.h"
43
#include "eGameObject.h"
54
#include "eDebugLine.h"
55
#include "tDirectories.h"
56
#include "eRectangle.h"
65
REAL upper_height=100;
71
static rFileTexture sky(rTextureGroups::TEX_FLOOR,"textures/sky.png",1,1,true);
72
static rFileTexture sky_moviepack(rTextureGroups::TEX_FLOOR,"moviepack/sky.png",1,1,true);
74
extern bool sg_MoviePack();
76
static void sky_select(){
78
// Since old movie packs usually don't include sky.png we need to
79
// be nice and fall back to the default sky tecture. -k
80
tString s = tDirectories::Data().GetReadPath( "moviepack/sky.png" );
82
sky_moviepack.Select();
91
// if the rip bug is activated, don't use the rim to draw the floor
92
extern short se_bugRip;
94
// passes a vertex with z-projected texture coordinates to OpenGL
95
static inline void TexVertex( REAL x, REAL y, REAL h)
101
// renders a finite rectangle
102
static void finite_xy_plane( const eCoord &pos,const eCoord &dir,REAL h, eRectangle rect )
104
// expand plane to camera position to avoid embarrasing reflection bug
105
if ( sr_floorMirror )
108
// fetch rectangle coordinates
109
REAL lx = rect.GetLow().x;
110
REAL ly = rect.GetLow().y;
111
REAL hx = rect.GetHigh().x;
112
REAL hy = rect.GetHigh().y;
114
// draw rectangle as triangle fan (good for avoiding artefacts near pos)
116
TexVertex( pos.x-dir.x, pos.y-dir.y, h );
117
TexVertex(lx, ly, h);
118
TexVertex(lx, hy, h);
119
TexVertex(hx, hy, h);
120
TexVertex(hx, ly, h);
121
TexVertex(lx, ly, h);
125
static void infinity_xy_plane(eCoord const & pos, const eCoord &dir,REAL h=0){
126
glEdgeFlag(GL_FALSE);
137
// always use the rim if infinity rendering is turned off
138
use_rim |= !sr_infinityPlane;
142
// the rim wall based rendering does not work properly for shaped arenas, so
143
// it's been replaced.
146
for(int i=se_rimWalls.Len()-1;i>=0;i--){
147
eCoord p1=se_rimWalls(i)->EndPoint(0);
148
eCoord p2=se_rimWalls(i)->EndPoint(1);
150
glTexCoord2f(pos.x, pos.y);
151
glVertex3f (pos.x, pos.y, h);
153
glTexCoord2f(p1.x, p1.y);
154
glVertex3f (p1.x, p1.y, h);
156
glTexCoord2f(p2.x, p2.y);
157
glVertex3f (p2.x, p2.y, h);
161
finite_xy_plane( pos, dir, h, eWallRim::GetBounds() );
165
if (!sr_infinityPlane)
170
glTexCoord4f(pos.x-dir.x, pos.y-dir.y, h, 1);
171
glVertex4f (pos.x-dir.x, pos.y-dir.y, h, 1);
173
glTexCoord4f(1,0.1,zero*h,zero);
174
glVertex4f (1,0.1,zero*h,zero);
176
glTexCoord4f(0.1,1.1,zero*h,zero);
177
glVertex4f (0.1,1.1,zero*h,zero);
179
glTexCoord4f(-1,0.1,zero*h,zero);
180
glVertex4f (-1,0.1,zero*h,zero);
182
glTexCoord4f(0.1,-1.1,zero*h,zero);
183
glVertex4f (0.1,-1.1,zero*h,zero);
185
glTexCoord4f(1,0.1,zero*h,zero);
186
glVertex4f (1,0.1,zero*h,zero);
195
int eGrid::NumberOfCameras(){return cameras.Len();}
196
const eCoord& eGrid::CameraPos(int i){return cameras(i)->CameraPos();}
197
eCoord eGrid::CameraGlancePos(int i){return cameras(i)->CameraGlancePos();}
198
const eCoord& eGrid::CameraDir(int i){return cameras(i)->CameraDir();}
199
REAL eGrid::CameraHeight(int i){return cameras(i)->CameraZ();}
204
eWall *displayed_eWall=0;
206
void draw_eWall(eGrid* grid, int v,int i, REAL& zNear, eCamera const * cam)
208
if (i<se_wallsVisible[v].Len())
210
eWallView *view=se_wallsVisible[v](i);
212
if (view->Value()<=z)
215
displayed_eWall = view->Belongs();
216
REAL len = displayed_eWall->Len();
219
REAL zDist = z - displayed_eWall->Height();
222
const eCoord& camPos = grid->CameraPos( v );
223
const eCoord& camDir = grid->CameraDir( v );
224
eCoord base = displayed_eWall->EndPoint(0);
225
eCoord end = displayed_eWall->EndPoint(1);
227
if ( eCoord::F( base-camPos, camDir ) > 0.01f || eCoord::F( end-camPos, camDir ) > 0.01f )
229
eCoord dirNorm = end - base;
231
eCoord camRelative = ( camPos - base ).Turn( dirNorm.Conj() );
232
REAL dist = fabs( camRelative.y );
233
if ( camRelative.x < 0 )
235
dist -= camRelative.x;
237
if ( camRelative.x > len )
239
dist += camRelative.x - len;
245
// TODO: better criterion for ingoring of walls
246
if ( dist < zNear && dist > 0.001f )
253
displayed_eWall->Render(cam);
257
draw_eWall(grid,v,tHeapBase::UpperL(i),zNear,cam);
258
draw_eWall(grid,v,tHeapBase::UpperR(i),zNear,cam);
267
void paint_sr_lowerSky(eGrid *grid, int viewer,bool sr_upperSky, eCoord const & camPos){
270
glScalef(.005,.005,.005);
271
glEnable(GL_TEXTURE_2D);
272
glDisable(GL_CULL_FACE);
275
glTranslatef(se_GameTime()*.1,se_GameTime()*.07145,0);
276
glScalef(1+.2*sin(se_GameTime()),1+.1*cos(se_GameTime()),1);
277
glTranslatef(-300,-200,0);
282
REAL sa=(lower_height-z)*.1;
286
glBlendFunc(GL_SRC_ALPHA,GL_ZERO);
290
infinity_xy_plane(camPos,grid->CameraDir(viewer),lower_height);
292
if (!sr_upperSky && sr_alphaBlend)
293
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
296
void eGrid::display_simple( int viewer,bool floor,
297
bool sr_upperSky,bool sr_lowerSky,
299
bool eWalls,bool gameObjects,
302
static GLfloat S[]={1,0,0,0};
303
static GLfloat T[]={0,1,0,0};
304
static GLfloat R[]={0,0,1,0};
305
static GLfloat Q[]={0,0,0,1};
307
glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
308
glTexGenfv(GL_S,GL_OBJECT_PLANE,S);
310
glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
311
glTexGenfv(GL_T,GL_OBJECT_PLANE,T);
313
glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
314
glTexGenfv(GL_R,GL_OBJECT_PLANE,R);
316
glTexGeni(GL_Q,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
317
glTexGenfv(GL_Q,GL_OBJECT_PLANE,Q);
319
glDisable(GL_TEXTURE_GEN_T);
320
glDisable(GL_TEXTURE_GEN_S);
321
glDisable(GL_TEXTURE_GEN_R);
322
glDisable(GL_TEXTURE_GEN_Q);
326
glEdgeFlag(GL_FALSE);
328
glDisable(GL_DEPTH_TEST);
330
glDisable(GL_CULL_FACE);
332
eCoord camPos = CameraGlancePos( viewer );
333
// eWallRim::Bound( camPos, 10 );
335
if (sr_upperSky || se_BlackSky()){
337
//glDisable(GL_TEXTURE);
338
glDisable(GL_TEXTURE_2D);
342
if ( z < lower_height )
343
infinity_xy_plane(camPos, this->CameraDir(viewer),lower_height);
345
glEnable(GL_TEXTURE_2D);
350
// glScalef(.25,.25,.25);
356
if ( z < upper_height )
357
infinity_xy_plane(camPos, this->CameraDir(viewer),upper_height);
361
if (sr_lowerSky && !sr_highRim){
362
paint_sr_lowerSky(this, viewer,sr_upperSky, camPos);
366
su_FetchAndStoreSDLInput();
367
int floorDetail = sr_floorDetail;
369
// no multitexturing without alpha blending
370
if ( !sr_alphaBlend && floorDetail > rFLOOR_TEXTURE )
371
floorDetail = rFLOOR_TEXTURE;
378
#define SIDELEN (se_GridSize())
381
eCoord center = CameraPos(viewer) + CameraDir(viewer) * (SIDELEN * EXTENSION * .8);
385
int xn=static_cast<int>(x/SIDELEN);
386
int yn=static_cast<int>(y/SIDELEN);
389
//glDisable(GL_TEXTURE);
390
glDisable(GL_TEXTURE_2D);
392
#define INTENSITY(x,xx) (1-(((x)-(xx))*((x)-(xx))/(EXTENSION*SIDELEN*EXTENSION*SIDELEN)))
396
for(int i=xn-EXTENSION;i<=xn+EXTENSION;i++){
397
REAL intens=INTENSITY(i*SIDELEN,x);
398
if (intens<0) intens=0;
399
se_glFloorColor(intens,intens);
400
glVertex2f(i*SIDELEN,y-SIDELEN*(EXTENSION+1));
401
glVertex2f(i*SIDELEN,y+SIDELEN*(EXTENSION+1));
403
for(int j=yn-EXTENSION;j<=yn+EXTENSION;j++){
404
REAL intens=INTENSITY(j*SIDELEN,y);
405
if (intens<0) intens=0;
406
se_glFloorColor(intens,intens);
407
glVertex2f(x-(EXTENSION+1)*SIDELEN,j*SIDELEN);
408
glVertex2f(x+(EXTENSION+1)*SIDELEN,j*SIDELEN);
417
glScalef(1/se_GridSize(),1/se_GridSize(),1/se_GridSize());
420
se_glFloorColor(flooralpha);
422
infinity_xy_plane( camPos, CameraDir(viewer) );
424
/* old way: draw every triangle
425
for(int i=eFace::faces.Len()-1;i>=0;i--){
426
eFace *f=eFace::faces(i);
428
if (f->visHeight[viewer]<z){
429
glBegin(GL_TRIANGLES);
430
for(int j=0;j<=2;j++){
431
glVertex3f(f->p[j]->x,f->p[j]->y,0);
440
case rFLOOR_TWOTEXTURE:
441
se_glFloorColor(flooralpha);
445
REAL gs = 1/se_GridSize();
446
glScalef(0.01*gs,gs,gs);
448
se_glFloorTexture_a();
449
infinity_xy_plane( camPos, CameraDir(viewer) );
451
se_glFloorColor(flooralpha);
455
glScalef(gs,.01*gs,gs);
457
se_glFloorTexture_b();
459
glDepthFunc(GL_LEQUAL);
460
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
461
infinity_xy_plane( camPos, CameraDir(viewer) );
462
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
472
// glDisable(GL_TEXTURE_GEN_S);
473
// glDisable(GL_TEXTURE_GEN_T);
474
// glDisable(GL_TEXTURE_GEN_Q);
475
// glDisable(GL_TEXTURE_GEN_R);
477
glEnable(GL_DEPTH_TEST);
480
for(int i=se_rimWalls.Len()-1;i>=0;i--){
481
su_FetchAndStoreSDLInput();
482
se_rimWalls(i)->RenderReal(cameras(viewer));
485
if (sr_lowerSky && sr_highRim){
486
// glEnable(GL_TEXTURE_GEN_S);
487
// glEnable(GL_TEXTURE_GEN_T);
488
// glEnable(GL_TEXTURE_GEN_Q);
489
// glEnable(GL_TEXTURE_GEN_R);
491
paint_sr_lowerSky(this, viewer,sr_upperSky, camPos);
493
// glDisable(GL_TEXTURE_GEN_S);
494
// glDisable(GL_TEXTURE_GEN_T);
495
// glDisable(GL_TEXTURE_GEN_Q);
496
// glDisable(GL_TEXTURE_GEN_R);
503
glEnable(GL_DEPTH_TEST);
506
glEnable(GL_DEPTH_TEST);
509
glDisable(GL_CULL_FACE);
510
draw_eWall(this,viewer,0,zNear,cameras(viewer));
514
for(int i=sg_netPlayerWalls.Len()-1;i>=0;i--){
515
glMatrixMode(GL_MODELVIEW);
517
if (sg_netPlayerWalls(i)->Preliminary())
521
if (sg_netPlayerWalls(i)->Wall())
522
sg_netPlayerWalls(i)->Wall()->RenderList(false);
530
int newlen=sg_netPlayerWalls.Len();
532
con << "Number of player eWalls now " << newlen << '\n';
540
eGameObject::RenderAll(this, cameras(viewer));
542
eDebugLine::Render();
548
//glDisable(GL_TEXTURE);
549
glDisable(GL_TEXTURE_2D);
550
glDisable(GL_LIGHTING);
554
for(i=edges.Len()-1;i>=0;i--){
555
eHalfEdge *e=edges[i];
561
glVertex3f(e->Point()->x,e->Point()->y,10);
562
glVertex3f(e->Point()->x,e->Point()->y,15);
563
glVertex3f(e->Point()->x,e->Point()->y,.1);
564
glVertex3f(e->other->Point()->x,e->other->Point()->y,.1);
565
glVertex3f(e->other->Point()->x,e->other->Point()->y,10);
566
glVertex3f(e->other->Point()->x,e->other->Point()->y,15);
570
for(i=points.Len()-1;i>=0;i--){
573
glVertex3f(p->x,p->y,0);
574
glVertex3f(p->x,p->y,(p->GetRefcount()+1)*5);
577
for(int i=sg_netPlayerWalls.Len()-1;i>=0;i--){
578
eEdge *e=sg_netPlayerWalls[i]->Edge();
581
glVertex3f(e->Point()->x,e->Point()->y,5);
582
glVertex3f(e->Point()->x,e->Point()->y,10);
583
glVertex3f(e->Point()->x,e->Point()->y,10);
584
glVertex3f(e->other->Point()->x,e->other->Point()->y,10);
585
glVertex3f(e->other->Point()->x,e->other->Point()->y,10);
586
glVertex3f(e->other->Point()->x,e->other->Point()->y,5);
596
void eGrid::Render( eCamera* cam, int viewer, REAL& zNear ){
602
z=CameraHeight(viewer);
618
if (sr_floorMirror>=rMIRROR_ALL){
622
else if (sr_floorMirror>=rMIRROR_WALLS){
625
else if (sr_upperSky)
629
cam->SetRenderingMain(false);
630
display_simple(viewer,false,
633
sr_floorMirror>=rMIRROR_WALLS,
634
sr_floorMirror>=rMIRROR_OBJECTS,
636
z=CameraHeight(viewer);
642
cam->SetRenderingMain(true);
643
display_simple(viewer,true,
644
sr_upperSky,sr_lowerSky,
645
1-sr_floorMirror_strength,
651
cam->SetRenderingMain(true);
652
display_simple(viewer,true,
653
sr_upperSky,sr_lowerSky,
660
// for(int i=eEdge_crossing.Len()-1;i>=0;i--){
661
// eEdge_crossing(i)->Render();
668
//void eEdgeViewer::Render(){}
671
void eViewerCrossesEdge::Render(){
673
ePoint *p1=e->Point();
674
ePoint *p2=e->other->Point();
676
REAL timeLeft=value-se_GameTime();
691
//glColor4f(1,0,0,.5);
693
static rTexture ArmageTron_invis_eWall(rTEX_WALL,"textures/eWall2.png",1,0);
695
ArmageTron_invis_eWall.Select();
697
eWall::Render_helper(e,(p1->x+p1->y)/4,(p2->x+p2->y)/4,h,1,4);