1 /***************************************************************************
2 terenderer.cpp - Rendering class of the track editor
3 -------------------
4 begin : ma mei 23 2005
5 copyright : (C) 2005 by CJP
6 email : cornware-cjp@users.sourceforge.net
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17 #include <GL/gl.h>
18 #include <cstdio>
19
20 #include "terenderer.h"
21 #include "tecamera.h"
22 #include "usmacros.h"
23 #include "datafile.h"
24
25 #include "trackdocument.h"
26
CTERenderer()27 CTERenderer::CTERenderer()
28 {
29 camx = camy = camz = 0;
30 tgtx = tgty = tgtz = 0;
31
32 m_X = m_Y = m_W = m_H = 0;
33 m_TrackCache = NULL;
34
35 m_Settings.m_VisibleTiles = 100; //make sure that a lot of tiles are visible
36
37 m_RouteErrorMarker = new CGraphObj(NULL, CDataObject::eGraphObj);
38 m_RouteErrorMarker->load("misc/routeerror.glb", CParamList());
39 }
40
~CTERenderer()41 CTERenderer::~CTERenderer()
42 {
43 delete m_RouteErrorMarker;
44 }
45
updateScreenSize()46 void CTERenderer::updateScreenSize()
47 {
48 ; //Don't update screen size: it is filled in from the outside
49 }
50
update()51 void CTERenderer::update()
52 {
53 //set up viewport
54 CRenderer::update();
55
56 //Set the camera
57 const CMatrix &cammat = m_Camera->getOrientation();
58 glLoadMatrixf(cammat.transpose().gl_mtr());
59 const CVector &camera = m_Camera->getPosition();
60 glTranslatef (-camera.x, -camera.y, -camera.z);
61
62 camx = (int)(0.5 + (camera.x)/TILESIZE);
63 camy = (int)(0.5 + (camera.y)/VERTSIZE);
64 camz = (int)(0.5 + (camera.z)/TILESIZE);
65 tgtx = theTrackDocument->getCursorX();
66 tgty = theTrackDocument->getCursorY();
67 tgtz = theTrackDocument->getCursorZ();
68 //printf ("x,y,z = %d,%d,%d\n",camx,camy,camz);
69
70 m_TrackCache = theTrackDocument->getDisplayedTrack();
71 if(m_TrackCache == NULL) return; //error: don't continue
72
73 glColor3f(1,1,1);
74
75 //Draw the track
76 glDisable(GL_FOG);
77 drawTrack();
78
79 //Draw the markers:
80 vector<CEditTrack::SMarker> &markers = m_TrackCache->m_Markers;
81 for(unsigned int i=0; i < markers.size(); i++)
82 {
83 glPushMatrix();
84 glTranslatef(
85 TILESIZE*markers[i].pos.x,
86 VERTSIZE*markers[i].pos.y,
87 TILESIZE*markers[i].pos.z);
88
89 m_RouteErrorMarker->draw(&m_Settings, NULL, 1, 0.0);
90
91 glPopMatrix();
92 }
93
94 //Some line graphics
95 float color[] = {1.0, 1.0, 1.0, 1.0};
96 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
97 glDisable(GL_TEXTURE_2D);
98 glDisable(GL_LIGHTING);
99
100 //The routes
101 vector<CTrack::CRoute> &routes = m_TrackCache->m_Routes;
102 for(unsigned int r=0; r < routes.size(); r++)
103 {
104 if(routes[r].size() < 2) continue;
105
106 color[2] = 1.0 * !(r & 1);
107 color[0] = 1.0 * !(r & 2);
108 color[1] = 1.0 * !(r & 4);
109 glColor3f(color[0], color[1], color[2]);
110
111 glBegin(GL_LINES);
112
113 for(unsigned int i=1; i < routes[r].size(); i++)
114 {
115 CVector pos1(
116 TILESIZE*routes[r][i-1].x, VERTSIZE*routes[r][i-1].y, TILESIZE*routes[r][i-1].z);
117 CVector pos2(
118 TILESIZE*routes[r][i].x, VERTSIZE*routes[r][i].y, TILESIZE*routes[r][i].z);
119
120 pos1 += CVector(0.0, 0.5*VERTSIZE, 0.0); //in the middle of the tile
121 pos2 += CVector(0.0, 0.5*VERTSIZE, 0.0); //in the middle of the tile
122
123 glVertex3f(pos1.x, pos1.y, pos1.z);
124 glVertex3f(pos2.x, pos2.y, pos2.z);
125
126 glVertex3f(pos2.x-2.0, pos2.y, pos2.z);
127 glVertex3f(pos2.x+2.0, pos2.y, pos2.z);
128 glVertex3f(pos2.x, pos2.y-2.0, pos2.z);
129 glVertex3f(pos2.x, pos2.y+2.0, pos2.z);
130 glVertex3f(pos2.x, pos2.y, pos2.z-2.0);
131 glVertex3f(pos2.x, pos2.y, pos2.z+2.0);
132 }
133
134 glEnd();
135 }
136
137 glColor3f(1,1,1); //back to white
138
139 //The active tile
140 int lengte = m_TrackCache->m_L;
141 int breedte = m_TrackCache->m_W;
142 if(tgtx>=0 && tgtx<lengte && tgtz>=0 && tgtz<breedte)
143 {
144 int hoogte = m_TrackCache->m_H;
145 int pilaar_index = hoogte * tgtz + hoogte * breedte * tgtx;
146
147 int ymin = 1000, ymax = -1000;
148 for (int i = 0; i < hoogte; i++) //bottom to top
149 {
150 STile temp = m_TrackCache->m_Track[pilaar_index + i]; //welke tile?
151
152 if(temp.m_Model == 0) break; //0 = empty tile
153
154 if(temp.m_Z > ymax) ymax = temp.m_Z;
155 if(temp.m_Z < ymin) ymin = temp.m_Z;
156 }
157 ymax++;
158
159 if(ymax < ymin) //no tiles on this place
160 {
161 ymin = ymax = 0;
162 }
163
164 glPushMatrix();
165 glTranslatef(TILESIZE*tgtx, 0.0, TILESIZE*tgtz);
166
167 glBegin(GL_LINE_LOOP);
168
169 glVertex3f(-TILESIZE/2,VERTSIZE*ymin,-TILESIZE/2);
170 glVertex3f(-TILESIZE/2,VERTSIZE*ymin, TILESIZE/2);
171 glVertex3f( TILESIZE/2,VERTSIZE*ymin, TILESIZE/2);
172 glVertex3f( TILESIZE/2,VERTSIZE*ymin,-TILESIZE/2);
173
174 glEnd();
175
176 glBegin(GL_LINE_LOOP);
177
178 glVertex3f(-TILESIZE/2,VERTSIZE*ymax,-TILESIZE/2);
179 glVertex3f(-TILESIZE/2,VERTSIZE*ymax, TILESIZE/2);
180 glVertex3f( TILESIZE/2,VERTSIZE*ymax, TILESIZE/2);
181 glVertex3f( TILESIZE/2,VERTSIZE*ymax,-TILESIZE/2);
182
183 glEnd();
184
185 glBegin(GL_LINES);
186
187 glVertex3f(-TILESIZE/2,VERTSIZE*ymin,-TILESIZE/2);
188 glVertex3f(-TILESIZE/2,VERTSIZE*ymax,-TILESIZE/2);
189 glVertex3f(-TILESIZE/2,VERTSIZE*ymin, TILESIZE/2);
190 glVertex3f(-TILESIZE/2,VERTSIZE*ymax, TILESIZE/2);
191 glVertex3f( TILESIZE/2,VERTSIZE*ymin, TILESIZE/2);
192 glVertex3f( TILESIZE/2,VERTSIZE*ymax, TILESIZE/2);
193 glVertex3f( TILESIZE/2,VERTSIZE*ymin,-TILESIZE/2);
194 glVertex3f( TILESIZE/2,VERTSIZE*ymax,-TILESIZE/2);
195
196 glEnd();
197
198 glPopMatrix();
199 }
200
201 glEnable(GL_LIGHTING);
202 glEnable(GL_TEXTURE_2D);
203 }
204
drawTrack()205 void CTERenderer::drawTrack()
206 {
207 glPushMatrix();
208
209 //Nu volgt de weergave-routine
210 int lengte = m_TrackCache->m_L;
211 int breedte = m_TrackCache->m_W;
212
213 //Nu: de dynamische begrenzing om weergavesnelheid te vergroten
214 /*
215 int xmin = (camx-m_Settings.m_VisibleTiles < 0)? 0 : camx-m_Settings.m_VisibleTiles;
216 int xmax = (camx+m_Settings.m_VisibleTiles > lengte)? lengte : camx+m_Settings.m_VisibleTiles;
217 int zmin = (camz-m_Settings.m_VisibleTiles < 0)? 0 : camz-m_Settings.m_VisibleTiles;
218 int zmax = (camz+m_Settings.m_VisibleTiles > breedte)? breedte : camz+m_Settings.m_VisibleTiles;
219 */
220 int xmin = 0;
221 int xmax = lengte;
222 int zmin = 0;
223 int zmax = breedte;
224
225 if (camx >= 0) //Linker deel
226 {
227 if (camz <= breedte) viewTrackPart(xmin,zmax-1, camx,camz, 1,-1, camy); //achter
228 if (camz >= 0) viewTrackPart(xmin,zmin, camx,camz+1, 1,1, camy); //voor+linker strook
229 }
230 if (camx <= lengte) //Rechter deel
231 {
232 if (camz <= breedte) viewTrackPart(xmax-1,zmax-1, camx-1,camz, -1,-1, camy); //achter
233 if (camz >= 0) viewTrackPart(xmax-1,zmin, camx-1,camz+1, -1,1, camy); //voor+rechter strook
234 }
235
236 glPopMatrix();
237 }
238
viewTrackPart(int xmin,int ymin,int xmax,int ymax,int dx,int dy,int cur_zpos)239 void CTERenderer::viewTrackPart(
240 int xmin,int ymin,
241 int xmax,int ymax,
242 int dx, int dy,
243 int cur_zpos)
244 {
245 int lengte = m_TrackCache->m_L;
246 int breedte = m_TrackCache->m_W;
247
248 glPushMatrix();
249 glTranslatef(xmin * TILESIZE, 0, ymin * TILESIZE);
250
251 if(xmin<0) xmin=0;
252 if(ymin<0) ymin=0;
253 if(xmin>=lengte) xmin=lengte-1;
254 if(ymin>=breedte) ymin=breedte-1;
255 if(xmax<-1) xmax=-1;
256 if(ymax<-1) ymax=-1;
257 if(xmax>lengte) xmax=lengte;
258 if(ymax>breedte) ymax=breedte;
259
260 for (int i = xmin; dx*i < dx*xmax; i+=dx)
261 {
262 glPushMatrix();
263 for (int j = ymin; dy*j < dy*ymax; j+=dy)
264 {
265 viewPilaar(i, j, cur_zpos);
266 glTranslatef(0, 0, dy * TILESIZE);
267 }
268 glPopMatrix();
269 glTranslatef(dx * TILESIZE, 0, 0);
270 }
271
272 glPopMatrix();
273 }
274
viewPilaar(int x,int y,int cur_zpos)275 void CTERenderer::viewPilaar(int x, int y, int cur_zpos)
276 {
277 int breedte = m_TrackCache->m_W;
278 int hoogte = m_TrackCache->m_H;
279
280 glPushMatrix();
281
282 int lod;
283 int d=abs(camx-x);
284 int dy=abs(camz-y); //Dit (camz) is geen typefout!!!
285 if(dy>d) d=dy; //d is de grootste van de 2
286
287 if(d>7)
288 lod = 4;
289 else if(d>3)
290 lod = 3;
291 else if(d>1)
292 lod = 2;
293 else
294 lod = 1;
295
296 //One LOD closer in the track editor:
297 if(lod>1) lod--;
298
299 int pilaar_index = hoogte * y + hoogte * breedte * x;
300 int ynu = 0;
301 int rnu = 0;
302
303 for (int i = 0; i < hoogte; i++) //bottom to top
304 {
305 STile temp = m_TrackCache->m_Track[pilaar_index + i]; //welke tile?
306
307 if(temp.m_Model == 0) break; //0 = empty tile
308
309 //goede hoogte
310 int ystrax = temp.m_Z;
311
312 if(ystrax >= camy)
313 {
314 for(int j = hoogte-1; j >= i; j--) //top to bottom
315 {
316 temp = m_TrackCache->m_Track[pilaar_index + j]; //welke tile?
317
318 if(temp.m_Model > 0) //0 = empty tile
319 {
320 //goede hoogte
321 ystrax = temp.m_Z;
322
323 glTranslatef(0, VERTSIZE*(ystrax-ynu),0);
324 ynu = ystrax;
325
326 //goede orientatie
327 int rstrax = temp.m_R;
328 if (rstrax != rnu)
329 {
330 glRotatef(90*(rstrax-rnu),0,1,0);
331 rnu = rstrax;
332 }
333
334 //draw the model
335 theTrackDocument->m_DataManager->getTile(temp.m_Model)->draw(&m_Settings, NULL, lod, 0.0);
336 }
337 }
338 break;
339 }
340
341 glTranslatef(0, VERTSIZE*(ystrax-ynu),0);
342 ynu = ystrax;
343
344 //goede orientatie
345 int rstrax = temp.m_R;
346 if (rstrax != rnu)
347 {
348 glRotatef(90*(rstrax-rnu),0,1,0);
349 rnu = rstrax;
350 }
351
352 //tekenen
353 theTrackDocument->m_DataManager->getTile(temp.m_Model)->draw(&m_Settings, NULL, lod, 0.0);
354 }
355
356 glPopMatrix();
357 }
358