TORCS  1.3.10
The Open Racing Car Simulator
Loading...
Searching...
No Matches
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.
31const float cGrTrackMap::RESOLUTION = 5.0;
32
33// Minimum and Maximum line width in pixels to draw the track.
34const float cGrTrackMap::MINLINEWIDTH = 5.0;
35const float cGrTrackMap::MAXLINEWIDTH = 20.0;
36
37// Some data needs just one initalization, after first initialization this is set to true.
38bool cGrTrackMap::isinitalized = false;
39
40// Track overview texture object.
42
43// The car "dot" display list.
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.
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
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.
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.
660void 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.
681void 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
700inline 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
710inline 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
static Vector y[4]
Definition Convex.cpp:56
static const double PI
Scalar length(const Quaternion &q)
Definition Quaternion.h:193
#define RM_CAR_STATE_PULLSIDE
Car pulled out in the air.
Definition car.h:214
#define RM_CAR_STATE_DNF
Car did not finish.
Definition car.h:212
struct CarElt tCarElt
Car structure (tCarElt).
#define RM_CAR_STATE_PULLUP
Car pulled out in the air.
Definition car.h:213
#define RM_CAR_STATE_PULLDN
Car pulled out in the air.
Definition car.h:215
void initColors()
static float track_y_ratio
Definition grtrackmap.h:119
static int map_size
Definition grtrackmap.h:124
static GLuint mapTexture
Definition grtrackmap.h:104
void selectTrackMap()
static GLfloat behindCarColor[4]
Definition grtrackmap.h:132
static int map_x
Definition grtrackmap.h:122
static const float MAXLINEWIDTH
Definition grtrackmap.h:98
void drawTrackPanning(int Winx, int Winy, int Winw, int Winh, tCarElt *currentCar, tSituation *situation)
static float track_width
Definition grtrackmap.h:114
static float track_max_y
Definition grtrackmap.h:113
static float track_min_x
Definition grtrackmap.h:110
void checkAndSetMaximum(float &currentmax, float &value)
static GLfloat currentCarColor[4]
Definition grtrackmap.h:130
void display(tCarElt *currentCar, tSituation *situation, int Winx, int Winy, int Winw, int Winh)
static const float RESOLUTION
Definition grtrackmap.h:94
void setViewMode(int vm)
void drawTrackNormal(int x, int y)
void drawCars(tCarElt *currentCar, tSituation *s, int x, int y)
static const float MINLINEWIDTH
Definition grtrackmap.h:97
static GLfloat aheadCarColor[4]
Definition grtrackmap.h:131
void drawCar(tCarElt *currentCar, GLfloat *color, int x, int y)
static float track_min_y
Definition grtrackmap.h:112
void checkAndSetMinimum(float &currentmin, float &value)
static float track_max_x
Definition grtrackmap.h:111
static GLuint cardot
Definition grtrackmap.h:107
static float ratio
Definition grtrackmap.h:127
int getDefaultViewMode()
static float track_x_ratio
Definition grtrackmap.h:118
void drawTrackPanningAligned(int Winx, int Winy, int Winw, int Winh, tCarElt *currentCar, tSituation *s)
static int map_y
Definition grtrackmap.h:123
static bool isinitalized
Definition grtrackmap.h:101
int getViewMode()
static float track_height
Definition grtrackmap.h:115
bool isCompressARBAvailable(void)
static int Winw
Definition grboard.cpp:52
static int Winx
Definition grboard.cpp:51
static int Winh
Definition grboard.cpp:54
static int Winy
Definition grboard.cpp:53
int grWinw
Definition grmain.cpp:61
int grWinh
Definition grmain.cpp:61
struct trackSeg tTrackSeg
Track segment (tTrackSeg) The segments can be straights (type TR_STR): (the track goes from the right...
#define TRACK_MAP_PAN_ALIGNED
Definition grtrackmap.h:47
#define TRACK_MAP_PAN
Definition grtrackmap.h:45
tTrack * grTrack
Definition grscene.cpp:58
#define TRACK_MAP_PAN_WITH_OPPONENTS
Definition grtrackmap.h:46
#define TRACK_MAP_NORMAL_WITH_OPPONENTS
Definition grtrackmap.h:44
#define TRACK_MAP_MASK
Definition grtrackmap.h:51
#define TRACK_MAP_NONE
Definition grtrackmap.h:42
#define TRACK_MAP_NORMAL
Definition grtrackmap.h:43
#define TRACK_MAP_PAN_ALIGNED_WITH_OPPONENTS
Definition grtrackmap.h:48
struct Situation tSituation
cars situation used to inform the GUI and the drivers
tCarRaceInfo race
public
Definition car.h:462
tCarElt ** cars
list of cars
Definition raceman.h:89
tdble y
y coordinate
Definition tgf.h:116
tdble x
x coordinate
Definition tgf.h:115
int pos
Definition car.h:152
Track structure.
Definition track.h:533
int type
Geometrical type:
Definition track.h:297
t3Dd vertex[4]
Coordinates of the 4 corners of the segment.
Definition track.h:342
tdble radius
Radius in meters of the middle of the track (>0)
Definition track.h:337
t3Dd center
Center of the curve.
Definition track.h:341
struct trackSeg * next
Next segment.
Definition track.h:412
#define MIN(x, y)
Definition tgf.h:56
#define MAX(x, y)
Definition tgf.h:52
#define TR_LFT
Left curve.
Definition track.h:303
#define TR_STR
Straight.
Definition track.h:304
#define TR_SL
Start-Left corner.
Definition track.h:349
#define TR_SR
Start-Right corner.
Definition track.h:350
int track(tModInfo *modInfo)
Definition trackitf.cpp:85