1 /*
2 
3 *************************************************************************
4 
5 ArmageTron -- Just another Tron Lightcycle Game in 3D.
6 Copyright (C) 2000  Manuel Moos (manuel@moosnet.de)
7 
8 **************************************************************************
9 
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.
14 
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.
19 
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.
23 
24 ***************************************************************************
25 
26 */
27 
28 //void se_FetchAndStoreSDLInput();
29 
30 #include "rSDL.h"
31 
32 #include "tConfiguration.h"
33 
34 // floor mirror
35 #ifndef DEDICATED
36 static REAL sr_floorMirror_strength=.1;
37 static tSettingItem<REAL> f_m("FLOOR_MIRROR_INT",sr_floorMirror_strength);
38 
39 #include "tEventQueue.h"
40 #include "uInputQueue.h"
41 #include "eTess2.h"
42 #include "rTexture.h"
43 #include "eGameObject.h"
44 #include "rFont.h"
45 #include "eTimer.h"
46 #include "eCamera.h"
47 #include "eSensor.h"
48 #include "rScreen.h"
49 #include "rRender.h"
50 #include "eWall.h"
51 #include "eAdvWall.h"
52 #include "eFloor.h"
53 #include "ePath.h"
54 #include "eGrid.h"
55 #include "eDebugLine.h"
56 #include "tDirectories.h"
57 #include "eRectangle.h"
58 
59 #define eWall_h 4
60 #define view_h 2.7
61 
62 #ifdef DEBUG
63 bool debug_grid=0;
64 #endif
65 
66 REAL upper_height=100;
67 REAL lower_height=50;
68 
69 
70 #ifndef DEDICATED
71 
72 static rFileTexture sky(rTextureGroups::TEX_FLOOR,"textures/sky.png",1,1,true);
73 static rFileTexture sky_moviepack(rTextureGroups::TEX_FLOOR,"moviepack/sky.png",1,1,true);
74 
75 extern bool sg_MoviePack();
76 
sky_select()77 static void sky_select(){
78     if (sg_MoviePack()){
79         // Since old movie packs usually don't include sky.png we need to
80         // be nice and fall back to the default sky tecture. -k
81         tString s = tDirectories::Data().GetReadPath( "moviepack/sky.png" );
82         if(strlen(s) > 0)
83             sky_moviepack.Select();
84         else
85             sky.Select();
86     }
87     else {
88         sky.Select();
89     }
90 }
91 
92 // if the rip bug is activated, don't use the rim to draw the floor
93 extern short se_bugRip;
94 
95 // passes a vertex with z-projected texture coordinates to OpenGL
TexVertex(REAL x,REAL y,REAL h)96 static inline void TexVertex( REAL x, REAL y, REAL h)
97 {
98     glTexCoord2f(x, y);
99     glVertex3f  (x, y, h);
100 }
101 
102 // renders a finite rectangle
finite_xy_plane(const eCoord & pos,const eCoord & dir,REAL h,eRectangle rect)103 static void finite_xy_plane( const eCoord &pos,const eCoord &dir,REAL h, eRectangle rect )
104 {
105     // expand plane to camera position to avoid embarrasing reflection bug
106     if ( sr_floorMirror )
107         rect.Include( pos );
108 
109     // fetch rectangle coordinates
110     REAL lx = rect.GetLow().x;
111     REAL ly = rect.GetLow().y;
112     REAL hx = rect.GetHigh().x;
113     REAL hy = rect.GetHigh().y;
114 
115     // draw rectangle as triangle fan (good for avoiding artefacts near pos)
116     BeginTriangleFan();
117     TexVertex( pos.x-dir.x, pos.y-dir.y, h );
118     TexVertex(lx, ly, h);
119     TexVertex(lx, hy, h);
120     TexVertex(hx, hy, h);
121     TexVertex(hx, ly, h);
122     TexVertex(lx, ly, h);
123     RenderEnd();
124 }
125 
infinity_xy_plane(eCoord const & pos,const eCoord & dir,REAL h=0)126 static void infinity_xy_plane(eCoord const & pos, const eCoord &dir,REAL h=0){
127     bool use_rim=false;
128     REAL zero=0;
129 
130     if (sr_highRim)
131         use_rim=true;
132 
133     if ( se_bugRip )
134         use_rim=false;
135 
136     // always use the rim if infinity rendering is turned off
137     use_rim |= !sr_infinityPlane;
138 
139     if (use_rim){
140         /*
141           // the rim wall based rendering does not work properly for shaped arenas, so
142           // it's been replaced.
143 
144                 BeginTriangles();
145                 for(int i=se_rimWalls.Len()-1;i>=0;i--){
146                     eCoord p1=se_rimWalls(i)->EndPoint(0);
147                     eCoord p2=se_rimWalls(i)->EndPoint(1);
148 
149                     glTexCoord2f(pos.x, pos.y);
150                     glVertex3f  (pos.x, pos.y, h);
151 
152                     glTexCoord2f(p1.x, p1.y);
153                     glVertex3f  (p1.x, p1.y, h);
154 
155                     glTexCoord2f(p2.x, p2.y);
156                     glVertex3f  (p2.x, p2.y, h);
157                 }
158                 RenderEnd();
159         */
160         finite_xy_plane( pos, dir, h, eWallRim::GetBounds() );
161     }
162     else
163     {
164         if (!sr_infinityPlane)
165             zero=.001;
166 
167         BeginTriangleFan();
168 
169         glTexCoord4f(pos.x-dir.x, pos.y-dir.y, h, 1);
170         glVertex4f  (pos.x-dir.x, pos.y-dir.y, h, 1);
171 
172         glTexCoord4f(1,0.1,zero*h,zero);
173         glVertex4f  (1,0.1,zero*h,zero);
174 
175         glTexCoord4f(0.1,1.1,zero*h,zero);
176         glVertex4f  (0.1,1.1,zero*h,zero);
177 
178         glTexCoord4f(-1,0.1,zero*h,zero);
179         glVertex4f  (-1,0.1,zero*h,zero);
180 
181         glTexCoord4f(0.1,-1.1,zero*h,zero);
182         glVertex4f  (0.1,-1.1,zero*h,zero);
183 
184         glTexCoord4f(1,0.1,zero*h,zero);
185         glVertex4f  (1,0.1,zero*h,zero);
186 
187         RenderEnd();
188     }
189 }
190 
191 static REAL z=0;
192 
193 
NumberOfCameras()194 int           eGrid::NumberOfCameras(){return cameras.Len();}
CameraPos(int i)195 const eCoord& eGrid::CameraPos(int i){return cameras(i)->CameraPos();}
CameraGlancePos(int i)196 eCoord eGrid::CameraGlancePos(int i){return cameras(i)->CameraGlancePos();}
CameraDir(int i)197 const eCoord& eGrid::CameraDir(int i){return cameras(i)->CameraDir();}
CameraHeight(int i)198 REAL          eGrid::CameraHeight(int i){return cameras(i)->CameraZ();}
199 
200 
201 
202 
203 class eZNearSensor: public eSensor
204 {
205 public:
AdaptZNear(REAL & zNear,eWall const * wall,eCamera const * camera)206     static bool AdaptZNear( REAL & zNear, eWall const * wall, eCamera const * camera )
207     {
208         REAL len = wall->Len();
209         if ( len > .01)
210         {
211             REAL zDist = ::z - wall->Height();
212             if ( zDist < zNear )
213             {
214                 const eCoord& camPos = camera->CameraPos();
215                 const eCoord& camDir = camera->CameraDir();
216                 eCoord base = wall->EndPoint(0);
217                 eCoord end = wall->EndPoint(1);
218 
219                 if ( eCoord::F( base-camPos, camDir ) > 0.01f || eCoord::F( end-camPos, camDir ) > 0.01f )
220                 {
221                     eCoord dirNorm = end - base;
222                     dirNorm.Normalize();
223                     eCoord camRelative = ( camPos - base ).Turn( dirNorm.Conj() );
224                     REAL dist = fabs( camRelative.y );
225                     if ( camRelative.x < 0 )
226                     {
227                         dist -= camRelative.x;
228                     }
229                     if ( camRelative.x > len )
230                     {
231                         dist += camRelative.x - len;
232                     }
233                     if ( dist < zDist )
234                     {
235                         dist = zDist;
236                     }
237                     // TODO: better criterion for ingoring of walls
238                     if ( dist < zNear && dist > 0.001f )
239                     {
240                         zNear = dist;
241                         return true;
242                     }
243                 }
244             }
245         }
246 
247         return false;
248     }
249 
eZNearSensor(eGameObject * o,const eCoord & start,const eCoord & d,REAL & zNear,eCamera const * camera)250     eZNearSensor(eGameObject *o,const eCoord &start,const eCoord &d, REAL & zNear, eCamera const * camera )
251     :eSensor( o, start, d ), zNear_( zNear ), camera_( camera )
252     {}
253 
Detect()254     void Detect()
255     {
256         detect( zNear_ * 2 );
257     }
258 
259     // called when passing an edge
PassEdge(const eWall * w,REAL time,REAL,int)260     void PassEdge( const eWall * w, REAL time, REAL, int)
261     {
262         // adapt zNear and be done
263         if( AdaptZNear( zNear_, w, camera_ ) )
264         {
265             throw eSensorFinished();
266         }
267     }
268 private:
269     REAL & zNear_; // the reference to the near clipping plane value
270     eCamera const * camera_; // the camera currently in use
271 };
272 
paint_sr_lowerSky(eGrid * grid,int viewer,bool sr_upperSky,eCoord const & camPos)273 void paint_sr_lowerSky(eGrid *grid, int viewer,bool sr_upperSky, eCoord const & camPos){
274     TexMatrix();
275     glLoadIdentity();
276     glScalef(.005,.005,.005);
277     glEnable(GL_TEXTURE_2D);
278     glDisable(GL_CULL_FACE);
279 
280     if (sr_skyWobble){
281         glTranslatef(se_GameTime()*.1,se_GameTime()*.07145,0);
282         glScalef(1+.2*sin(se_GameTime()),1+.1*cos(se_GameTime()),1);
283         glTranslatef(-300,-200,0);
284     }
285 
286     sky_select();
287 
288     REAL sa=(lower_height-z)*.1;
289     if (sa>1) sa=1;
290     if (!sr_upperSky){
291         sa=1;
292         glBlendFunc(GL_SRC_ALPHA,GL_ZERO);
293     }
294     if (sa>0){
295         glColor4f(1,1,1,sa);
296         infinity_xy_plane(camPos,grid->CameraDir(viewer),lower_height);
297     }
298     if (!sr_upperSky && sr_alphaBlend)
299         glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
300 }
301 
display_simple(int viewer,bool floor,bool sr_upperSky,bool sr_lowerSky,REAL flooralpha,bool eWalls,bool gameObjects,REAL & zNear)302 void eGrid::display_simple( int viewer,bool floor,
303                             bool sr_upperSky,bool sr_lowerSky,
304                             REAL flooralpha,
305                             bool eWalls,bool gameObjects,
306                             REAL& zNear){
307     /*
308     static GLfloat S[]={1,0,0,0};
309     static GLfloat T[]={0,1,0,0};
310     static GLfloat R[]={0,0,1,0};
311     static GLfloat Q[]={0,0,0,1};
312 
313     glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
314     glTexGenfv(GL_S,GL_OBJECT_PLANE,S);
315 
316     glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
317     glTexGenfv(GL_T,GL_OBJECT_PLANE,T);
318 
319     glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
320     glTexGenfv(GL_R,GL_OBJECT_PLANE,R);
321 
322     glTexGeni(GL_Q,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
323     glTexGenfv(GL_Q,GL_OBJECT_PLANE,Q);
324 
325     glDisable(GL_TEXTURE_GEN_T);
326     glDisable(GL_TEXTURE_GEN_S);
327     glDisable(GL_TEXTURE_GEN_R);
328     glDisable(GL_TEXTURE_GEN_Q);
329     */
330 
331 
332     glDisable(GL_DEPTH_TEST);
333     glDepthMask(GL_FALSE);
334 
335     glDisable(GL_CULL_FACE);
336 
337     eCoord camPos = CameraGlancePos( viewer );
338     // eWallRim::Bound( camPos, 10 );
339 
340     if (sr_upperSky || se_BlackSky()){
341         if (se_BlackSky()){
342             //glDisable(GL_TEXTURE);
343             glDisable(GL_TEXTURE_2D);
344 
345             glColor3f(0,0,0);
346 
347             if ( z < lower_height )
348                 infinity_xy_plane(camPos, this->CameraDir(viewer),lower_height);
349 
350             glEnable(GL_TEXTURE_2D);
351         }
352         else {
353             TexMatrix();
354             glLoadIdentity();
355             //      glScalef(.25,.25,.25);
356 
357             se_glFloorTexture();
358 
359             glColor3f(.5,.5,1);
360 
361             if ( z < upper_height )
362                 infinity_xy_plane(camPos, this->CameraDir(viewer),upper_height);
363         }
364     }
365 
366     if (sr_lowerSky && !sr_highRim){
367         paint_sr_lowerSky(this, viewer,sr_upperSky, camPos);
368     }
369 
370     if (floor){
371         sr_DepthOffset(false);
372 
373         su_FetchAndStoreSDLInput();
374         int floorDetail = sr_floorDetail;
375 
376         // no multitexturing without alpha blending
377         if ( !sr_alphaBlend && floorDetail > rFLOOR_TEXTURE )
378             floorDetail = rFLOOR_TEXTURE;
379 
380         switch(floorDetail){
381         case rFLOOR_OFF:
382             break;
383         case rFLOOR_GRID:
384             {
385 	#define SIDELEN   (se_GridSize())
386 	#define EXTENSION 10
387 
388                 eCoord center = CameraPos(viewer) + CameraDir(viewer) * (SIDELEN * EXTENSION * .8);
389 
390                 REAL x=center.x;
391                 REAL y=center.y;
392                 int xn=static_cast<int>(x/SIDELEN);
393                 int yn=static_cast<int>(y/SIDELEN);
394 
395 
396                 //glDisable(GL_TEXTURE);
397                 glDisable(GL_TEXTURE_2D);
398 
399 	#define INTENSITY(x,xx) (1-(((x)-(xx))*((x)-(xx))/(EXTENSION*SIDELEN*EXTENSION*SIDELEN)))
400 
401 
402                 BeginLines();
403                 for(int i=xn-EXTENSION;i<=xn+EXTENSION;i++){
404                     REAL intens=INTENSITY(i*SIDELEN,x);
405                     if (intens<0) intens=0;
406                     se_glFloorColor(intens,intens);
407                     glVertex2f(i*SIDELEN,y-SIDELEN*(EXTENSION+1));
408                     glVertex2f(i*SIDELEN,y+SIDELEN*(EXTENSION+1));
409                 }
410                 for(int j=yn-EXTENSION;j<=yn+EXTENSION;j++){
411                     REAL intens=INTENSITY(j*SIDELEN,y);
412                     if (intens<0) intens=0;
413                     se_glFloorColor(intens,intens);
414                     glVertex2f(x-(EXTENSION+1)*SIDELEN,j*SIDELEN);
415                     glVertex2f(x+(EXTENSION+1)*SIDELEN,j*SIDELEN);
416                 }
417                 RenderEnd();
418             }
419             break;
420 
421         case rFLOOR_TEXTURE:
422             TexMatrix();
423             glLoadIdentity();
424             glScalef(1/se_GridSize(),1/se_GridSize(),1/se_GridSize());
425 
426             se_glFloorTexture();
427             se_glFloorColor(flooralpha);
428 
429             infinity_xy_plane( camPos, CameraDir(viewer) );
430 
431             /* old way: draw every triangle
432             for(int i=eFace::faces.Len()-1;i>=0;i--){
433             eFace *f=eFace::faces(i);
434 
435             if (f->visHeight[viewer]<z){
436             glBegin(GL_TRIANGLES);
437             for(int j=0;j<=2;j++){
438             glVertex3f(f->p[j]->x,f->p[j]->y,0);
439             }
440             glEnd();
441             }
442             }
443             */
444 
445             break;
446 
447         case rFLOOR_TWOTEXTURE:
448             se_glFloorColor(flooralpha);
449 
450             TexMatrix();
451             glLoadIdentity();
452             REAL gs = 1/se_GridSize();
453             glScalef(0.01*gs,gs,gs);
454 
455             se_glFloorTexture_a();
456             infinity_xy_plane( camPos, CameraDir(viewer) );
457 
458             se_glFloorColor(flooralpha);
459 
460             TexMatrix();
461             glLoadIdentity();
462             glScalef(gs,.01*gs,gs);
463 
464             se_glFloorTexture_b();
465 
466             glDepthFunc(GL_LEQUAL);
467             glBlendFunc(GL_SRC_ALPHA,GL_ONE);
468             infinity_xy_plane( camPos, CameraDir(viewer) );
469             glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
470 
471             break;
472         }
473     }
474 
475     glEnable(GL_DEPTH_TEST);
476     glDepthMask(GL_TRUE);
477 
478     TexMatrix();
479     glLoadIdentity();
480     ModelMatrix();
481 
482     //  glDisable(GL_TEXTURE_GEN_S);
483     //  glDisable(GL_TEXTURE_GEN_T);
484     //  glDisable(GL_TEXTURE_GEN_Q);
485     //  glDisable(GL_TEXTURE_GEN_R);
486 
487     if(eWalls){
488         {
489             su_FetchAndStoreSDLInput();
490 
491             eWallRim::RenderAll( cameras(viewer) );
492         }
493 
494         if (sr_lowerSky && sr_highRim){
495             //      glEnable(GL_TEXTURE_GEN_S);
496             //      glEnable(GL_TEXTURE_GEN_T);
497             //      glEnable(GL_TEXTURE_GEN_Q);
498             //      glEnable(GL_TEXTURE_GEN_R);
499 
500             paint_sr_lowerSky(this, viewer,sr_upperSky, camPos);
501 
502             //      glDisable(GL_TEXTURE_GEN_S);
503             //      glDisable(GL_TEXTURE_GEN_T);
504             //      glDisable(GL_TEXTURE_GEN_Q);
505             //      glDisable(GL_TEXTURE_GEN_R);
506 
507             TexMatrix();
508             glLoadIdentity();
509             ModelMatrix();
510         }
511     }
512 
513     if (eWalls){
514         // send out sensors to find walls close to the camera
515         if ( z < 3 )
516         {
517             eCamera const * camera = cameras(viewer);
518             if( camera && camera->Center() )
519             {
520                 eCoord dir = camera->CameraDir().Turn(1,.5);
521                 for(int i = 8; i > 0; --i)
522                 {
523                     dir = dir.Turn(sqrt(.5),sqrt(.5));
524                     eZNearSensor s( camera->Center(), camPos, dir, zNear, camera );
525                     s.Detect();
526                 }
527             }
528         }
529 
530         // glDisable(GL_CULL_FACE);
531         // draw_eWall(this,viewer,0,zNear,cameras(viewer));
532 
533         /*
534         #ifdef DEBUG
535         for(int i=sg_netPlayerWalls.Len()-1;i>=0;i--){
536           glMatrixMode(GL_MODELVIEW);
537           glPushMatrix();
538           if (sg_netPlayerWalls(i)->Preliminary())
539         glTranslatef(0,0,4);
540           else
541         glTranslatef(0,0,8);
542           if (sg_netPlayerWalls(i)->Wall())
543         sg_netPlayerWalls(i)->Wall()->RenderList(false);
544           glPopMatrix();
545           }
546         #endif
547         */
548 
549         /*
550         static int oldlen=0;
551         int newlen=sg_netPlayerWalls.Len();
552         if (newlen!=oldlen){
553           con << "Number of player eWalls now " << newlen << '\n';
554           oldlen=newlen;
555         }
556         */
557 
558     }
559 
560     if (gameObjects)
561         eGameObject::RenderAll(this, cameras(viewer));
562 
563     eDebugLine::Render();
564 #ifdef DEBUG
565 
566     ePath::RenderLast();
567 
568     if (debug_grid){
569         //glDisable(GL_TEXTURE);
570         glDisable(GL_TEXTURE_2D);
571         glDisable(GL_LIGHTING);
572         BeginLines();
573 
574         int i;
575         for(i=edges.Len()-1;i>=0;i--){
576             eHalfEdge *e=edges[i];
577             if (e->Face())
578                 glColor4f(1,1,1,1);
579             else
580                 glColor4f(0,0,1,1);
581 
582             glVertex3f(e->Point()->x,e->Point()->y,10);
583             glVertex3f(e->Point()->x,e->Point()->y,15);
584             glVertex3f(e->Point()->x,e->Point()->y,.1);
585             glVertex3f(e->other->Point()->x,e->other->Point()->y,.1);
586             glVertex3f(e->other->Point()->x,e->other->Point()->y,10);
587             glVertex3f(e->other->Point()->x,e->other->Point()->y,15);
588 
589         }
590 
591         for(i=points.Len()-1;i>=0;i--){
592             ePoint *p=points[i];
593             glColor4f(1,0,0,1);
594             glVertex3f(p->x,p->y,0);
595             glVertex3f(p->x,p->y,(p->GetRefcount()+1)*5);
596         }
597         /*
598         for(int i=sg_netPlayerWalls.Len()-1;i>=0;i--){
599           eEdge *e=sg_netPlayerWalls[i]->Edge();
600         glColor4f(0,1,0,1);
601 
602           glVertex3f(e->Point()->x,e->Point()->y,5);
603           glVertex3f(e->Point()->x,e->Point()->y,10);
604           glVertex3f(e->Point()->x,e->Point()->y,10);
605           glVertex3f(e->other->Point()->x,e->other->Point()->y,10);
606           glVertex3f(e->other->Point()->x,e->other->Point()->y,10);
607           glVertex3f(e->other->Point()->x,e->other->Point()->y,5);
608         }
609         */
610         RenderEnd();
611     }
612 #endif
613 
614 }
615 #endif
616 
Render(eCamera * cam,int viewer,REAL & zNear)617 void eGrid::Render( eCamera* cam, int viewer, REAL& zNear ){
618     if (!sr_glOut)
619         return;
620 #ifndef DEDICATED
621     ProjMatrix();
622 
623     z=CameraHeight(viewer);
624     if ( zNear > z )
625     {
626         zNear = z;
627     }
628 
629     if (sr_floorMirror){
630         ModelMatrix();
631         glScalef(1,1,-1);
632 
633         if (z>10) z=10;
634         glFrontFace(GL_CW);
635 
636         bool us=false;
637         bool ls=false;
638 
639         if (sr_floorMirror>=rMIRROR_ALL){
640             us=sr_upperSky;
641             ls=sr_lowerSky;
642         }
643         else if (sr_floorMirror>=rMIRROR_WALLS){
644             if (sr_lowerSky)
645                 ls=true;
646             else if (sr_upperSky)
647                 us=true;
648         }
649 
650         cam->SetRenderingMain(false);
651         display_simple(viewer,false,
652                        us,ls,
653                        0,
654                        sr_floorMirror>=rMIRROR_WALLS,
655                        sr_floorMirror>=rMIRROR_OBJECTS,
656                        zNear);
657         z=CameraHeight(viewer);
658         glFrontFace(GL_CCW);
659         ModelMatrix();
660         glScalef(1,1,-1);
661 
662 
663         cam->SetRenderingMain(true);
664         display_simple(viewer,true,
665                        sr_upperSky,sr_lowerSky,
666                        1-sr_floorMirror_strength,
667                        true,true,zNear);
668 
669     }
670     else
671     {
672         cam->SetRenderingMain(true);
673         display_simple(viewer,true,
674                        sr_upperSky,sr_lowerSky,
675                        1,
676                        true,true,zNear);
677     }
678 
679 
680 #ifdef EVENT_DEB
681     //  for(int i=eEdge_crossing.Len()-1;i>=0;i--){
682     //    eEdge_crossing(i)->Render();
683     //  }
684 #endif
685 #endif
686 }
687 
688 
689 //void eEdgeViewer::Render(){}
690 
691 /*
692 void eViewerCrossesEdge::Render(){
693 #ifndef DEDICATED
694   ePoint *p1=e->Point();
695   ePoint *p2=e->other->Point();
696 
697   REAL timeLeft=value-se_GameTime();
698 
699   REAL h;
700 
701   if (viewer==1){
702     if (timeLeft>0){
703       h=timeLeft+4;
704       glColor4f(0,0,1,.5);
705     }
706     else{
707       h=-timeLeft+4;
708       glColor4f(1,0,0,.5);
709     }
710 
711     //  else
712     //glColor4f(1,0,0,.5);
713 
714     static rTexture ArmageTron_invis_eWall(rTEX_WALL,"textures/eWall2.png",1,0);
715 
716     ArmageTron_invis_eWall.Select();
717 
718     eWall::Render_helper(e,(p1->x+p1->y)/4,(p2->x+p2->y)/4,h,1,4);
719   }
720 #endif
721 }
722 */
723 
724 #endif
725 
726 
727