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 modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 Lugaru 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. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Lugaru. If not, see <http://www.gnu.org/licenses/>.
24 extern float viewdistance;
25 extern float fadestart;
26 extern int environment;
27 extern float texscale;
29 extern float multiplier;
30 extern FRUSTUM frustum;
31 extern float texdetail;
34 extern float blurness;
35 extern float targetblurness;
36 extern Objects objects;
37 extern TGAImageRec texture;
38 extern bool visibleloading;
39 extern bool skyboxtexture;
40 extern int tutoriallevel;
44 int Terrain::lineTerrain(XYZ p1, XYZ p2, XYZ *p)
47 static float distance;
48 static float olddistance;
49 static int intersecting;
50 static int firstintersecting;
52 static int startx, starty;
53 static int endx, endy;
54 static float highest, lowest;
56 firstintersecting = -1;
90 for (i = startx; i <= endx; i++) {
91 for (j = starty; j <= endy; j++) {
94 for (k = 0; k < 2; k++) {
95 if (heightmap[i + k][j] > highest)
96 highest = heightmap[i + k][j];
97 if (heightmap[i + k][j] < lowest)
98 lowest = heightmap[i + k][j];
99 if (heightmap[i + k][j + 1] > highest)
100 highest = heightmap[i + k][j + 1];
101 if (heightmap[i + k][j + 1] < lowest)
102 lowest = heightmap[i + k][j + 1];
104 if ((p1.y <= highest || p2.y <= highest) && (p1.y >= lowest || p2.y >= lowest)) {
106 triangles[0].y = heightmap[i][j];
110 triangles[1].y = heightmap[i][j + 1];
111 triangles[1].z = j + 1;
113 triangles[2].x = i + 1;
114 triangles[2].y = heightmap[i + 1][j];
117 intersecting = LineFacet(p1, p2, triangles[0], triangles[1], triangles[2], &point);
118 distance = distsq(&p1, &point);
119 if ((distance < olddistance || firstintersecting == -1) && intersecting == 1) {
120 olddistance = distance;
121 firstintersecting = 1;
125 triangles[0].x = i + 1;
126 triangles[0].y = heightmap[i + 1][j];
130 triangles[1].y = heightmap[i][j + 1];
131 triangles[1].z = j + 1;
133 triangles[2].x = i + 1;
134 triangles[2].y = heightmap[i + 1][j + 1];
135 triangles[2].z = j + 1;
137 intersecting = LineFacet(p1, p2, triangles[0], triangles[1], triangles[2], &point);
138 distance = distsq(&p1, &point);
139 if ((distance < olddistance || firstintersecting == -1) && intersecting == 1) {
140 olddistance = distance;
141 firstintersecting = 1;
147 return firstintersecting;
150 void Terrain::UpdateTransparency(int whichx, int whichy)
153 static int i, j, a, b, c, d, patch_size, stepsize;
154 static float distance;
156 static float viewdistsquared;
158 viewdistsquared = viewdistance * viewdistance;
159 patch_size = size / subdivision;
162 c = whichx * patch_elements + whichy * patch_elements * subdivision;
164 for (i = patch_size * whichx; i < patch_size * (whichx + 1) + 1; i += stepsize) {
165 for (j = patch_size * whichy; j < patch_size * (whichy + 1) + 1; j += stepsize) {
166 if (i < size && j < size) {
167 vertex.x = i * scale;
168 vertex.z = j * scale;
169 vertex.y = heightmap[i][j] * scale;
170 distance = distsq(&viewer, &vertex);
171 if (distance > viewdistsquared)
172 distance = viewdistsquared;
173 colors[i][j][3] = (viewdistsquared - (distance - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
178 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
179 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
180 a = (i - (patch_size * whichx)) / stepsize;
181 b = (j - (patch_size * whichy)) / stepsize;
182 d = (a * 54) + (b * 54 * patch_size / stepsize);
183 vArray[d + c + 6] = colors[i][j][3];
185 vArray[d + c + 15] = colors[i][j + stepsize][3];
187 vArray[d + c + 24] = colors[i + stepsize][j][3];
189 vArray[d + c + 33] = colors[i + stepsize][j][3];
191 vArray[d + c + 42] = colors[i][j + stepsize][3];
193 vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3];
198 void Terrain::UpdateTransparencyother(int whichx, int whichy)
201 static int i, j, a, b, c, d, patch_size, stepsize;
203 patch_size = size / subdivision;
206 c = whichx * patch_elements + whichy * patch_elements * subdivision;
208 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
209 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
210 a = (i - (patch_size * whichx)) / stepsize;
211 b = (j - (patch_size * whichy)) / stepsize;
212 d = (a * 54) + (b * 54 * patch_size / stepsize);
213 vArray[d + c + 6] = colors[i][j][3] * opacityother[i][j];
215 vArray[d + c + 15] = colors[i][j + stepsize][3] * opacityother[i][j + stepsize];
217 vArray[d + c + 24] = colors[i + stepsize][j][3] * opacityother[i + stepsize][j];
219 vArray[d + c + 33] = colors[i + stepsize][j][3] * opacityother[i + stepsize][j];
221 vArray[d + c + 42] = colors[i][j + stepsize][3] * opacityother[i][j + stepsize];
223 vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3] * opacityother[i + stepsize][j + stepsize];
228 void Terrain::UpdateTransparencyotherother(int whichx, int whichy)
231 static int i, j, a, b, c, d, patch_size, stepsize;
232 static float distance;
234 static float viewdistsquared;
236 viewdistsquared = viewdistance * viewdistance;
237 patch_size = size / subdivision;
240 c = whichx * patch_elements + whichy * patch_elements * subdivision;
242 for (i = patch_size * whichx; i < patch_size * (whichx + 1) + 1; i += stepsize) {
243 for (j = patch_size * whichy; j < patch_size * (whichy + 1) + 1; j += stepsize) {
244 if (i < size && j < size) {
245 vertex.x = i * scale;
246 vertex.z = j * scale;
247 vertex.y = heightmap[i][j] * scale;
248 distance = distsq(&viewer, &vertex);
249 if (distance > viewdistsquared)
250 distance = viewdistsquared;
251 colors[i][j][3] = (viewdistsquared - (distance - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
256 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
257 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
258 a = (i - (patch_size * whichx)) / stepsize;
259 b = (j - (patch_size * whichy)) / stepsize;
260 d = (a * 54) + (b * 54 * patch_size / stepsize);
261 vArray[d + c + 6] = colors[i][j][3];
263 vArray[d + c + 15] = colors[i][j + stepsize][3];
265 vArray[d + c + 24] = colors[i + stepsize][j][3];
267 vArray[d + c + 33] = colors[i + stepsize][j][3];
269 vArray[d + c + 42] = colors[i][j + stepsize][3];
271 vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3];
276 void Terrain::UpdateVertexArray(int whichx, int whichy)
278 static int i, j, a, b, c, patch_size, stepsize;
281 numtris[whichx][whichy] = 0;
283 patch_size = size / subdivision;
286 c = whichx * patch_elements + whichy * patch_elements * subdivision;
287 for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
288 for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
289 a = (i - ((float)size / subdivision * (float)whichx)) / stepsize;
290 b = (j - ((float)size / subdivision * (float)whichy)) / stepsize;
291 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 0] = i * scale;
292 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 1] = heightmap[i][j] * scale;
293 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 2] = j * scale;
294 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 3] = colors[i][j][0];
295 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 4] = colors[i][j][1];
296 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 5] = colors[i][j][2];
297 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 6] = colors[i][j][3];
298 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 7] = i * scale * texscale + texoffsetx[i][j];
299 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 8] = j * scale * texscale + texoffsety[i][j];
301 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 9] = i * scale;
302 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 10] = heightmap[i][j + stepsize] * scale;
303 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 11] = j * scale + stepsize * scale;
304 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 12] = colors[i][j + stepsize][0];
305 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 13] = colors[i][j + stepsize][1];
306 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 14] = colors[i][j + stepsize][2];
307 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 15] = colors[i][j + stepsize][3];
308 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 16] = i * scale * texscale + texoffsetx[i][j + stepsize];
309 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 17] = j * scale * texscale + stepsize * scale * texscale + texoffsety[i][j + stepsize];
311 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 18] = i * scale + stepsize * scale;
312 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 19] = heightmap[i + stepsize][j] * scale;
313 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 20] = j * scale;
314 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 21] = colors[i + stepsize][j][0];
315 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 22] = colors[i + stepsize][j][1];
316 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 23] = colors[i + stepsize][j][2];
317 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 24] = colors[i + stepsize][j][3];
318 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 25] = i * scale * texscale + stepsize * scale * texscale + texoffsetx[i + stepsize][j];
319 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 26] = j * scale * texscale + texoffsety[i + stepsize][j];
321 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 27] = i * scale + stepsize * scale;
322 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 28] = heightmap[i + stepsize][j] * scale;
323 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 29] = j * scale;
324 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 30] = colors[i + stepsize][j][0];
325 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 31] = colors[i + stepsize][j][1];
326 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 32] = colors[i + stepsize][j][2];
327 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 33] = colors[i + stepsize][j][3];
328 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 34] = i * scale * texscale + stepsize * scale * texscale + texoffsetx[i + stepsize][j];
329 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 35] = j * scale * texscale + texoffsety[i + stepsize][j];
331 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 36] = i * scale;
332 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 37] = heightmap[i][j + stepsize] * scale;
333 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 38] = j * scale + stepsize * scale;
334 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 39] = colors[i][j + stepsize][0];
335 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 40] = colors[i][j + stepsize][1];
336 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 41] = colors[i][j + stepsize][2];
337 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 42] = colors[i][j + stepsize][3];
338 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 43] = i * scale * texscale + texoffsetx[i][j + stepsize];
339 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 44] = j * scale * texscale + stepsize * scale * texscale + texoffsety[i][j + stepsize];
341 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 45] = i * scale + stepsize * scale;
342 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 46] = heightmap[i + stepsize][j + stepsize] * scale;
343 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 47] = j * scale + stepsize * scale;
344 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 48] = colors[i + stepsize][j + stepsize][0];
345 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 49] = colors[i + stepsize][j + stepsize][1];
346 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 50] = colors[i + stepsize][j + stepsize][2];
347 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 51] = colors[i + stepsize][j + stepsize][3];
348 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 52] = i * scale * texscale + stepsize * scale * texscale + texoffsetx[i + stepsize][j + stepsize];
349 vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 53] = j * scale * texscale + stepsize * scale * texscale + texoffsety[i + stepsize][j + stepsize];
350 numtris[whichx][whichy] += 2;
354 maxypatch[whichx][whichy] = -10000;
355 minypatch[whichx][whichy] = 10000;
356 for (a = 0; a < size / subdivision; a++) {
357 for (b = 0; b < size / subdivision; b++) {
358 if (heightmap[(size / subdivision)*whichx + a][(size / subdivision)*whichy + b]*scale > maxypatch[whichx][whichy])
359 maxypatch[whichx][whichy] = heightmap[(size / subdivision) * whichx + a][(size / subdivision) * whichy + b] * scale;
360 if (heightmap[(size / subdivision)*whichx + a][(size / subdivision)*whichy + b]*scale < minypatch[whichx][whichy])
361 minypatch[whichx][whichy] = heightmap[(size / subdivision) * whichx + a][(size / subdivision) * whichy + b] * scale;
364 heightypatch[whichx][whichy] = (maxypatch[whichx][whichy] - minypatch[whichx][whichy]);
365 if (heightypatch[whichx][whichy] < size / subdivision * scale)
366 heightypatch[whichx][whichy] = size / subdivision * scale;
367 avgypatch[whichx][whichy] = (minypatch[whichx][whichy] + maxypatch[whichx][whichy]) / 2;
369 for (i = whichx * size / subdivision; i < (whichx + 1)*size / subdivision - 1; i++) {
370 for (j = whichy * size / subdivision; j < (whichy + 1)*size / subdivision - 1; j++) {
371 triangles[(i * (size - 1) * 2) + (j * 2)][0].x = i * scale;
372 triangles[(i * (size - 1) * 2) + (j * 2)][0].y = heightmap[i][j] * scale;
373 triangles[(i * (size - 1) * 2) + (j * 2)][0].z = j * scale;
375 triangles[(i * (size - 1) * 2) + (j * 2)][1].x = i * scale;
376 triangles[(i * (size - 1) * 2) + (j * 2)][1].y = heightmap[i][j + 1] * scale;
377 triangles[(i * (size - 1) * 2) + (j * 2)][1].z = j * scale + scale;
379 triangles[(i * (size - 1) * 2) + (j * 2)][2].x = i * scale + 1 * scale;
380 triangles[(i * (size - 1) * 2) + (j * 2)][2].y = heightmap[i + 1][j] * scale;
381 triangles[(i * (size - 1) * 2) + (j * 2)][2].z = j * scale;
383 triangles[(i * (size - 1) * 2) + (j * 2) + 1][0].x = i * scale + 1 * scale;
384 triangles[(i * (size - 1) * 2) + (j * 2) + 1][0].y = heightmap[i + 1][j] * scale;
385 triangles[(i * (size - 1) * 2) + (j * 2) + 1][0].z = j * scale;
387 triangles[(i * (size - 1) * 2) + (j * 2) + 1][1].x = i * scale;
388 triangles[(i * (size - 1) * 2) + (j * 2) + 1][1].y = heightmap[i][j + 1] * scale;
389 triangles[(i * (size - 1) * 2) + (j * 2) + 1][1].z = j * scale + 1 * scale;
391 triangles[(i * (size - 1) * 2) + (j * 2) + 1][2].x = i * scale + 1 * scale;
392 triangles[(i * (size - 1) * 2) + (j * 2) + 1][2].y = heightmap[i + 1][j + 1] * scale;
393 triangles[(i * (size - 1) * 2) + (j * 2) + 1][2].z = j * scale + 1 * scale;
400 bool Terrain::load(const char *fileName)
404 static float patch_size;
406 float temptexdetail = texdetail;
407 //LoadTGA( fileName );
409 // Fixing filename so that it works with its own os
410 char * FixedFN = ConvertFileName(fileName);
412 unsigned char fileNamep[256];
413 CopyCStringToPascal(FixedFN, fileNamep);
415 upload_image( fileNamep , 0);
418 if (texture.bpp > 24) {
419 int bytesPerPixel = texture.bpp / 8;
422 for (i = 0; i < (long)(texture.sizeY * texture.sizeX * bytesPerPixel); i++) {
424 texture.data[tempnum] = texture.data[i];
431 Game::LoadingScreen();
433 texdetail = temptexdetail;
437 /*if ( texture.bpp == 24 )
442 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
444 if(!terraintexture)glGenTextures( 1, &terraintexture );
445 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
447 glBindTexture( GL_TEXTURE_2D, terraintexture);
448 //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
449 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
451 gluBuild2DMipmaps( GL_TEXTURE_2D, type, texture.sizeX, texture.sizeY, type, GL_UNSIGNED_BYTE, texture.data );
454 size = texture.sizeX;
456 for (i = 0; i < size; i++) {
457 for (j = 0; j < size; j++) {
458 heightmap[size - 1 - i][j] = (float)((texture.data[(i + (j * size)) * texture.bpp / 8])) / 5;
464 Game::LoadingScreen();
468 for (i = 0; i < subdivision; i++) {
469 for (j = 0; j < subdivision; j++) {
470 textureness[i][j] = -1;
474 Game::LoadingScreen();
477 for (i = 0; i < size; i++) {
478 for (j = 0; j < size; j++) {
479 heightmap[i][j] *= .5;
481 texoffsetx[i][j] = (float)abs(Random() % 100) / 1200 / scale * 3;
482 texoffsety[i][j] = (float)abs(Random() % 100) / 1200 / scale * 3;
485 if (environment == snowyenvironment) {
486 if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) {
487 slopeness = heightmap[i][j] - heightmap[i][j - 1];
489 opacityother[i][j] = slopeness * slopeness * 2;
490 if (opacityother[i][j] > 1)
491 opacityother[i][j] = 1;
492 opacityother[i][j] -= (float)abs(Random() % 100) / 300;
494 if (environment == desertenvironment) {
495 if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) {
496 slopeness = heightmap[i][j] - heightmap[i][j - 1];
498 opacityother[i][j] = slopeness * slopeness * 2;
499 if (opacityother[i][j] > 1)
500 opacityother[i][j] = 1;
501 opacityother[i][j] -= (float)abs(Random() % 100) / 300;
503 if (environment == grassyenvironment) {
504 if (i != 0 && heightmap[i][j] - heightmap[i - 1][j] > slopeness) {
505 slopeness = heightmap[i][j] - heightmap[i - 1][j];
507 if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) {
508 slopeness = heightmap[i][j] - heightmap[i][j - 1];
510 if (i < size - 1 && heightmap[i][j] - heightmap[i + 1][j] > slopeness) {
511 slopeness = heightmap[i][j] - heightmap[i + 1][j];
513 if (j < size - 1 && heightmap[i][j] - heightmap[i][j + 1] > slopeness) {
514 slopeness = heightmap[i][j] - heightmap[i][j + 1];
516 opacityother[i][j] = slopeness * slopeness * 10;
517 if (opacityother[i][j] > 1)
518 opacityother[i][j] = 1;
519 opacityother[i][j] -= (float)abs(Random() % 100) / 100;
524 Game::LoadingScreen();
526 for (i = 0; i < size; i++) {
527 for (j = 0; j < size; j++) {
528 if (environment == snowyenvironment) {
529 heightmap[i][j] -= opacityother[i][j];
531 if (environment == desertenvironment) {
532 heightmap[i][j] -= opacityother[i][j];
537 Game::LoadingScreen();
541 //Smooth opacityother
546 if(i!=0){total+=opacityother[j][i-1]; todivide++;}
547 if(i!=size-1){total+=opacityother[j][i+1]; todivide++;}
548 if(j!=0){total+=opacityother[j-1][i]; todivide++;}
549 if(j!=size-1){total+=opacityother[j+1][i]; todivide++;}
550 if(i!=0&&j!=0){total+=opacityother[j-1][i-1]; todivide++;}
551 if(i!=size-1&&j!=0){total+=opacityother[j-1][i+1]; todivide++;}
552 if(j!=size-1&&i!=size-1){total+=opacityother[j+1][i+1]; todivide++;}
553 if(j!=size-1&&i!=0){total+=opacityother[j+1][i-1]; todivide++;}
554 total+=opacityother[j][i]; todivide++;
556 opacityother[j][i]=total/(float)todivide;
561 for (i = 0; i < size; i++) {
562 for (j = 0; j < size; j++) {
563 if (opacityother[i][j] < .1)
564 opacityother[i][j] = 0;
565 if (textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == -1) {
566 if (!opacityother[i][j])
567 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = allfirst;
568 if (opacityother[i][j] == 1)
569 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = allsecond;
571 if (opacityother[i][j] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
572 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
573 if (opacityother[i][j] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
574 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
580 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
581 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
582 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
583 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
584 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
585 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
586 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
587 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
591 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
592 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
593 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
594 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
595 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
596 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
597 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
598 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
604 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
605 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
606 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
607 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
608 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
609 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
610 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
611 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
619 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
620 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
621 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
622 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
623 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
624 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
625 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
626 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
630 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
631 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
632 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
633 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
634 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
635 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
636 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
637 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
643 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
644 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
645 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
646 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
647 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
648 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
649 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
650 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
658 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
659 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
660 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
661 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
662 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
663 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
664 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
665 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
671 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
672 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
673 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
674 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
675 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
676 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
677 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
678 textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
685 Game::LoadingScreen();
687 patch_size = size / subdivision;
688 patch_elements = (patch_size) * (patch_size) * 54;
692 for(i=0;i<subdivision;i++){
693 for(j=0;j<subdivision;j++){
694 UpdateVertexArray(i,j);
701 void Terrain::CalculateNormals()
704 static XYZ facenormal;
705 static XYZ p, q, a, b, c;
707 for (i = 0; i < size; i++) {
708 for (j = 0; j < size; j++) {
715 for (i = 0; i < size - 1; i++) {
716 for (j = 0; j < size - 1; j++) {
718 a.y = heightmap[i][j];
721 b.y = heightmap[i][j + 1];
724 c.y = heightmap[i + 1][j];
734 CrossProduct(&p, &q, &facenormal);
736 facenormals[i][j] = facenormal;
738 normals[i][j] = normals[i][j] + facenormal;
739 normals[i][j + 1] = normals[i][j + 1] + facenormal;
740 normals[i + 1][j] = normals[i + 1][j] + facenormal;
744 a.y = heightmap[i + 1][j];
747 b.y = heightmap[i][j + 1];
750 c.y = heightmap[i + 1][j + 1];
760 CrossProduct(&p, &q, &facenormal);
762 normals[i + 1][j + 1] = normals[i + 1][j + 1] + facenormal;
763 normals[i][j + 1] = normals[i][j + 1] + facenormal;
764 normals[i + 1][j] = normals[i + 1][j] + facenormal;
766 Normalise(&facenormals[i][j]);
770 for (i = 0; i < size; i++) {
771 for (j = 0; j < size; j++) {
772 Normalise(&normals[i][j]);
773 normals[i][j] = normals[i][j];
778 void Terrain::drawpatch(int whichx, int whichy, float opacity)
784 UpdateTransparency(whichx, whichy);
786 glColor4f(1, 1, 1, 1);
787 //Set up vertex array
788 glEnableClientState(GL_VERTEX_ARRAY);
789 glEnableClientState(GL_COLOR_ARRAY);
790 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
791 glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]);
792 glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]);
793 glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]);
796 glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3);
798 glDisableClientState(GL_VERTEX_ARRAY);
799 glDisableClientState(GL_COLOR_ARRAY);
800 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
803 void Terrain::drawpatchother(int whichx, int whichy, float opacity)
807 UpdateTransparency(whichx, whichy);
809 UpdateTransparencyother(whichx, whichy);
810 glColor4f(1, 1, 1, 1);
811 //Set up vertex array
812 glEnableClientState(GL_VERTEX_ARRAY);
813 glEnableClientState(GL_COLOR_ARRAY);
814 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
815 glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]);
816 glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]);
817 glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]);
820 glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3);
822 glDisableClientState(GL_VERTEX_ARRAY);
823 glDisableClientState(GL_COLOR_ARRAY);
824 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
827 void Terrain::drawpatchotherother(int whichx, int whichy, float opacity)
830 UpdateTransparencyotherother(whichx, whichy);
832 glMatrixMode(GL_TEXTURE);
836 glColor4f(1, 1, 1, 1);
838 //Set up vertex array
839 glEnableClientState(GL_VERTEX_ARRAY);
840 glEnableClientState(GL_COLOR_ARRAY);
841 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
842 glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]);
843 glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]);
844 glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]);
847 glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3);
849 glDisableClientState(GL_VERTEX_ARRAY);
850 glDisableClientState(GL_COLOR_ARRAY);
851 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
854 glMatrixMode(GL_MODELVIEW);
858 float Terrain::getHeight(float pointx, float pointz)
860 static int tilex, tiley;
861 static XYZ startpoint, endpoint, intersect, triangle[3], average;
866 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
869 startpoint.x = pointx;
870 startpoint.y = -1000;
871 startpoint.z = pointz;
873 endpoint = startpoint;
879 triangle[0].x = tilex;
880 triangle[0].z = tiley;
881 triangle[0].y = heightmap[tilex][tiley];
883 triangle[1].x = tilex + 1;
884 triangle[1].z = tiley;
885 triangle[1].y = heightmap[tilex + 1][tiley];
887 triangle[2].x = tilex;
888 triangle[2].z = tiley + 1;
889 triangle[2].y = heightmap[tilex][tiley + 1];
891 if (!LineFacetd(&startpoint, &endpoint, &triangle[0], &triangle[1], &triangle[2], &intersect)) {
892 triangle[0].x = tilex + 1;
893 triangle[0].z = tiley;
894 triangle[0].y = heightmap[tilex + 1][tiley];
896 triangle[1].x = tilex + 1;
897 triangle[1].z = tiley + 1;
898 triangle[1].y = heightmap[tilex + 1][tiley + 1];
900 triangle[2].x = tilex;
901 triangle[2].z = tiley + 1;
902 triangle[2].y = heightmap[tilex][tiley + 1];
903 LineFacetd(&startpoint, &endpoint, &triangle[0], &triangle[1], &triangle[2], &intersect);
905 return intersect.y * scale + getOpacity(pointx * scale, pointz * scale) / 8;
907 //height1=heightmap[tilex][tiley]*(1-(pointx-tilex))+heightmap[tilex+1][tiley]*(pointx-tilex);
908 //height2=heightmap[tilex][tiley+1]*(1-(pointx-tilex))+heightmap[tilex+1][tiley+1]*(pointx-tilex);
910 //return height1*(1-(pointz-tiley))*scale+height2*(pointz-tiley)*scale;
913 float Terrain::getHeightExtrude(float pointx, float pointz, float point2x, float point2z)
915 static int tilex, tiley;
916 static XYZ startpoint, endpoint, intersect, triangle[3], average;
923 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
925 if (point2x >= size - 1 || point2z >= size - 1 || point2x <= 0 || point2z <= 0)
928 startpoint.x = point2x;
929 startpoint.y = -1000;
930 startpoint.z = point2z;
932 endpoint = startpoint;
938 triangle[0].x = tilex;
939 triangle[0].z = tiley;
940 triangle[0].y = heightmap[tilex][tiley];
942 triangle[1].x = tilex + 1;
943 triangle[1].z = tiley;
944 triangle[1].y = heightmap[tilex + 1][tiley];
946 triangle[2].x = tilex;
947 triangle[2].z = tiley + 1;
948 triangle[2].y = heightmap[tilex][tiley + 1];
952 mid = (triangle[0] + triangle[1] + triangle[2]) / 2;
954 triangle[0] = mid + (triangle[0] - mid) * 10;
955 triangle[1] = mid + (triangle[0] - mid) * 10;
956 triangle[2] = mid + (triangle[0] - mid) * 10;
959 if(!LineFacetd(&startpoint,&endpoint,&triangle[0],&triangle[1],&triangle[2],&intersect)){
960 triangle[0].x=tilex+1;
962 triangle[0].y=heightmap[tilex+1][tiley];
964 triangle[1].x=tilex+1;
965 triangle[1].z=tiley+1;
966 triangle[1].y=heightmap[tilex+1][tiley+1];
969 triangle[2].z=tiley+1;
970 triangle[2].y=heightmap[tilex][tiley+1];
971 LineFacetd(&startpoint,&endpoint,&triangle[0],&triangle[1],&triangle[2],&intersect);
973 return intersect.y * scale + getOpacity(pointx * scale, pointz * scale) / 8;
975 //height1=heightmap[tilex][tiley]*(1-(pointx-tilex))+heightmap[tilex+1][tiley]*(pointx-tilex);
976 //height2=heightmap[tilex][tiley+1]*(1-(pointx-tilex))+heightmap[tilex+1][tiley+1]*(pointx-tilex);
978 //return height1*(1-(pointz-tiley))*scale+height2*(pointz-tiley)*scale;
982 float Terrain::getOpacity(float pointx, float pointz)
984 static float height1, height2;
985 static int tilex, tiley;
990 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
996 height1 = opacityother[tilex][tiley] * (1 - (pointx - tilex)) + opacityother[tilex + 1][tiley] * (pointx - tilex);
997 height2 = opacityother[tilex][tiley + 1] * (1 - (pointx - tilex)) + opacityother[tilex + 1][tiley + 1] * (pointx - tilex);
999 return height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley);
1002 XYZ Terrain::getNormal(float pointx, float pointz)
1004 static XYZ height1, height2, total;
1005 static int tilex, tiley;
1011 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
1016 height1 = normals[tilex][tiley] * (1 - (pointx - tilex)) + normals[tilex + 1][tiley] * (pointx - tilex);
1017 height2 = normals[tilex][tiley + 1] * (1 - (pointx - tilex)) + normals[tilex + 1][tiley + 1] * (pointx - tilex);
1018 total = height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley);
1023 XYZ Terrain::getLighting(float pointx, float pointz)
1025 static XYZ height1, height2;
1026 static int tilex, tiley;
1032 if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
1037 height1.x = colors[tilex][tiley][0] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][0] * (pointx - tilex);
1038 height1.y = colors[tilex][tiley][1] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][1] * (pointx - tilex);
1039 height1.z = colors[tilex][tiley][2] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][2] * (pointx - tilex);
1040 height2.x = colors[tilex][tiley + 1][0] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][0] * (pointx - tilex);
1041 height2.y = colors[tilex][tiley + 1][1] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][1] * (pointx - tilex);
1042 height2.z = colors[tilex][tiley + 1][2] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][2] * (pointx - tilex);
1044 return height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley);
1047 void Terrain::draw(int layer)
1050 static float opacity;
1051 static XYZ terrainpoint;
1052 static float distance[subdivision][subdivision];
1054 static int beginx, endx;
1055 static int beginz, endz;
1057 static float patch_size = size / subdivision * scale;
1058 static float viewdistsquared;
1060 viewdistsquared = viewdistance * viewdistance;
1062 //Only nearby blocks
1063 beginx = (viewer.x - viewdistance) / (patch_size) - 1;
1066 beginz = (viewer.z - viewdistance) / (patch_size) - 1;
1070 endx = (viewer.x + viewdistance) / (patch_size) + 1;
1071 if (endx > subdivision)
1073 endz = (viewer.z + viewdistance) / (patch_size) + 1;
1074 if (endz > subdivision)
1078 for (i = beginx; i < endx; i++) {
1079 for (j = beginz; j < endz; j++) {
1080 terrainpoint.x = i * patch_size + (patch_size) / 2;
1081 terrainpoint.y = viewer.y; //heightmap[i][j]*scale;
1082 terrainpoint.z = j * patch_size + (patch_size) / 2;
1083 distance[i][j] = distsq(&viewer, &terrainpoint);
1087 for (i = beginx; i < endx; i++) {
1088 for (j = beginz; j < endz; j++) {
1089 if (distance[i][j] < (viewdistance + patch_size) * (viewdistance + patch_size)) {
1091 if (distance[i][j] > viewdistsquared * fadestart - viewdistsquared)
1093 if (opacity == 1 && i != subdivision)
1094 if (distance[i + 1][j] > viewdistsquared * fadestart - viewdistsquared)
1096 if (opacity == 1 && j != subdivision)
1097 if (distance[i][j + 1] > viewdistsquared * fadestart - viewdistsquared)
1099 if (opacity == 1 && j != subdivision && i != subdivision)
1100 if (distance[i + 1][j + 1] > viewdistsquared * fadestart - viewdistsquared)
1102 glMatrixMode(GL_MODELVIEW);
1104 if (frustum.CubeInFrustum(i * patch_size + patch_size * .5, avgypatch[i][j], j * patch_size + patch_size * .5, heightypatch[i][j] / 2)) {
1105 if (environment == desertenvironment && distance[i][j] > viewdistsquared / 4)
1106 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, blurness);
1107 else if (environment == desertenvironment)
1108 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
1109 if (!layer && textureness[i][j] != allsecond)
1110 drawpatch(i, j, opacity);
1111 if (layer == 1 && textureness[i][j] != allfirst)
1112 drawpatchother(i, j, opacity);
1113 if (layer == 2 && textureness[i][j] != allfirst)
1114 drawpatchotherother(i, j, opacity);
1120 if (environment == desertenvironment)
1121 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
1124 void Terrain::drawdecals()
1128 static float distancemult;
1129 static int lasttype;
1131 static float viewdistsquared;
1134 viewdistsquared = viewdistance * viewdistance;
1139 glDisable(GL_LIGHTING);
1140 glDisable(GL_CULL_FACE);
1141 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1143 for (i = 0; i < numdecals; i++) {
1144 if (decaltype[i] == blooddecalfast && decalalivetime[i] < 2)
1145 decalalivetime[i] = 2;
1146 if ((decaltype[i] == shadowdecal || decaltype[i] == shadowdecalpermanent) && decaltype[i] != lasttype) {
1147 shadowtexture.bind();
1150 glAlphaFunc(GL_GREATER, 0.0001);
1151 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1154 if (decaltype[i] == footprintdecal && decaltype[i] != lasttype) {
1155 footprinttexture.bind();
1158 glAlphaFunc(GL_GREATER, 0.0001);
1159 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1162 if (decaltype[i] == bodyprintdecal && decaltype[i] != lasttype) {
1163 bodyprinttexture.bind();
1166 glAlphaFunc(GL_GREATER, 0.0001);
1167 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1170 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalslow) && decaltype[i] != lasttype) {
1171 bloodtexture.bind();
1174 glAlphaFunc(GL_GREATER, 0.15);
1175 glBlendFunc(GL_ONE, GL_ZERO);
1178 if ((decaltype[i] == blooddecalfast) && decaltype[i] != lasttype) {
1179 bloodtexture2.bind();
1182 glAlphaFunc(GL_GREATER, 0.15);
1183 glBlendFunc(GL_ONE, GL_ZERO);
1186 if (decaltype[i] == shadowdecal || decaltype[i] == shadowdecalpermanent) {
1187 distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
1188 if (distancemult >= 1)
1189 glColor4f(1, 1, 1, decalopacity[i]);
1190 if (distancemult < 1)
1191 glColor4f(1, 1, 1, decalopacity[i]*distancemult);
1193 if (decaltype[i] == footprintdecal || decaltype[i] == bodyprintdecal) {
1194 distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
1195 if (distancemult >= 1) {
1196 glColor4f(1, 1, 1, decalopacity[i]);
1197 if (decalalivetime[i] > 3)
1198 glColor4f(1, 1, 1, decalopacity[i] * (5 - decalalivetime[i]) / 2);
1200 if (distancemult < 1) {
1201 glColor4f(1, 1, 1, decalopacity[i]*distancemult);
1202 if (decalalivetime[i] > 3)
1203 glColor4f(1, 1, 1, decalopacity[i] * (5 - decalalivetime[i]) / 2 * distancemult);
1206 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow)) {
1207 distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
1208 if (distancemult >= 1) {
1209 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]);
1210 if (decalalivetime[i] < 4)
1211 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*decalalivetime[i]*.25);
1212 if (decalalivetime[i] > 58)
1213 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i] * (60 - decalalivetime[i]) / 2);
1215 if (distancemult < 1) {
1216 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*distancemult);
1217 if (decalalivetime[i] < 4)
1218 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*decalalivetime[i]*distancemult * .25);
1219 if (decalalivetime[i] > 58)
1220 glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i] * (60 - decalalivetime[i]) / 2 * distancemult);
1223 lasttype = decaltype[i];
1224 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1225 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1227 glMatrixMode(GL_MODELVIEW);
1229 glBegin(GL_TRIANGLES);
1230 for (int j = 0; j < 3; j++) {
1231 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]);
1232 glVertex3f(decalvertex[i][j].x, decalvertex[i][j].y, decalvertex[i][j].z);
1237 for (i = numdecals - 1; i >= 0; i--) {
1238 decalalivetime[i] += multiplier;
1239 if (decaltype[i] == blooddecalslow)
1240 decalalivetime[i] -= multiplier * 2 / 3;
1241 if (decaltype[i] == blooddecalfast)
1242 decalalivetime[i] += multiplier * 4;
1243 if (decaltype[i] == shadowdecal)
1245 if (decaltype[i] == footprintdecal && decalalivetime[i] >= 5)
1247 if (decaltype[i] == bodyprintdecal && decalalivetime[i] >= 5)
1249 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow) && decalalivetime[i] >= 60)
1252 glAlphaFunc(GL_GREATER, 0.0001);
1256 void Terrain::AddObject(XYZ where, float radius, int id)
1261 if (id >= 0 && id < 10000)
1262 for (i = 0; i < subdivision; i++) {
1263 for (j = 0; j < subdivision; j++) {
1264 if (patchobjectnum[i][j] < 300 - 1) {
1266 points[0].x = (size / subdivision) * i;
1267 points[0].z = (size / subdivision) * j;
1268 points[0].y = heightmap[(int)points[0].x][(int)points[0].z];
1269 points[1].x = (size / subdivision) * (i + 1);
1270 points[1].z = (size / subdivision) * j;
1271 points[1].y = heightmap[(int)points[1].x][(int)points[1].z];
1272 points[2].x = (size / subdivision) * (i + 1);
1273 points[2].z = (size / subdivision) * (j + 1);
1274 points[2].y = heightmap[(int)points[2].x][(int)points[2].z];
1275 points[3].x = (size / subdivision) * i;
1276 points[3].z = (size / subdivision) * (j + 1);
1277 points[3].y = heightmap[(int)points[3].x][(int)points[3].z];
1282 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) {
1283 patchobjects[i][j][patchobjectnum[i][j]] = id;
1284 patchobjectnum[i][j]++;
1292 void Terrain::DeleteDecal(int which)
1295 decaltype[which] = decaltype[numdecals - 1];
1296 decalposition[which] = decalposition[numdecals - 1];
1297 for (int i = 0; i < 3; i++) {
1298 decalvertex[which][i] = decalvertex[numdecals - 1][i];
1299 decaltexcoords[which][i][0] = decaltexcoords[numdecals - 1][i][0];
1300 decaltexcoords[which][i][1] = decaltexcoords[numdecals - 1][i][1];
1302 decalrotation[which] = decalrotation[numdecals - 1];
1303 decalalivetime[which] = decalalivetime[numdecals - 1];
1304 decalopacity[which] = decalopacity[numdecals - 1];
1305 decalbrightness[which] = decalbrightness[numdecals - 1];
1310 void Terrain::MakeDecal(int type, XYZ where, float size, float opacity, float rotation)
1313 if (opacity > 0 && size > 0) {
1314 static int patchx[4];
1315 static int patchy[4];
1317 decaltexcoords[numdecals][0][0] = 1;
1318 decaltexcoords[numdecals][0][1] = 0;
1320 patchx[0] = (where.x + size) / scale;
1321 patchx[1] = (where.x - size) / scale;
1322 patchx[2] = (where.x - size) / scale;
1323 patchx[3] = (where.x + size) / scale;
1325 patchy[0] = (where.z - size) / scale;
1326 patchy[1] = (where.z - size) / scale;
1327 patchy[2] = (where.z + size) / scale;
1328 patchy[3] = (where.z + size) / scale;
1330 /*if(patchx[1]<subdivision-1&&patchy[1]<subdivision-1&&patchx[1]>0&&patchy[1]>0)
1331 if(patchx[2]<subdivision-1&&patchy[2]<subdivision-1&&patchx[2]>0&&patchy[2]>0)
1332 if(patchx[3]<subdivision-1&&patchy[3]<subdivision-1&&patchx[3]>0&&patchy[3]>0)
1333 if(patchx[0]<subdivision-1&&patchy[0]<subdivision-1&&patchx[0]>0&&patchy[0]>0){
1335 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])) {
1336 MakeDecalLock(type, where, patchx[0], patchy[0], size, opacity, rotation);
1339 if ((patchx[1] != patchx[2] || patchy[1] != patchy[2]) && (patchx[1] != patchx[3] || patchy[1] != patchy[3])) {
1340 MakeDecalLock(type, where, patchx[1], patchy[1], size, opacity, rotation);
1343 if ((patchx[2] != patchx[3] || patchy[2] != patchy[3])) {
1344 MakeDecalLock(type, where, patchx[2], patchy[2], size, opacity, rotation);
1346 MakeDecalLock(type, where, patchx[3], patchy[3], size, opacity, rotation);
1352 void Terrain::MakeDecalLock(int type, XYZ where, int whichx, int whichy, float size, float opacity, float rotation)
1355 static float placex, placez;
1360 rot = getLighting(where.x, where.z);
1361 decalbrightness[numdecals] = (rot.x + rot.y + rot.z) / 3;
1362 if (decalbrightness[numdecals] < .4)
1363 decalbrightness[numdecals] = .4;
1365 if (environment == grassyenvironment) {
1366 decalbrightness[numdecals] *= .6;
1369 if (decalbrightness[numdecals] > 1)
1370 decalbrightness[numdecals] = 1;
1371 decalbright = decalbrightness[numdecals];
1373 decalposition[numdecals] = where;
1374 decaltype[numdecals] = type;
1375 decalopacity[numdecals] = opacity;
1376 decalrotation[numdecals] = rotation;
1377 decalalivetime[numdecals] = 0;
1379 placex = (float)whichx * scale + scale;
1380 placez = (float)whichy * scale;
1382 decaltexcoords[numdecals][0][0] = (placex - where.x) / size / 2 + .5;
1383 decaltexcoords[numdecals][0][1] = (placez - where.z) / size / 2 + .5;
1385 decalvertex[numdecals][0].x = placex;
1386 decalvertex[numdecals][0].z = placez;
1387 decalvertex[numdecals][0].y = heightmap[whichx + 1][whichy] * scale + .01;
1390 placex = (float)whichx * scale + scale;
1391 placez = (float)whichy * scale + scale;
1393 decaltexcoords[numdecals][1][0] = (placex - where.x) / size / 2 + .5;
1394 decaltexcoords[numdecals][1][1] = (placez - where.z) / size / 2 + .5;
1396 decalvertex[numdecals][1].x = placex;
1397 decalvertex[numdecals][1].z = placez;
1398 decalvertex[numdecals][1].y = heightmap[whichx + 1][whichy + 1] * scale + .01;
1401 placex = (float)whichx * scale;
1402 placez = (float)whichy * scale + scale;
1404 decaltexcoords[numdecals][2][0] = (placex - where.x) / size / 2 + .5;
1405 decaltexcoords[numdecals][2][1] = (placez - where.z) / size / 2 + .5;
1407 decalvertex[numdecals][2].x = placex;
1408 decalvertex[numdecals][2].z = placez;
1409 decalvertex[numdecals][2].y = heightmap[whichx][whichy + 1] * scale + .01;
1411 if (decalrotation[numdecals]) {
1412 for (int i = 0; i < 3; i++) {
1414 rot.x = decaltexcoords[numdecals][i][0] - .5;
1415 rot.z = decaltexcoords[numdecals][i][1] - .5;
1416 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1417 decaltexcoords[numdecals][i][0] = rot.x + .5;
1418 decaltexcoords[numdecals][i][1] = rot.z + .5;
1422 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1423 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1424 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1425 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1))
1426 if (numdecals < max_decals - 1)
1429 decalbrightness[numdecals] = decalbright;
1431 decalposition[numdecals] = where;
1432 decaltype[numdecals] = type;
1433 decalopacity[numdecals] = opacity;
1434 decalrotation[numdecals] = rotation;
1435 decalalivetime[numdecals] = 0;
1437 placex = (float)whichx * scale + scale;
1438 placez = (float)whichy * scale;
1440 decaltexcoords[numdecals][0][0] = (placex - where.x) / size / 2 + .5;
1441 decaltexcoords[numdecals][0][1] = (placez - where.z) / size / 2 + .5;
1443 decalvertex[numdecals][0].x = placex;
1444 decalvertex[numdecals][0].z = placez;
1445 decalvertex[numdecals][0].y = heightmap[whichx + 1][whichy] * scale + .01;
1448 placex = (float)whichx * scale;
1449 placez = (float)whichy * scale;
1451 decaltexcoords[numdecals][1][0] = (placex - where.x) / size / 2 + .5;
1452 decaltexcoords[numdecals][1][1] = (placez - where.z) / size / 2 + .5;
1454 decalvertex[numdecals][1].x = placex;
1455 decalvertex[numdecals][1].z = placez;
1456 decalvertex[numdecals][1].y = heightmap[whichx][whichy] * scale + .01;
1459 placex = (float)whichx * scale;
1460 placez = (float)whichy * scale + scale;
1462 decaltexcoords[numdecals][2][0] = (placex - where.x) / size / 2 + .5;
1463 decaltexcoords[numdecals][2][1] = (placez - where.z) / size / 2 + .5;
1465 decalvertex[numdecals][2].x = placex;
1466 decalvertex[numdecals][2].z = placez;
1467 decalvertex[numdecals][2].y = heightmap[whichx][whichy + 1] * scale + .01;
1469 if (decalrotation[numdecals]) {
1470 for (int i = 0; i < 3; i++) {
1472 rot.x = decaltexcoords[numdecals][i][0] - .5;
1473 rot.z = decaltexcoords[numdecals][i][1] - .5;
1474 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1475 decaltexcoords[numdecals][i][0] = rot.x + .5;
1476 decaltexcoords[numdecals][i][1] = rot.z + .5;
1480 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1481 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1482 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1483 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1))
1484 if (numdecals < max_decals - 1)
1489 void Terrain::DoLighting()
1491 static int i, j, k, todivide;
1492 static float brightness, total;
1493 static XYZ blank, terrainpoint, lightloc;
1494 lightloc = light.location;
1495 Normalise(&lightloc);
1497 for (i = 0; i < size; i++) {
1498 for (j = 0; j < size; j++) {
1499 terrainpoint.x = (float)i * scale;
1500 terrainpoint.z = (float)j * scale;
1501 terrainpoint.y = heightmap[i][j] * scale + .1;
1503 if(lineTerrain(lightlocation*10+terrainpoint,terrainpoint,&blank)==-1)
1505 brightness = dotproduct(&lightloc, &normals[i][j]);
1512 colors[i][j][0] = light.color[0] * brightness + light.ambient[0];
1513 colors[i][j][1] = light.color[1] * brightness + light.ambient[1];
1514 colors[i][j][2] = light.color[2] * brightness + light.ambient[2];
1516 if (colors[i][j][0] > 1) colors[i][j][0] = 1;
1517 if (colors[i][j][1] > 1) colors[i][j][1] = 1;
1518 if (colors[i][j][2] > 1) colors[i][j][2] = 1;
1519 if (colors[i][j][0] < 0) colors[i][j][0] = 0;
1520 if (colors[i][j][1] < 0) colors[i][j][1] = 0;
1521 if (colors[i][j][2] < 0) colors[i][j][2] = 0;
1526 for (i = 0; i < size; i++) {
1527 for (j = 0; j < size; j++) {
1528 for (k = 0; k < 3; k++) {
1532 total += colors[j][i - 1][k];
1535 if (i != size - 1) {
1536 total += colors[j][i + 1][k];
1540 total += colors[j - 1][i][k];
1543 if (j != size - 1) {
1544 total += colors[j + 1][i][k];
1547 if (i != 0 && j != 0) {
1548 total += colors[j - 1][i - 1][k];
1551 if (i != size - 1 && j != 0) {
1552 total += colors[j - 1][i + 1][k];
1555 if (j != size - 1 && i != size - 1) {
1556 total += colors[j + 1][i + 1][k];
1559 if (j != size - 1 && i != 0) {
1560 total += colors[j + 1][i - 1][k];
1563 total += colors[j][i][k];
1566 colors[j][i][k] = total / todivide;
1572 void Terrain::DoShadows()
1574 static int i, j, k, l, todivide;
1575 static float brightness, total;
1576 static XYZ testpoint, testpoint2, terrainpoint, lightloc, col;
1577 lightloc = light.location;
1578 if (!skyboxtexture) {
1582 if (skyboxtexture && tutoriallevel) {
1588 Normalise(&lightloc);
1590 for (i = 0; i < size; i++) {
1591 for (j = 0; j < size; j++) {
1592 terrainpoint.x = (float)(i) * scale;
1593 terrainpoint.z = (float)(j) * scale;
1594 terrainpoint.y = heightmap[i][j] * scale;
1597 patchx = (float)(i) * subdivision / size;
1598 patchz = (float)(j) * subdivision / size;
1599 if (patchobjectnum[patchx][patchz]) {
1600 for (k = 0; k < patchobjectnum[patchx][patchz]; k++) {
1601 l = patchobjects[patchx][patchz][k];
1602 if (objects.type[l] != treetrunktype) {
1603 testpoint = terrainpoint;
1604 testpoint2 = terrainpoint + lightloc * 50 * (1 - shadowed);
1605 if (objects.model[l].LineCheck(&testpoint, &testpoint2, &col, &objects.position[l], &objects.yaw[l]) != -1) {
1606 shadowed = 1 - (findDistance(&terrainpoint, &col) / 50);
1611 Game::LoadingScreen();
1613 brightness = dotproduct(&lightloc, &normals[i][j]);
1615 brightness *= 1 - shadowed;
1622 colors[i][j][0] = light.color[0] * brightness + light.ambient[0];
1623 colors[i][j][1] = light.color[1] * brightness + light.ambient[1];
1624 colors[i][j][2] = light.color[2] * brightness + light.ambient[2];
1626 if (colors[i][j][0] > 1) colors[i][j][0] = 1;
1627 if (colors[i][j][1] > 1) colors[i][j][1] = 1;
1628 if (colors[i][j][2] > 1) colors[i][j][2] = 1;
1629 if (colors[i][j][0] < 0) colors[i][j][0] = 0;
1630 if (colors[i][j][1] < 0) colors[i][j][1] = 0;
1631 if (colors[i][j][2] < 0) colors[i][j][2] = 0;
1636 Game::LoadingScreen();
1639 for (i = 0; i < size; i++) {
1640 for (j = 0; j < size; j++) {
1641 for (k = 0; k < 3; k++) {
1645 total += colors[j][i - 1][k];
1648 if (i != size - 1) {
1649 total += colors[j][i + 1][k];
1653 total += colors[j - 1][i][k];
1656 if (j != size - 1) {
1657 total += colors[j + 1][i][k];
1660 if (i != 0 && j != 0) {
1661 total += colors[j - 1][i - 1][k];
1664 if (i != size - 1 && j != 0) {
1665 total += colors[j - 1][i + 1][k];
1668 if (j != size - 1 && i != size - 1) {
1669 total += colors[j + 1][i + 1][k];
1672 if (j != size - 1 && i != 0) {
1673 total += colors[j + 1][i - 1][k];
1676 total += colors[j][i][k];
1679 colors[j][i][k] = total / todivide;
1684 for (i = 0; i < subdivision; i++) {
1685 for (j = 0; j < subdivision; j++) {
1686 UpdateVertexArray(i, j);
1695 memset(patchobjectnum, 0, sizeof(patchobjectnum));
1696 memset(patchobjects, 0, sizeof(patchobjects));
1700 memset(heightmap, 0, sizeof(heightmap));
1701 memset(normals, 0, sizeof(normals));
1702 memset(facenormals, 0, sizeof(facenormals));
1703 memset(triangles, 0, sizeof(triangles));
1704 memset(colors, 0, sizeof(colors));
1705 memset(opacityother, 0, sizeof(opacityother));
1706 memset(texoffsetx, 0, sizeof(texoffsetx));
1707 memset(texoffsety, 0, sizeof(texoffsety));
1708 memset(numtris, 0, sizeof(numtris));
1709 memset(textureness, 0, sizeof(textureness));
1711 memset(vArray, 0, sizeof(vArray));
1713 memset(visible, 0, sizeof(visible));
1714 memset(avgypatch, 0, sizeof(avgypatch));
1715 memset(maxypatch, 0, sizeof(maxypatch));
1716 memset(minypatch, 0, sizeof(minypatch));
1717 memset(heightypatch, 0, sizeof(heightypatch));
1721 memset(decaltexcoords, 0, sizeof(decaltexcoords));
1722 memset(decalvertex, 0, sizeof(decalvertex));
1723 memset(decaltype, 0, sizeof(decaltype));
1724 memset(decalopacity, 0, sizeof(decalopacity));
1725 memset(decalrotation, 0, sizeof(decalrotation));
1726 memset(decalalivetime, 0, sizeof(decalalivetime));
1727 memset(decalbrightness, 0, sizeof(decalbrightness));
1728 memset(decalposition, 0, sizeof(decalposition));
1733 terraintexture.destroy();
1734 shadowtexture.destroy();
1735 bodyprinttexture.destroy();
1736 footprinttexture.destroy();
1737 bloodtexture.destroy();
1738 bloodtexture2.destroy();
1739 breaktexture.destroy();