TORCS  1.3.9
The Open Racing Car Simulator
grtrackmap.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 
3  file : grtrackmap.cpp
4  created : Fri Aug 29 00:58:00 CEST 2003
5  copyright : (C) 2003 by Bernhard Wymann
6  email : berniw@bluewin.ch
7  version : $Id$
8 
9  ***************************************************************************/
10 
11 /***************************************************************************
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * *
18  ***************************************************************************/
19 
20 /*
21  This class displays an overview map of the track, such that you can see the
22  upcoming track layout. Your car is displayed as a dot.
23  To get reasonable efficiency, the track is first rendered into a texture. During the
24  game just the texture needs to be redrawn.
25 */
26 
27 #include "grtrackmap.h"
28 #include <tgfclient.h>
29 
30 // The resolution in [m] to analyse turns.
31 const float cGrTrackMap::RESOLUTION = 5.0;
32 
33 // Minimum and Maximum line width in pixels to draw the track.
34 const float cGrTrackMap::MINLINEWIDTH = 5.0;
35 const float cGrTrackMap::MAXLINEWIDTH = 20.0;
36 
37 // Some data needs just one initalization, after first initialization this is set to true.
38 bool cGrTrackMap::isinitalized = false;
39 
40 // Track overview texture object.
42 
43 // The car "dot" display list.
44 GLuint cGrTrackMap::cardot;
45 
46 // Track bounding box properties, lower left, upper right corner, width and height.
53 
54 // The ratio of width and height to MAX(width, height)
57 
58 // Position and size of the map (relative to top left).
62 
63 // Scaling factor from meters to texels.
64 float cGrTrackMap::ratio;
65 
66 // Color of the cars "dots".
70 
71 
72 // The constructor creates a texture of the track data, such that the track
73 // layout can be displayed efficiently. Additional data gets initialized.
75 {
76  // Hardcoded initial view mode, available per instance.
78 
79  // For all views we need the same track texture, so create it just once.
80  if (isinitalized) {
81  return;
82  } else {
83  // Initialize colors for the various car "dots".
84  initColors();
85 
86  tTrack *track = grTrack;
87  tTrackSeg* first = track->seg;
88  tTrackSeg* seg = first;
89 
90  // Search the maximum/minimum x/y values of the track (axis aligned bounding box),
91  // to compute later the texture parameters and to be able to place the cars (dots)
92  // correct. The impementation is inefficient, but it's just executed one time per
93  // race, so it doesn't matter.
94  track_min_x = FLT_MAX;
95  track_max_x = -FLT_MAX;
96  track_min_y = FLT_MAX;
97  track_max_y = -FLT_MAX;
98 
99  do {
100  // We analyse the straight and turns different, because (read on)
101  if (seg->type == TR_STR) {
102  // Straights are trivial, because the corners are sufficient to create a
103  // bounding box.
104  // TODO: If CCW/CW is known, you just need to check one side (the outside).
105  // TODO: More effiecient checking.
110 
115  } else {
116  // Turns are not that easy, think of a definition of a circle or an arc. If you
117  // just consider the corners the bounding box might be any order too small
118  // or too big.
119  // To avoid that we create intermediate steps, such that we get a defined
120  // accuracy (e.g. 5 meters).
121  float curseglen = 0.0;
122  float dphi = RESOLUTION / seg->radius;
123  double xc = seg->center.x;
124  double yc = seg->center.y;
125  dphi = (seg->type == TR_LFT) ? dphi : -dphi;
126  float phi = 0.0;
127 
128  while (curseglen < seg->length) {
129  float cs = cos(phi), ss = sin(phi);
130  // TODO: If CCW/CW is known, you just need to check one side (the outside).
131  float lx, ly, rx, ry;
132  lx = seg->vertex[TR_SL].x * cs - seg->vertex[TR_SL].y * ss - xc * cs + yc * ss + xc;
133  ly = seg->vertex[TR_SL].x * ss + seg->vertex[TR_SL].y * cs - xc * ss - yc * cs + yc;
134 
135  rx = seg->vertex[TR_SR].x * cs - seg->vertex[TR_SR].y * ss - xc * cs + yc * ss + xc;
136  ry = seg->vertex[TR_SR].x * ss + seg->vertex[TR_SR].y * cs - xc * ss - yc * cs + yc;
137 
138  // TODO: More effiecient checking.
143 
148 
149  curseglen += RESOLUTION;
150  phi += dphi;
151  }
152  }
153  seg = seg->next;
154  } while (seg != first);
155 
156  // Compute the maximum possible texture size possible to create the track texture.
157  // TODO: use pbuffer if available or subdivide and render/readback in multiple passes.
158  int texturesize = 1;
159  int maxtexturesize = MIN(grWinw, grWinh);
160  while (texturesize <= maxtexturesize) {
161  texturesize <<= 1;
162  }
163  texturesize >>= 1;
164 
165  // Get maximum OpenGL texture size and reduce texturesize if necessary.
166  int maxOpenGLtexturesize;
167  glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxOpenGLtexturesize);
168  if (texturesize > maxOpenGLtexturesize) {
169  texturesize = maxOpenGLtexturesize;
170  }
171 
172  // Compute an estimate of the overall width and height of the track in [m].
175 
176  // Compute the final line width to draw the track.
177  float linewidth = MIN(MAXLINEWIDTH, MINLINEWIDTH*4000.0/MAX(track_width, track_height));
178  linewidth = linewidth*(texturesize/512.0);
179 
180  // Compute a first estimate of the pixel to distance ratio.
181  ratio = texturesize/MAX(track_width, track_height);
182 
183  // Compute final minimum/maximum values.
184  track_max_x = track_max_x + RESOLUTION + linewidth/ratio;
185  track_max_y = track_max_y + RESOLUTION + linewidth/ratio;
186  track_min_x = track_min_x - RESOLUTION - linewidth/ratio;
187  track_min_y = track_min_y - RESOLUTION - linewidth/ratio;
188 
189  // Compute final ratio, width and height.
192  ratio = texturesize/MAX(track_width, track_height);
193 
194  // Compute the ratios
195  if (track_width >= track_height) {
196  track_x_ratio = 1.0;
198  } else {
199  track_y_ratio = 1.0;
201  }
202 
203  isinitalized = true;
204 
205  // Now we are ready to render the track into the framebuffer (backbuffer).
206  // Clear the framebuffer (backbuffer), make it "transparent" (alpha = 0.0).
207  glFinish();
208  glClearColor(0.0, 0.0, 0.0, 0.0);
209  glClear(GL_COLOR_BUFFER_BIT);
210 
211  // Set transformations and projection such that one pixel is one unit.
212  glViewport (0, 0, grWinw, grWinh);
213  glMatrixMode(GL_MODELVIEW);
214  glPushMatrix();
215  glLoadIdentity();
216 
217  glMatrixMode(GL_PROJECTION);
218  glLoadIdentity();
219  gluOrtho2D(0.0, grWinw, 0.0, grWinh);
220  glMatrixMode(GL_MODELVIEW);
221 
222  // Now draw the track as quad strip. The reason for that is that drawing with
223  // glEnable(GL_LINE_SMOOTH) and glHint(GL_LINE_SMOOTH_HINT, GL_NICEST) caused problems
224  // with the alpha channel.
225  float halflinewidth = linewidth/2.0;
226  bool firstvert = true;
227  float xf1, yf1 , xf2, yf2;
228  xf1 = yf1 = xf2 = yf2 = 0.0;
229  glBegin(GL_QUAD_STRIP);
230  seg = first;
231  do {
232  if (seg->type == TR_STR) {
233  // Draw a straight.
234  // Compute global coordinate on track middle.
235  float xm = (seg->vertex[TR_SL].x + seg->vertex[TR_SR].x) / 2.0;
236  float ym = (seg->vertex[TR_SL].y + seg->vertex[TR_SR].y) / 2.0;
237  xm = (xm - track_min_x)*ratio;
238  ym = (ym - track_min_y)*ratio;
239 
240  // Compute normal to the track middle.
241  float xn = seg->vertex[TR_SL].x - seg->vertex[TR_SR].x;
242  float yn = seg->vertex[TR_SL].y - seg->vertex[TR_SR].y;
243  float length = sqrt(xn*xn+yn*yn);
244  xn /= length;
245  yn /= length;
246 
247  // Compute the new points.
248  float x1 = (xm - xn*halflinewidth);
249  float y1 = (ym - yn*halflinewidth);
250  float x2 = (xm + xn*halflinewidth);
251  float y2 = (ym + yn*halflinewidth);
252 
253  if (firstvert) {
254  firstvert = false;
255  xf1 = x1;
256  yf1 = y1;
257  xf2 = x2;
258  yf2 = y2;
259  }
260  glVertex2f(x1, y1);
261  glVertex2f(x2, y2);
262  } else {
263  // To draw the turns correct we subdivide them again, like above.
264  float curseglen = 0.0;
265  float dphi = RESOLUTION / seg->radius;
266  double xc = seg->center.x;
267  double yc = seg->center.y;
268  dphi = (seg->type == TR_LFT) ? dphi : -dphi;
269  float mx = (seg->vertex[TR_SL].x + seg->vertex[TR_SR].x) / 2.0;
270  float my = (seg->vertex[TR_SL].y + seg->vertex[TR_SR].y) / 2.0;
271  float phi = 0.0;
272 
273  while (curseglen < seg->length) {
274  float cs = cos(phi), ss = sin(phi);
275  float x = mx * cs - my * ss - xc * cs + yc * ss + xc;
276  float y = mx * ss + my * cs - xc * ss - yc * cs + yc;
277 
278  float xn = x - xc;
279  float yn = y - yc;
280  float length = sqrt(xn*xn+yn*yn);
281  xn /= length;
282  yn /= length;
283 
284  x = (x - track_min_x)*ratio;
285  y = (y - track_min_y)*ratio;
286 
287  float x1 = (x + xn*halflinewidth);
288  float y1 = (y + yn*halflinewidth);
289  float x2 = (x - xn*halflinewidth);
290  float y2 = (y - yn*halflinewidth);
291 
292  if (seg->type == TR_LFT) {
293  glVertex2f(x1, y1);
294  glVertex2f(x2, y2);
295  if (firstvert) {
296  firstvert = false;
297  xf1 = x1;
298  yf1 = y1;
299  xf2 = x2;
300  yf2 = y2;
301  }
302  } else {
303  glVertex2f(x2, y2);
304  glVertex2f(x1, y1);
305  if (firstvert) {
306  firstvert = false;
307  xf1 = x2;
308  yf1 = y2;
309  xf2 = x1;
310  yf2 = y1;
311  }
312  }
313 
314  curseglen += RESOLUTION;
315  phi += dphi;
316  }
317  }
318  seg = seg->next;
319  } while (seg != first);
320 
321  if (!firstvert) {
322  glVertex2f(xf1, yf1);
323  glVertex2f(xf2, yf2);
324  }
325  glEnd();
326 
327  // Read track picture into memory to be able to generate mipmaps. I read back an RGBA
328  // image because I don't know yet what people want to add to the map, so RGBA is most
329  // flexible to add things like start line, elevation coloring etc.
330  // Do not use GL_ALPHA or GL_LUMINANCE to save memory, somehow this leads to a
331  // performance penalty (at least on NVidia cards).
332  GLuint *trackImage = (GLuint*) malloc(texturesize*texturesize*sizeof(GLuint));
333  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
334  glPixelStorei(GL_PACK_ALIGNMENT, 1);
335  glReadBuffer(GL_BACK);
336  glReadPixels(0, 0, texturesize, texturesize, GL_RGBA, GL_BYTE, trackImage);
337 
338  // Check if the color buffer has alpha, if not fix the texture. Black gets
339  // replaced by transparent black, so don't draw black in the texture, you
340  // won't see anything.
341  if (glutGet(GLUT_WINDOW_ALPHA_SIZE) == 0) {
342  // There is no alpha, so we fix it manually. Because we added a little border
343  // around the track map the first pixel should always contain the
344  // clearcolor.
345  GLuint clearcolor = trackImage[0];
346  int i;
347  for (i = 0; i < texturesize*texturesize; i++) {
348  if (trackImage[i] == clearcolor) {
349  // Assumption: transparent black is 0, portable?
350  trackImage[i] = 0;
351  }
352  }
353  }
354 
355  // Finally copy the created image of the track from the framebuffer into the texture.
356  glGenTextures (1, &mapTexture);
357  glBindTexture(GL_TEXTURE_2D, mapTexture);
358  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
359  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
360  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
361  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
362 
363 
364  // If GL_ARB_texture_compression is available at runtime, (try to) compress the
365  // texture. This is done with the specification of the internal format to
366  // GL_COMPRESSED_RGBA_ARB.
367  if (isCompressARBAvailable()) {
368  // This texture contains mostly the clear color value and should therefore
369  // compress well even with high quality.
370  glHint(GL_TEXTURE_COMPRESSION_HINT_ARB, GL_NICEST);
371  gluBuild2DMipmaps(GL_TEXTURE_2D, GL_COMPRESSED_RGBA_ARB, texturesize, texturesize, GL_RGBA, GL_BYTE, trackImage);
372  // The following commented code is just for testing purposes.
373  /*int compressed;
374  glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_ARB, &compressed);
375  if (compressed == GL_TRUE) {
376  int csize;
377  printf("compression succesful!\n");
378  glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &csize);
379  printf("compression ratio: %d to %d\n", csize, texturesize*texturesize*sizeof(GLuint));
380  }*/
381  } else {
382  // GL_ARB_texture_compression not available at runtime, fallback.
383  gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, texturesize, texturesize, GL_RGBA, GL_BYTE, trackImage);
384  }
385 
386  // Free the memory of the initial texture.
387  free(trackImage);
388 
389  // Init the position and size of the map in the window.
390  map_x = -10;
391  map_y = -40;
392  map_size = 170;
393 
394  // Restore some state.
395  glPopMatrix();
396 
397  // Compile the car "dot" display list.
398  cardot = glGenLists(1);
399  if (cardot != 0) {
400  glNewList(cardot, GL_COMPILE);
401  glBegin(GL_TRIANGLE_FAN);
402  // The center.
403  glVertex2f(0.0, 0.0);
404  // The border.
405  int i;
406  const int borderpoints = 8;
407  halflinewidth = halflinewidth*float(map_size)/float(texturesize);
408  for (i = 0; i < borderpoints + 1; i++) {
409  float phi = 2.0*PI*float(i)/float(borderpoints);
410  glVertex2f(halflinewidth*cos(phi), halflinewidth*sin(phi));
411  }
412  glEnd();
413  glEndList();
414  }
415 
416  // Clear the screen, that in case of a delay the track is not visible.
417  glClear(GL_COLOR_BUFFER_BIT);
418  }
419 }
420 
421 
422 // Release the texture and data.
424 {
425  // We have just one track texture object, so delete it just once.
426  if (isinitalized) {
427  glDeleteTextures(1, &mapTexture);
428  isinitalized = false;
429  if (cardot != 0) {
430  glDeleteLists(cardot, 1);
431  }
432  }
433 }
434 
435 
436 // Walk trough the different available display modes
438 {
439  viewmode <<= 1;
440  if (viewmode > TRACK_MAP_MASK) {
442  }
443 }
444 
445 
446 // Draw the track map according to the display mode
448  tCarElt *currentCar,
449  tSituation *situation,
450  int Winx,
451  int Winy,
452  int Winw,
453  int Winh
454 )
455 {
456  if (viewmode == TRACK_MAP_NONE) {
457  return;
458  }
459 
460  // Compute track map position.
461  int x = Winx + Winw + map_x - (int) (map_size*track_x_ratio);
462  int y = Winy + Winh + map_y - (int) (map_size*track_y_ratio);
463 
464  // Setup and display track map.
465  glEnable(GL_BLEND);
466  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
467  glEnable(GL_TEXTURE_2D);
468  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
469  glBindTexture(GL_TEXTURE_2D, mapTexture);
470 
471  // Draw track.
473  drawTrackNormal(x, y);
475  drawTrackPanning(Winx, Winy, Winw, Winh, currentCar, situation);
477  drawTrackPanningAligned(Winx, Winy, Winw, Winh, currentCar, situation);
478  }
479 
480  // Draw cars in normal map mode.
482  drawCars(currentCar, situation, x, y);
483  }
485  drawCar(currentCar, currentCarColor, x, y);
486  }
487 
488 }
489 
490 
491 // Draw the track full visible and static.
493 {
494  glBegin(GL_QUADS);
495  glTexCoord2f(0.0, 0.0); glVertex2f(x, y);
496  glTexCoord2f(1.0, 0.0); glVertex2f(x + map_size, y);
497  glTexCoord2f(1.0, 1.0); glVertex2f(x + map_size, y + map_size);
498  glTexCoord2f(0.0, 1.0); glVertex2f(x, y + map_size);
499  glEnd();
500 }
501 
502 
503 // Draw the track in the panning mode.
505  int Winx,
506  int Winy,
507  int Winw,
508  int Winh,
509  tCarElt *currentCar,
510  tSituation *s
511 )
512 {
513  float x1, y1, x2, y2;
514  float tracksize = MAX(track_width, track_height);
515  float radius = MIN(500.0, tracksize/2.0);
516  x1 = (currentCar->_pos_X - radius - track_min_x)/tracksize;
517  y1 = (currentCar->_pos_Y - radius - track_min_y)/tracksize;
518  x2 = (currentCar->_pos_X + radius - track_min_x)/tracksize;
519  y2 = (currentCar->_pos_Y + radius - track_min_y)/tracksize;
520 
521  // Draw track.
522  int x = Winx + Winw + map_x - map_size;
523  int y = Winy + Winh + map_y - map_size;
524  glBegin(GL_QUADS);
525  glTexCoord2f(x1, y1); glVertex2f(x, y);
526  glTexCoord2f(x2, y1); glVertex2f(x + map_size, y);
527  glTexCoord2f(x2, y2); glVertex2f(x + map_size, y + map_size);
528  glTexCoord2f(x1, y2); glVertex2f(x, y + map_size);
529  glEnd();
530 
531  // Draw car "dots".
532  glDisable(GL_BLEND);
533  glDisable(GL_TEXTURE_2D);
534 
536  int i;
537  for (i = 0; i < s->_ncars; i++) {
538  if ((s->cars[i] != currentCar) &&
539  !(s->cars[i]->_state &
541  {
542  if (s->cars[i]->race.pos > currentCar->race.pos) {
543  glColor4fv(behindCarColor);
544  } else {
545  glColor4fv(aheadCarColor);
546  }
547  float xc = s->cars[i]->_pos_X - currentCar->_pos_X;
548  float yc = s->cars[i]->_pos_Y - currentCar->_pos_Y;
549  if (fabs(xc) < radius && fabs(yc) < radius) {
550  xc = xc/radius*map_size;
551  yc = yc/radius*map_size;
552 
553  glPushMatrix();
554  glTranslatef(x + (xc + map_size)/2.0, y + (yc + map_size)/2.0, 0.0);
555  float factor = tracksize/(2.0*radius);
556  glScalef(factor, factor, 1.0);
557  glCallList(cardot);
558  glPopMatrix();
559  }
560  }
561  }
562  }
563 
564  glColor4fv(currentCarColor);
565  if (cardot != 0) {
566  glMatrixMode(GL_MODELVIEW);
567  glPushMatrix();
568  glTranslatef(x + map_size/2.0, y + map_size/2.0, 0.0);
569  float factor = tracksize/(2.0*radius);
570  glScalef(factor, factor, 1.0);
571  glCallList(cardot);
572  glPopMatrix();
573  }
574 }
575 
576 
577 // Draw the track in the panning aligned mode.
579  int Winx,
580  int Winy,
581  int Winw,
582  int Winh,
583  tCarElt *currentCar,
584  tSituation *s
585 )
586 {
587  float tracksize = MAX(track_width, track_height);
588  float radius = MIN(500.0, tracksize/2.0);
589 
590  float x = Winx + Winw + map_x - map_size;
591  float y = Winy + Winh + map_y - map_size;
592  glMatrixMode(GL_TEXTURE);
593  glPushMatrix();
594 
595  glTranslatef(
596  (currentCar->_pos_X - track_min_x)/tracksize,
597  (currentCar->_pos_Y - track_min_y)/tracksize,
598  0.0
599  );
600  glRotatef(currentCar->_yaw*360.0/(2.0*PI) - 90.0, 0.0, 0.0, 1.0);
601  float factor = (2.0*radius)/tracksize;
602  glScalef(factor, factor, 1.0);
603  glTranslatef(-0.5, -0.5, 0.0);
604 
605  glBegin(GL_QUADS);
606  glTexCoord2f(0.0, 0.0); glVertex2f(x, y);
607  glTexCoord2f(1.0, 0.0); glVertex2f(x + map_size, y);
608  glTexCoord2f(1.0, 1.0); glVertex2f(x + map_size, y + map_size);
609  glTexCoord2f(0.0, 1.0); glVertex2f(x, y + map_size);
610  glEnd();
611 
612  glPopMatrix();
613  glMatrixMode(GL_MODELVIEW);
614 
615  // Draw car "dots".
616  glDisable(GL_BLEND);
617  glDisable(GL_TEXTURE_2D);
618 
620  int i;
621  for (i = 0; i < s->_ncars; i++) {
622  if ((s->cars[i] != currentCar) && !(s->cars[i]->_state & (RM_CAR_STATE_DNF | RM_CAR_STATE_PULLUP | RM_CAR_STATE_PULLSIDE | RM_CAR_STATE_PULLDN))) {
623  if (s->cars[i]->race.pos > currentCar->race.pos) {
624  glColor4fv(behindCarColor);
625  } else {
626  glColor4fv(aheadCarColor);
627  }
628  float xc = (s->cars[i]->_pos_X - currentCar->_pos_X)/(radius*2.0)*map_size;
629  float yc = (s->cars[i]->_pos_Y - currentCar->_pos_Y)/(radius*2.0)*map_size;
630  float ss = sin(-currentCar->_yaw + PI/2.0);
631  float cs = cos(-currentCar->_yaw + PI/2.0);
632  float xrc = xc * cs - yc * ss;
633  float yrc = xc * ss + yc * cs;
634 
635  if (fabs(xrc) < map_size/2.0 && fabs(yrc) < map_size/2.0) {
636  glPushMatrix();
637  glTranslatef(x + xrc + map_size/2.0, y + yrc + map_size/2.0, 0.0);
638  float factor = tracksize/(2.0*radius);
639  glScalef(factor, factor, 1.0);
640  glCallList(cardot);
641  glPopMatrix();
642  }
643  }
644  }
645  }
646 
647  glColor4fv(currentCarColor);
648  if (cardot != 0) {
649  glMatrixMode(GL_MODELVIEW);
650  glPushMatrix();
651  glTranslatef(x + map_size/2.0, y + map_size/2.0, 0.0);
652  glScalef(1.0/factor, 1.0/factor, 1.0);
653  glCallList(cardot);
654  glPopMatrix();
655  }
656 }
657 
658 
659 // Draw the dot of the car.
660 void cGrTrackMap::drawCar(tCarElt *currentCar, GLfloat* color, int x, int y)
661 {
662  // Compute screen coordinates of the car.
663  float car_x = (currentCar->_pos_X - track_min_x)/track_width*map_size*track_x_ratio + x;
664  float car_y = (currentCar->_pos_Y - track_min_y)/track_height*map_size*track_y_ratio + y;
665 
666  glDisable(GL_BLEND);
667  glDisable(GL_TEXTURE_2D);
668  glColor4fv(color);
669 
670  if (cardot != 0) {
671  glMatrixMode(GL_MODELVIEW);
672  glPushMatrix();
673  glTranslatef(car_x, car_y, 0.0);
674  glCallList(cardot);
675  glPopMatrix();
676  }
677 }
678 
679 
680 // Draw all opponents of the current car.
681 void cGrTrackMap::drawCars(tCarElt *currentCar, tSituation *s, int x, int y)
682 {
683  int i;
684  for (i = 0; i < s->_ncars; i++) {
685  if ((s->cars[i] != currentCar) &&
686  !(s->cars[i]->_state &
688  {
689  if (s->cars[i]->race.pos > currentCar->race.pos) {
690  drawCar(s->cars[i], behindCarColor, x, y);
691  } else {
692  drawCar(s->cars[i], aheadCarColor, x, y);
693  }
694  }
695  }
696 }
697 
698 
699 // Checks if the new value is a minimum, and if true it assigns it
700 inline void cGrTrackMap::checkAndSetMinimum(float &currentmin, float &value)
701 {
702  if (value < currentmin) {
703  currentmin = value;
704  }
705  return;
706 }
707 
708 
709 // Checks if the new value is a maximum, and if true it assigns it
710 inline void cGrTrackMap::checkAndSetMaximum(float &currentmax, float &value)
711 {
712  if (value > currentmax) {
713  currentmax = value;
714  }
715  return;
716 }
717 
718 
719 // Setus up colors.
721 {
722  currentCarColor[0] = 1.0;
723  currentCarColor[1] = 0.0;
724  currentCarColor[2] = 0.0;
725  currentCarColor[3] = 1.0;
726 
727  aheadCarColor[0] = 0.0;
728  aheadCarColor[1] = 1.0;
729  aheadCarColor[2] = 0.0;
730  aheadCarColor[3] = 1.0;
731 
732  behindCarColor[0] = 0.0;
733  behindCarColor[1] = 0.0;
734  behindCarColor[2] = 1.0;
735  behindCarColor[3] = 1.0;
736 }
737 
738 
739 // Set the view mode
741  viewmode = vm;
742 }
743 
744 // Get The view mode
746  return viewmode;
747 }
748 
749 // Get the default view mode
752 }
static int map_x
Definition: grtrackmap.h:122
tTrack * grTrack
Definition: grscene.cpp:57
#define RM_CAR_STATE_DNF
Car did not finish.
Definition: car.h:212
static float track_x_ratio
Definition: grtrackmap.h:118
#define TR_SR
Start-Right corner.
Definition: track.h:333
tCarRaceInfo race
public
Definition: car.h:460
static const float RESOLUTION
Definition: grtrackmap.h:94
int type
Geometrical type:
Definition: track.h:280
t3Dd center
Center of the curve.
Definition: track.h:324
static bool isinitalized
Definition: grtrackmap.h:101
cars situation used to inform the GUI and the drivers
Definition: raceman.h:85
static GLuint mapTexture
Definition: grtrackmap.h:104
static float track_max_x
Definition: grtrackmap.h:111
#define TR_STR
Straight.
Definition: track.h:287
tCarElt ** cars
list of cars
Definition: raceman.h:90
static float track_min_y
Definition: grtrackmap.h:112
Car structure (tCarElt).
Definition: car.h:455
static GLfloat aheadCarColor[4]
Definition: grtrackmap.h:131
#define TR_SL
Start-Left corner.
Definition: track.h:332
#define TRACK_MAP_PAN_ALIGNED
Definition: grtrackmap.h:47
Track structure.
Definition: track.h:502
#define RM_CAR_STATE_PULLSIDE
Car pulled out in the air.
Definition: car.h:214
void checkAndSetMaximum(float &currentmax, float &value)
Definition: grtrackmap.cpp:710
void drawTrackPanningAligned(int Winx, int Winy, int Winw, int Winh, tCarElt *currentCar, tSituation *s)
Definition: grtrackmap.cpp:578
void initColors()
Definition: grtrackmap.cpp:720
const double PI
PI.
Definition: tgf.h:69
void display(tCarElt *currentCar, tSituation *situation, int Winx, int Winy, int Winw, int Winh)
Definition: grtrackmap.cpp:447
static float track_min_x
Definition: grtrackmap.h:110
The Gaming Framework API (client part).
static GLuint cardot
Definition: grtrackmap.h:107
bool isCompressARBAvailable(void)
Definition: glfeatures.cpp:93
#define RM_CAR_STATE_PULLDN
Car pulled out in the air.
Definition: car.h:215
int grWinh
Definition: grmain.cpp:62
static float track_width
Definition: grtrackmap.h:114
void drawTrackPanning(int Winx, int Winy, int Winw, int Winh, tCarElt *currentCar, tSituation *situation)
Definition: grtrackmap.cpp:504
#define TRACK_MAP_NONE
Definition: grtrackmap.h:42
static int Winx
Definition: grboard.cpp:52
static GLfloat currentCarColor[4]
Definition: grtrackmap.h:130
#define TRACK_MAP_NORMAL_WITH_OPPONENTS
Definition: grtrackmap.h:44
#define TRACK_MAP_NORMAL
Definition: grtrackmap.h:43
static const float MINLINEWIDTH
Definition: grtrackmap.h:97
static float track_y_ratio
Definition: grtrackmap.h:119
int getDefaultViewMode()
Definition: grtrackmap.cpp:750
#define TR_LFT
Left curve.
Definition: track.h:286
Scalar length(const Quaternion &q)
Definition: Quaternion.h:193
static int Winy
Definition: grboard.cpp:54
static int map_size
Definition: grtrackmap.h:124
Definition: Endpoint.h:36
static GLfloat behindCarColor[4]
Definition: grtrackmap.h:132
static int Winh
Definition: grboard.cpp:55
tdble radius
Radius in meters of the middle of the track (>0)
Definition: track.h:320
tdble y
y coordinate
Definition: tgf.h:117
int pos
Definition: car.h:152
t3Dd vertex[4]
Coordinates of the 4 corners of the segment.
Definition: track.h:325
#define TRACK_MAP_PAN_WITH_OPPONENTS
Definition: grtrackmap.h:46
void selectTrackMap()
Definition: grtrackmap.cpp:437
Track segment (tTrackSeg) The segments can be straights (type TR_STR): (the track goes from the right...
Definition: track.h:276
int track(tModInfo *modInfo)
Definition: trackitf.cpp:85
static Vector y[4]
Definition: Convex.cpp:56
#define TRACK_MAP_PAN
Definition: grtrackmap.h:45
static int map_y
Definition: grtrackmap.h:123
void drawCars(tCarElt *currentCar, tSituation *s, int x, int y)
Definition: grtrackmap.cpp:681
#define TRACK_MAP_MASK
Definition: grtrackmap.h:51
struct trackSeg * next
Next segment.
Definition: track.h:397
void checkAndSetMinimum(float &currentmin, float &value)
Definition: grtrackmap.cpp:700
int getViewMode()
Definition: grtrackmap.cpp:745
static float ratio
Definition: grtrackmap.h:127
Definition: Endpoint.h:36
void drawCar(tCarElt *currentCar, GLfloat *color, int x, int y)
Definition: grtrackmap.cpp:660
int grWinw
Definition: grmain.cpp:62
void drawTrackNormal(int x, int y)
Definition: grtrackmap.cpp:492
#define TRACK_MAP_PAN_ALIGNED_WITH_OPPONENTS
Definition: grtrackmap.h:48
#define RM_CAR_STATE_PULLUP
Car pulled out in the air.
Definition: car.h:213
tdble x
x coordinate
Definition: tgf.h:116
static float track_max_y
Definition: grtrackmap.h:113
void setViewMode(int vm)
Definition: grtrackmap.cpp:740
static int Winw
Definition: grboard.cpp:53
static float track_height
Definition: grtrackmap.h:115
static const float MAXLINEWIDTH
Definition: grtrackmap.h:98