2 Copyright (C) 2003, 2010 - Wolfire Games
4 This file is part of Lugaru.
6 Lugaru is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 See the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 extern float viewdistance;
27 extern float fadestart;
28 extern int environment;
29 extern float texscale;
31 extern float multiplier;
32 extern FRUSTUM frustum;
33 extern float texdetail;
36 extern float blurness;
37 extern float targetblurness;
38 extern Objects objects;
39 extern TGAImageRec texture;
40 extern bool visibleloading;
41 extern bool skyboxtexture;
42 extern int tutoriallevel;
46 int Terrain::lineTerrain(XYZ p1, XYZ p2, XYZ *p)
49 static float distance;
50 static float olddistance;
51 static int intersecting;
52 static int firstintersecting;
54 static int startx, starty;
56 static int endx, endy;
57 static int numtris = (size - 1) * (size - 1) * 2;
58 static float highest, lowest;
60 firstintersecting = -1;
94 for (i = startx; i <= endx; i++) {
95 for (j = starty; j <= endy; j++) {
98 for (k = 0; k < 2; k++) {
99 if (heightmap[i + k][j] > highest)
100 highest = heightmap[i + k][j];
101 if (heightmap[i + k][j] < lowest)
102 lowest = heightmap[i + k][j];
103 if (heightmap[i + k][j + 1] > highest)
104 highest = heightmap[i + k][j + 1];
105 if (heightmap[i + k][j + 1] < lowest)
106 lowest = heightmap[i + k][j + 1];
108 if ((p1.y <= highest || p2.y <= highest) && (p1.y >= lowest || p2.y >= lowest)) {
110 triangles[0].y = heightmap[i][j];
114 triangles[1].y = heightmap[i][j + 1];
115 triangles[1].z = j + 1;
117 triangles[2].x = i + 1;
118 triangles[2].y = heightmap[i + 1][j];
121 intersecting = LineFacet(p1, p2, triangles[0], triangles[1], triangles[2], &point);
122 distance = distsq(&p1, &point);
123 if ((distance < olddistance || firstintersecting == -1) && intersecting == 1) {
124 olddistance = distance;
125 firstintersecting = 1;
129 triangles[0].x = i + 1;
130 triangles[0].y = heightmap[i + 1][j];
134 triangles[1].y = heightmap[i][j + 1];
135 triangles[1].z = j + 1;
137 triangles[2].x = i + 1;
138 triangles[2].y = heightmap[i + 1][j + 1];
139 triangles[2].z = j + 1;
141 intersecting = LineFacet(p1, p2, triangles[0], triangles[1], triangles[2], &point);
142 distance = distsq(&p1, &point);
143 if ((distance < olddistance || firstintersecting == -1) && intersecting == 1) {
144 olddistance = distance;
145 firstintersecting = 1;
151 return firstintersecting;
154 void Terrain::UpdateTransparency(int whichx, int whichy)
157 static int i, j, a, b, c, d, patch_size, stepsize;
158 static float distance;
160 static float viewdistsquared;
162 viewdistsquared = viewdistance * viewdistance;
163 patch_size = size / subdivision;
166 c = whichx * patch_elements + whichy * patch_elements * subdivision;
168 for (i = patch_size * whichx; i < patch_size * (whichx + 1) + 1; i += stepsize) {
169 for (j = patch_size * whichy; j < patch_size * (whichy + 1) + 1; j += stepsize) {
170 if (i < size && j < size) {
171 vertex.x = i * scale;
172 vertex.z = j * scale;
173 vertex.y = heightmap[i][j] * scale;
174 distance = distsq(&viewer, &vertex);
175 if (distance > viewdistsquared)
176 distance = viewdistsquared;
177 colors[i][j][3] = (viewdistsquared - (distance - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
182 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
183 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
184 a = (i - (patch_size * whichx)) / stepsize;
185 b = (j - (patch_size * whichy)) / stepsize;
186 d = (a * 54) + (b * 54 * patch_size / stepsize);
187 vArray[d + c + 6] = colors[i][j][3];
189 vArray[d + c + 15] = colors[i][j + stepsize][3];
191 vArray[d + c + 24] = colors[i + stepsize][j][3];
193 vArray[d + c + 33] = colors[i + stepsize][j][3];
195 vArray[d + c + 42] = colors[i][j + stepsize][3];
197 vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3];
202 void Terrain::UpdateTransparencyother(int whichx, int whichy)
205 static int i, j, a, b, c, d, patch_size, stepsize;
206 static float distance;
208 patch_size = size / subdivision;
211 c = whichx * patch_elements + whichy * patch_elements * subdivision;
213 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
214 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
215 a = (i - (patch_size * whichx)) / stepsize;
216 b = (j - (patch_size * whichy)) / stepsize;
217 d = (a * 54) + (b * 54 * patch_size / stepsize);
218 vArray[d + c + 6] = colors[i][j][3] * opacityother[i][j];
220 vArray[d + c + 15] = colors[i][j + stepsize][3] * opacityother[i][j + stepsize];
222 vArray[d + c + 24] = colors[i + stepsize][j][3] * opacityother[i + stepsize][j];
224 vArray[d + c + 33] = colors[i + stepsize][j][3] * opacityother[i + stepsize][j];
226 vArray[d + c + 42] = colors[i][j + stepsize][3] * opacityother[i][j + stepsize];
228 vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3] * opacityother[i + stepsize][j + stepsize];
233 void Terrain::UpdateTransparencyotherother(int whichx, int whichy)
236 static int i, j, a, b, c, d, patch_size, stepsize;
237 static float distance;
239 static float viewdistsquared;
241 viewdistsquared = viewdistance * viewdistance;
242 patch_size = size / subdivision;
245 c = whichx * patch_elements + whichy * patch_elements * subdivision;
247 for (i = patch_size * whichx; i < patch_size * (whichx + 1) + 1; i += stepsize) {
248 for (j = patch_size * whichy; j < patch_size * (whichy + 1) + 1; j += stepsize) {
249 if (i < size && j < size) {
250 vertex.x = i * scale;
251 vertex.z = j * scale;
252 vertex.y = heightmap[i][j] * scale;
253 distance = distsq(&viewer, &vertex);
254 if (distance > viewdistsquared)
255 distance = viewdistsquared;
256 colors[i][j][3] = (viewdistsquared - (distance - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
261 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
262 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
263 a = (i - (patch_size * whichx)) / stepsize;
264 b = (j - (patch_size * whichy)) / stepsize;
265 d = (a * 54) + (b * 54 * patch_size / stepsize);
266 vArray[d + c + 6] = colors[i][j][3];
268 vArray[d + c + 15] = colors[i][j + stepsize][3];
270 vArray[d + c + 24] = colors[i + stepsize][j][3];
272 vArray[d + c + 33] = colors[i + stepsize][j][3];
274 vArray[d + c + 42] = colors[i][j + stepsize][3];
276 vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3];
281 void Terrain::UpdateVertexArray(int whichx, int whichy)
283 static int i, j, a, b, c, patch_size, stepsize;
286 numtris[whichx][whichy] = 0;
288 patch_size = size / subdivision;
291 c = whichx * patch_elements + whichy * patch_elements * subdivision;
292 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
293 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
294 a = (i - ((float)size / subdivision * (float)whichx)) / stepsize;
295 b = (j - ((float)size / subdivision * (float)whichy)) / stepsize;
296 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 0] = i * scale;
297 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 1] = heightmap[i][j] * scale;
298 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 2] = j * scale;
299 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 3] = colors[i][j][0];
300 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 4] = colors[i][j][1];
301 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 5] = colors[i][j][2];
302 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 6] = colors[i][j][3];
303 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 7] = i * scale * texscale + texoffsetx[i][j];
304 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 8] = j * scale * texscale + texoffsety[i][j];
306 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 9] = i * scale;
307 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 10] = heightmap[i][j + stepsize] * scale;
308 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 11] = j * scale + stepsize * scale;
309 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 12] = colors[i][j + stepsize][0];
310 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 13] = colors[i][j + stepsize][1];
311 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 14] = colors[i][j + stepsize][2];
312 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 15] = colors[i][j + stepsize][3];
313 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 16] = i * scale * texscale + texoffsetx[i][j + stepsize];
314 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 17] = j * scale * texscale + stepsize * scale * texscale + texoffsety[i][j + stepsize];
316 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 18] = i * scale + stepsize * scale;
317 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 19] = heightmap[i + stepsize][j] * scale;
318 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 20] = j * scale;
319 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 21] = colors[i + stepsize][j][0];
320 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 22] = colors[i + stepsize][j][1];
321 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 23] = colors[i + stepsize][j][2];
322 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 24] = colors[i + stepsize][j][3];
323 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 25] = i * scale * texscale + stepsize * scale * texscale + texoffsetx[i + stepsize][j];
324 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 26] = j * scale * texscale + texoffsety[i + stepsize][j];
326 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 27] = i * scale + stepsize * scale;
327 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 28] = heightmap[i + stepsize][j] * scale;
328 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 29] = j * scale;
329 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 30] = colors[i + stepsize][j][0];
330 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 31] = colors[i + stepsize][j][1];
331 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 32] = colors[i + stepsize][j][2];
332 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 33] = colors[i + stepsize][j][3];
333 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 34] = i * scale * texscale + stepsize * scale * texscale + texoffsetx[i + stepsize][j];
334 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 35] = j * scale * texscale + texoffsety[i + stepsize][j];
336 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 36] = i * scale;
337 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 37] = heightmap[i][j + stepsize] * scale;
338 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 38] = j * scale + stepsize * scale;
339 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 39] = colors[i][j + stepsize][0];
340 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 40] = colors[i][j + stepsize][1];
341 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 41] = colors[i][j + stepsize][2];
342 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 42] = colors[i][j + stepsize][3];
343 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 43] = i * scale * texscale + texoffsetx[i][j + stepsize];
344 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 44] = j * scale * texscale + stepsize * scale * texscale + texoffsety[i][j + stepsize];
346 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 45] = i * scale + stepsize * scale;
347 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 46] = heightmap[i + stepsize][j + stepsize] * scale;
348 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 47] = j * scale + stepsize * scale;
349 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 48] = colors[i + stepsize][j + stepsize][0];
350 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 49] = colors[i + stepsize][j + stepsize][1];
351 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 50] = colors[i + stepsize][j + stepsize][2];
352 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 51] = colors[i + stepsize][j + stepsize][3];
353 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 52] = i * scale * texscale + stepsize * scale * texscale + texoffsetx[i + stepsize][j + stepsize];
354 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 53] = j * scale * texscale + stepsize * scale * texscale + texoffsety[i + stepsize][j + stepsize];
355 numtris[whichx][whichy] += 2;
359 maxypatch[whichx][whichy] = -10000;
360 minypatch[whichx][whichy] = 10000;
361 for (a = 0; a < size / subdivision; a++) {
362 for (b = 0; b < size / subdivision; b++) {
363 if (heightmap[(size / subdivision)*whichx + a][(size / subdivision)*whichy + b]*scale > maxypatch[whichx][whichy])
364 maxypatch[whichx][whichy] = heightmap[(size / subdivision) * whichx + a][(size / subdivision) * whichy + b] * scale;
365 if (heightmap[(size / subdivision)*whichx + a][(size / subdivision)*whichy + b]*scale < minypatch[whichx][whichy])
366 minypatch[whichx][whichy] = heightmap[(size / subdivision) * whichx + a][(size / subdivision) * whichy + b] * scale;
369 heightypatch[whichx][whichy] = (maxypatch[whichx][whichy] - minypatch[whichx][whichy]);
370 if (heightypatch[whichx][whichy] < size / subdivision * scale)
371 heightypatch[whichx][whichy] = size / subdivision * scale;
372 avgypatch[whichx][whichy] = (minypatch[whichx][whichy] + maxypatch[whichx][whichy]) / 2;
374 for (i = whichx * size / subdivision; i < (whichx + 1)*size / subdivision - 1; i++) {
375 for (j = whichy * size / subdivision; j < (whichy + 1)*size / subdivision - 1; j++) {
376 triangles[(i * (size - 1) * 2) + (j * 2)][0].x = i * scale;
377 triangles[(i * (size - 1) * 2) + (j * 2)][0].y = heightmap[i][j] * scale;
378 triangles[(i * (size - 1) * 2) + (j * 2)][0].z = j * scale;
380 triangles[(i * (size - 1) * 2) + (j * 2)][1].x = i * scale;
381 triangles[(i * (size - 1) * 2) + (j * 2)][1].y = heightmap[i][j + 1] * scale;
382 triangles[(i * (size - 1) * 2) + (j * 2)][1].z = j * scale + scale;
384 triangles[(i * (size - 1) * 2) + (j * 2)][2].x = i * scale + 1 * scale;
385 triangles[(i * (size - 1) * 2) + (j * 2)][2].y = heightmap[i + 1][j] * scale;
386 triangles[(i * (size - 1) * 2) + (j * 2)][2].z = j * scale;
388 triangles[(i * (size - 1) * 2) + (j * 2) + 1][0].x = i * scale + 1 * scale;
389 triangles[(i * (size - 1) * 2) + (j * 2) + 1][0].y = heightmap[i + 1][j] * scale;
390 triangles[(i * (size - 1) * 2) + (j * 2) + 1][0].z = j * scale;
392 triangles[(i * (size - 1) * 2) + (j * 2) + 1][1].x = i * scale;
393 triangles[(i * (size - 1) * 2) + (j * 2) + 1][1].y = heightmap[i][j + 1] * scale;
394 triangles[(i * (size - 1) * 2) + (j * 2) + 1][1].z = j * scale + 1 * scale;
396 triangles[(i * (size - 1) * 2) + (j * 2) + 1][2].x = i * scale + 1 * scale;
397 triangles[(i * (size - 1) * 2) + (j * 2) + 1][2].y = heightmap[i + 1][j + 1] * scale;
398 triangles[(i * (size - 1) * 2) + (j * 2) + 1][2].z = j * scale + 1 * scale;
405 bool Terrain::load(const char *fileName)
409 static float patch_size;
411 float temptexdetail = texdetail;
412 //LoadTGA( fileName );
414 // Fixing filename so that it works with its own os
415 char * FixedFN = ConvertFileName(fileName);
417 unsigned char fileNamep[256];
418 CopyCStringToPascal(FixedFN, fileNamep);
420 upload_image( fileNamep , 0);
423 if (texture.bpp > 24) {
424 int bytesPerPixel = texture.bpp / 8;
427 for (i = 0; i < (long)(texture.sizeY * texture.sizeX * bytesPerPixel); i++) {
429 texture.data[tempnum] = texture.data[i];
436 Game::LoadingScreen();
438 texdetail = temptexdetail;
442 /*if ( texture.bpp == 24 )
447 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
449 if(!terraintexture)glGenTextures( 1, &terraintexture );
450 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
452 glBindTexture( GL_TEXTURE_2D, terraintexture);
453 //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
454 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
456 gluBuild2DMipmaps( GL_TEXTURE_2D, type, texture.sizeX, texture.sizeY, type, GL_UNSIGNED_BYTE, texture.data );
459 size = texture.sizeX;
461 for (i = 0; i < size; i++) {
462 for (j = 0; j < size; j++) {
463 heightmap[size - 1 - i][j] = (float)((texture.data[(i + (j * size)) * texture.bpp / 8])) / 5;
469 Game::LoadingScreen();
473 for (i = 0; i < subdivision; i++) {
474 for (j = 0; j < subdivision; j++) {
475 textureness[i][j] = -1;
479 Game::LoadingScreen();
482 for (i = 0; i < size; i++) {
483 for (j = 0; j < size; j++) {
484 heightmap[i][j] *= .5;
486 texoffsetx[i][j] = (float)abs(Random() % 100) / 1200 / scale * 3;
487 texoffsety[i][j] = (float)abs(Random() % 100) / 1200 / scale * 3;
490 if (environment == snowyenvironment) {
491 if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) {
492 slopeness = heightmap[i][j] - heightmap[i][j - 1];
494 opacityother[i][j] = slopeness * slopeness * 2;
495 if (opacityother[i][j] > 1)
496 opacityother[i][j] = 1;
497 opacityother[i][j] -= (float)abs(Random() % 100) / 300;
499 if (environment == desertenvironment) {
500 if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) {
501 slopeness = heightmap[i][j] - heightmap[i][j - 1];
503 opacityother[i][j] = slopeness * slopeness * 2;
504 if (opacityother[i][j] > 1)
505 opacityother[i][j] = 1;
506 opacityother[i][j] -= (float)abs(Random() % 100) / 300;
508 if (environment == grassyenvironment) {
509 if (i != 0 && heightmap[i][j] - heightmap[i - 1][j] > slopeness) {
510 slopeness = heightmap[i][j] - heightmap[i - 1][j];
512 if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) {
513 slopeness = heightmap[i][j] - heightmap[i][j - 1];
515 if (i < size - 1 && heightmap[i][j] - heightmap[i + 1][j] > slopeness) {
516 slopeness = heightmap[i][j] - heightmap[i + 1][j];
518 if (j < size - 1 && heightmap[i][j] - heightmap[i][j + 1] > slopeness) {
519 slopeness = heightmap[i][j] - heightmap[i][j + 1];
521 opacityother[i][j] = slopeness * slopeness * 10;
522 if (opacityother[i][j] > 1)
523 opacityother[i][j] = 1;
524 opacityother[i][j] -= (float)abs(Random() % 100) / 100;
529 Game::LoadingScreen();
531 for (i = 0; i < size; i++) {
532 for (j = 0; j < size; j++) {
533 if (environment == snowyenvironment) {
534 heightmap[i][j] -= opacityother[i][j];
536 if (environment == desertenvironment) {
537 heightmap[i][j] -= opacityother[i][j];
542 Game::LoadingScreen();
546 //Smooth opacityother
551 if(i!=0){total+=opacityother[j][i-1]; todivide++;}
552 if(i!=size-1){total+=opacityother[j][i+1]; todivide++;}
553 if(j!=0){total+=opacityother[j-1][i]; todivide++;}
554 if(j!=size-1){total+=opacityother[j+1][i]; todivide++;}
555 if(i!=0&&j!=0){total+=opacityother[j-1][i-1]; todivide++;}
556 if(i!=size-1&&j!=0){total+=opacityother[j-1][i+1]; todivide++;}
557 if(j!=size-1&&i!=size-1){total+=opacityother[j+1][i+1]; todivide++;}
558 if(j!=size-1&&i!=0){total+=opacityother[j+1][i-1]; todivide++;}
559 total+=opacityother[j][i]; todivide++;
561 opacityother[j][i]=total/(float)todivide;
566 for (i = 0; i < size; i++) {
567 for (j = 0; j < size; j++) {
568 if (opacityother[i][j] < .1)
569 opacityother[i][j] = 0;
570 if (textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == -1) {
571 if (!opacityother[i][j])
572 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = allfirst;
573 if (opacityother[i][j] == 1)
574 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = allsecond;
576 if (opacityother[i][j] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
577 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
578 if (opacityother[i][j] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
579 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
585 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
586 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
587 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
588 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
589 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
590 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
591 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
592 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
596 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
597 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
598 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
599 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
600 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
601 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
602 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
603 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
609 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
610 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
611 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
612 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
613 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
614 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
615 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
616 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
624 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
625 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
626 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
627 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
628 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
629 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
630 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
631 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
635 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
636 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
637 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
638 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
639 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
640 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
641 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
642 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
648 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
649 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
650 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
651 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
652 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
653 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
654 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
655 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
663 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
664 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
665 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
666 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
667 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
668 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
669 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
670 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
676 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
677 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
678 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
679 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
680 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
681 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
682 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
683 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
690 Game::LoadingScreen();
692 patch_size = size / subdivision;
693 patch_elements = (patch_size) * (patch_size) * 54;
697 for(i=0;i<subdivision;i++){
698 for(j=0;j<subdivision;j++){
699 UpdateVertexArray(i,j);
706 void Terrain::CalculateNormals()
709 static XYZ facenormal;
710 static XYZ p, q, a, b, c;
712 for (i = 0; i < size; i++) {
713 for (j = 0; j < size; j++) {
720 for (i = 0; i < size - 1; i++) {
721 for (j = 0; j < size - 1; j++) {
723 a.y = heightmap[i][j];
726 b.y = heightmap[i][j + 1];
729 c.y = heightmap[i + 1][j];
739 CrossProduct(&p, &q, &facenormal);
741 facenormals[i][j] = facenormal;
743 normals[i][j] = normals[i][j] + facenormal;
744 normals[i][j + 1] = normals[i][j + 1] + facenormal;
745 normals[i + 1][j] = normals[i + 1][j] + facenormal;
749 a.y = heightmap[i + 1][j];
752 b.y = heightmap[i][j + 1];
755 c.y = heightmap[i + 1][j + 1];
765 CrossProduct(&p, &q, &facenormal);
767 normals[i + 1][j + 1] = normals[i + 1][j + 1] + facenormal;
768 normals[i][j + 1] = normals[i][j + 1] + facenormal;
769 normals[i + 1][j] = normals[i + 1][j] + facenormal;
771 Normalise(&facenormals[i][j]);
775 for (i = 0; i < size; i++) {
776 for (j = 0; j < size; j++) {
777 Normalise(&normals[i][j]);
778 normals[i][j] = normals[i][j];
783 void Terrain::drawpatch(int whichx, int whichy, float opacity)
789 UpdateTransparency(whichx, whichy);
791 glColor4f(1, 1, 1, 1);
792 //Set up vertex array
793 glEnableClientState(GL_VERTEX_ARRAY);
794 glEnableClientState(GL_COLOR_ARRAY);
795 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
796 glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]);
797 glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]);
798 glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]);
801 glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3);
803 glDisableClientState(GL_VERTEX_ARRAY);
804 glDisableClientState(GL_COLOR_ARRAY);
805 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
808 void Terrain::drawpatchother(int whichx, int whichy, float opacity)
812 UpdateTransparency(whichx, whichy);
814 UpdateTransparencyother(whichx, whichy);
815 glColor4f(1, 1, 1, 1);
816 //Set up vertex array
817 glEnableClientState(GL_VERTEX_ARRAY);
818 glEnableClientState(GL_COLOR_ARRAY);
819 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
820 glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]);
821 glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]);
822 glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]);
825 glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3);
827 glDisableClientState(GL_VERTEX_ARRAY);
828 glDisableClientState(GL_COLOR_ARRAY);
829 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
832 void Terrain::drawpatchotherother(int whichx, int whichy, float opacity)
835 UpdateTransparencyotherother(whichx, whichy);
837 glMatrixMode(GL_TEXTURE);
841 glColor4f(1, 1, 1, 1);
843 //Set up vertex array
844 glEnableClientState(GL_VERTEX_ARRAY);
845 glEnableClientState(GL_COLOR_ARRAY);
846 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
847 glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]);
848 glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]);
849 glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]);
852 glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3);
854 glDisableClientState(GL_VERTEX_ARRAY);
855 glDisableClientState(GL_COLOR_ARRAY);
856 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
859 glMatrixMode(GL_MODELVIEW);
863 float Terrain::getHeight(float pointx, float pointz)
865 static float height1, height2;
866 static int tilex, tiley;
867 static XYZ startpoint, endpoint, intersect, triangle[3], average;
872 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
875 startpoint.x = pointx;
876 startpoint.y = -1000;
877 startpoint.z = pointz;
879 endpoint = startpoint;
885 triangle[0].x = tilex;
886 triangle[0].z = tiley;
887 triangle[0].y = heightmap[tilex][tiley];
889 triangle[1].x = tilex + 1;
890 triangle[1].z = tiley;
891 triangle[1].y = heightmap[tilex + 1][tiley];
893 triangle[2].x = tilex;
894 triangle[2].z = tiley + 1;
895 triangle[2].y = heightmap[tilex][tiley + 1];
897 if (!LineFacetd(&startpoint, &endpoint, &triangle[0], &triangle[1], &triangle[2], &intersect)) {
898 triangle[0].x = tilex + 1;
899 triangle[0].z = tiley;
900 triangle[0].y = heightmap[tilex + 1][tiley];
902 triangle[1].x = tilex + 1;
903 triangle[1].z = tiley + 1;
904 triangle[1].y = heightmap[tilex + 1][tiley + 1];
906 triangle[2].x = tilex;
907 triangle[2].z = tiley + 1;
908 triangle[2].y = heightmap[tilex][tiley + 1];
909 LineFacetd(&startpoint, &endpoint, &triangle[0], &triangle[1], &triangle[2], &intersect);
911 return intersect.y * scale + getOpacity(pointx * scale, pointz * scale) / 8;
913 //height1=heightmap[tilex][tiley]*(1-(pointx-tilex))+heightmap[tilex+1][tiley]*(pointx-tilex);
914 //height2=heightmap[tilex][tiley+1]*(1-(pointx-tilex))+heightmap[tilex+1][tiley+1]*(pointx-tilex);
916 //return height1*(1-(pointz-tiley))*scale+height2*(pointz-tiley)*scale;
919 float Terrain::getHeightExtrude(float pointx, float pointz, float point2x, float point2z)
921 static float height1, height2;
922 static int tilex, tiley;
923 static XYZ startpoint, endpoint, intersect, triangle[3], average;
930 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
932 if (point2x >= size - 1 || point2z >= size - 1 || point2x <= 0 || point2z <= 0)
935 startpoint.x = point2x;
936 startpoint.y = -1000;
937 startpoint.z = point2z;
939 endpoint = startpoint;
945 triangle[0].x = tilex;
946 triangle[0].z = tiley;
947 triangle[0].y = heightmap[tilex][tiley];
949 triangle[1].x = tilex + 1;
950 triangle[1].z = tiley;
951 triangle[1].y = heightmap[tilex + 1][tiley];
953 triangle[2].x = tilex;
954 triangle[2].z = tiley + 1;
955 triangle[2].y = heightmap[tilex][tiley + 1];
959 mid = (triangle[0] + triangle[1] + triangle[2]) / 2;
961 triangle[0] = mid + (triangle[0] - mid) * 10;
962 triangle[1] = mid + (triangle[0] - mid) * 10;
963 triangle[2] = mid + (triangle[0] - mid) * 10;
966 if(!LineFacetd(&startpoint,&endpoint,&triangle[0],&triangle[1],&triangle[2],&intersect)){
967 triangle[0].x=tilex+1;
969 triangle[0].y=heightmap[tilex+1][tiley];
971 triangle[1].x=tilex+1;
972 triangle[1].z=tiley+1;
973 triangle[1].y=heightmap[tilex+1][tiley+1];
976 triangle[2].z=tiley+1;
977 triangle[2].y=heightmap[tilex][tiley+1];
978 LineFacetd(&startpoint,&endpoint,&triangle[0],&triangle[1],&triangle[2],&intersect);
980 return intersect.y * scale + getOpacity(pointx * scale, pointz * scale) / 8;
982 //height1=heightmap[tilex][tiley]*(1-(pointx-tilex))+heightmap[tilex+1][tiley]*(pointx-tilex);
983 //height2=heightmap[tilex][tiley+1]*(1-(pointx-tilex))+heightmap[tilex+1][tiley+1]*(pointx-tilex);
985 //return height1*(1-(pointz-tiley))*scale+height2*(pointz-tiley)*scale;
989 float Terrain::getOpacity(float pointx, float pointz)
991 static float height1, height2;
992 static int tilex, tiley;
997 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
1003 height1 = opacityother[tilex][tiley] * (1 - (pointx - tilex)) + opacityother[tilex + 1][tiley] * (pointx - tilex);
1004 height2 = opacityother[tilex][tiley + 1] * (1 - (pointx - tilex)) + opacityother[tilex + 1][tiley + 1] * (pointx - tilex);
1006 return height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley);
1009 XYZ Terrain::getNormal(float pointx, float pointz)
1011 static XYZ height1, height2, total;
1012 static int tilex, tiley;
1018 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
1023 height1 = normals[tilex][tiley] * (1 - (pointx - tilex)) + normals[tilex + 1][tiley] * (pointx - tilex);
1024 height2 = normals[tilex][tiley + 1] * (1 - (pointx - tilex)) + normals[tilex + 1][tiley + 1] * (pointx - tilex);
1025 total = height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley);
1030 XYZ Terrain::getLighting(float pointx, float pointz)
1032 static XYZ height1, height2;
1033 static int tilex, tiley;
1039 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
1044 height1.x = colors[tilex][tiley][0] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][0] * (pointx - tilex);
1045 height1.y = colors[tilex][tiley][1] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][1] * (pointx - tilex);
1046 height1.z = colors[tilex][tiley][2] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][2] * (pointx - tilex);
1047 height2.x = colors[tilex][tiley + 1][0] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][0] * (pointx - tilex);
1048 height2.y = colors[tilex][tiley + 1][1] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][1] * (pointx - tilex);
1049 height2.z = colors[tilex][tiley + 1][2] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][2] * (pointx - tilex);
1051 return height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley);
1054 void Terrain::draw(int layer)
1057 static float opacity;
1058 static XYZ terrainpoint;
1059 static float distance[subdivision][subdivision];
1061 static int beginx, endx;
1062 static int beginz, endz;
1064 static float patch_size = size / subdivision * scale;
1065 static float viewdistsquared;
1067 viewdistsquared = viewdistance * viewdistance;
1069 //Only nearby blocks
1070 beginx = (viewer.x - viewdistance) / (patch_size) - 1;
1073 beginz = (viewer.z - viewdistance) / (patch_size) - 1;
1077 endx = (viewer.x + viewdistance) / (patch_size) + 1;
1078 if (endx > subdivision)
1080 endz = (viewer.z + viewdistance) / (patch_size) + 1;
1081 if (endz > subdivision)
1085 for (i = beginx; i < endx; i++) {
1086 for (j = beginz; j < endz; j++) {
1087 terrainpoint.x = i * patch_size + (patch_size) / 2;
1088 terrainpoint.y = viewer.y; //heightmap[i][j]*scale;
1089 terrainpoint.z = j * patch_size + (patch_size) / 2;
1090 distance[i][j] = distsq(&viewer, &terrainpoint);
1094 for (i = beginx; i < endx; i++) {
1095 for (j = beginz; j < endz; j++) {
1096 if (distance[i][j] < (viewdistance + patch_size) * (viewdistance + patch_size)) {
1098 if (distance[i][j] > viewdistsquared * fadestart - viewdistsquared)
1100 if (opacity == 1 && i != subdivision)
1101 if (distance[i + 1][j] > viewdistsquared * fadestart - viewdistsquared)
1103 if (opacity == 1 && j != subdivision)
1104 if (distance[i][j + 1] > viewdistsquared * fadestart - viewdistsquared)
1106 if (opacity == 1 && j != subdivision && i != subdivision)
1107 if (distance[i + 1][j + 1] > viewdistsquared * fadestart - viewdistsquared)
1109 glMatrixMode(GL_MODELVIEW);
1111 if (frustum.CubeInFrustum(i * patch_size + patch_size * .5, avgypatch[i][j], j * patch_size + patch_size * .5, heightypatch[i][j] / 2)) {
1112 if (environment == desertenvironment && distance[i][j] > viewdistsquared / 4)
1113 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, blurness);
1114 else if (environment == desertenvironment)
1115 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
1116 if (!layer && textureness[i][j] != allsecond)
1117 drawpatch(i, j, opacity);
1118 if (layer == 1 && textureness[i][j] != allfirst)
1119 drawpatchother(i, j, opacity);
1120 if (layer == 2 && textureness[i][j] != allfirst)
1121 drawpatchotherother(i, j, opacity);
1127 if (environment == desertenvironment)
1128 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
1131 void Terrain::drawdecals()
1135 static float distancemult;
1136 static int lasttype;
1138 static float patch_size = size / subdivision * scale;
1139 static float viewdistsquared;
1142 viewdistsquared = viewdistance * viewdistance;
1147 glDisable(GL_LIGHTING);
1148 glDisable(GL_CULL_FACE);
1149 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1151 for (i = 0; i < numdecals; i++) {
1152 if (decaltype[i] == blooddecalfast && decalalivetime[i] < 2)
1153 decalalivetime[i] = 2;
1154 if ((decaltype[i] == shadowdecal || decaltype[i] == shadowdecalpermanent) && decaltype[i] != lasttype) {
1155 shadowtexture.bind();
1158 glAlphaFunc(GL_GREATER, 0.0001);
1159 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1162 if (decaltype[i] == footprintdecal && decaltype[i] != lasttype) {
1163 footprinttexture.bind();
1166 glAlphaFunc(GL_GREATER, 0.0001);
1167 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1170 if (decaltype[i] == bodyprintdecal && decaltype[i] != lasttype) {
1171 bodyprinttexture.bind();
1174 glAlphaFunc(GL_GREATER, 0.0001);
1175 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1178 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalslow) && decaltype[i] != lasttype) {
1179 bloodtexture.bind();
1182 glAlphaFunc(GL_GREATER, 0.15);
1183 glBlendFunc(GL_ONE, GL_ZERO);
1186 if ((decaltype[i] == blooddecalfast) && decaltype[i] != lasttype) {
1187 bloodtexture2.bind();
1190 glAlphaFunc(GL_GREATER, 0.15);
1191 glBlendFunc(GL_ONE, GL_ZERO);
1194 if (decaltype[i] == shadowdecal || decaltype[i] == shadowdecalpermanent) {
1195 distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
1196 if (distancemult >= 1)
1197 glColor4f(1, 1, 1, decalopacity[i]);
1198 if (distancemult < 1)
1199 glColor4f(1, 1, 1, decalopacity[i]*distancemult);
1201 if (decaltype[i] == footprintdecal || decaltype[i] == bodyprintdecal) {
1202 distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
1203 if (distancemult >= 1) {
1204 glColor4f(1, 1, 1, decalopacity[i]);
1205 if (decalalivetime[i] > 3)
1206 glColor4f(1, 1, 1, decalopacity[i] * (5 - decalalivetime[i]) / 2);
1208 if (distancemult < 1) {
1209 glColor4f(1, 1, 1, decalopacity[i]*distancemult);
1210 if (decalalivetime[i] > 3)
1211 glColor4f(1, 1, 1, decalopacity[i] * (5 - decalalivetime[i]) / 2 * distancemult);
1214 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow)) {
1215 distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
1216 if (distancemult >= 1) {
1217 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]);
1218 if (decalalivetime[i] < 4)
1219 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*decalalivetime[i]*.25);
1220 if (decalalivetime[i] > 58)
1221 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i] * (60 - decalalivetime[i]) / 2);
1223 if (distancemult < 1) {
1224 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*distancemult);
1225 if (decalalivetime[i] < 4)
1226 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*decalalivetime[i]*distancemult * .25);
1227 if (decalalivetime[i] > 58)
1228 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i] * (60 - decalalivetime[i]) / 2 * distancemult);
1231 lasttype = decaltype[i];
1232 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1233 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1235 glMatrixMode(GL_MODELVIEW);
1237 glBegin(GL_TRIANGLES);
1238 for (int j = 0; j < 3; j++) {
1239 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]);
1240 glVertex3f(decalvertex[i][j].x, decalvertex[i][j].y, decalvertex[i][j].z);
1245 for (i = numdecals - 1; i >= 0; i--) {
1246 decalalivetime[i] += multiplier;
1247 if (decaltype[i] == blooddecalslow)
1248 decalalivetime[i] -= multiplier * 2 / 3;
1249 if (decaltype[i] == blooddecalfast)
1250 decalalivetime[i] += multiplier * 4;
1251 if (decaltype[i] == shadowdecal)
1253 if (decaltype[i] == footprintdecal && decalalivetime[i] >= 5)
1255 if (decaltype[i] == bodyprintdecal && decalalivetime[i] >= 5)
1257 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow) && decalalivetime[i] >= 60)
1260 glAlphaFunc(GL_GREATER, 0.0001);
1264 void Terrain::AddObject(XYZ where, float radius, int id)
1269 if (id >= 0 && id < 10000)
1270 for (i = 0; i < subdivision; i++) {
1271 for (j = 0; j < subdivision; j++) {
1272 if (patchobjectnum[i][j] < 300 - 1) {
1274 points[0].x = (size / subdivision) * i;
1275 points[0].z = (size / subdivision) * j;
1276 points[0].y = heightmap[(int)points[0].x][(int)points[0].z];
1277 points[1].x = (size / subdivision) * (i + 1);
1278 points[1].z = (size / subdivision) * j;
1279 points[1].y = heightmap[(int)points[1].x][(int)points[1].z];
1280 points[2].x = (size / subdivision) * (i + 1);
1281 points[2].z = (size / subdivision) * (j + 1);
1282 points[2].y = heightmap[(int)points[2].x][(int)points[2].z];
1283 points[3].x = (size / subdivision) * i;
1284 points[3].z = (size / subdivision) * (j + 1);
1285 points[3].y = heightmap[(int)points[3].x][(int)points[3].z];
1290 if (!done && where.x + radius > points[0].x && where.x - radius < points[2].x && where.z + radius > points[0].z && where.z - radius < points[2].z) {
1291 patchobjects[i][j][patchobjectnum[i][j]] = id;
1292 patchobjectnum[i][j]++;
1300 void Terrain::DeleteDecal(int which)
1303 decaltype[which] = decaltype[numdecals - 1];
1304 decalposition[which] = decalposition[numdecals - 1];
1305 for (int i = 0; i < 3; i++) {
1306 decalvertex[which][i] = decalvertex[numdecals - 1][i];
1307 decaltexcoords[which][i][0] = decaltexcoords[numdecals - 1][i][0];
1308 decaltexcoords[which][i][1] = decaltexcoords[numdecals - 1][i][1];
1310 decalrotation[which] = decalrotation[numdecals - 1];
1311 decalalivetime[which] = decalalivetime[numdecals - 1];
1312 decalopacity[which] = decalopacity[numdecals - 1];
1313 decalbrightness[which] = decalbrightness[numdecals - 1];
1318 void Terrain::MakeDecal(int type, XYZ where, float size, float opacity, float rotation)
1321 if (opacity > 0 && size > 0) {
1322 static int patchx[4];
1323 static int patchy[4];
1325 decaltexcoords[numdecals][0][0] = 1;
1326 decaltexcoords[numdecals][0][1] = 0;
1328 patchx[0] = (where.x + size) / scale;
1329 patchx[1] = (where.x - size) / scale;
1330 patchx[2] = (where.x - size) / scale;
1331 patchx[3] = (where.x + size) / scale;
1333 patchy[0] = (where.z - size) / scale;
1334 patchy[1] = (where.z - size) / scale;
1335 patchy[2] = (where.z + size) / scale;
1336 patchy[3] = (where.z + size) / scale;
1338 /*if(patchx[1]<subdivision-1&&patchy[1]<subdivision-1&&patchx[1]>0&&patchy[1]>0)
1339 if(patchx[2]<subdivision-1&&patchy[2]<subdivision-1&&patchx[2]>0&&patchy[2]>0)
1340 if(patchx[3]<subdivision-1&&patchy[3]<subdivision-1&&patchx[3]>0&&patchy[3]>0)
1341 if(patchx[0]<subdivision-1&&patchy[0]<subdivision-1&&patchx[0]>0&&patchy[0]>0){
1343 if ((patchx[0] != patchx[1] || patchy[0] != patchy[1]) && (patchx[0] != patchx[2] || patchy[0] != patchy[2]) && (patchx[0] != patchx[3] || patchy[0] != patchy[3])) {
1344 MakeDecalLock(type, where, patchx[0], patchy[0], size, opacity, rotation);
1347 if ((patchx[1] != patchx[2] || patchy[1] != patchy[2]) && (patchx[1] != patchx[3] || patchy[1] != patchy[3])) {
1348 MakeDecalLock(type, where, patchx[1], patchy[1], size, opacity, rotation);
1351 if ((patchx[2] != patchx[3] || patchy[2] != patchy[3])) {
1352 MakeDecalLock(type, where, patchx[2], patchy[2], size, opacity, rotation);
1354 MakeDecalLock(type, where, patchx[3], patchy[3], size, opacity, rotation);
1360 void Terrain::MakeDecalLock(int type, XYZ where, int whichx, int whichy, float size, float opacity, float rotation)
1363 static float placex, placez;
1368 rot = getLighting(where.x, where.z);
1369 decalbrightness[numdecals] = (rot.x + rot.y + rot.z) / 3;
1370 if (decalbrightness[numdecals] < .4)
1371 decalbrightness[numdecals] = .4;
1373 if (environment == grassyenvironment) {
1374 decalbrightness[numdecals] *= .6;
1377 if (decalbrightness[numdecals] > 1)
1378 decalbrightness[numdecals] = 1;
1379 decalbright = decalbrightness[numdecals];
1381 decalposition[numdecals] = where;
1382 decaltype[numdecals] = type;
1383 decalopacity[numdecals] = opacity;
1384 decalrotation[numdecals] = rotation;
1385 decalalivetime[numdecals] = 0;
1387 placex = (float)whichx * scale + scale;
1388 placez = (float)whichy * scale;
1390 decaltexcoords[numdecals][0][0] = (placex - where.x) / size / 2 + .5;
1391 decaltexcoords[numdecals][0][1] = (placez - where.z) / size / 2 + .5;
1393 decalvertex[numdecals][0].x = placex;
1394 decalvertex[numdecals][0].z = placez;
1395 decalvertex[numdecals][0].y = heightmap[whichx + 1][whichy] * scale + .01;
1398 placex = (float)whichx * scale + scale;
1399 placez = (float)whichy * scale + scale;
1401 decaltexcoords[numdecals][1][0] = (placex - where.x) / size / 2 + .5;
1402 decaltexcoords[numdecals][1][1] = (placez - where.z) / size / 2 + .5;
1404 decalvertex[numdecals][1].x = placex;
1405 decalvertex[numdecals][1].z = placez;
1406 decalvertex[numdecals][1].y = heightmap[whichx + 1][whichy + 1] * scale + .01;
1409 placex = (float)whichx * scale;
1410 placez = (float)whichy * scale + scale;
1412 decaltexcoords[numdecals][2][0] = (placex - where.x) / size / 2 + .5;
1413 decaltexcoords[numdecals][2][1] = (placez - where.z) / size / 2 + .5;
1415 decalvertex[numdecals][2].x = placex;
1416 decalvertex[numdecals][2].z = placez;
1417 decalvertex[numdecals][2].y = heightmap[whichx][whichy + 1] * scale + .01;
1419 if (decalrotation[numdecals]) {
1420 for (int i = 0; i < 3; i++) {
1422 rot.x = decaltexcoords[numdecals][i][0] - .5;
1423 rot.z = decaltexcoords[numdecals][i][1] - .5;
1424 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1425 decaltexcoords[numdecals][i][0] = rot.x + .5;
1426 decaltexcoords[numdecals][i][1] = rot.z + .5;
1430 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1431 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1432 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1433 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1))
1434 if (numdecals < max_decals - 1)
1437 decalbrightness[numdecals] = decalbright;
1439 decalposition[numdecals] = where;
1440 decaltype[numdecals] = type;
1441 decalopacity[numdecals] = opacity;
1442 decalrotation[numdecals] = rotation;
1443 decalalivetime[numdecals] = 0;
1445 placex = (float)whichx * scale + scale;
1446 placez = (float)whichy * scale;
1448 decaltexcoords[numdecals][0][0] = (placex - where.x) / size / 2 + .5;
1449 decaltexcoords[numdecals][0][1] = (placez - where.z) / size / 2 + .5;
1451 decalvertex[numdecals][0].x = placex;
1452 decalvertex[numdecals][0].z = placez;
1453 decalvertex[numdecals][0].y = heightmap[whichx + 1][whichy] * scale + .01;
1456 placex = (float)whichx * scale;
1457 placez = (float)whichy * scale;
1459 decaltexcoords[numdecals][1][0] = (placex - where.x) / size / 2 + .5;
1460 decaltexcoords[numdecals][1][1] = (placez - where.z) / size / 2 + .5;
1462 decalvertex[numdecals][1].x = placex;
1463 decalvertex[numdecals][1].z = placez;
1464 decalvertex[numdecals][1].y = heightmap[whichx][whichy] * scale + .01;
1467 placex = (float)whichx * scale;
1468 placez = (float)whichy * scale + scale;
1470 decaltexcoords[numdecals][2][0] = (placex - where.x) / size / 2 + .5;
1471 decaltexcoords[numdecals][2][1] = (placez - where.z) / size / 2 + .5;
1473 decalvertex[numdecals][2].x = placex;
1474 decalvertex[numdecals][2].z = placez;
1475 decalvertex[numdecals][2].y = heightmap[whichx][whichy + 1] * scale + .01;
1477 if (decalrotation[numdecals]) {
1478 for (int i = 0; i < 3; i++) {
1480 rot.x = decaltexcoords[numdecals][i][0] - .5;
1481 rot.z = decaltexcoords[numdecals][i][1] - .5;
1482 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1483 decaltexcoords[numdecals][i][0] = rot.x + .5;
1484 decaltexcoords[numdecals][i][1] = rot.z + .5;
1488 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1489 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1490 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1491 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1))
1492 if (numdecals < max_decals - 1)
1497 void Terrain::DoLighting()
1499 static int i, j, k, todivide;
1500 static float brightness, total;
1501 static XYZ blank, terrainpoint, lightloc;
1502 lightloc = light.location;
1503 Normalise(&lightloc);
1505 for (i = 0; i < size; i++) {
1506 for (j = 0; j < size; j++) {
1507 terrainpoint.x = (float)i * scale;
1508 terrainpoint.z = (float)j * scale;
1509 terrainpoint.y = heightmap[i][j] * scale + .1;
1511 if(lineTerrain(lightlocation*10+terrainpoint,terrainpoint,&blank)==-1)
1513 brightness = dotproduct(&lightloc, &normals[i][j]);
1520 colors[i][j][0] = light.color[0] * brightness + light.ambient[0];
1521 colors[i][j][1] = light.color[1] * brightness + light.ambient[1];
1522 colors[i][j][2] = light.color[2] * brightness + light.ambient[2];
1524 if (colors[i][j][0] > 1) colors[i][j][0] = 1;
1525 if (colors[i][j][1] > 1) colors[i][j][1] = 1;
1526 if (colors[i][j][2] > 1) colors[i][j][2] = 1;
1527 if (colors[i][j][0] < 0) colors[i][j][0] = 0;
1528 if (colors[i][j][1] < 0) colors[i][j][1] = 0;
1529 if (colors[i][j][2] < 0) colors[i][j][2] = 0;
1534 for (i = 0; i < size; i++) {
1535 for (j = 0; j < size; j++) {
1536 for (k = 0; k < 3; k++) {
1540 total += colors[j][i - 1][k];
1543 if (i != size - 1) {
1544 total += colors[j][i + 1][k];
1548 total += colors[j - 1][i][k];
1551 if (j != size - 1) {
1552 total += colors[j + 1][i][k];
1555 if (i != 0 && j != 0) {
1556 total += colors[j - 1][i - 1][k];
1559 if (i != size - 1 && j != 0) {
1560 total += colors[j - 1][i + 1][k];
1563 if (j != size - 1 && i != size - 1) {
1564 total += colors[j + 1][i + 1][k];
1567 if (j != size - 1 && i != 0) {
1568 total += colors[j + 1][i - 1][k];
1571 total += colors[j][i][k];
1574 colors[j][i][k] = total / todivide;
1580 void Terrain::DoShadows()
1582 static int i, j, k, l, todivide;
1583 static float brightness, total;
1584 static XYZ testpoint, testpoint2, terrainpoint, lightloc, col;
1585 lightloc = light.location;
1586 if (!skyboxtexture) {
1590 if (skyboxtexture && tutoriallevel) {
1596 Normalise(&lightloc);
1598 for (i = 0; i < size; i++) {
1599 for (j = 0; j < size; j++) {
1600 terrainpoint.x = (float)(i) * scale;
1601 terrainpoint.z = (float)(j) * scale;
1602 terrainpoint.y = heightmap[i][j] * scale;
1605 patchx = (float)(i) * subdivision / size;
1606 patchz = (float)(j) * subdivision / size;
1607 if (patchobjectnum[patchx][patchz]) {
1608 for (k = 0; k < patchobjectnum[patchx][patchz]; k++) {
1609 l = patchobjects[patchx][patchz][k];
1610 if (objects.type[l] != treetrunktype) {
1611 testpoint = terrainpoint;
1612 testpoint2 = terrainpoint + lightloc * 50 * (1 - shadowed);
1613 if (objects.model[l].LineCheck(&testpoint, &testpoint2, &col, &objects.position[l], &objects.yaw[l]) != -1) {
1614 shadowed = 1 - (findDistance(&terrainpoint, &col) / 50);
1619 Game::LoadingScreen();
1621 brightness = dotproduct(&lightloc, &normals[i][j]);
1623 brightness *= 1 - shadowed;
1630 colors[i][j][0] = light.color[0] * brightness + light.ambient[0];
1631 colors[i][j][1] = light.color[1] * brightness + light.ambient[1];
1632 colors[i][j][2] = light.color[2] * brightness + light.ambient[2];
1634 if (colors[i][j][0] > 1) colors[i][j][0] = 1;
1635 if (colors[i][j][1] > 1) colors[i][j][1] = 1;
1636 if (colors[i][j][2] > 1) colors[i][j][2] = 1;
1637 if (colors[i][j][0] < 0) colors[i][j][0] = 0;
1638 if (colors[i][j][1] < 0) colors[i][j][1] = 0;
1639 if (colors[i][j][2] < 0) colors[i][j][2] = 0;
1644 Game::LoadingScreen();
1647 for (i = 0; i < size; i++) {
1648 for (j = 0; j < size; j++) {
1649 for (k = 0; k < 3; k++) {
1653 total += colors[j][i - 1][k];
1656 if (i != size - 1) {
1657 total += colors[j][i + 1][k];
1661 total += colors[j - 1][i][k];
1664 if (j != size - 1) {
1665 total += colors[j + 1][i][k];
1668 if (i != 0 && j != 0) {
1669 total += colors[j - 1][i - 1][k];
1672 if (i != size - 1 && j != 0) {
1673 total += colors[j - 1][i + 1][k];
1676 if (j != size - 1 && i != size - 1) {
1677 total += colors[j + 1][i + 1][k];
1680 if (j != size - 1 && i != 0) {
1681 total += colors[j + 1][i - 1][k];
1684 total += colors[j][i][k];
1687 colors[j][i][k] = total / todivide;
1692 for (i = 0; i < subdivision; i++) {
1693 for (j = 0; j < subdivision; j++) {
1694 UpdateVertexArray(i, j);
1703 memset(patchobjectnum, 0, sizeof(patchobjectnum));
1704 memset(patchobjects, 0, sizeof(patchobjects));
1708 memset(heightmap, 0, sizeof(heightmap));
1709 memset(normals, 0, sizeof(normals));
1710 memset(facenormals, 0, sizeof(facenormals));
1711 memset(triangles, 0, sizeof(triangles));
1712 memset(colors, 0, sizeof(colors));
1713 memset(opacityother, 0, sizeof(opacityother));
1714 memset(texoffsetx, 0, sizeof(texoffsetx));
1715 memset(texoffsety, 0, sizeof(texoffsety));
1716 memset(numtris, 0, sizeof(numtris));
1717 memset(textureness, 0, sizeof(textureness));
1719 memset(vArray, 0, sizeof(vArray));
1721 memset(visible, 0, sizeof(visible));
1722 memset(avgypatch, 0, sizeof(avgypatch));
1723 memset(maxypatch, 0, sizeof(maxypatch));
1724 memset(minypatch, 0, sizeof(minypatch));
1725 memset(heightypatch, 0, sizeof(heightypatch));
1729 memset(decaltexcoords, 0, sizeof(decaltexcoords));
1730 memset(decalvertex, 0, sizeof(decalvertex));
1731 memset(decaltype, 0, sizeof(decaltype));
1732 memset(decalopacity, 0, sizeof(decalopacity));
1733 memset(decalrotation, 0, sizeof(decalrotation));
1734 memset(decalalivetime, 0, sizeof(decalalivetime));
1735 memset(decalbrightness, 0, sizeof(decalbrightness));
1736 memset(decalposition, 0, sizeof(decalposition));
1741 terraintexture.destroy();
1742 shadowtexture.destroy();
1743 bodyprinttexture.destroy();
1744 footprinttexture.destroy();
1745 bloodtexture.destroy();
1746 bloodtexture2.destroy();
1747 breaktexture.destroy();