1 /*-------------------------------------------------------------------------------
2
3 BARONY
4 File: opengl.cpp
5 Desc: contains all drawing functions for opengl
6
7 Copyright 2013-2016 (c) Turning Wheel LLC, all rights reserved.
8 See LICENSE for details.
9
10 -------------------------------------------------------------------------------*/
11
12 #include "main.hpp"
13 #include "draw.hpp"
14 #include "entity.hpp"
15 #include "files.hpp"
16
17 #ifdef WINDOWS
18 PFNGLGENBUFFERSPROC SDL_glGenBuffers;
19 PFNGLBINDBUFFERPROC SDL_glBindBuffer;
20 PFNGLBUFFERDATAPROC SDL_glBufferData;
21 PFNGLDELETEBUFFERSPROC SDL_glDeleteBuffers;
22 PFNGLGENVERTEXARRAYSPROC SDL_glGenVertexArrays;
23 PFNGLBINDVERTEXARRAYPROC SDL_glBindVertexArray;
24 PFNGLDELETEVERTEXARRAYSPROC SDL_glDeleteVertexArrays;
25 PFNGLENABLEVERTEXATTRIBARRAYPROC SDL_glEnableVertexAttribArray;
26 PFNGLVERTEXATTRIBPOINTERPROC SDL_glVertexAttribPointer;
27 #endif
28
29 /*-------------------------------------------------------------------------------
30
31 getLightForEntity
32
33 Returns a shade factor (0.0-1.0) to shade an entity with, based on
34 its surroundings
35
36 -------------------------------------------------------------------------------*/
37
getLightForEntity(real_t x,real_t y)38 real_t getLightForEntity(real_t x, real_t y)
39 {
40 if ( x < 0 || y < 0 || x >= map.width || y >= map.height )
41 {
42 return 1.f;
43 }
44 int u = x;
45 int v = y;
46 return std::min(std::max(0, lightmapSmoothed[v + u * map.height]), 255) / 255.0;
47 }
48
49 /*-------------------------------------------------------------------------------
50
51 glDrawVoxel
52
53 Draws a voxel model at the given world coordinates
54
55 -------------------------------------------------------------------------------*/
56
57 bool wholevoxels = false;
glDrawVoxel(view_t * camera,Entity * entity,int mode)58 void glDrawVoxel(view_t* camera, Entity* entity, int mode)
59 {
60 real_t dx, dy, dz;
61 int voxX, voxY, voxZ;
62 real_t s = 1;
63 //int x = 0;
64 //int y = 0;
65 Sint32 index;
66 Sint32 indexdown[3];
67 voxel_t* model;
68 int modelindex = 0;
69 GLfloat rotx, roty, rotz;
70 //GLuint uidcolor;
71
72 if (!entity)
73 {
74 return;
75 }
76
77 // assign model
78 if ( entity->sprite >= 0 && entity->sprite < nummodels )
79 {
80 if ( models[entity->sprite] != NULL )
81 {
82 model = models[entity->sprite];
83 }
84 else
85 {
86 model = models[0];
87 }
88 modelindex = entity->sprite;
89 }
90 else
91 {
92 model = models[0];
93 modelindex = 0;
94 }
95
96 if ( model == models[0] )
97 {
98 return; // don't draw green balls
99 }
100
101 // model array indexes
102 indexdown[0] = model->sizez * model->sizey;
103 indexdown[1] = model->sizez;
104 indexdown[2] = 1;
105
106 glBindTexture(GL_TEXTURE_2D, 0);
107
108 // setup projection
109 glMatrixMode( GL_PROJECTION );
110 glLoadIdentity();
111 glViewport(camera->winx, yres - camera->winh - camera->winy, camera->winw, camera->winh);
112 gluPerspective(fov, (real_t)camera->winw / (real_t)camera->winh, CLIPNEAR, CLIPFAR * 2);
113 glEnable( GL_DEPTH_TEST );
114 if ( !entity->flags[OVERDRAW] )
115 {
116 rotx = camera->vang * 180 / PI; // get x rotation
117 roty = (camera->ang - 3 * PI / 2) * 180 / PI; // get y rotation
118 rotz = 0; // get z rotation
119 glRotatef(rotx, 1, 0, 0); // rotate pitch
120 glRotatef(roty, 0, 1, 0); // rotate yaw
121 glRotatef(rotz, 0, 0, 1); // rotate roll
122 glTranslatef(-camera->x * 32, camera->z, -camera->y * 32); // translates the scene based on camera position
123 }
124 else
125 {
126 glRotatef(90, 0, 1, 0);
127 }
128
129 // setup model matrix
130 glMatrixMode( GL_MODELVIEW );
131 glLoadIdentity();
132 glPushMatrix();
133 rotx = entity->roll * 180 / PI; // get x rotation
134 roty = 360 - entity->yaw * 180 / PI; // get y rotation
135 rotz = 360 - entity->pitch * 180 / PI; // get z rotation
136 glTranslatef(entity->x * 2, -entity->z * 2 - 1, entity->y * 2);
137 glRotatef(roty, 0, 1, 0); // rotate yaw
138 glRotatef(rotz, 0, 0, 1); // rotate pitch
139 glRotatef(rotx, 1, 0, 0); // rotate roll
140 glTranslatef(entity->focalx * 2, -entity->focalz * 2, entity->focaly * 2);
141 glScalef(entity->scalex, entity->scalez, entity->scaley);
142 if ( mode == REALCOLORS )
143 {
144 glEnable(GL_BLEND);
145 }
146 else
147 {
148 glDisable(GL_BLEND);
149 }
150
151 if ( entity->flags[OVERDRAW] || entity->monsterEntityRenderAsTelepath == 1 )
152 {
153 glDepthRange(0, 0.1);
154 }
155
156 // get shade factor
157 if (!entity->flags[BRIGHT])
158 {
159 if ( !entity->flags[OVERDRAW] )
160 {
161 if ( entity->monsterEntityRenderAsTelepath == 1 )
162 {
163 if ( globalLightModifierActive )
164 {
165 s = globalLightTelepathyModifier;
166 }
167 }
168 else
169 {
170 s = getLightForEntity(entity->x / 16, entity->y / 16);
171 }
172 }
173 else
174 {
175 s = getLightForEntity(camera->x, camera->y);
176 }
177 }
178
179 if ( globalLightModifierActive && entity->monsterEntityRenderAsTelepath == 0 )
180 {
181 s *= globalLightModifier;
182 }
183
184 // Moved glBeign / glEnd outside the loops, to limit the number of calls (helps gl4es on Pandora)
185 if ( wholevoxels )
186 {
187 glBegin( GL_QUADS );
188 for ( index = 0, voxX = 0; voxX < model->sizex; voxX++ )
189 {
190 for ( voxY = 0; voxY < model->sizey; voxY++ )
191 {
192 for ( voxZ = 0; voxZ < model->sizez; voxZ++, index++ )
193 {
194 // get the bit color
195 if ( model->data[index] == 255 || model->data[index] == 0 )
196 {
197 continue;
198 }
199 if ( mode == REALCOLORS )
200 {
201 glColor3f((model->palette[model->data[index]][0] / 255.0)*s, (model->palette[model->data[index]][1] / 255.0)*s, (model->palette[model->data[index]][2] / 255.0)*s );
202 }
203 else
204 {
205 Uint32 uid = entity->getUID();
206 glColor4ub((Uint8)(uid), (Uint8)(uid >> 8), (Uint8)(uid >> 16), (Uint8)(uid >> 24));
207 }
208
209 // calculate model offsets
210 dx = (real_t)voxX - ((real_t)model->sizex) / 2.f;
211 dy = (real_t)voxY - ((real_t)model->sizey) / 2.f;
212 dz = ((real_t)model->sizez) / 2.f - (real_t)voxZ;
213
214 // draw front of cube
215 bool drawFront = false;
216 if ( voxX == model->sizex - 1 )
217 {
218 drawFront = true;
219 }
220 else if ( model->data[index + indexdown[0]] == 255 )
221 {
222 drawFront = true;
223 }
224 if ( drawFront )
225 {
226 //glBegin( GL_QUADS );
227 glVertex3f(dx + 1, dz + 0, dy + 1);
228 glVertex3f(dx + 1, dz + 0, dy + 0);
229 glVertex3f(dx + 1, dz + 1, dy + 0);
230 glVertex3f(dx + 1, dz + 1, dy + 1);
231 //glEnd();
232 }
233
234 // draw back of cube
235 bool drawBack = false;
236 if ( voxX == 0 )
237 {
238 drawBack = true;
239 }
240 else if ( model->data[index - indexdown[0]] == 255 )
241 {
242 drawBack = true;
243 }
244 if ( drawBack )
245 {
246 //glBegin( GL_QUADS );
247 glVertex3f(dx + 0, dz + 0, dy + 1);
248 glVertex3f(dx + 0, dz + 1, dy + 1);
249 glVertex3f(dx + 0, dz + 1, dy + 0);
250 glVertex3f(dx + 0, dz + 0, dy + 0);
251 //glEnd();
252 }
253
254 // draw right side of cube
255 bool drawRight = false;
256 if ( voxY == model->sizey - 1 )
257 {
258 drawRight = true;
259 }
260 else if ( model->data[index + indexdown[1]] == 255 )
261 {
262 drawRight = true;
263 }
264 if ( drawRight )
265 {
266 //glBegin( GL_QUADS );
267 glVertex3f(dx + 0, dz + 0, dy + 1);
268 glVertex3f(dx + 1, dz + 0, dy + 1);
269 glVertex3f(dx + 1, dz + 1, dy + 1);
270 glVertex3f(dx + 0, dz + 1, dy + 1);
271 //glEnd();
272 }
273
274 // draw left side of cube
275 bool drawLeft = false;
276 if ( voxY == 0 )
277 {
278 drawLeft = true;
279 }
280 else if ( model->data[index - indexdown[1]] == 255 )
281 {
282 drawLeft = true;
283 }
284 if ( drawLeft )
285 {
286 //glBegin( GL_QUADS );
287 glVertex3f(dx + 0, dz + 0, dy + 0);
288 glVertex3f(dx + 0, dz + 1, dy + 0);
289 glVertex3f(dx + 1, dz + 1, dy + 0);
290 glVertex3f(dx + 1, dz + 0, dy + 0);
291 //glEnd();
292 }
293
294 // draw bottom of cube
295 bool drawBottom = false;
296 if ( voxZ == model->sizez - 1 )
297 {
298 drawBottom = true;
299 }
300 else if ( model->data[index + indexdown[2]] == 255 )
301 {
302 drawBottom = true;
303 }
304 if ( drawBottom )
305 {
306 //glBegin( GL_QUADS );
307 glVertex3f(dx + 0, dz + 0, dy + 0);
308 glVertex3f(dx + 1, dz + 0, dy + 0);
309 glVertex3f(dx + 1, dz + 0, dy + 1);
310 glVertex3f(dx + 0, dz + 0, dy + 1);
311 //glEnd();
312 }
313
314 // draw top of cube
315 bool drawTop = false;
316 if ( voxZ == 0 )
317 {
318 drawTop = true;
319 }
320 else if ( model->data[index - indexdown[2]] == 255 )
321 {
322 drawTop = true;
323 }
324 if ( drawTop )
325 {
326 //glBegin( GL_QUADS );
327 glVertex3f(dx + 0, dz + 1, dy + 0);
328 glVertex3f(dx + 0, dz + 1, dy + 1);
329 glVertex3f(dx + 1, dz + 1, dy + 1);
330 glVertex3f(dx + 1, dz + 1, dy + 0);
331 //glEnd();
332 }
333 }
334 }
335 }
336 glEnd();
337 }
338 else
339 {
340 if ( disablevbos )
341 {
342 glBegin( GL_TRIANGLES ); //moved outside
343 for ( index = 0; index < polymodels[modelindex].numfaces; index++ )
344 {
345 if ( mode == REALCOLORS )
346 {
347 if ( entity->flags[USERFLAG2] )
348 {
349 if ( entity->behavior == &actMonster
350 && (entity->isPlayerHeadSprite() || entity->sprite == 467 || !monsterChangesColorWhenAlly(nullptr, entity)) )
351 {
352 // dont invert human heads, or automaton heads.
353 glColor3f((polymodels[modelindex].faces[index].r / 255.f)*s, (polymodels[modelindex].faces[index].g / 255.f)*s, (polymodels[modelindex].faces[index].b / 255.f)*s );
354 }
355 else
356 {
357 glColor3f((polymodels[modelindex].faces[index].b / 255.f)*s, (polymodels[modelindex].faces[index].r / 255.f)*s, (polymodels[modelindex].faces[index].g / 255.f)*s);
358 }
359 }
360 else
361 {
362 glColor3f((polymodels[modelindex].faces[index].b / 255.f)*s, (polymodels[modelindex].faces[index].r / 255.f)*s, (polymodels[modelindex].faces[index].g / 255.f)*s );
363 }
364 }
365 else
366 {
367 Uint32 uid = entity->getUID();
368 glColor4ub((Uint8)(uid), (Uint8)(uid >> 8), (Uint8)(uid >> 16), (Uint8)(uid >> 24));
369 }
370
371 polytriangle_t* face = &polymodels[modelindex].faces[index];
372
373 //glBegin( GL_TRIANGLES );
374 glVertex3f(face->vertex[0].x, -face->vertex[0].z, face->vertex[0].y);
375 glVertex3f(face->vertex[1].x, -face->vertex[1].z, face->vertex[1].y);
376 glVertex3f(face->vertex[2].x, -face->vertex[2].z, face->vertex[2].y);
377 //glEnd();
378 }
379 glEnd();
380 }
381 else
382 {
383 SDL_glBindVertexArray(polymodels[modelindex].va);
384 SDL_glBindBuffer(GL_ARRAY_BUFFER, polymodels[modelindex].vbo);
385 glVertexPointer( 3, GL_FLOAT, 0, (char*) NULL ); // Set The Vertex Pointer To The Vertex Buffer
386 glEnableClientState(GL_VERTEX_ARRAY); // enable the vertex array on the client side
387 if ( mode == REALCOLORS )
388 {
389 glEnableClientState(GL_COLOR_ARRAY); // enable the color array on the client side
390 if ( entity->flags[USERFLAG2] )
391 {
392 if ( entity->behavior == &actMonster && (entity->isPlayerHeadSprite()
393 || entity->sprite == 467 || !monsterChangesColorWhenAlly(nullptr, entity)) )
394 {
395 SDL_glBindBuffer(GL_ARRAY_BUFFER, polymodels[modelindex].colors);
396 }
397 else
398 {
399 SDL_glBindBuffer(GL_ARRAY_BUFFER, polymodels[modelindex].colors_shifted);
400 }
401 }
402 else
403 {
404 SDL_glBindBuffer(GL_ARRAY_BUFFER, polymodels[modelindex].colors);
405 }
406 glColorPointer(3, GL_FLOAT, 0, 0);
407 GLfloat params_col[4] = {static_cast<GLfloat>(s), static_cast<GLfloat>(s), static_cast<GLfloat>(s), 1.f};
408 glEnable(GL_LIGHTING);
409 glEnable(GL_COLOR_MATERIAL);
410 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, params_col);
411 }
412 else
413 {
414 GLfloat uidcolors[4];
415 Uint32 uid = entity->getUID();
416 uidcolors[0] = ((Uint8)(uid)) / 255.f;
417 uidcolors[1] = ((Uint8)(uid >> 8)) / 255.f;
418 uidcolors[2] = ((Uint8)(uid >> 16)) / 255.f;
419 uidcolors[3] = ((Uint8)(uid >> 24)) / 255.f;
420 glColor4f(uidcolors[0], uidcolors[1], uidcolors[2], uidcolors[3]);
421 }
422 glDrawArrays(GL_TRIANGLES, 0, 3 * polymodels[modelindex].numfaces);
423 if ( mode == REALCOLORS )
424 {
425 glDisable(GL_COLOR_MATERIAL);
426 glDisable(GL_LIGHTING);
427 glDisableClientState(GL_COLOR_ARRAY); // disable the color array on the client side
428 }
429 glDisableClientState(GL_VERTEX_ARRAY); // disable the vertex array on the client side
430 }
431 }
432 glDepthRange(0, 1);
433 glPopMatrix();
434 }
435
436 /*-------------------------------------------------------------------------------
437
438 glDrawSprite
439
440 Draws a 2D sprite to represent an object in 3D
441
442 -------------------------------------------------------------------------------*/
443
glDrawSprite(view_t * camera,Entity * entity,int mode)444 void glDrawSprite(view_t* camera, Entity* entity, int mode)
445 {
446 SDL_Surface* sprite;
447 //int x, y;
448 real_t s = 1;
449
450 // setup projection
451 glMatrixMode( GL_PROJECTION );
452 glLoadIdentity();
453 glViewport(camera->winx, yres - camera->winh - camera->winy, camera->winw, camera->winh);
454 gluPerspective(fov, (real_t)camera->winw / (real_t)camera->winh, CLIPNEAR, CLIPFAR * 2);
455 glEnable( GL_DEPTH_TEST );
456 if (!entity->flags[OVERDRAW])
457 {
458 GLfloat rotx = camera->vang * 180 / PI; // get x rotation
459 GLfloat roty = (camera->ang - 3 * PI / 2) * 180 / PI; // get y rotation
460 GLfloat rotz = 0; // get z rotation
461 glRotatef(rotx, 1, 0, 0); // rotate pitch
462 glRotatef(roty, 0, 1, 0); // rotate yaw
463 glRotatef(rotz, 0, 0, 1); // rotate roll
464 glTranslatef(-camera->x * 32, camera->z, -camera->y * 32); // translates the scene based on camera position
465 }
466 else
467 {
468 glRotatef(90, 0, 1, 0);
469
470 }
471
472 // setup model matrix
473 glMatrixMode( GL_MODELVIEW );
474 glLoadIdentity();
475 glPushMatrix();
476 if ( mode == REALCOLORS )
477 {
478 glEnable(GL_BLEND);
479 }
480 else
481 {
482 glDisable(GL_BLEND);
483 }
484
485 // assign texture
486 if ( entity->sprite >= 0 && entity->sprite < numsprites )
487 {
488 if ( sprites[entity->sprite] != NULL )
489 {
490 sprite = sprites[entity->sprite];
491 }
492 else
493 {
494 sprite = sprites[0];
495 }
496 }
497 else
498 {
499 sprite = sprites[0];
500 }
501 if ( mode == REALCOLORS )
502 {
503 glBindTexture(GL_TEXTURE_2D, texid[sprite->refcount]);
504 }
505 else
506 {
507 glBindTexture(GL_TEXTURE_2D, 0);
508 }
509
510 // translate sprite and rotate towards camera
511 //double tangent = atan2( entity->y-camera->y*16, camera->x*16-entity->x ) * (180/PI);
512 glTranslatef(entity->x * 2, -entity->z * 2 - 1, entity->y * 2);
513 if (!entity->flags[OVERDRAW])
514 {
515 real_t tangent = 180 - camera->ang * (180 / PI);
516 glRotatef(tangent, 0, 1, 0);
517 }
518 else
519 {
520 real_t tangent = 180;
521 glRotatef(tangent, 0, 1, 0);
522 }
523 glScalef(entity->scalex, entity->scalez, entity->scaley);
524
525 if ( entity->flags[OVERDRAW] )
526 {
527 glDepthRange(0, 0.1);
528 }
529
530 // get shade factor
531 if ( mode == REALCOLORS )
532 {
533 if (!entity->flags[BRIGHT])
534 {
535 if (!entity->flags[OVERDRAW])
536 {
537 s = getLightForEntity(entity->x / 16, entity->y / 16);
538 }
539 else
540 {
541 s = getLightForEntity(camera->x, camera->y);
542 }
543
544 if ( globalLightModifierActive )
545 {
546 s *= globalLightModifier;
547 }
548
549 glColor4f(s, s, s, 1);
550 }
551 else
552 {
553 if ( globalLightModifierActive )
554 {
555 glColor4f(globalLightModifier, globalLightModifier, globalLightModifier, 1);
556 }
557 else
558 {
559 glColor4f(1.f, 1.f, 1.f, 1);
560 }
561 }
562 }
563 else
564 {
565 Uint32 uid = entity->getUID();
566 glColor4ub((Uint8)(uid), (Uint8)(uid >> 8), (Uint8)(uid >> 16), (Uint8)(uid >> 24));
567 }
568
569 // draw quad
570 glBegin(GL_QUADS);
571 glTexCoord2f(0, 0);
572 glVertex3f(0, sprite->h / 2, sprite->w / 2);
573 glTexCoord2f(0, 1);
574 glVertex3f(0, -sprite->h / 2, sprite->w / 2);
575 glTexCoord2f(1, 1);
576 glVertex3f(0, -sprite->h / 2, -sprite->w / 2);
577 glTexCoord2f(1, 0);
578 glVertex3f(0, sprite->h / 2, -sprite->w / 2);
579 glEnd();
580 glDepthRange(0, 1);
581 glPopMatrix();
582 }
583
glDrawSpriteFromImage(view_t * camera,Entity * entity,std::string text,int mode)584 void glDrawSpriteFromImage(view_t* camera, Entity* entity, std::string text, int mode)
585 {
586 //int x, y;
587 real_t s = 1;
588 SDL_Surface* image = sprites[0];
589 GLuint textureId = texid[sprites[0]->refcount];
590 char textToRetrieve[128];
591
592 if ( text.compare("") == 0 )
593 {
594 return;
595 }
596
597 // strncpy() does not copy N bytes if a terminating null is encountered first
598 // see http://www.cplusplus.com/reference/cstring/strncpy/
599 // see https://en.cppreference.com/w/c/string/byte/strncpy
600 // GCC throws a warning (intended) when the length argument to strncpy()
601 // in any way depends on strlen(src) to discourage this (and related) construct(s).
602 strncpy(textToRetrieve, text.c_str(), 22);
603 textToRetrieve[std::min(static_cast<int>(strlen(text.c_str())), 22)] = '\0';
604 if ( (image = ttfTextHashRetrieve(ttfTextHash, textToRetrieve, ttf12, true)) != NULL )
605 {
606 textureId = texid[image->refcount];
607 }
608 else
609 {
610 // create the text outline surface
611 TTF_SetFontOutline(ttf12, 2);
612 SDL_Color sdlColorBlack = { 0, 0, 0, 255 };
613 image = TTF_RenderUTF8_Blended(ttf12, textToRetrieve, sdlColorBlack);
614
615 // create the text surface
616 TTF_SetFontOutline(ttf12, 0);
617 SDL_Color sdlColorWhite = { 255, 255, 255, 255 };
618 SDL_Surface* textSurf = TTF_RenderUTF8_Blended(ttf12, textToRetrieve, sdlColorWhite);
619
620 // combine the surfaces
621 SDL_Rect pos;
622 pos.x = 2;
623 pos.y = 2;
624 pos.h = 0;
625 pos.w = 0;
626
627 SDL_BlitSurface(textSurf, NULL, image, &pos);
628 // load the text outline surface as a GL texture
629 allsurfaces[imgref] = image;
630 allsurfaces[imgref]->refcount = imgref;
631 glLoadTexture(allsurfaces[imgref], imgref);
632 imgref++;
633 // store the surface in the text surface cache
634 if ( !ttfTextHashStore(ttfTextHash, textToRetrieve, ttf12, true, image) )
635 {
636 printlog("warning: failed to store text outline surface with imgref %d\n", imgref - 1);
637 }
638 textureId = texid[image->refcount];
639 }
640 // setup projection
641 glMatrixMode(GL_PROJECTION);
642 glLoadIdentity();
643 glViewport(camera->winx, yres - camera->winh - camera->winy, camera->winw, camera->winh);
644 gluPerspective(fov, (real_t)camera->winw / (real_t)camera->winh, CLIPNEAR, CLIPFAR * 2);
645 glEnable(GL_DEPTH_TEST);
646 if ( !entity->flags[OVERDRAW] )
647 {
648 GLfloat rotx = camera->vang * 180 / PI; // get x rotation
649 GLfloat roty = (camera->ang - 3 * PI / 2) * 180 / PI; // get y rotation
650 GLfloat rotz = 0; // get z rotation
651 glRotatef(rotx, 1, 0, 0); // rotate pitch
652 glRotatef(roty, 0, 1, 0); // rotate yaw
653 glRotatef(rotz, 0, 0, 1); // rotate roll
654 glTranslatef(-camera->x * 32, camera->z, -camera->y * 32); // translates the scene based on camera position
655 }
656 else
657 {
658 glRotatef(90, 0, 1, 0);
659 }
660
661
662 // setup model matrix
663 glMatrixMode(GL_MODELVIEW);
664 glLoadIdentity();
665 glPushMatrix();
666 if ( mode == REALCOLORS )
667 {
668 glEnable(GL_BLEND);
669 }
670 else
671 {
672 glDisable(GL_BLEND);
673 }
674
675 // assign texture
676 if ( mode == REALCOLORS )
677 {
678 glBindTexture(GL_TEXTURE_2D, textureId);
679 }
680 else
681 {
682 glBindTexture(GL_TEXTURE_2D, 0);
683 }
684
685 // translate sprite and rotate towards camera
686 //double tangent = atan2( entity->y-camera->y*16, camera->x*16-entity->x ) * (180/PI);
687 glTranslatef(entity->x * 2, -entity->z * 2 - 1, entity->y * 2);
688 if ( !entity->flags[OVERDRAW] )
689 {
690 real_t tangent = 180 - camera->ang * (180 / PI);
691 glRotatef(tangent, 0, 1, 0);
692 }
693 else
694 {
695 real_t tangent = 180;
696 glRotatef(tangent, 0, 1, 0);
697 }
698 glScalef(entity->scalex, entity->scalez, entity->scaley);
699
700 if ( entity->flags[OVERDRAW] )
701 {
702 glDepthRange(0, 0.1);
703 }
704
705 // get shade factor
706 if ( mode == REALCOLORS )
707 {
708 if ( !entity->flags[BRIGHT] )
709 {
710 if ( !entity->flags[OVERDRAW] )
711 {
712 s = getLightForEntity(entity->x / 16, entity->y / 16);
713 }
714 else
715 {
716 s = getLightForEntity(camera->x, camera->y);
717 }
718 glColor4f(s, s, s, 1);
719 }
720 else
721 {
722 glColor4f(1.f, 1.f, 1.f, 1);
723 }
724 }
725 else
726 {
727 Uint32 uid = entity->getUID();
728 glColor4ub((Uint8)(uid), (Uint8)(uid >> 8), (Uint8)(uid >> 16), (Uint8)(uid >> 24));
729 }
730
731 // draw quad
732 glBegin(GL_QUADS);
733 glTexCoord2f(0, 0);
734 glVertex3f(0, image->h / 2, image->w / 2);
735 glTexCoord2f(0, 1);
736 glVertex3f(0, -image->h / 2, image->w / 2);
737 glTexCoord2f(1, 1);
738 glVertex3f(0, -image->h / 2, -image->w / 2);
739 glTexCoord2f(1, 0);
740 glVertex3f(0, image->h / 2, -image->w / 2);
741 glEnd();
742 glDepthRange(0, 1);
743 glPopMatrix();
744 }
745
746 /*-------------------------------------------------------------------------------
747
748 getLightAt
749
750 returns the light shade factor for the vertex at the given x/y point
751
752 -------------------------------------------------------------------------------*/
753
getLightAt(int x,int y)754 real_t getLightAt(int x, int y)
755 {
756 real_t l = 0;
757 int u, v;
758
759 for ( u = x - 1; u < x + 1; u++ )
760 {
761 for ( v = y - 1; v < y + 1; v++ )
762 {
763 if ( u >= 0 && u < map.width && v >= 0 && v < map.height )
764 {
765 l += std::min(std::max(0, lightmapSmoothed[v + u * map.height]), 255) / 255.0;
766 }
767 }
768 }
769
770 if ( globalLightModifierActive )
771 {
772 l *= globalLightModifier;
773 }
774
775 return l / 4.f;
776 }
777
778 /*-------------------------------------------------------------------------------
779
780 glDrawWorld
781
782 Draws the current map from the given camera point
783
784 -------------------------------------------------------------------------------*/
785
glDrawWorld(view_t * camera,int mode)786 void glDrawWorld(view_t* camera, int mode)
787 {
788 int x, y, z;
789 int index;
790 real_t s;
791 bool clouds = false;
792 int cloudtile = 0;
793 int mapceilingtile = 50;
794
795 if ( softwaremode == true )
796 {
797 return;
798 }
799
800 if ( (!strncmp(map.name, "Hell", 4) || map.skybox != 0) && smoothlighting )
801 {
802 clouds = true;
803 if ( !strncmp(map.name, "Hell", 4) )
804 {
805 cloudtile = 77;
806 }
807 else
808 {
809 cloudtile = map.skybox;
810 }
811 }
812
813 for ( int v = 0; v < map.height; v++ )
814 {
815 for ( int u = 0; u < map.width; u++ )
816 {
817 int smoothingRate = globalLightSmoothingRate;
818 int difference = abs(lightmapSmoothed[v + u * map.height] - lightmap[v + u * map.height]);
819 if ( difference > 64 )
820 {
821 smoothingRate *= 4;
822 }
823 else if ( difference > 32 )
824 {
825 smoothingRate *= 2;
826 }
827 if ( lightmapSmoothed[v + u * map.height] < lightmap[v + u * map.height] )
828 {
829 lightmapSmoothed[v + u * map.height] = std::min(lightmap[v + u * map.height], lightmapSmoothed[v + u * map.height] + smoothingRate);
830 }
831 else if ( lightmapSmoothed[v + u * map.height] > lightmap[v + u * map.height] )
832 {
833 lightmapSmoothed[v + u * map.height] = std::max(lightmap[v + u * map.height], lightmapSmoothed[v + u * map.height] - smoothingRate);
834 }
835 }
836 }
837
838 if ( map.flags[MAP_FLAG_CEILINGTILE] != 0 && map.flags[MAP_FLAG_CEILINGTILE] < numtiles )
839 {
840 mapceilingtile = map.flags[MAP_FLAG_CEILINGTILE];
841 }
842
843 glEnable(GL_SCISSOR_TEST);
844 glScissor(camera->winx, yres - camera->winh - camera->winy, camera->winw, camera->winh);
845
846 if ( clouds && mode == REALCOLORS )
847 {
848 // draw sky "box"
849 glMatrixMode( GL_PROJECTION );
850 glLoadIdentity();
851 glViewport(camera->winx, yres - camera->winh - camera->winy, camera->winw, camera->winh);
852 gluPerspective(fov, (real_t)camera->winw / (real_t)camera->winh, CLIPNEAR, CLIPFAR * 16);
853 GLfloat rotx = camera->vang * 180 / PI; // get x rotation
854 GLfloat roty = (camera->ang - 3 * PI / 2) * 180 / PI; // get y rotation
855 GLfloat rotz = 0; // get z rotation
856 glRotatef(rotx, 1, 0, 0); // rotate pitch
857 glRotatef(roty, 0, 1, 0); // rotate yaw
858 glRotatef(rotz, 0, 0, 1); // rotate roll
859 glMatrixMode( GL_MODELVIEW );
860 glLoadIdentity();
861 glEnable( GL_DEPTH_TEST );
862 glDepthMask(GL_FALSE);
863 glEnable(GL_BLEND);
864
865 // first (higher) sky layer
866 glColor4f(1.f, 1.f, 1.f, .5);
867 glBindTexture(GL_TEXTURE_2D, texid[tiles[cloudtile]->refcount]); // sky tile
868 glBegin( GL_QUADS );
869 glTexCoord2f((real_t)(ticks % 60) / 60, (real_t)(ticks % 60) / 60);
870 glVertex3f(-CLIPFAR * 16, 64, -CLIPFAR * 16);
871
872 glTexCoord2f((CLIPFAR) / 2 + (real_t)(ticks % 60) / 60, (real_t)(ticks % 60) / 60);
873 glVertex3f(CLIPFAR * 16, 64, -CLIPFAR * 16);
874
875 glTexCoord2f((CLIPFAR) / 2 + (real_t)(ticks % 60) / 60, (CLIPFAR) / 2 + (real_t)(ticks % 60) / 60);
876 glVertex3f(CLIPFAR * 16, 64, CLIPFAR * 16);
877
878 glTexCoord2f((real_t)(ticks % 60) / 60, (CLIPFAR) / 2 + (real_t)(ticks % 60) / 60);
879 glVertex3f(-CLIPFAR * 16, 64, CLIPFAR * 16);
880 glEnd();
881
882 // second (closer) sky layer
883 glColor4f(1.f, 1.f, 1.f, .5);
884 glBindTexture(GL_TEXTURE_2D, texid[tiles[cloudtile]->refcount]); // sky tile
885 glBegin( GL_QUADS );
886 glTexCoord2f((real_t)(ticks % 240) / 240, (real_t)(ticks % 240) / 240);
887 glVertex3f(-CLIPFAR * 16, 32, -CLIPFAR * 16);
888
889 glTexCoord2f((CLIPFAR) / 2 + (real_t)(ticks % 240) / 240, (real_t)(ticks % 240) / 240);
890 glVertex3f(CLIPFAR * 16, 32, -CLIPFAR * 16);
891
892 glTexCoord2f((CLIPFAR) / 2 + (real_t)(ticks % 240) / 240, (CLIPFAR) / 2 + (real_t)(ticks % 240) / 240);
893 glVertex3f(CLIPFAR * 16, 32, CLIPFAR * 16);
894
895 glTexCoord2f((real_t)(ticks % 240) / 240, (CLIPFAR) / 2 + (real_t)(ticks % 240) / 240);
896 glVertex3f(-CLIPFAR * 16, 32, CLIPFAR * 16);
897 glEnd();
898 }
899
900 // setup projection
901 glMatrixMode( GL_PROJECTION );
902 glLoadIdentity();
903 glViewport(camera->winx, yres - camera->winh - camera->winy, camera->winw, camera->winh);
904 gluPerspective(fov, (real_t)camera->winw / (real_t)camera->winh, CLIPNEAR, CLIPFAR * 2);
905 GLfloat rotx = camera->vang * 180 / PI; // get x rotation
906 GLfloat roty = (camera->ang - 3 * PI / 2) * 180 / PI; // get y rotation
907 GLfloat rotz = 0; // get z rotation
908 glRotatef(rotx, 1, 0, 0); // rotate pitch
909 glRotatef(roty, 0, 1, 0); // rotate yaw
910 glRotatef(rotz, 0, 0, 1); // rotate roll
911 glTranslatef(-camera->x * 32, camera->z, -camera->y * 32); // translates the scene based on camera position
912 glMatrixMode( GL_MODELVIEW );
913 glLoadIdentity();
914 glEnable( GL_DEPTH_TEST );
915 glDepthMask(GL_TRUE);
916 if ( mode == REALCOLORS )
917 {
918 glEnable(GL_BLEND);
919 }
920 else
921 {
922 glDisable(GL_BLEND);
923 }
924
925 // glBegin / glEnd are also moved outside,
926 // but needs to track the texture used to "flush" current drawing before switching
927 GLuint cur_tex = 0, new_tex = 0;
928 glBindTexture(GL_TEXTURE_2D, 0);
929 glBegin(GL_QUADS);
930 for ( x = 0; x < map.width; x++ )
931 {
932 for ( y = 0; y < map.height; y++ )
933 {
934 if ( x >= (int)camera->x - 3 && x <= (int)camera->x + 3 && y >= (int)camera->y - 3 && y <= (int)camera->y + 3 )
935 {
936 vismap[y + x * map.height] = true;
937 }
938 if ( vismap[y + x * map.height] )
939 {
940 for ( z = 0; z < MAPLAYERS + 1; z++ )
941 {
942 index = z + y * MAPLAYERS + x * MAPLAYERS * map.height;
943
944 if ( z >= 0 && z < MAPLAYERS )
945 {
946 // skip "air" tiles
947 if ( map.tiles[index] == 0 )
948 {
949 continue;
950 }
951
952 // bind texture
953 if ( mode == REALCOLORS )
954 {
955 if ( map.tiles[index] < 0 || map.tiles[index] >= numtiles )
956 {
957 new_tex = texid[sprites[0]->refcount];
958 //glBindTexture(GL_TEXTURE_2D, texid[sprites[0]->refcount]);
959 }
960 else
961 {
962 new_tex = texid[tiles[map.tiles[index]]->refcount];
963 //glBindTexture(GL_TEXTURE_2D, texid[tiles[map.tiles[index]]->refcount]);
964 }
965 }
966 else
967 {
968 new_tex = 0;
969 //glBindTexture(GL_TEXTURE_2D, 0);
970 }
971 // check if the texture has changed (flushing drawing if it's the case)
972 if(new_tex != cur_tex)
973 {
974 glEnd();
975 glBindTexture(GL_TEXTURE_2D, new_tex);
976 cur_tex=new_tex;
977 glBegin(GL_QUADS);
978 }
979
980 // draw east wall
981 if ( x == map.width - 1 || !map.tiles[index + MAPLAYERS * map.height] )
982 {
983 if ( smoothlighting && mode == REALCOLORS )
984 {
985 //glBegin( GL_QUADS );
986 if ( z )
987 {
988 s = getLightAt(x + 1, y + 1);
989 glColor3f(s, s, s);
990 glTexCoord2f(0, 0);
991 glVertex3f(x * 32 + 32, z * 32 - 16, y * 32 + 32);
992 glTexCoord2f(0, 1);
993 glVertex3f(x * 32 + 32, z * 32 - 48, y * 32 + 32);
994 s = getLightAt(x + 1, y);
995 glColor3f(s, s, s);
996 glTexCoord2f(1, 1);
997 glVertex3f(x * 32 + 32, z * 32 - 48, y * 32 + 0);
998 glTexCoord2f(1, 0);
999 glVertex3f(x * 32 + 32, z * 32 - 16, y * 32 + 0);
1000 }
1001 else
1002 {
1003 s = getLightAt(x + 1, y + 1);
1004 glColor3f(s, s, s);
1005 glTexCoord2f(0, 0);
1006 glVertex3f(x * 32 + 32, z * 32 - 16, y * 32 + 32);
1007 glColor3f(0, 0, 0);
1008 glTexCoord2f(0, 2);
1009 glVertex3f(x * 32 + 32, z * 32 - 48 - 32, y * 32 + 32);
1010 s = getLightAt(x + 1, y);
1011 glColor3f(0, 0, 0);
1012 glTexCoord2f(1, 2);
1013 glVertex3f(x * 32 + 32, z * 32 - 48 - 32, y * 32 + 0);
1014 glColor3f(s, s, s);
1015 glTexCoord2f(1, 0);
1016 glVertex3f(x * 32 + 32, z * 32 - 16, y * 32 + 0);
1017 }
1018 //glEnd();
1019 }
1020 else
1021 {
1022 if ( mode == REALCOLORS )
1023 {
1024 if ( x < map.width - 1 )
1025 {
1026 s = std::min(std::max(0, lightmapSmoothed[y + (x + 1) * map.height]), 255) / 255.0;
1027 if ( globalLightModifierActive )
1028 {
1029 s *= globalLightModifier;
1030 }
1031 }
1032 else
1033 {
1034 s = .5;
1035 }
1036 glColor3f(s, s, s);
1037 }
1038 else
1039 {
1040 glColor4ub(0, 0, 0, 0);
1041 }
1042 if ( x == map.width - 1 || !map.tiles[z + y * MAPLAYERS + (x + 1)*MAPLAYERS * map.height] )
1043 {
1044 //glBegin( GL_QUADS );
1045 glTexCoord2f(0, 0);
1046 glVertex3f(x * 32 + 32, z * 32 - 16, y * 32 + 32);
1047 glTexCoord2f(0, 1);
1048 glVertex3f(x * 32 + 32, z * 32 - 48, y * 32 + 32);
1049 glTexCoord2f(1, 1);
1050 glVertex3f(x * 32 + 32, z * 32 - 48, y * 32 + 0);
1051 glTexCoord2f(1, 0);
1052 glVertex3f(x * 32 + 32, z * 32 - 16, y * 32 + 0);
1053 //glEnd();
1054 }
1055 }
1056 }
1057
1058 // draw south wall
1059 if ( y == map.height - 1 || !map.tiles[index + MAPLAYERS] )
1060 {
1061 if ( smoothlighting && mode == REALCOLORS )
1062 {
1063 //glBegin( GL_QUADS );
1064 if ( z )
1065 {
1066 s = getLightAt(x, y + 1);
1067 glColor3f(s, s, s);
1068 glTexCoord2f(0, 0);
1069 glVertex3f(x * 32 + 0, z * 32 - 16, y * 32 + 32);
1070 glTexCoord2f(0, 1);
1071 glVertex3f(x * 32 + 0, z * 32 - 48, y * 32 + 32);
1072 s = getLightAt(x + 1, y + 1);
1073 glColor3f(s, s, s);
1074 glTexCoord2f(1, 1);
1075 glVertex3f(x * 32 + 32, z * 32 - 48, y * 32 + 32);
1076 glTexCoord2f(1, 0);
1077 glVertex3f(x * 32 + 32, z * 32 - 16, y * 32 + 32);
1078 }
1079 else
1080 {
1081 s = getLightAt(x, y + 1);
1082 glColor3f(s, s, s);
1083 glTexCoord2f(0, 0);
1084 glVertex3f(x * 32 + 0, z * 32 - 16, y * 32 + 32);
1085 glColor3f(0, 0, 0);
1086 glTexCoord2f(0, 2);
1087 glVertex3f(x * 32 + 0, z * 32 - 48 - 32, y * 32 + 32);
1088 s = getLightAt(x + 1, y + 1);
1089 glColor3f(0, 0, 0);
1090 glTexCoord2f(1, 2);
1091 glVertex3f(x * 32 + 32, z * 32 - 48 - 32, y * 32 + 32);
1092 glColor3f(s, s, s);
1093 glTexCoord2f(1, 0);
1094 glVertex3f(x * 32 + 32, z * 32 - 16, y * 32 + 32);
1095 }
1096 //glEnd();
1097 }
1098 else
1099 {
1100 if ( mode == REALCOLORS )
1101 {
1102 if ( y < map.height - 1 )
1103 {
1104 s = std::min(std::max(0, lightmapSmoothed[(y + 1) + x * map.height]), 255) / 255.0;
1105 if ( globalLightModifierActive )
1106 {
1107 s *= globalLightModifier;
1108 }
1109 }
1110 else
1111 {
1112 s = .5;
1113 }
1114 glColor3f(s, s, s);
1115 }
1116 if ( y == map.height - 1 || !map.tiles[z + (y + 1)*MAPLAYERS + x * MAPLAYERS * map.height] )
1117 {
1118 //glBegin( GL_QUADS );
1119 glTexCoord2f(0, 0);
1120 glVertex3f(x * 32 + 0, z * 32 - 16, y * 32 + 32);
1121 glTexCoord2f(0, 1);
1122 glVertex3f(x * 32 + 0, z * 32 - 48, y * 32 + 32);
1123 glTexCoord2f(1, 1);
1124 glVertex3f(x * 32 + 32, z * 32 - 48, y * 32 + 32);
1125 glTexCoord2f(1, 0);
1126 glVertex3f(x * 32 + 32, z * 32 - 16, y * 32 + 32);
1127 //glEnd();
1128 }
1129 }
1130 }
1131
1132 // draw west wall
1133 if ( x == 0 || !map.tiles[index - MAPLAYERS * map.height] )
1134 {
1135 if ( smoothlighting && mode == REALCOLORS )
1136 {
1137 //glBegin( GL_QUADS );
1138 if ( z )
1139 {
1140 s = getLightAt(x, y);
1141 glColor3f(s, s, s);
1142 glTexCoord2f(0, 0);
1143 glVertex3f(x * 32 + 0, z * 32 - 16, y * 32 + 0);
1144 glTexCoord2f(0, 1);
1145 glVertex3f(x * 32 + 0, z * 32 - 48, y * 32 + 0);
1146 s = getLightAt(x, y + 1);
1147 glColor3f(s, s, s);
1148 glTexCoord2f(1, 1);
1149 glVertex3f(x * 32 + 0, z * 32 - 48, y * 32 + 32);
1150 glTexCoord2f(1, 0);
1151 glVertex3f(x * 32 + 0, z * 32 - 16, y * 32 + 32);
1152 }
1153 else
1154 {
1155 s = getLightAt(x, y);
1156 glColor3f(s, s, s);
1157 glTexCoord2f(0, 0);
1158 glVertex3f(x * 32 + 0, z * 32 - 16, y * 32 + 0);
1159 glColor3f(0, 0, 0);
1160 glTexCoord2f(0, 2);
1161 glVertex3f(x * 32 + 0, z * 32 - 48 - 32, y * 32 + 0);
1162 s = getLightAt(x, y + 1);
1163 glColor3f(0, 0, 0);
1164 glTexCoord2f(1, 2);
1165 glVertex3f(x * 32 + 0, z * 32 - 48 - 32, y * 32 + 32);
1166 glColor3f(s, s, s);
1167 glTexCoord2f(1, 0);
1168 glVertex3f(x * 32 + 0, z * 32 - 16, y * 32 + 32);
1169 }
1170 //glEnd();
1171 }
1172 else
1173 {
1174 if ( mode == REALCOLORS )
1175 {
1176 if ( x > 0 )
1177 {
1178 s = std::min(std::max(0, lightmapSmoothed[y + (x - 1) * map.height]), 255) / 255.0;
1179 if ( globalLightModifierActive )
1180 {
1181 s *= globalLightModifier;
1182 }
1183 }
1184 else
1185 {
1186 s = .5;
1187 }
1188 glColor3f(s, s, s);
1189 }
1190 if ( x == 0 || !map.tiles[z + y * MAPLAYERS + (x - 1)*MAPLAYERS * map.height] )
1191 {
1192 //glBegin( GL_QUADS );
1193 glTexCoord2f(0, 0);
1194 glVertex3f(x * 32 + 0, z * 32 - 16, y * 32 + 0);
1195 glTexCoord2f(0, 1);
1196 glVertex3f(x * 32 + 0, z * 32 - 48, y * 32 + 0);
1197 glTexCoord2f(1, 1);
1198 glVertex3f(x * 32 + 0, z * 32 - 48, y * 32 + 32);
1199 glTexCoord2f(1, 0);
1200 glVertex3f(x * 32 + 0, z * 32 - 16, y * 32 + 32);
1201 //glEnd();
1202 }
1203 }
1204 }
1205
1206 // draw north wall
1207 if ( y == 0 || !map.tiles[index - MAPLAYERS] )
1208 {
1209 if ( smoothlighting && mode == REALCOLORS )
1210 {
1211 //glBegin( GL_QUADS );
1212 if ( z )
1213 {
1214 s = getLightAt(x + 1, y);
1215 glColor3f(s, s, s);
1216 glTexCoord2f(0, 0);
1217 glVertex3f(x * 32 + 32, z * 32 - 16, y * 32 + 0);
1218 glTexCoord2f(0, 1);
1219 glVertex3f(x * 32 + 32, z * 32 - 48, y * 32 + 0);
1220 s = getLightAt(x, y);
1221 glColor3f(s, s, s);
1222 glTexCoord2f(1, 1);
1223 glVertex3f(x * 32 + 0, z * 32 - 48, y * 32 + 0);
1224 glTexCoord2f(1, 0);
1225 glVertex3f(x * 32 + 0, z * 32 - 16, y * 32 + 0);
1226 }
1227 else
1228 {
1229 s = getLightAt(x + 1, y);
1230 glColor3f(s, s, s);
1231 glTexCoord2f(0, 0);
1232 glVertex3f(x * 32 + 32, z * 32 - 16, y * 32 + 0);
1233 glColor3f(0, 0, 0);
1234 glTexCoord2f(0, 2);
1235 glVertex3f(x * 32 + 32, z * 32 - 48 - 32, y * 32 + 0);
1236 s = getLightAt(x, y);
1237 glColor3f(0, 0, 0);
1238 glTexCoord2f(1, 2);
1239 glVertex3f(x * 32 + 0, z * 32 - 48 - 32, y * 32 + 0);
1240 glColor3f(s, s, s);
1241 glTexCoord2f(1, 0);
1242 glVertex3f(x * 32 + 0, z * 32 - 16, y * 32 + 0);
1243 }
1244 //glEnd();
1245 }
1246 else
1247 {
1248 if ( mode == REALCOLORS )
1249 {
1250 if ( y > 0 )
1251 {
1252 s = std::min(std::max(0, lightmapSmoothed[(y - 1) + x * map.height]), 255) / 255.0;
1253 if ( globalLightModifierActive )
1254 {
1255 s *= globalLightModifier;
1256 }
1257 }
1258 else
1259 {
1260 s = .5;
1261 }
1262 glColor3f(s, s, s);
1263 }
1264 if ( y == 0 || !map.tiles[z + (y - 1)*MAPLAYERS + x * MAPLAYERS * map.height] )
1265 {
1266 //glBegin( GL_QUADS );
1267 glTexCoord2f(0, 0);
1268 glVertex3f(x * 32 + 32, z * 32 - 16, y * 32 + 0);
1269 glTexCoord2f(0, 1);
1270 glVertex3f(x * 32 + 32, z * 32 - 48, y * 32 + 0);
1271 glTexCoord2f(1, 1);
1272 glVertex3f(x * 32 + 0, z * 32 - 48, y * 32 + 0);
1273 glTexCoord2f(1, 0);
1274 glVertex3f(x * 32 + 0, z * 32 - 16, y * 32 + 0);
1275 //glEnd();
1276 }
1277 }
1278 }
1279 }
1280 else
1281 {
1282 // bind texture
1283 if ( mode == REALCOLORS )
1284 {
1285 new_tex = texid[tiles[mapceilingtile]->refcount];
1286 //glBindTexture(GL_TEXTURE_2D, texid[tiles[50]->refcount]); // rock tile
1287 if (cur_tex!=new_tex)
1288 {
1289 glEnd();
1290 cur_tex = new_tex;
1291 glBindTexture(GL_TEXTURE_2D, new_tex);
1292 glBegin(GL_QUADS);
1293 }
1294 }
1295 else
1296 {
1297 continue;
1298 }
1299 }
1300
1301 if ( smoothlighting && mode == REALCOLORS )
1302 {
1303 // draw floor
1304 if ( z < OBSTACLELAYER )
1305 {
1306 if ( !map.tiles[index + 1] )
1307 {
1308 //glBegin( GL_QUADS );
1309 s = getLightAt(x, y);
1310 glColor3f(s, s, s);
1311 glTexCoord2f(0, 0);
1312 glVertex3f(x * 32 + 0, -16 - 32 * abs(z), y * 32 + 0);
1313 s = getLightAt(x, y + 1);
1314 glColor3f(s, s, s);
1315 glTexCoord2f(0, 1);
1316 glVertex3f(x * 32 + 0, -16 - 32 * abs(z), y * 32 + 32);
1317 s = getLightAt(x + 1, y + 1);
1318 glColor3f(s, s, s);
1319 glTexCoord2f(1, 1);
1320 glVertex3f(x * 32 + 32, -16 - 32 * abs(z), y * 32 + 32);
1321 s = getLightAt(x + 1, y);
1322 glColor3f(s, s, s);
1323 glTexCoord2f(1, 0);
1324 glVertex3f(x * 32 + 32, -16 - 32 * abs(z), y * 32 + 0);
1325 //glEnd();
1326 }
1327 }
1328
1329 // draw ceiling
1330 else if ( z > OBSTACLELAYER && (!clouds || z < MAPLAYERS) )
1331 {
1332 if ( !map.tiles[index - 1] )
1333 {
1334 //glBegin( GL_QUADS );
1335 s = getLightAt(x, y);
1336 glColor3f(s, s, s);
1337 glTexCoord2f(0, 0);
1338 glVertex3f(x * 32 + 0, 16 + 32 * abs(z - 2), y * 32 + 0);
1339 s = getLightAt(x + 1, y);
1340 glColor3f(s, s, s);
1341 glTexCoord2f(1, 0);
1342 glVertex3f(x * 32 + 32, 16 + 32 * abs(z - 2), y * 32 + 0);
1343 s = getLightAt(x + 1, y + 1);
1344 glColor3f(s, s, s);
1345 glTexCoord2f(1, 1);
1346 glVertex3f(x * 32 + 32, 16 + 32 * abs(z - 2), y * 32 + 32);
1347 s = getLightAt(x, y + 1);
1348 glColor3f(s, s, s);
1349 glTexCoord2f(0, 1);
1350 glVertex3f(x * 32 + 0, 16 + 32 * abs(z - 2), y * 32 + 32);
1351 //glEnd();
1352 }
1353 }
1354 }
1355 else
1356 {
1357 // unsmooth lighting
1358 if ( mode == REALCOLORS )
1359 {
1360 s = std::min(std::max(0, lightmapSmoothed[y + x * map.height]), 255) / 255.0;
1361 glColor3f(s, s, s);
1362 }
1363
1364 // draw floor
1365 if ( z < OBSTACLELAYER )
1366 {
1367 if ( !map.tiles[index + 1] )
1368 {
1369 //glBegin( GL_QUADS );
1370 glTexCoord2f(0, 0);
1371 glVertex3f(x * 32 + 0, -16 - 32 * abs(z), y * 32 + 0);
1372 glTexCoord2f(0, 1);
1373 glVertex3f(x * 32 + 0, -16 - 32 * abs(z), y * 32 + 32);
1374 glTexCoord2f(1, 1);
1375 glVertex3f(x * 32 + 32, -16 - 32 * abs(z), y * 32 + 32);
1376 glTexCoord2f(1, 0);
1377 glVertex3f(x * 32 + 32, -16 - 32 * abs(z), y * 32 + 0);
1378 //glEnd();
1379 }
1380 }
1381
1382 // draw ceiling
1383 else if ( z > OBSTACLELAYER )
1384 {
1385 if ( !map.tiles[index - 1] )
1386 {
1387 //glBegin( GL_QUADS );
1388 glTexCoord2f(0, 0);
1389 glVertex3f(x * 32 + 0, 16 + 32 * abs(z - 2), y * 32 + 0);
1390 glTexCoord2f(1, 0);
1391 glVertex3f(x * 32 + 32, 16 + 32 * abs(z - 2), y * 32 + 0);
1392 glTexCoord2f(1, 1);
1393 glVertex3f(x * 32 + 32, 16 + 32 * abs(z - 2), y * 32 + 32);
1394 glTexCoord2f(0, 1);
1395 glVertex3f(x * 32 + 0, 16 + 32 * abs(z - 2), y * 32 + 32);
1396 //glEnd();
1397 }
1398 }
1399 }
1400 }
1401 }
1402 }
1403 }
1404 glEnd();
1405
1406 glDisable(GL_SCISSOR_TEST);
1407 glScissor(0, 0, xres, yres);
1408 }
1409
1410 /*GLuint create_shader(const char* filename, GLenum type)
1411 {
1412 FILE* input = fopen(filename, "rb");
1413 if( !input ) {
1414 printlog("Couldn't open shader file \"%s\"", filename);
1415 return 0;
1416 //TODO: Error.
1417 }
1418 fclose(input);
1419 const GLchar* source=NULL;
1420 if (source == NULL) {
1421 printlog("Error opening %s: ", filename); perror("");
1422 return 0;
1423 }
1424 GLuint res = glCreateShader(type);
1425 const GLchar* sources[2] = {
1426 #ifdef GL_ES_VERSION_2_0
1427 "#version 100\n"
1428 "#define GLES2\n",
1429 #else
1430 "#version 120\n",
1431 #endif
1432 source };
1433 glShaderSource(res, 2, sources, NULL);
1434 free((void*)source);
1435
1436 glCompileShader(res);
1437 GLint compile_ok = GL_FALSE;
1438 glGetShaderiv(res, GL_COMPILE_STATUS, &compile_ok);
1439 if (compile_ok == GL_FALSE) {
1440 printlog("%s:", filename);
1441 glDeleteShader(res);
1442 return 0;
1443 }
1444
1445 return res;
1446 }
1447 */
1448
1449 static int dirty = 1;
1450 static int oldx = 0, oldy = 0;
1451 static unsigned int oldpix = 0;
1452
GO_GetPixelU32(int x,int y,view_t & camera)1453 unsigned int GO_GetPixelU32(int x, int y, view_t& camera)
1454 {
1455 if(!dirty && (oldx==x) && (oldy==y))
1456 return oldpix;
1457
1458 if(dirty) {
1459 #ifdef PANDORA
1460 // Pandora fbo
1461 if((xres==800) && (yres==480)) {
1462 glBindFramebuffer(GL_FRAMEBUFFER, fbo_fbo);
1463 }
1464 #endif
1465 // generate object buffer
1466 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
1467 glDrawWorld(&camera, ENTITYUIDS);
1468 drawEntities3D(&camera, ENTITYUIDS);
1469 }
1470
1471 GLubyte pixel[4];
1472 glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)pixel);
1473 oldpix = pixel[0] + (((Uint32)pixel[1]) << 8) + (((Uint32)pixel[2]) << 16) + (((Uint32)pixel[3]) << 24);
1474 #ifdef PANDORA
1475 if((dirty) && (xres==800) && (yres==480)) {
1476 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1477 }
1478 #endif
1479 dirty = 0;
1480 return oldpix;
1481 }
1482
GO_SwapBuffers(SDL_Window * screen)1483 void GO_SwapBuffers(SDL_Window* screen)
1484 {
1485 dirty = 1;
1486 #ifdef PANDORA
1487 bool bBlit = !(xres==800 && yres==480);
1488
1489 int vp_old[4];
1490 if(bBlit) {
1491 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1492 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
1493 glGetIntegerv(GL_VIEWPORT, vp_old);
1494 glViewport(0, 0, 800, 480);
1495 glMatrixMode( GL_PROJECTION );
1496 glLoadIdentity();
1497 glOrtho(0, 800, 480, 0, 1, -1);
1498 glMatrixMode( GL_MODELVIEW );
1499 glLoadIdentity();
1500
1501 glDisable(GL_BLEND);
1502 glDisable(GL_ALPHA_TEST);
1503 glDisable(GL_DEPTH_TEST);
1504 glDisable(GL_LIGHTING);
1505
1506 glBindTexture(GL_TEXTURE_2D, fbo_tex);
1507 glColor4f(1,1,1,1);
1508
1509 glBegin(GL_QUADS);
1510 glTexCoord2f(0,yres/1024.0f); glVertex2f(0,0);
1511 glTexCoord2f(0, 0); glVertex2f(0,480);
1512 glTexCoord2f(xres/1024.0f, 0); glVertex2f(800,480);
1513 glTexCoord2f(xres/1024.0f, yres/1024.0f); glVertex2f(800,0);
1514 glEnd();
1515
1516 glBindTexture(GL_TEXTURE_2D, 0);
1517 }
1518 #endif
1519 #ifdef APPLE
1520 SDL_RenderPresent(renderer);
1521 #else
1522 SDL_GL_SwapWindow(screen);
1523 #endif
1524 #ifdef PANDORA
1525 if(bBlit) {
1526 glBindFramebuffer(GL_FRAMEBUFFER, fbo_fbo);
1527 glViewport(vp_old[0], vp_old[1], vp_old[2], vp_old[3]);
1528 }
1529 #endif
1530 }
1531