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