1 //
2 // Copyright (C) 2004-2006 Jasmine Langridge, ja-reiko@users.sourceforge.net
3 // Copyright (C) 2015 Andrei Bondor, ab396356@users.sourceforge.net
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 //
19
20 #include <cmath>
21 #include "main.h"
22
resize()23 void MainApp::resize()
24 {
25 glClearColor(1.0,1.0,1.0,1.0);
26 glEnable(GL_TEXTURE_2D);
27
28 glEnable(GL_BLEND);
29 glBlendFunc(GL_ONE,GL_ZERO);
30
31 glDepthFunc(GL_LEQUAL);
32 glEnable(GL_DEPTH_TEST);
33 glClearDepth(1.0);
34
35 glEnable(GL_CULL_FACE);
36
37 glEnable(GL_FOG);
38 glFogi(GL_FOG_MODE, GL_EXP);
39
40 glEnable(GL_LIGHT0);
41 glEnable(GL_LIGHTING);
42
43 const GLfloat ambcol[] = {0.1f, 0.1f, 0.1f, 0.0f};
44 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambcol);
45
46 float white[] = { 1.0,1.0,1.0,1.0 };
47 //float black[] = { 0.0,0.0,0.0,1.0 };
48 glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,white);
49
50 float spec[] = { 0.3f, 0.5f, 0.5f, 1.0f };
51 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
52 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 6.0f);
53
54 float litcol[] = { 0.6,0.6,0.6,0.0 };
55 glLightfv(GL_LIGHT0,GL_DIFFUSE,litcol);
56 glLightfv(GL_LIGHT0,GL_SPECULAR,litcol);
57
58 glEnable(GL_NORMALIZE);
59 }
60
drawBlades(float radius,float ang,float trace)61 void drawBlades(float radius, float ang, float trace)
62 {
63 float invtrace = 1.0 / trace;
64 glPushMatrix();
65 glScalef(radius, radius, 1.0);
66 for (float ba=0; ba<PI*2.0-0.01; ba+=PI/2.0)
67 {
68 glBegin(GL_TRIANGLE_FAN);
69 glColor4f(0.1,0.1,0.1,0.24 * invtrace);
70 glVertex2f(0.0,0.0);
71 glColor4f(0.1,0.1,0.1,0.06 * invtrace);
72 int num = (int)(trace / 0.1);
73 if (num < 2) num = 2;
74 float mult = trace / (float)(num-1);
75 float angadd = ba + ang;
76 for (int i=0; i<num; ++i)
77 {
78 float a = (float)i * mult + angadd;
79 glVertex2f(cos(a),sin(a));
80 }
81 glEnd();
82 }
83 glPopMatrix();
84 }
85
renderWater()86 void MainApp::renderWater()
87 {
88 tex_water->bind();
89 {
90 float tgens[] = { 0.5,0,0,0 };
91 float tgent[] = { 0,0.5,0,0 };
92 glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
93 glTexGenfv(GL_S,GL_OBJECT_PLANE,tgens);
94 glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
95 glTexGenfv(GL_T,GL_OBJECT_PLANE,tgent);
96 }
97 glEnable(GL_TEXTURE_GEN_S);
98 glEnable(GL_TEXTURE_GEN_T);
99 glPushMatrix();
100 glScalef(20.0,20.0,1.0);
101 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
102 glEnable(GL_BLEND);
103 {
104 int minx = (int)(campos.x / 20.0)-20,
105 maxx = minx + 40,
106 miny = (int)(campos.y / 20.0)-20,
107 maxy = miny + 40;
108 for (int y=miny; y<maxy; ++y)
109 {
110 glBegin(GL_TRIANGLE_STRIP);
111 for (int x=minx; x<=maxx; ++x)
112 {
113 float maxalpha = 0.5f;
114
115 if (game->water.useralpha)
116 maxalpha = game->water.alpha;
117
118 if (game->water.fixedalpha)
119 {
120 glColor4f(1.0f, 1.0f, 1.0f, maxalpha);
121 glVertex3f(x, y+1, game->water.height);
122 glVertex3f(x, y, game->water.height);
123 }
124 else
125 {
126 float ht,alpha;
127 ht = game->terrain->getHeight((x)*20.0,(y+1)*20.0);
128 alpha = 1.0 - exp(ht - game->water.height);
129 CLAMP(alpha, 0.0f, maxalpha);
130 glColor4f(1.0,1.0,1.0,alpha);
131 glVertex3f(x, y+1, game->water.height);
132 ht = game->terrain->getHeight((x)*20.0,(y)*20.0);
133 alpha = 1.0 - exp(ht - game->water.height);
134 CLAMP(alpha, 0.0f, maxalpha);
135 glColor4f(1.0,1.0,1.0,alpha);
136 glVertex3f(x, y, game->water.height);
137 }
138 }
139 glEnd();
140 }
141 }
142 glPopMatrix();
143 glBlendFunc(GL_ONE,GL_ZERO);
144
145 glDisable(GL_TEXTURE_GEN_S);
146 glDisable(GL_TEXTURE_GEN_T);
147 }
148
renderSky(const mat44f & cammat)149 void MainApp::renderSky(const mat44f &cammat)
150 {
151 glFogf(GL_FOG_DENSITY, game->weather.fog.density_sky);
152 glDepthRange(0.999,1.0);
153 glDisable(GL_CULL_FACE);
154 glPushMatrix(); // 1
155 glLoadIdentity();
156 glMultMatrixf(cammat);
157 tex_sky[0]->bind();
158 #define CLRANGE 10
159 #define CLFACTOR 0.02//0.014
160 glMatrixMode(GL_TEXTURE);
161 glPushMatrix();
162 glTranslatef(cloudscroll,0.0,0.0);
163 glRotatef(30.0,0.0,0.0,1.0);
164 glScalef(0.4,0.4,1.0);
165 for (int y=-CLRANGE; y<CLRANGE; y++)
166 {
167 glBegin(GL_TRIANGLE_STRIP);
168 for (int x=-CLRANGE; x<CLRANGE+1; x++)
169 {
170 glTexCoord2i(x,y);
171 glVertex3f(x,y,0.3-(x*x+y*y)*CLFACTOR);
172 glTexCoord2i(x,y+1);
173 glVertex3f(x,y+1,0.3-(x*x+(y+1)*(y+1))*CLFACTOR);
174 }
175 glEnd();
176 }
177 glPopMatrix();
178 glMatrixMode(GL_MODELVIEW);
179 glPopMatrix(); // 1
180 glEnable(GL_CULL_FACE);
181 glDepthRange(0.0,0.999);
182 glFogf(GL_FOG_DENSITY, game->weather.fog.density);
183 }
184
render(float eyetranslation)185 void MainApp::render(float eyetranslation)
186 {
187 switch (appstate)
188 {
189 case AS_LOAD_1:
190 renderStateLoading(eyetranslation);
191 break;
192
193 case AS_LOAD_2:
194 case AS_LOAD_3:
195 break;
196
197 case AS_LEVEL_SCREEN:
198 renderStateLevel(eyetranslation);
199 break;
200
201 case AS_CHOOSE_VEHICLE:
202 renderStateChoose(eyetranslation);
203 break;
204
205 case AS_IN_GAME:
206 renderStateGame(eyetranslation);
207 break;
208
209 case AS_END_SCREEN:
210 renderStateEnd(eyetranslation);
211 break;
212 }
213
214 glFinish();
215 }
216
renderStateLoading(float eyetranslation)217 void MainApp::renderStateLoading(float eyetranslation)
218 {
219 UNREFERENCED_PARAMETER(eyetranslation);
220
221 glMatrixMode(GL_PROJECTION);
222 glPushMatrix();
223 glLoadIdentity();
224 glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
225 glMatrixMode(GL_MODELVIEW);
226
227 tex_splash_screen->bind();
228
229 glDisable(GL_DEPTH_TEST);
230 glDisable(GL_FOG);
231 glDisable(GL_LIGHTING);
232 glEnable(GL_BLEND);
233 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
234
235 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
236
237 glBegin(GL_QUADS);
238 // the background image is square and cut out a piece based on aspect ratio
239 // -------- if aspect ratio is larger than 4:3
240 // if aspect ratio is larger than 1:1
241 if ((float)getWidth()/(float)getHeight() > 1.0f)
242 {
243
244 // lower and upper offset based on aspect ratio
245 float off_l = (1 - ((float)getHeight() / (float)getWidth())) / 2.f;
246 float off_u = 1 - off_l;
247 glTexCoord2f(1.0f,off_u); glVertex2f(1.0f, 1.0f);
248 glTexCoord2f(0.0f,off_u); glVertex2f(-1.0f, 1.0f);
249 glTexCoord2f(0.0f,off_l); glVertex2f(-1.0f, -1.0f);
250 glTexCoord2f(1.0f,off_l); glVertex2f(1.0f, -1.0f);
251 }
252 // other cases (including 4:3, in which case off_l and off_u are = 1)
253 else
254 {
255
256 float off_l = (1 - ((float)getWidth() / (float)getHeight())) / 2.f;
257 float off_u = 1 - off_l;
258 glTexCoord2f(off_u,1.0f); glVertex2f(1.0f, 1.0f);
259 glTexCoord2f(off_l,1.0f); glVertex2f(-1.0f, 1.0f);
260 glTexCoord2f(off_l,0.0f); glVertex2f(-1.0f, -1.0f);
261 glTexCoord2f(off_u,0.0f); glVertex2f(1.0f, -1.0f);
262 }
263 glEnd();
264
265 tex_loading_screen->bind();
266
267 GLfloat logovratio = static_cast<float> (getWidth()) / getHeight();
268 GLfloat logohratio = static_cast<float> (getHeight()) / getWidth();
269
270 // FIXME: nasty, nasty code
271 if (logovratio > 1.0f)
272 logohratio = 1.0f;
273 else
274 if (logohratio > 1.0f)
275 logovratio = 1.0f;
276
277 #define LOGO_VRATIO (logovratio/3.5)
278 #define LOGO_HRATIO (logohratio/3.5)
279 glBegin(GL_QUADS);
280 glTexCoord2f(1.0f, 1.0f); glVertex2f( LOGO_HRATIO, LOGO_VRATIO);
281 glTexCoord2f(0.0f, 1.0f); glVertex2f(-LOGO_HRATIO, LOGO_VRATIO);
282 glTexCoord2f(0.0f, 0.0f); glVertex2f(-LOGO_HRATIO, -LOGO_VRATIO);
283 glTexCoord2f(1.0f, 0.0f); glVertex2f( LOGO_HRATIO, -LOGO_VRATIO);
284 glEnd();
285 #undef LOGO_VRATIO
286 #undef LOGO_HRATIO
287
288 glEnable(GL_DEPTH_TEST);
289 glEnable(GL_FOG);
290 glEnable(GL_LIGHTING);
291
292 glMatrixMode(GL_PROJECTION);
293 glPopMatrix();
294 glMatrixMode(GL_MODELVIEW);
295 }
296
297 const char *creditstext[] =
298 {
299 "Trigger Rally " PACKAGE_VERSION,
300 "",
301 "Copyright (C) 2004-2006",
302 "Jasmine Langridge and Richard Langridge",
303 "Posit Interactive",
304 "",
305 "Copyright (C) 2006-2016",
306 "Various Contributors",
307 "(see DATA_AUTHORS.txt)",
308 "",
309 "",
310 "",
311 "Coding",
312 "Jasmine Langridge",
313 "",
314 "Art & SFX",
315 "Richard Langridge",
316 "",
317 "",
318 "",
319 "Contributors",
320 "",
321 "Build system",
322 "Matze Braune",
323 "",
324 "Stereo support",
325 "Chuck Sites",
326 "",
327 "Mac OS X porting",
328 "Tim Douglas",
329 "",
330 "Fixes",
331 "LavaPunk",
332 "Bernhard Kaindl",
333 "Liviu Andronic",
334 "Ishmael Turner",
335 "Iwan 'qubodup' Gabovitch",
336 "Farrer",
337 "Andrei Bondor",
338 "Nikolay Orlyuk",
339 "Emanuele Sorce",
340 "",
341 "New levels",
342 "Tim Wintle",
343 "David Pagnier",
344 "Jared Buckner",
345 "Andreas Rosdal",
346 "Ivan",
347 "Viktor Radnai",
348 "Pierre-Alexis",
349 "Bruno 'Fuddl' Kleinert",
350 "Agnius Vasiliauskas",
351 "Matthias Keysermann",
352 "Marcio Bremm",
353 "Onsemeliot",
354 "",
355 "Graphics",
356 "Alex",
357 "Roberto Diez Gonzalez",
358 "",
359 "",
360 "",
361 "",
362 "",
363 "Thanks to Jonathan C. Hatfull",
364 "",
365 "",
366 "",
367 "",
368 "And thanks to Simon Brown too",
369 "",
370 "",
371 "",
372 "",
373 "",
374 "",
375 "Thanks for playing Trigger"
376 };
377
378 #define NUMCREDITSTRINGS (sizeof(creditstext) / sizeof(char*))
379
renderStateEnd(float eyetranslation)380 void MainApp::renderStateEnd(float eyetranslation)
381 {
382 eyetranslation = eyetranslation;
383
384 glMatrixMode(GL_PROJECTION);
385 glPushMatrix();
386 glLoadIdentity();
387 glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
388 glMatrixMode(GL_MODELVIEW);
389
390 tex_end_screen->bind();
391
392 glDisable(GL_DEPTH_TEST);
393 glDisable(GL_FOG);
394 glDisable(GL_LIGHTING);
395 glBlendFunc(GL_ONE, GL_ZERO);
396
397 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
398
399 glBegin(GL_QUADS);
400 // the background image is square and cut out a piece based on aspect ratio
401 // -------- if aspect ratio is larger than 4:3
402 // if aspect ratio is larger than 1:1
403 if ((float)getWidth()/(float)getHeight() > 1.0f)
404 {
405
406 // lower and upper offset based on aspect ratio
407 float off_l = (1 - ((float)getHeight() / (float)getWidth())) / 2.f;
408 float off_u = 1 - off_l;
409 glTexCoord2f(1.0f,off_u); glVertex2f(1.0f, 1.0f);
410 glTexCoord2f(0.0f,off_u); glVertex2f(-1.0f, 1.0f);
411 glTexCoord2f(0.0f,off_l); glVertex2f(-1.0f, -1.0f);
412 glTexCoord2f(1.0f,off_l); glVertex2f(1.0f, -1.0f);
413 }
414 // other cases (including 4:3, in which case off_l and off_u are = 1)
415 else
416 {
417
418 float off_l = (1 - ((float)getWidth() / (float)getHeight())) / 2.f;
419 float off_u = 1 - off_l;
420 glTexCoord2f(off_u,1.0f); glVertex2f(1.0f, 1.0f);
421 glTexCoord2f(off_l,1.0f); glVertex2f(-1.0f, 1.0f);
422 glTexCoord2f(off_l,0.0f); glVertex2f(-1.0f, -1.0f);
423 glTexCoord2f(off_u,0.0f); glVertex2f(1.0f, -1.0f);
424 }
425 glEnd();
426
427 tex_fontSourceCodeOutlined->bind();
428
429 glMatrixMode(GL_PROJECTION);
430 glPopMatrix();
431 glPushMatrix();
432 glLoadIdentity();
433 glOrtho(0 - hratio, hratio, 0 - vratio, vratio, 0 - 1.0, 1.0);
434 //glOrtho(-1, 1, -1, 1, -1, 1);
435 //glOrtho(800, 0, 600, 0, -1, 1);
436 glMatrixMode(GL_MODELVIEW);
437
438 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
439
440 glPushMatrix();
441
442 float scroll = splashtimeout;
443 const float maxscroll = (float)(NUMCREDITSTRINGS - 1) * 2.0f;
444 RANGEADJUST(scroll, 0.0f, 0.9f, -10.0f, maxscroll);
445 CLAMP_UPPER(scroll, maxscroll);
446
447 glScalef(0.1f, 0.1f, 1.0f);
448
449 glTranslatef(0.0f, scroll, 0.0f);
450
451 for (int i = 0; i < (int)NUMCREDITSTRINGS; i++)
452 {
453 float level = fabsf(scroll + (float)i * -2.0f);
454 RANGEADJUST(level, 0.0f, 9.0f, 3.0f, 0.0f);
455
456 if (level > 0.0f)
457 {
458 CLAMP_UPPER(level, 1.0f);
459
460 glPushMatrix();
461 glTranslatef(0.0f, (float)i * -2.0f, 0.0f);
462
463 float enlarge = 1.0f;
464
465 #if 1
466 if (splashtimeout > 0.9f)
467 {
468 float amt = (splashtimeout - 0.9f) * 10.0f;
469 float amt2 = amt * amt;
470
471 enlarge += amt2 / ((1.0001f - amt) * (1.0001f - amt));
472 level -= amt2;
473 }
474 #endif
475
476 glScalef(enlarge, enlarge, 0.0f);
477 glColor4f(1.0f, 1.0f, 1.0f, level);
478
479 getSSRender().drawText(creditstext[i], PTEXT_HZA_CENTER | PTEXT_VTA_CENTER);
480 glPopMatrix();
481 }
482 }
483
484 glPopMatrix();
485
486 glEnable(GL_DEPTH_TEST);
487 glEnable(GL_FOG);
488 glEnable(GL_LIGHTING);
489
490 glMatrixMode(GL_PROJECTION);
491 glPopMatrix();
492 glMatrixMode(GL_MODELVIEW);
493 }
494
renderStateChoose(float eyetranslation)495 void MainApp::renderStateChoose(float eyetranslation)
496 {
497 PVehicleType *vtype = game->vehiclechoices[choose_type];
498
499 glClearColor(0.0, 0.0, 0.0, 1.0);
500 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
501
502 glMatrixMode(GL_PROJECTION);
503
504 glPushMatrix();
505 glLoadIdentity();
506 glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
507
508 glMatrixMode(GL_MODELVIEW);
509
510 // draw background image
511
512 glBlendFunc(GL_ONE, GL_ZERO);
513 glDisable(GL_DEPTH_TEST);
514 glDisable(GL_FOG);
515 glDisable(GL_LIGHTING);
516
517 tex_splash_screen->bind();
518
519 //glColor4f(0.0f, 0.0f, 0.2f, 1.0f); // make image dark blue
520 glColor4f(1.0f, 1.0f, 1.0f, 1.0f); // use image's normal colors
521 //glColor4f(0.5f, 0.5f, 0.5f, 1.0f); // make image darker
522
523 glBegin(GL_QUADS);
524 // the background image is square and cut out a piece based on aspect ratio
525 // -------- if aspect ratio is larger than 4:3
526 // if aspect ratio is larger than 1:1
527 if ((float)getWidth()/(float)getHeight() > 1.0f)
528 {
529
530 // lower and upper offset based on aspect ratio
531 float off_l = (1 - ((float)getHeight() / (float)getWidth())) / 2.f;
532 float off_u = 1 - off_l;
533 glTexCoord2f(1.0f,off_u); glVertex2f(1.0f, 1.0f);
534 glTexCoord2f(0.0f,off_u); glVertex2f(-1.0f, 1.0f);
535 glTexCoord2f(0.0f,off_l); glVertex2f(-1.0f, -1.0f);
536 glTexCoord2f(1.0f,off_l); glVertex2f(1.0f, -1.0f);
537 }
538 // other cases (including 4:3, in which case off_l and off_u are = 1)
539 else
540 {
541
542 float off_l = (1 - ((float)getWidth() / (float)getHeight())) / 2.f;
543 float off_u = 1 - off_l;
544 glTexCoord2f(off_u,1.0f); glVertex2f(1.0f, 1.0f);
545 glTexCoord2f(off_l,1.0f); glVertex2f(-1.0f, 1.0f);
546 glTexCoord2f(off_l,0.0f); glVertex2f(-1.0f, -1.0f);
547 glTexCoord2f(off_u,0.0f); glVertex2f(1.0f, -1.0f);
548 }
549 glEnd();
550
551 glMatrixMode(GL_PROJECTION);
552 glPopMatrix();
553
554 glMatrixMode(GL_PROJECTION);
555 glLoadIdentity();
556
557 float fnear = 0.1f, fov = 0.6f;
558 float aspect = (float)getWidth() / (float)getHeight();
559 stereoFrustum(-fnear*aspect*fov,fnear*aspect*fov,-fnear*fov,fnear*fov,fnear,100000.0f,
560 0.8f, eyetranslation);
561 glMatrixMode(GL_MODELVIEW);
562
563
564 glPushMatrix(); // 0
565
566 // glTranslatef(-eyetranslation, 0.5f, -5.0f);
567 glTranslatef(-eyetranslation, 0.9f, -5.0f);
568 glRotatef(28.0f, 1.0f, 0.0f, 0.0f);
569
570 glDisable(GL_FOG);
571 glEnable(GL_LIGHTING);
572 glEnable(GL_DEPTH_TEST);
573
574 vec4f lpos = vec4f(0.0f, 1.0f, 0.0f, 0.0f);
575 glLightfv(GL_LIGHT0, GL_POSITION, lpos);
576
577 //float tmp = 1.0f;
578 //float tmp = sinf(choose_spin * 2.0f) * 0.5f;
579 float tmp = cosf(choose_spin * 2.0f) * 0.5f;
580 tmp += choose_spin;
581 glRotatef(90.0f, -1.0f, 0.0f, 0.0f);
582 glRotatef(DEGREES(tmp), 0.0f, 0.0f, 1.0f);
583
584 {
585 for (unsigned int i=0; i<vtype->part.size(); ++i)
586 {
587 glPushMatrix(); // 1
588
589 vec3f vpos = vtype->part[i].ref_local.pos;
590 glTranslatef(vpos.x, vpos.y, vpos.z);
591
592 mat44f vorim = vtype->part[i].ref_local.ori_mat_inv;
593 glMultMatrixf(vorim);
594 if (vtype->part[i].model)
595 {
596
597 glPushMatrix(); // 2
598
599 float scale = vtype->part[i].scale;
600 glScalef(scale,scale,scale);
601 drawModel(*vtype->part[i].model);
602
603 glPopMatrix(); // 2
604 }
605
606 if (vtype->wheelmodel)
607 {
608 for (unsigned int j=0; j<vtype->part[i].wheel.size(); j++)
609 {
610
611 glPushMatrix(); // 2
612
613 vec3f &wpos = vtype->part[i].wheel[j].pt;
614 glTranslatef(wpos.x, wpos.y, wpos.z);
615
616 float scale = vtype->wheelscale * vtype->part[i].wheel[j].radius;
617 glScalef(scale,scale,scale);
618
619 drawModel(*vtype->wheelmodel);
620
621 glPopMatrix(); // 2
622 }
623 }
624
625 glPopMatrix(); // 1
626 }
627 }
628
629 glPopMatrix(); // 0
630
631 glDisable(GL_LIGHTING);
632
633 glMatrixMode(GL_PROJECTION);
634 glPushMatrix();
635 glLoadIdentity();
636 glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
637 glMatrixMode(GL_MODELVIEW);
638
639 // use the same colors as the menu
640 const GuiWidgetColors gwc = gui.getColors();
641
642 tex_fontSourceCodeShadowed->bind();
643
644 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
645 glDisable(GL_DEPTH_TEST);
646 glDisable(GL_LIGHTING);
647
648 glPushMatrix(); // 0
649
650 const GLdouble margin = (800.0 - 600.0 * cx / cy) / 2.0;
651
652 glOrtho(margin, 600.0 * cx / cy + margin, 0.0, 600.0, -1.0, 1.0);
653
654 glPushMatrix(); // 1
655 glTranslatef(10.0f, 570.0f, 0.0f);
656 glScalef(30.0f, 30.0f, 1.0f);
657 glColor4f(gwc.weak.x, gwc.weak.y, gwc.weak.z, gwc.weak.w);
658 getSSRender().drawText("Trigger Rally", PTEXT_HZA_LEFT | PTEXT_VTA_CENTER);
659 glPopMatrix(); // 1
660
661 glPushMatrix(); // 1
662 glTranslatef(790.0f, 570.0f, 0.0f);
663 glScalef(20.0f, 20.0f, 1.0f);
664 glColor4f(gwc.weak.x, gwc.weak.y, gwc.weak.z, gwc.weak.w);
665 getSSRender().drawText(
666 "car selection " + std::to_string(choose_type + 1) + '/' + std::to_string(game->vehiclechoices.size()),
667 PTEXT_HZA_RIGHT | PTEXT_VTA_CENTER);
668 glPopMatrix(); // 1
669
670 glPushMatrix(); // 1
671 glTranslatef(100.0f, 230.0f, 0.0f);
672 glScalef(30.0f, 30.0f, 1.0f);
673 glColor4f(gwc.header.x, gwc.header.y, gwc.header.z, gwc.header.w);
674 getSSRender().drawText(vtype->proper_name.substr(0, 9), PTEXT_HZA_LEFT | PTEXT_VTA_CENTER);
675 glPopMatrix(); // 1
676
677 glPushMatrix(); // 1
678 glTranslatef(100.0f, 200.0f, 0.0f);
679 glScalef(20.0f, 20.0f, 1.0f);
680 glColor4f(gwc.strong.x, gwc.strong.y, gwc.strong.z, gwc.strong.w);
681 getSSRender().drawText(vtype->proper_class.substr(0, 8), PTEXT_HZA_LEFT | PTEXT_VTA_CENTER);
682 glPopMatrix(); // 1
683
684 glPushMatrix(); // 1
685 glTranslatef(500.0f, 230.0f, 0.0f);
686 glScalef(20.0f, 20.0f, 1.0f);
687 glColor4f(gwc.weak.x, gwc.weak.y, gwc.weak.z, gwc.weak.w);
688 getSSRender().drawText("Weight (Kg)", PTEXT_HZA_RIGHT | PTEXT_VTA_CENTER);
689 glPopMatrix(); // 1
690
691 glPushMatrix(); // 1
692 glTranslatef(500.0f, 190.0f, 0.0f);
693 glScalef(20.0f, 20.0f, 1.0f);
694 glColor4f(gwc.weak.x, gwc.weak.y, gwc.weak.z, gwc.weak.w);
695 getSSRender().drawText("Engine (BHP)", PTEXT_HZA_RIGHT | PTEXT_VTA_CENTER);
696 glPopMatrix(); // 1
697
698 glPushMatrix(); // 1
699 glTranslatef(500.0f, 150.0f, 0.0f);
700 glScalef(20.0f, 20.0f, 1.0f);
701 glColor4f(gwc.weak.x, gwc.weak.y, gwc.weak.z, gwc.weak.w);
702 getSSRender().drawText("Wheel drive", PTEXT_HZA_RIGHT | PTEXT_VTA_CENTER);
703 glPopMatrix(); // 1
704
705 glPushMatrix(); // 1
706 glTranslatef(500.0f, 110.0f, 0.0f);
707 glScalef(20.0f, 20.0f, 1.0f);
708 glColor4f(gwc.weak.x, gwc.weak.y, gwc.weak.z, gwc.weak.w);
709 getSSRender().drawText("Roadholding", PTEXT_HZA_RIGHT | PTEXT_VTA_CENTER);
710 glPopMatrix(); // 1
711
712 glPushMatrix(); // 1
713 glTranslatef(520.0f, 230.0f, 0.0f);
714 glScalef(30.0f, 30.0f, 1.0f);
715 glColor4f(gwc.strong.x, gwc.strong.y, gwc.strong.z, gwc.strong.w);
716 getSSRender().drawText(std::to_string(static_cast<int>(vtype->mass)), PTEXT_HZA_LEFT | PTEXT_VTA_CENTER);
717 glPopMatrix(); // 1
718
719 glPushMatrix(); // 1
720 glTranslatef(520.0f, 190.0f, 0.0f);
721 glScalef(30.0f, 30.0f, 1.0f);
722 glColor4f(gwc.strong.x, gwc.strong.y, gwc.strong.z, gwc.strong.w);
723 getSSRender().drawText(vtype->pstat_enginepower, PTEXT_HZA_LEFT | PTEXT_VTA_CENTER);
724 glPopMatrix(); // 1
725
726 glPushMatrix(); // 1
727 glTranslatef(520.0f, 150.0f, 0.0f);
728 glScalef(30.0f, 30.0f, 1.0f);
729 glColor4f(gwc.strong.x, gwc.strong.y, gwc.strong.z, gwc.strong.w);
730 getSSRender().drawText(vtype->pstat_wheeldrive, PTEXT_HZA_LEFT | PTEXT_VTA_CENTER);
731 glPopMatrix(); // 1
732
733 glPushMatrix(); // 1
734 glTranslatef(520.0f, 110.0f, 0.0f);
735 glScalef(30.0f, 30.0f, 1.0f);
736 glColor4f(gwc.strong.x, gwc.strong.y, gwc.strong.z, gwc.strong.w);
737 getSSRender().drawText(vtype->pstat_roadholding, PTEXT_HZA_LEFT | PTEXT_VTA_CENTER);
738 glPopMatrix(); // 1
739
740 std::string racename;
741
742 if (lss.state == AM_TOP_EVT_PREP || lss.state == AM_TOP_PRAC_SEL_PREP)
743 racename = events[lss.currentevent].name + ": " + events[lss.currentevent].levels[lss.currentlevel].name;
744 else
745 if (lss.state == AM_TOP_LVL_PREP)
746 racename = levels[lss.currentlevel].name;
747
748 glPushMatrix(); // 1
749 glTranslatef(400.0f, 30.0f, 0.0f);
750 glScalef(20.0f, 20.0f, 1.0f);
751 glColor4f(gwc.weak.x, gwc.weak.y, gwc.weak.z, gwc.weak.w);
752 getSSRender().drawText(racename, PTEXT_HZA_CENTER | PTEXT_VTA_CENTER);
753 glPopMatrix(); // 1
754
755 glPopMatrix(); // 0
756
757 glBlendFunc(GL_ONE, GL_ZERO);
758 glEnable(GL_DEPTH_TEST);
759 glEnable(GL_FOG);
760 glEnable(GL_LIGHTING);
761
762 glMatrixMode(GL_PROJECTION);
763 glPopMatrix();
764 glMatrixMode(GL_MODELVIEW);
765 }
766
renderStateGame(float eyetranslation)767 void MainApp::renderStateGame(float eyetranslation)
768 {
769 PVehicle *vehic = game->vehicle[0];
770
771 glClear(GL_DEPTH_BUFFER_BIT);
772 //glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
773
774 glMatrixMode(GL_PROJECTION);
775 glLoadIdentity();
776
777 float fnear = 0.1f, fov = 0.6f;
778 float aspect = (float)getWidth() / (float)getHeight();
779 stereoFrustum(-fnear*aspect*fov,fnear*aspect*fov,-fnear*fov,fnear*fov,fnear,100000.0f,
780 0.8f, eyetranslation);
781 glMatrixMode(GL_MODELVIEW);
782
783 glColor3f(1.0,1.0,1.0);
784
785 vec4f fogcolor(game->weather.fog.color, 1.0f);
786 glFogfv(GL_FOG_COLOR, fogcolor);
787
788 glDepthRange(0.0,0.999);
789
790 glPushMatrix(); // 0
791
792 mat44f cammat = camori.getMatrix();
793 mat44f cammat_inv = cammat.transpose();
794
795 //glTranslatef(0.0,0.0,-40.0);
796 glTranslatef(-eyetranslation, 0.0f, 0.0f);
797
798 glMultMatrixf(cammat);
799
800 glTranslatef(-campos.x, -campos.y, -campos.z);
801
802 float lpos[] = { 0.2, 0.5, 1.0, 0.0 };
803 glLightfv(GL_LIGHT0, GL_POSITION, lpos);
804
805 glColor3ub(255,255,255);
806
807 glDisable(GL_LIGHTING);
808
809 glActiveTextureARB(GL_TEXTURE1_ARB);
810 glEnable(GL_TEXTURE_2D);
811 glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
812 glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_ADD_SIGNED);
813 glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA,GL_MODULATE);
814 tex_detail->bind();
815 glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
816 glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
817 float tgens[] = { 0.05, 0.0, 0.0, 0.0 };
818 float tgent[] = { 0.0, 0.05, 0.0, 0.0 };
819 glTexGenfv(GL_S,GL_OBJECT_PLANE,tgens);
820 glTexGenfv(GL_T,GL_OBJECT_PLANE,tgent);
821 glEnable(GL_TEXTURE_GEN_S);
822 glEnable(GL_TEXTURE_GEN_T);
823 glActiveTextureARB(GL_TEXTURE0_ARB);
824
825 // draw terrain
826 game->terrain->render(campos, cammat_inv);
827
828 glDisable(GL_TEXTURE_GEN_S);
829 glDisable(GL_TEXTURE_GEN_T);
830
831 glActiveTextureARB(GL_TEXTURE1_ARB);
832 glDisable(GL_TEXTURE_2D);
833 glActiveTextureARB(GL_TEXTURE0_ARB);
834
835 if (renderowncar)
836 {
837 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
838
839 tex_shadow->bind();
840
841 glColor4f(1.0f, 1.0f, 1.0f, 0.7f);
842
843 vec3f vpos = game->vehicle[0]->body->pos;
844 vec3f forw = makevec3f(game->vehicle[0]->body->getOrientationMatrix().row[0]);
845 float forwangle = atan2(forw.y, forw.x);
846 game->terrain->drawSplat(vpos.x, vpos.y, 1.4f, forwangle + PI*0.5f);
847
848 glBlendFunc(GL_ONE, GL_ZERO);
849 }
850
851 renderSky(cammat);
852
853 glEnable(GL_LIGHTING);
854
855 for (unsigned int v=0; v<game->vehicle.size(); ++v)
856 {
857
858 if (!renderowncar && v == 0) continue;
859
860 PVehicle *vehic = game->vehicle[v];
861 for (unsigned int i=0; i<vehic->part.size(); ++i)
862 {
863 if (vehic->type->part[i].model)
864 {
865 glPushMatrix(); // 1
866
867 vec3f vpos = vehic->part[i].ref_world.pos;
868 glTranslatef(vpos.x, vpos.y, vpos.z);
869
870 mat44f vorim = vehic->part[i].ref_world.ori_mat_inv;
871 glMultMatrixf(vorim);
872
873 float scale = vehic->type->part[i].scale;
874 glScalef(scale,scale,scale);
875
876 drawModel(*vehic->type->part[i].model);
877
878 glPopMatrix(); // 1
879 }
880
881 if (vehic->type->wheelmodel)
882 {
883 for (unsigned int j=0; j<vehic->type->part[i].wheel.size(); j++)
884 {
885
886 glPushMatrix(); // 1
887
888 vec3f wpos = vehic->part[i].wheel[j].ref_world.getPosition();
889 glTranslatef(wpos.x,wpos.y,wpos.z);
890
891 mat44f worim = vehic->part[i].wheel[j].ref_world.ori_mat_inv;
892 glMultMatrixf(worim);
893
894 float scale = vehic->type->wheelscale * vehic->type->part[i].wheel[j].radius;
895 glScalef(scale,scale,scale);
896
897 drawModel(*vehic->type->wheelmodel);
898
899 glPopMatrix(); // 1
900 }
901 }
902 }
903 }
904
905 glDisable(GL_LIGHTING);
906
907 glDepthMask(GL_FALSE);
908 glDisable(GL_CULL_FACE);
909
910 glDisable(GL_TEXTURE_2D);
911
912 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
913
914 #define RAINDROP_WIDTH 0.015
915 const vec4f raindrop_col(0.5,0.5,0.5,0.4);
916
917 vec3f offsetdrops = campos - campos_prev;
918
919 for (unsigned int i = 0; i < rain.size(); i++)
920 {
921 vec3f tempv;
922 const float prevlife = rain[i].prevlife;
923 vec3f pt1 = rain[i].drop_pt + rain[i].drop_vect * prevlife + offsetdrops;
924 vec3f pt2 = rain[i].drop_pt + rain[i].drop_vect * rain[i].life;
925 vec3f zag = campos - rain[i].drop_pt;
926 zag = zag.cross(rain[i].drop_vect);
927 zag *= RAINDROP_WIDTH / zag.length();
928 glBegin(GL_TRIANGLE_STRIP);
929 glColor4f(raindrop_col[0],raindrop_col[1],raindrop_col[2],0.0);
930 tempv = pt1 - zag;
931 glVertex3fv(tempv);
932 tempv = pt2 - zag;
933 glVertex3fv(tempv);
934
935 glColor4fv(raindrop_col);
936 glVertex3fv(pt1);
937 glVertex3fv(pt2);
938
939 glColor4f(raindrop_col[0],raindrop_col[1],raindrop_col[2],0.0);
940 tempv = pt1 + zag;
941 glVertex3fv(tempv);
942 tempv = pt2 + zag;
943 glVertex3fv(tempv);
944 glEnd();
945 }
946
947 #define SNOWFLAKE_POINT_SIZE 3.0f
948 #define SNOWFLAKE_BOX_SIZE 0.175f
949
950 // NOTE: must be greater than 1.0f
951 #define SNOWFLAKE_MAXLIFE 4.5f
952
953 GLfloat ops; // Original Point Size, for to be restored
954
955 if (cfg_snowflaketype == SnowFlakeType::point)
956 {
957 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
958 glGetFloatv(GL_POINT_SIZE, &ops);
959 glPointSize(SNOWFLAKE_POINT_SIZE);
960 }
961 else
962 if (cfg_snowflaketype == SnowFlakeType::textured)
963 {
964 glEnable(GL_TEXTURE_2D);
965 glBlendFunc(GL_SRC_COLOR, GL_ONE);
966 tex_snowflake->bind();
967 }
968
969 for (const SnowFlake &sf: snowfall)
970 {
971 const vec3f pt = sf.drop_pt + sf.drop_vect * sf.life;
972 GLfloat alpha;
973
974 if (sf.life > SNOWFLAKE_MAXLIFE)
975 {
976 alpha = 0.0f;
977 }
978 else
979 if (sf.life > 1.0f)
980 {
981 #define ML SNOWFLAKE_MAXLIFE
982 // this equation ensures that snowflaks fade in
983 alpha = (sf.life - ML) / (1 - ML);
984 #undef ML
985 }
986 else
987 alpha = 1.0f;
988
989 if (cfg_snowflaketype == SnowFlakeType::point)
990 {
991 glBegin(GL_POINTS);
992 glColor4f(1.0f, 1.0f, 1.0f, alpha);
993 glVertex3fv(pt);
994 glEnd();
995 }
996 else
997 {
998 #define SBS SNOWFLAKE_BOX_SIZE
999 vec3f zag = campos - sf.drop_pt;
1000
1001 zag = zag.cross(sf.drop_vect);
1002 zag.normalize();
1003 zag *= SBS;
1004
1005 if (cfg_snowflaketype == SnowFlakeType::square)
1006 {
1007 glBegin(GL_TRIANGLE_STRIP);
1008 glColor4f(1.0f, 1.0f, 1.0f, alpha);
1009 glVertex3f(pt.x, pt.y, pt.z );
1010 glVertex3f(pt.x, pt.y, pt.z + zag.z + SBS );
1011 glVertex3f(pt.x + zag.x, pt.y + zag.y, pt.z );
1012 glVertex3f(pt.x + zag.x, pt.y + zag.y, pt.z + zag.z + SBS );
1013 glEnd();
1014 }
1015 else // cfg_snowflaketype == SnowFlakeType::textured
1016 {
1017 glBegin(GL_TRIANGLE_STRIP);
1018 glColor4f(1.0f, 1.0f, 1.0f, alpha);
1019 glTexCoord2f(1.0f, 1.0f);
1020 glVertex3f(pt.x, pt.y, pt.z );
1021 glTexCoord2f(0.0f, 1.0f);
1022 glVertex3f(pt.x, pt.y, pt.z + zag.z + SBS );
1023 glTexCoord2f(1.0f, 0.0f);
1024 glVertex3f(pt.x + zag.x, pt.y + zag.y, pt.z );
1025 glTexCoord2f(0.0f, 0.0f);
1026 glVertex3f(pt.x + zag.x, pt.y + zag.y, pt.z + zag.z + SBS );
1027 glEnd();
1028 }
1029 #undef SBS
1030 }
1031 }
1032
1033 if (cfg_snowflaketype == SnowFlakeType::point)
1034 glPointSize(ops); // restore original point size
1035
1036 // disable textures
1037 if (cfg_snowflaketype == SnowFlakeType::textured)
1038 {
1039 glDisable(GL_TEXTURE_2D);
1040 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1041 }
1042
1043 const vec4f checkpoint_col[3] =
1044 {
1045 vec4f(1.0f, 0.0f, 0.0f, 0.8f), // 0 = next checkpoint
1046 vec4f(0.7f, 0.7f, 0.1f, 0.6f), // 1 = checkpoint after next
1047 vec4f(0.2f, 0.8f, 0.2f, 0.4f) // 2 = all other checkpoints
1048 };
1049
1050 if (showcheckpoint)
1051 {
1052 for (unsigned int i=0; i<game->checkpt.size(); i++)
1053 {
1054 vec4f colr = checkpoint_col[2];
1055
1056 if ((int)i == vehic->nextcp)
1057 colr = checkpoint_col[0];
1058 else if ((int)i == (vehic->nextcp + 1) % (int)game->checkpt.size())
1059 colr = checkpoint_col[1];
1060
1061 glPushMatrix(); // 1
1062 glTranslatef(game->checkpt[i].pt.x, game->checkpt[i].pt.y, game->checkpt[i].pt.z);
1063 glScalef(25.0f, 25.0f, 1.0f);
1064
1065 #if 0 // Checkpoint style one
1066 glBegin(GL_TRIANGLE_STRIP);
1067
1068 for (float a = 0.0f; a < 0.99f; a += 0.05f)
1069 {
1070 glColor4f(colr[0], colr[1], colr[2], colr[3] * a);
1071 float ang = cprotate + a * 6.0f;
1072 float ht = sinf(ang * 1.7f) * 7.0f + 8.0f;
1073 glVertex3f(cosf(ang), sinf(ang), ht - 1.0f);
1074 glVertex3f(cosf(ang), sinf(ang), ht + 1.0f);
1075 }
1076
1077 for (float a = 1.0f; a < 2.01f; a += 0.05f)
1078 {
1079 glColor4f(colr[0], colr[1], colr[2], colr[3] * (2.0f - a));
1080 float ang = cprotate + a * 6.0f;
1081 float ht = sinf(ang * 1.7f) * 7.0f + 8.0f;
1082 glVertex3f(cosf(ang), sinf(ang), ht - 1.0f);
1083 glVertex3f(cosf(ang), sinf(ang), ht + 1.0f);
1084 }
1085
1086 glEnd();
1087 #else // Regular checkpoint style
1088 glBegin(GL_TRIANGLE_STRIP);
1089 float ht = sinf(cprotate * 6.0f) * 7.0f + 8.0f;
1090 glColor4f(colr[0], colr[1], colr[2], 0.0f);
1091 glVertex3f(1.0f, 0.0f, ht - 1.0f);
1092 glColor4f(colr[0], colr[1], colr[2], colr[3]);
1093 glVertex3f(1.0f, 0.0f, ht + 0.0f);
1094 for (float a = PI/10.0f; a < PI*2.0f-0.01f; a += PI/10.0f)
1095 {
1096 glColor4f(colr[0], colr[1], colr[2], 0.0f);
1097 glVertex3f(cosf(a), sinf(a), ht - 1.0f);
1098 glColor4f(colr[0], colr[1], colr[2], colr[3]);
1099 glVertex3f(cosf(a), sinf(a), ht + 0.0f);
1100 }
1101 glColor4f(colr[0], colr[1], colr[2], 0.0f);
1102 glVertex3f(1.0f, 0.0f, ht - 1.0f);
1103 glColor4f(colr[0], colr[1], colr[2], colr[3]);
1104 glVertex3f(1.0f, 0.0f, ht + 0.0f);
1105 glEnd();
1106
1107 glBegin(GL_TRIANGLE_STRIP);
1108 glColor4f(colr[0], colr[1], colr[2], colr[3]);
1109 glVertex3f(1.0f, 0.0f, ht - 0.0f);
1110 glColor4f(colr[0], colr[1], colr[2], 0.0f);
1111 glVertex3f(1.0f, 0.0f, ht + 1.0f);
1112 for (float a = PI/10.0f; a < PI*2.0f-0.01f; a += PI/10.0f)
1113 {
1114 glColor4f(colr[0], colr[1], colr[2], colr[3]);
1115 glVertex3f(cosf(a), sinf(a), ht - 0.0f);
1116 glColor4f(colr[0], colr[1], colr[2], 0.0f);
1117 glVertex3f(cosf(a), sinf(a), ht + 1.0f);
1118 }
1119 glColor4f(colr[0], colr[1], colr[2], colr[3]);
1120 glVertex3f(1.0f, 0.0f, ht - 0.0f);
1121 glColor4f(colr[0], colr[1], colr[2], 0.0f);
1122 glVertex3f(1.0f, 0.0f, ht + 1.0f);
1123 glEnd();
1124 #endif
1125 glPopMatrix(); // 1
1126 }
1127
1128 // codriver checkpoints rendering
1129 #ifdef INDEVEL
1130
1131 // codriver checkpoints for debugging purposes
1132 const vec4f cdcheckpoint_col[3] =
1133 {
1134 {0.0f, 0.0f, 1.0f, 0.8f}, // 0 = next checkpoint
1135 {0.3f, 0.3f, 1.0f, 0.6f}, // 1 = checkpoint after next
1136 {0.6f, 0.6f, 1.0f, 0.4f} // 2 = all other checkpoints
1137 };
1138
1139 for (unsigned int i=0; i<game->codrivercheckpt.size(); i++)
1140 {
1141 vec4f colr = cdcheckpoint_col[2];
1142
1143 if (game->cdcheckpt_ordered)
1144 {
1145 if ((int)i == vehic->nextcdcp)
1146 colr = cdcheckpoint_col[0];
1147 else if ((int)i == (vehic->nextcdcp + 1) % (int)game->codrivercheckpt.size())
1148 colr = cdcheckpoint_col[1];
1149 }
1150 else
1151 colr = cdcheckpoint_col[1];
1152
1153 glPushMatrix(); // 1
1154 glTranslatef(game->codrivercheckpt[i].pt.x, game->codrivercheckpt[i].pt.y, game->codrivercheckpt[i].pt.z);
1155 glScalef(15.0f, 15.0f, 1.0f);
1156
1157 glBegin(GL_TRIANGLE_STRIP);
1158 float ht = sinf(cprotate * 6.0f) * 7.0f + 8.0f;
1159 glColor4f(colr[0], colr[1], colr[2], 0.0f);
1160 glVertex3f(1.0f, 0.0f, ht - 1.0f);
1161 glColor4f(colr[0], colr[1], colr[2], colr[3]);
1162 glVertex3f(1.0f, 0.0f, ht + 0.0f);
1163 for (float a = PI/10.0f; a < PI*2.0f-0.01f; a += PI/10.0f)
1164 {
1165 glColor4f(colr[0], colr[1], colr[2], 0.0f);
1166 glVertex3f(cosf(a), sinf(a), ht - 1.0f);
1167 glColor4f(colr[0], colr[1], colr[2], colr[3]);
1168 glVertex3f(cosf(a), sinf(a), ht + 0.0f);
1169 }
1170 glColor4f(colr[0], colr[1], colr[2], 0.0f);
1171 glVertex3f(1.0f, 0.0f, ht - 1.0f);
1172 glColor4f(colr[0], colr[1], colr[2], colr[3]);
1173 glVertex3f(1.0f, 0.0f, ht + 0.0f);
1174 glEnd();
1175
1176 glBegin(GL_TRIANGLE_STRIP);
1177 glColor4f(colr[0], colr[1], colr[2], colr[3]);
1178 glVertex3f(1.0f, 0.0f, ht - 0.0f);
1179 glColor4f(colr[0], colr[1], colr[2], 0.0f);
1180 glVertex3f(1.0f, 0.0f, ht + 1.0f);
1181 for (float a = PI/10.0f; a < PI*2.0f-0.01f; a += PI/10.0f)
1182 {
1183 glColor4f(colr[0], colr[1], colr[2], colr[3]);
1184 glVertex3f(cosf(a), sinf(a), ht - 0.0f);
1185 glColor4f(colr[0], colr[1], colr[2], 0.0f);
1186 glVertex3f(cosf(a), sinf(a), ht + 1.0f);
1187 }
1188 glColor4f(colr[0], colr[1], colr[2], colr[3]);
1189 glVertex3f(1.0f, 0.0f, ht - 0.0f);
1190 glColor4f(colr[0], colr[1], colr[2], 0.0f);
1191 glVertex3f(1.0f, 0.0f, ht + 1.0f);
1192 glEnd();
1193 glPopMatrix(); // 1
1194 }
1195 #endif
1196 }
1197
1198 glEnable(GL_TEXTURE_2D);
1199
1200 if (game->water.enabled)
1201 renderWater();
1202
1203 if (psys_dirt != nullptr) // cfg_dirteffect == false
1204 getSSRender().render(psys_dirt);
1205
1206 glDepthMask(GL_TRUE);
1207 glBlendFunc(GL_ONE,GL_ZERO);
1208 glEnable(GL_LIGHTING);
1209 glEnable(GL_CULL_FACE);
1210 glEnable(GL_FOG);
1211
1212 glDisable(GL_LIGHTING);
1213
1214 glPopMatrix(); // 0
1215
1216 glDisable(GL_DEPTH_TEST);
1217
1218 glMatrixMode(GL_PROJECTION);
1219 glPushMatrix();
1220 glLoadIdentity();
1221
1222 glOrtho(0 - hratio, hratio, 0 - vratio, vratio, 0 - 1.0, 1.0);
1223 glMatrixMode(GL_MODELVIEW);
1224
1225 glPushMatrix(); // 0
1226
1227 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1228
1229 if (showui)
1230 {
1231 game->renderCodriverSigns();
1232
1233 glPushMatrix(); // 1
1234 // position of rpm dial and needle
1235 //glTranslatef( hratio * (1.f - (5.75f/50.f)) - 0.3f, -vratio * (40.f/50.f) + 0.22f, 0.0f);
1236 glTranslatef( hratio * (1.f - (2.5f/50.f)) - 0.3f, -vratio * (43.5f/50.f) + 0.22f, 0.0f);
1237 glScalef(0.30f, 0.30f, 1.0f);
1238
1239 tex_hud_revs->bind();
1240 glColor3f(1.0f, 1.0f, 1.0f);
1241 glBegin(GL_QUADS);
1242 glTexCoord2f(1.0f,1.0f);
1243 glVertex2f(1.0f,1.0f);
1244 glTexCoord2f(0.0f,1.0f);
1245 glVertex2f(-1.0f,1.0f);
1246 glTexCoord2f(0.0f,0.0f);
1247 glVertex2f(-1.0f,-1.0f);
1248 glTexCoord2f(1.0f,0.0f);
1249 glVertex2f(1.0f,-1.0f);
1250 glEnd();
1251
1252 // draw the needle of the RPM dial
1253 glRotatef(225.0f - vehic->getEngineRPM() * 15.0f / 1000.0f, 0.0f, 0.0f, 1.0f);
1254 tex_hud_revneedle->bind();
1255 glColor3f(1.0f, 1.0f, 1.0f);
1256 glPushMatrix(); // 2
1257 glTranslatef(0.62f, 0.0f, 0.0f);
1258 glScalef(0.16f, 0.16f, 0.16f);
1259 glBegin(GL_QUADS);
1260 glTexCoord2f(1.0f,1.0f);
1261 glVertex2f(1.0f,1.0f);
1262 glTexCoord2f(0.0f,1.0f);
1263 glVertex2f(-1.0f,1.0f);
1264 glTexCoord2f(0.0f,0.0f);
1265 glVertex2f(-1.0f,-1.0f);
1266 glTexCoord2f(1.0f,0.0f);
1267 glVertex2f(1.0f,-1.0f);
1268 glEnd();
1269 glPopMatrix(); // 2
1270 glDisable(GL_TEXTURE_2D);
1271 glPopMatrix(); // 1
1272 }
1273
1274 // checkpoint pointing arrow thing
1275 #if 0
1276 glPushMatrix(); // 1
1277
1278 glTranslatef(0.0f, 0.8f, 0.0f);
1279
1280 glScalef(0.2f, 0.2f, 0.2f);
1281
1282 glRotatef(-30.0f, 1.0f, 0.0f, 0.0f);
1283 glRotatef(DEGREES(nextcpangle), 0.0f, -1.0f, 0.0f);
1284
1285 glBegin(GL_TRIANGLES);
1286 glColor4f(0.8f, 0.4f, 0.4f, 0.6f);
1287 glVertex3f(0.0f, 0.0f, -2.0f);
1288 glColor4f(0.8f, 0.8f, 0.8f, 0.6f);
1289 glVertex3f(1.0f, 0.0f, 1.0f);
1290 glVertex3f(-1.0f, 0.0f, 1.0f);
1291 glEnd();
1292 glBegin(GL_TRIANGLE_STRIP);
1293 glColor4f(0.8f, 0.4f, 0.4f, 0.6f);
1294 glVertex3f(0.0f, 0.0f, -2.0f);
1295 glColor4f(1.0f, 0.5f, 0.5f, 0.6f);
1296 glVertex3f(0.0f, 0.2f, -2.0f);
1297 glColor4f(0.8f, 0.8f, 0.8f, 0.6f);
1298 glVertex3f(1.0f, 0.0f, 1.0f);
1299 glColor4f(1.0f, 1.0f, 1.0f, 0.6f);
1300 glVertex3f(1.0f, 0.2f, 1.0f);
1301 glColor4f(0.8f, 0.8f, 0.8f, 0.6f);
1302 glVertex3f(-1.0f, 0.0f, 1.0f);
1303 glColor4f(1.0f, 1.0f, 1.0f, 0.6f);
1304 glVertex3f(-1.0f, 0.2f, 1.0f);
1305 glColor4f(0.8f, 0.4f, 0.4f, 0.6f);
1306 glVertex3f(0.0f, 0.0f, -2.0f);
1307 glColor4f(1.0f, 0.5f, 0.5f, 0.6f);
1308 glVertex3f(0.0f, 0.2f, -2.0f);
1309 glEnd();
1310
1311 glPopMatrix(); // 1
1312 #endif
1313
1314 if (showmap)
1315 {
1316 // position and size of map
1317 //glViewport(getWidth() * (5.75f/100.f), getHeight() * (6.15f/100.f), getHeight()/3.5f, getHeight()/3.5f);
1318 glViewport(getWidth() * (2.5f/100.f), getHeight() * (2.5f/100.f), getHeight()/3.5f, getHeight()/3.5f);
1319
1320 glPushMatrix(); // 1
1321 glScalef(hratio, vratio, 1.0f);
1322
1323 if (game->terrain->getHUDMapTexture())
1324 {
1325 glEnable(GL_TEXTURE_2D);
1326 game->terrain->getHUDMapTexture()->bind();
1327 }
1328
1329 glMatrixMode(GL_TEXTURE);
1330 glPushMatrix();
1331 float scalefac = 1.0f / game->terrain->getMapSize();
1332 glScalef(scalefac, scalefac, 1.0f);
1333 glTranslatef(campos.x, campos.y, 0.0f);
1334 glRotatef(DEGREES(camera_angle), 0.0f, 0.0f, 1.0f);
1335 glScalef(1.0f / 0.003f, 1.0f / 0.003f, 1.0f);
1336
1337 glBegin(GL_QUADS);
1338 glColor4f(1.0f, 1.0f, 1.0f, 0.7f);
1339 glTexCoord2f(1.0f, 1.0f);
1340 glVertex2f(1.0f, 1.0f);
1341 glTexCoord2f(-1.0f, 1.0f);
1342 glVertex2f(-1.0f, 1.0f);
1343 glTexCoord2f(-1.0f, -1.0f);
1344 glVertex2f(-1.0f, -1.0f);
1345 glTexCoord2f(1.0f, -1.0f);
1346 glVertex2f(1.0f, -1.0f);
1347 glEnd();
1348
1349 glPopMatrix();
1350 glMatrixMode(GL_MODELVIEW);
1351
1352 glDisable(GL_TEXTURE_2D);
1353
1354 glPushMatrix(); // 2
1355 glScalef(0.003f, 0.003f, 1.0f);
1356 glRotatef(DEGREES(-camera_angle), 0.0f, 0.0f, 1.0f);
1357 glTranslatef(-campos.x, -campos.y, 0.0f);
1358 for (unsigned int i=0; i<game->checkpt.size(); i++)
1359 {
1360 glPushMatrix();
1361 vec3f vpos = game->checkpt[i].pt;
1362 glTranslatef(vpos.x, vpos.y, 0.0f);
1363 glRotatef(DEGREES(camera_angle), 0.0f, 0.0f, 1.0f);
1364 glScalef(30.0f, 30.0f, 1.0f);
1365 vec4f colr = checkpoint_col[2];
1366 if ((int)i == vehic->nextcp)
1367 {
1368 float sc = 1.5f + sinf(cprotate * 10.0f) * 0.5f;
1369 glScalef(sc, sc, 1.0f);
1370 colr = checkpoint_col[0];
1371 }
1372 else if ((int)i == (vehic->nextcp + 1) % (int)game->checkpt.size())
1373 {
1374 colr = checkpoint_col[1];
1375 }
1376 glBegin(GL_TRIANGLE_FAN);
1377 glColor4fv(colr);
1378 glVertex2f(0.0f, 0.0f);
1379 glColor4f(colr[0], colr[1], colr[2], 0.0f);
1380 //glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
1381 glVertex2f(1.0f, 0.0f);
1382 glVertex2f(0.0f, 1.0f);
1383 glVertex2f(-1.0f, 0.0f);
1384 glVertex2f(0.0f, -1.0f);
1385 glVertex2f(1.0f, 0.0f);
1386 glEnd();
1387 glPopMatrix();
1388 }
1389 for (unsigned int i=0; i<game->vehicle.size(); i++)
1390 {
1391 glPushMatrix();
1392 vec3f vpos = game->vehicle[i]->body->getPosition();
1393 glTranslatef(vpos.x, vpos.y, 0.0f);
1394 glRotatef(DEGREES(camera_angle), 0.0f, 0.0f, 1.0f);
1395 glScalef(30.0f, 30.0f, 1.0f);
1396 glBegin(GL_TRIANGLE_FAN);
1397 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1398 glVertex2f(0.0f, 0.0f);
1399 glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
1400 glVertex2f(1.0f, 0.0f);
1401 glVertex2f(0.0f, 1.0f);
1402 glVertex2f(-1.0f, 0.0f);
1403 glVertex2f(0.0f, -1.0f);
1404 glVertex2f(1.0f, 0.0f);
1405 glEnd();
1406 glPopMatrix();
1407 }
1408 glPopMatrix(); // 2
1409
1410 glPopMatrix(); // 1
1411
1412 glViewport(0, 0, getWidth(), getHeight());
1413 }
1414
1415 glEnable(GL_TEXTURE_2D);
1416
1417 if (showui)
1418 {
1419
1420 glPushMatrix(); // 1
1421
1422 /*
1423 tex_hud_gear->bind();
1424 glPushMatrix(); // 2
1425
1426 glTranslatef(1.0f, 0.35f, 0.0f);
1427 glScalef(0.2f, 0.2f, 1.0f);
1428 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1429 glBegin(GL_QUADS);
1430 glTexCoord2f(1.0f,1.0f); glVertex2f(1.0f,1.0f);
1431 glTexCoord2f(0.0f,1.0f); glVertex2f(-1.0f,1.0f);
1432 glTexCoord2f(0.0f,0.0f); glVertex2f(-1.0f,-1.0f);
1433 glTexCoord2f(1.0f,0.0f); glVertex2f(1.0f,-1.0f);
1434 glEnd();
1435
1436 glPopMatrix(); // 2
1437 */
1438
1439 tex_fontSourceCodeOutlined->bind();
1440
1441 // time counter
1442
1443 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1444 glPushMatrix(); // 2
1445
1446 // time position (other time strings inherit this position)
1447 // -hratio is left border, 0 is center, +hratio is right
1448 // hratio * (1/50) gives 1% of the entire width
1449 // +vratio is top border, 0 is middle, -vratio is bottom
1450
1451 glTranslatef( -hratio + hratio * (2.5f/50.f), vratio - vratio * (5.5f/50.f), 0.0f);
1452 glScalef(0.125f, 0.125f, 1.0f);
1453
1454 if (game->gamestate == Gamestate::finished)
1455 {
1456 getSSRender().drawText(
1457 PUtil::formatTime(game->coursetime),
1458 PTEXT_HZA_LEFT | PTEXT_VTA_TOP);
1459 }
1460 else if (game->coursetime < game->cptime + 1.50f)
1461 {
1462 getSSRender().drawText(
1463 PUtil::formatTime(game->cptime),
1464 PTEXT_HZA_LEFT | PTEXT_VTA_TOP);
1465 }
1466 else if (game->coursetime < game->cptime + 3.50f)
1467 {
1468 float a = (((game->cptime + 3.50f) - game->coursetime) / 2);
1469 glColor4f(1.0f, 1.0f, 1.0f, a);
1470 getSSRender().drawText(
1471 PUtil::formatTime(game->cptime),
1472 PTEXT_HZA_LEFT | PTEXT_VTA_TOP);
1473 }
1474 else
1475 {
1476 getSSRender().drawText(
1477 PUtil::formatTime(game->coursetime),
1478 PTEXT_HZA_LEFT | PTEXT_VTA_TOP);
1479 }
1480
1481 // show target time
1482
1483 glColor4f(0.5f, 1.0f, 0.5f, 1.0f);
1484 glPushMatrix(); // 2
1485 glTranslatef(0.0f, -0.8f, 0.0f);
1486 getSSRender().drawText(PUtil::formatTime(game->targettime), PTEXT_HZA_LEFT | PTEXT_VTA_TOP);
1487
1488 {
1489 // show the time penalty if there is any
1490 const float timepen = game->uservehicle->offroadtime_total * game->offroadtime_penalty_multiplier;
1491
1492 // FIXME: why do glPushMatrix() and glPopMatrix() not work for me?
1493 if (timepen >= 0.1f)
1494 {
1495 glColor4f(1.0f, 1.0f, 0.5f, 1.0f);
1496 glTranslatef(0.0f, -1.60f, 0.0f);
1497 getSSRender().drawText(PUtil::formatTime(timepen) + '+', PTEXT_HZA_LEFT | PTEXT_VTA_TOP);
1498 glTranslatef(0.0f, +1.60f, 0.0f);
1499 }
1500 }
1501
1502 // time label
1503
1504 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1505 glTranslatef(0.0f, .52f, 0.0f);
1506 glScalef(0.65f, 0.65f, 1.0f);
1507 getSSRender().drawText("TIME", PTEXT_HZA_LEFT | PTEXT_VTA_TOP);
1508
1509 glPopMatrix(); // 2
1510
1511 // show Next/Total checkpoints
1512 {
1513
1514 // checkpoint counter
1515
1516 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1517 glPushMatrix(); // 2
1518 const std::string totalcp = std::to_string(game->checkpt.size());
1519 const std::string nextcp = std::to_string(vehic->nextcp);
1520
1521 // checkpoint position
1522 glTranslatef( hratio - hratio * (2.5f/50.f), vratio - vratio * (5.5f/50.f), 0.0f);
1523 glScalef(0.125f, 0.125f, 1.0f);
1524
1525 if (game->getFinishState() != Gamefinish::not_finished)
1526 getSSRender().drawText(totalcp + '/' + totalcp, PTEXT_HZA_RIGHT | PTEXT_VTA_TOP);
1527 else
1528 getSSRender().drawText(nextcp + '/' + totalcp, PTEXT_HZA_RIGHT | PTEXT_VTA_TOP);
1529
1530 // checkpoint label
1531
1532 //glPushMatrix(); // 3
1533 glTranslatef(0, 0.52f, 0.0f);
1534 glScalef(0.65f, 0.65f, 1.0f);
1535 getSSRender().drawText("CKPT", PTEXT_HZA_RIGHT | PTEXT_VTA_TOP);
1536
1537 //glPopMatrix(); // 3
1538 glPopMatrix(); // 2
1539 }
1540
1541 // show Current/Total laps
1542 if (game->number_of_laps > 1)
1543 {
1544 const std::string currentlap = std::to_string(vehic->currentlap);
1545 const std::string number_of_laps = std::to_string(game->number_of_laps);
1546
1547 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1548 glPushMatrix(); // 2
1549 glTranslatef( hratio - hratio * (2.5f/50.f), vratio - vratio * (5.5f/50.f) - 0.20f, 0.0f);
1550 glScalef(0.125f, 0.125f, 1.0f);
1551
1552 if (game->getFinishState() != Gamefinish::not_finished)
1553 getSSRender().drawText(number_of_laps + '/' + number_of_laps, PTEXT_HZA_RIGHT | PTEXT_VTA_TOP);
1554 else
1555 getSSRender().drawText(currentlap + '/' + number_of_laps, PTEXT_HZA_RIGHT | PTEXT_VTA_TOP);
1556
1557 glTranslatef(0, 0.52f, 0.0f);
1558 glScalef(0.65f, 0.65f, 1.0f);
1559 getSSRender().drawText("LAP", PTEXT_HZA_RIGHT | PTEXT_VTA_TOP);
1560
1561 glPopMatrix(); // 2
1562 }
1563
1564 #ifdef INDEVEL
1565 // show codriver checkpoint text (the pace notes)
1566 if (!game->codrivercheckpt.empty() && vehic->nextcdcp != 0)
1567 {
1568 glColor3f(1.0f, 1.0f, 0.0f);
1569 glPushMatrix();
1570 glTranslatef(0.0f, 0.3f, 0.0f);
1571 glScalef(0.1f, 0.1f, 1.0f);
1572 getSSRender().drawText(game->codrivercheckpt[vehic->nextcdcp - 1].notes, PTEXT_HZA_CENTER | PTEXT_VTA_CENTER);
1573 glPopMatrix();
1574 }
1575 #endif
1576
1577 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1578
1579 tex_fontSourceCodeBold->bind();
1580
1581 // show current gear and speed
1582 {
1583 // gear number
1584 const int gear = vehic->getCurrentGear();
1585 const std::string buff = (gear >= 0) ? PUtil::formatInt(gear + 1, 1) : "R";
1586
1587 glPushMatrix(); // 2
1588 // position of gear & speed number & label
1589 //glTranslatef( hratio * (1.f - (5.75f/50.f)) - 0.3f, -vratio * (40.f/50.f) + 0.21f, 0.0f);
1590 glTranslatef( hratio * (1.f - (2.5f/50.f)) - 0.3f, -vratio * (43.5f/50.f) + 0.21f, 0.0f);
1591 glScalef(0.20f, 0.20f, 1.0f);
1592 getSSRender().drawText(buff, PTEXT_HZA_CENTER | PTEXT_VTA_CENTER);
1593
1594 // speed number
1595 const int speed = std::fabs(vehic->getWheelSpeed()) * hud_speedo_mps_speed_mult;
1596 std::string speedstr = std::to_string(speed);
1597
1598 //glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1599 glTranslatef(1.1f, -0.625f, 0.0f);
1600 glScalef(0.5f, 0.5f, 1.0f);
1601 getSSRender().drawText(speedstr, PTEXT_HZA_RIGHT | PTEXT_VTA_CENTER);
1602
1603 // speed label
1604 glTranslatef(0.0f, -0.82f, 0.0f);
1605 glScalef(0.5f, 0.5f, 1.0f);
1606
1607 if (cfg_speed_unit == MainApp::Speedunit::mph)
1608 getSSRender().drawText("MPH", PTEXT_HZA_RIGHT | PTEXT_VTA_CENTER);
1609 else
1610 getSSRender().drawText("km/h", PTEXT_HZA_RIGHT | PTEXT_VTA_CENTER);
1611
1612 glPopMatrix(); // 2
1613 }
1614
1615 #ifndef NDEBUG
1616 // draw revs for debugging
1617 glPushMatrix(); // 2
1618 glTranslatef(1.17f, 0.52f, 0.0f);
1619 glScalef(0.2f, 0.2f, 1.0f);
1620 getSSRender().drawText(std::to_string(vehic->getEngineRPM()), PTEXT_HZA_RIGHT | PTEXT_VTA_TOP);
1621 glPopMatrix(); // 2
1622 #endif
1623
1624 #ifndef NDEBUG
1625 // draw real time penalty for debugging
1626 glPushMatrix();
1627 glScalef(0.1f, 0.1f, 1.0f);
1628 glTranslatef(0.0f, -4.0f, 0.0f);
1629 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1630 tex_fontSourceCodeOutlined->bind();
1631 getSSRender().drawText(std::string("true time penalty: ") +
1632 std::to_string(game->offroadtime_total * game->offroadtime_penalty_multiplier),
1633 PTEXT_HZA_CENTER | PTEXT_VTA_TOP);
1634 glPopMatrix();
1635 #endif
1636
1637 tex_fontSourceCodeShadowed->bind();
1638
1639 // draw "off road" warning sign and text
1640 if (game->isRacing())
1641 {
1642 //const vec3f bodypos = vehic->part[0].ref_world.getPosition();
1643 const vec3f bodypos = vehic->body->getPosition();
1644
1645 if (!game->terrain->getRmapOnRoad(bodypos))
1646 {
1647 glPushMatrix();
1648 glLoadIdentity();
1649 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1650 glScalef(0.25f, 0.25f, 1.0f);
1651 tex_hud_offroad->bind();
1652 glBegin(GL_QUADS);
1653 glTexCoord2f( 1.0f, 1.0f);
1654 glVertex2f( 1.0f, 1.0f);
1655 glTexCoord2f( 0.0f, 1.0f);
1656 glVertex2f( -1.0f, 1.0f);
1657 glTexCoord2f( 0.0f, 0.0f);
1658 glVertex2f( -1.0f, -1.0f);
1659 glTexCoord2f( 1.0f, 0.0f);
1660 glVertex2f( 1.0f, -1.0f);
1661 glEnd();
1662 glPopMatrix();
1663 glPushMatrix();
1664 glScalef(0.1f, 0.1f, 1.0f);
1665 glTranslatef(0.0f, -2.5f, 0.0f);
1666 glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
1667 tex_fontSourceCodeOutlined->bind();
1668 getSSRender().drawText(
1669 std::to_string(static_cast<int> (game->getOffroadTime() * game->offroadtime_penalty_multiplier)) +
1670 " seconds",
1671 PTEXT_HZA_CENTER | PTEXT_VTA_TOP);
1672 glPopMatrix();
1673 }
1674 }
1675
1676 // draw terrain info for debugging
1677 #ifdef INDEVEL
1678 {
1679 const vec3f wheelpos = vehic->part[0].wheel[0].ref_world.getPosition(); // wheel 0
1680 const TerrainType tt = game->terrain->getRoadSurface(wheelpos);
1681 const rgbcolor c = PUtil::getTerrainColor(tt);
1682 const std::string s = PUtil::getTerrainInfo(tt);
1683
1684 glPushMatrix(); // 2
1685 glTranslatef(0.0f, 0.5f, 0.0f);
1686 glScalef(0.1f, 0.1f, 1.0f);
1687
1688 if (tt != TerrainType::Unknown)
1689 {
1690 const GLfloat endx = s.length() * 8.0f / 12.0f + 0.1f;
1691
1692 glPushMatrix();
1693 glDisable(GL_TEXTURE_2D);
1694 glTranslatef(-0.5f * s.length() * 8.0f / 12.0f, 0.0f, 0.0f);
1695 glTranslatef(0.0f, -1.0f, 0.0f);
1696 glBegin(GL_TRIANGLE_STRIP);
1697 glColor3f(c.r / 255.0f, c.g / 255.0f, c.b / 255.0f);
1698 glVertex2f(-0.2f, 0.0f);
1699 glVertex2f(endx, 0.0f);
1700 glVertex2f(-0.2f, 1.1f);
1701 glVertex2f(endx, 1.1f);
1702 glEnd();
1703 glEnable(GL_TEXTURE_2D);
1704 glPopMatrix();
1705 }
1706
1707 glColor3f(1.0f, 1.0f, 1.0f);
1708 getSSRender().drawText(s, PTEXT_HZA_CENTER | PTEXT_VTA_TOP);
1709 glPopMatrix(); // 2
1710 }
1711 #endif
1712
1713 // draw if we're on road for debugging
1714 //#ifdef INDEVEL
1715 #if 0
1716 {
1717 const vec3f wheelpos = vehic->part[0].wheel[0].ref_world.getPosition(); // wheel 0
1718 std::string s;
1719 rgbcolor c;
1720
1721 if (game->terrain->getRmapOnRoad(wheelpos))
1722 {
1723 c = rgbcolor(0xFF, 0xFF, 0xFF);
1724 s = "on the road";
1725 }
1726 else
1727 {
1728 c = rgbcolor(0x00, 0x00, 0x00);
1729 s = "off-road";
1730 }
1731
1732 const GLfloat endx = s.length() * 8.0f / 12.0f + 0.1f;
1733
1734 glPushMatrix(); // 2
1735 glTranslatef(0.0f, 0.25f, 0.0f);
1736 glScalef(0.1f, 0.1f, 1.0f);
1737 glPushMatrix();
1738 glDisable(GL_TEXTURE_2D);
1739 glTranslatef(-0.5f * s.length() * 8.0f / 12.0f, 0.0f, 0.0f);
1740 glTranslatef(0.0f, -1.0f, 0.0f);
1741 glBegin(GL_TRIANGLE_STRIP);
1742 glColor3f(c.r / 255.0f, c.g / 255.0f, c.b / 255.0f);
1743 glVertex2f(-0.2f, 0.0f);
1744 glVertex2f(endx, 0.0f);
1745 glVertex2f(-0.2f, 1.1f);
1746 glVertex2f(endx, 1.1f);
1747 glEnd();
1748 glEnable(GL_TEXTURE_2D);
1749 glPopMatrix();
1750 glColor3f(1.0f, 1.0f, 1.0f);
1751 getSSRender().drawText(s, PTEXT_HZA_CENTER | PTEXT_VTA_TOP);
1752 glPopMatrix(); // 2
1753 }
1754 #endif
1755
1756 tex_fontSourceCodeOutlined->bind();
1757
1758 glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
1759 glPushMatrix(); // 2
1760 glTranslatef(0.0f, 0.2f, 0.0f);
1761 glScalef(0.6f, 0.6f, 1.0f);
1762 if (game->gamestate == Gamestate::countdown)
1763 {
1764 float sizer = fmodf(game->othertime, 1.0f) + 0.5f;
1765 glScalef(sizer, sizer, 1.0f);
1766 getSSRender().drawText(
1767 PUtil::formatInt(((int)game->othertime + 1), 1),
1768 PTEXT_HZA_CENTER | PTEXT_VTA_CENTER);
1769 }
1770 else if (game->gamestate == Gamestate::finished)
1771 {
1772 if (game->getFinishState() == Gamefinish::pass)
1773 {
1774 glColor4f(0.5f, 1.0f, 0.5f, 1.0f);
1775 getSSRender().drawText("WIN", PTEXT_HZA_CENTER | PTEXT_VTA_CENTER);
1776 }
1777 else
1778 {
1779 glScalef(0.5f, 0.5f, 1.0f);
1780 glColor4f(0.5f, 0.0f, 0.0f, 1.0f);
1781 getSSRender().drawText("TIME EXCEEDED", PTEXT_HZA_CENTER | PTEXT_VTA_CENTER);
1782 }
1783 }
1784 else if (game->coursetime < 1.0f)
1785 {
1786 glColor4f(0.5f, 1.0f, 0.5f, 1.0f);
1787 getSSRender().drawText("GO!", PTEXT_HZA_CENTER | PTEXT_VTA_CENTER);
1788 }
1789 else if (game->coursetime < 2.0f)
1790 {
1791 float a = 1.0f - (game->coursetime - 1.0f);
1792 glColor4f(0.5f, 1.0f, 0.5f, a);
1793 getSSRender().drawText("GO!", PTEXT_HZA_CENTER | PTEXT_VTA_CENTER);
1794 }
1795 glPopMatrix(); // 2
1796
1797 if (game->gamestate == Gamestate::countdown)
1798 {
1799 glPushMatrix(); // 2
1800 glTranslatef(0.0f, 0.6f, 0.0f);
1801 glScalef(0.08f, 0.08f, 1.0f);
1802 if (game->othertime < 1.0f)
1803 {
1804 glColor4f(1.0f, 1.0f, 1.0f, game->othertime);
1805 getSSRender().drawText(game->comment, PTEXT_HZA_CENTER | PTEXT_VTA_CENTER);
1806 }
1807 else
1808 {
1809 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1810 getSSRender().drawText(game->comment, PTEXT_HZA_CENTER | PTEXT_VTA_CENTER);
1811 }
1812 glPopMatrix(); // 2
1813 }
1814
1815 if (pauserace)
1816 {
1817 glPushMatrix(); // 2
1818 glColor4f(0.25f, 0.25f, 1.0f, 1.0f);
1819 glScalef(0.25f, 0.25f, 1.0f);
1820 getSSRender().drawText("PAUSED", PTEXT_HZA_CENTER | PTEXT_VTA_CENTER);
1821 glPopMatrix(); // 2
1822 }
1823
1824 glPopMatrix(); // 1
1825
1826 }
1827
1828 glPopMatrix(); // 0
1829
1830 glMatrixMode(GL_PROJECTION);
1831 glPopMatrix();
1832 glMatrixMode(GL_MODELVIEW);
1833
1834 glBlendFunc(GL_ONE, GL_ZERO);
1835
1836 glEnable(GL_DEPTH_TEST);
1837 glEnable(GL_LIGHTING);
1838 }
1839