1 #include <stdlib.h>
2 #include <string.h>
3 #include <math.h>
4 #include <SDL.h>
5 #include "shadows.h"
6 #include "2d_objects.h"
7 #include "3d_objects.h"
8 #include "bbox_tree.h"
9 #include "cal.h"
10 #include "cursors.h"
11 #include "draw_scene.h"
12 #include "e3d.h"
13 #include "elconfig.h"
14 #include "events.h"
15 #include "framebuffer.h"
16 #include "lights.h"
17 #include "map.h"
18 #include "new_actors.h"
19 #include "reflection.h"
20 #include "skeletons.h"
21 #include "textures.h"
22 #include "tiles.h"
23 #include "weather.h"
24 #include "io/e3d_io.h"
25
26 #ifdef OSX
27 #define GL_EXT_texture_env_combine 1
28 #endif
29
30 // TODO: pbuffers according to Mesa/progs/xdemos/glxpbdemo.c
31
32 float proj_on_ground[16];
33 float ground_plane[4]={0,0,1,0};
34 float sun_position[4]={400.0, 400.0, 500.0, 0.0};
35 double light_view_mat[16],light_proj_mat[16],shadow_texgen_mat[16];
36 int shadows_on=0;
37 int is_day=0;
38 int use_shadow_mapping=1;
39
40 //TODO: Would like to use TEXTURE_RECTANGLE for cards that support it, but for some reason it doesn't work??
41 GLenum depth_texture_target=GL_TEXTURE_2D;
42 int shadow_map_size;
43 GLuint depth_map_id = 0;
44 /* Good values:
45 #define depth_map_scale 15.0
46 #define light_view_near -30.0
47 #define light_view_far 6.0*/
48 GLuint shadow_fbo = 0;
49
50 GLfloat light_view_hscale=13.0;
51 GLfloat light_view_top=10.0;
52 GLfloat light_view_bottom=-10.0;
53 GLfloat light_view_near=-30.0;
54 GLfloat light_view_far=6.0;
55
56 #ifdef DEBUG
57 extern int e3d_count, e3d_total; // LRNR:stats testing only
58 extern int cur_e3d_count;
59 #endif
60 extern e3d_object *cur_e3d;
61
free_shadow_framebuffer()62 void free_shadow_framebuffer()
63 {
64 free_depth_framebuffer(&shadow_fbo, &depth_map_id);
65 }
66
make_shadow_framebuffer()67 void make_shadow_framebuffer()
68 {
69 change_shadow_framebuffer_size();
70 }
71
change_shadow_framebuffer_size()72 void change_shadow_framebuffer_size()
73 {
74 change_depth_framebuffer_size(shadow_map_size, shadow_map_size, &shadow_fbo, &depth_map_id);
75 }
76
calc_light_frustum(float light_xrot)77 void calc_light_frustum(float light_xrot)
78 {
79 float window_ratio=(GLfloat)window_width/(GLfloat)window_height;
80 float max_height=30.0; //TODO: Really calculate this from positions and heights of objects
81 float x,y;
82 float slight, clight;
83
84 light_xrot=-light_xrot;
85 clight=cos(light_xrot);
86 slight=sin(light_xrot);
87 //TODO: Optimize this function a bit.
88 //Assuming a max zoom_level of 3.75 and near/far distances of 20.0, we'll set the hscale to the radius of a circle that
89 //can just contain the view frustum of the player. To simplify things, we'll assume the view frustum is horizontal.
90 //light_view_hscale=sqrt(window_ratio*window_ratio*3.75f*3.75f+12.0f*12.0f);
91 light_view_hscale=sqrt(window_ratio*window_ratio+30.0f*30.0f);
92 // For the others, we can just use the parametric ellipse formula to find the value for this angle
93 x=light_view_hscale*slight;
94 y=max_height*clight;
95 light_view_top=sqrt(x*x+y*y);
96 y=3.75f*clight;
97 light_view_far=sqrt(x*x+y*y);
98 x=light_view_hscale*clight;
99 y=3.75f*slight;
100 light_view_bottom=-sqrt(x*x+y*y);
101 x=100.0f*slight; // A bit better than the real value (infinity)
102 y=max_height*clight;
103 light_view_near=-sqrt(x*x+y*y);
104 }
105
calc_shadow_matrix()106 void calc_shadow_matrix()
107 {
108 float light_pos[4];
109
110 if (!is_day && lightning_falling)
111 memcpy(light_pos, lightning_position, 4*sizeof(float));
112 else
113 memcpy(light_pos, sun_position, 4*sizeof(float));
114
115 if(use_shadow_mapping)
116 {
117 float xrot,zrot;
118
119 float div_length=1.0f/sqrt(light_pos[0]*light_pos[0]+light_pos[1]*light_pos[1]+light_pos[2]*light_pos[2]);
120 light_pos[0]*=div_length;
121 light_pos[1]*=div_length;
122 light_pos[2]*=div_length;
123 // Grumble, Old version of OS X don't have *f trig functions but I'm compiling on a version so I can't just #define my way out
124 #ifdef OSX
125 xrot=-acos(light_pos[2]);
126 #else
127 xrot=-acosf(light_pos[2]);
128 #endif
129 //xrot=-atan2f(light_pos[2],light_pos[0])*180.0f/(float)M_PI;
130 #ifdef OSX
131 zrot=-90.0f-atan2(light_pos[1],light_pos[0])*180.0f/(float)M_PI;
132 #else
133 zrot=-90.0f-atan2f(light_pos[1],light_pos[0])*180.0f/(float)M_PI;
134 #endif
135
136 glPushMatrix();
137 glLoadIdentity();
138 calc_light_frustum(xrot);
139 xrot*=180.0f/(float)M_PI;
140 glOrtho(-light_view_hscale,light_view_hscale,
141 light_view_bottom,light_view_top,light_view_near,light_view_far);
142 glGetDoublev(GL_MODELVIEW_MATRIX,light_proj_mat);
143 glLoadIdentity();
144 glRotatef(xrot,1.0f,0.0f,0.0f);
145 glRotatef(zrot,0.0f,0.0f,1.0f);
146 glGetDoublev(GL_MODELVIEW_MATRIX,light_view_mat);
147 glLoadIdentity();
148 if(depth_texture_target!=GL_TEXTURE_2D)glScalef(shadow_map_size,shadow_map_size,0);
149 glTranslatef(0.5,0.5,0.5); // This...
150 glScalef(0.5,0.5,0.5); // ...and this == S
151 glMultMatrixd(light_proj_mat); // Plight
152 glMultMatrixd(light_view_mat); // L^-1
153 glGetDoublev(GL_MODELVIEW_MATRIX,shadow_texgen_mat);
154 glPopMatrix();
155 }
156 else
157 {
158 float dot;
159
160 // dot product of plane and light position
161 dot = ground_plane[0] * light_pos[0]
162 + ground_plane[1] * light_pos[1]
163 + ground_plane[2] * light_pos[2]
164 + ground_plane[3] * light_pos[3];
165
166 // first column
167 proj_on_ground[0] = dot - light_pos[0] * ground_plane[0];
168 proj_on_ground[4] = 0.0f - light_pos[0] * ground_plane[1];
169 proj_on_ground[8] = 0.0f - light_pos[0] * ground_plane[2];
170 proj_on_ground[12] = 0.0f - light_pos[0] * ground_plane[3];
171
172 // second column
173 proj_on_ground[1] = 0.0f - light_pos[1] * ground_plane[0];
174 proj_on_ground[5] = dot - light_pos[1] * ground_plane[1];
175 proj_on_ground[9] = 0.0f - light_pos[1] * ground_plane[2];
176 proj_on_ground[13] = 0.0f - light_pos[1] * ground_plane[3];
177
178 // third column
179 proj_on_ground[2] = 0.0f - light_pos[2] * ground_plane[0];
180 proj_on_ground[6] = 0.0f - light_pos[2] * ground_plane[1];
181 proj_on_ground[10] = dot - light_pos[2] * ground_plane[2];
182 proj_on_ground[14] = 0.0f - light_pos[2] * ground_plane[3];
183
184 // fourth column
185 proj_on_ground[3] = 0.0f - light_pos[3] * ground_plane[0];
186 proj_on_ground[7] = 0.0f - light_pos[3] * ground_plane[1];
187 proj_on_ground[11] = 0.0f - light_pos[3] * ground_plane[2];
188 proj_on_ground[15] = dot - light_pos[3] * ground_plane[3];
189 }
190 main_bbox_tree->intersect[INTERSECTION_TYPE_SHADOW].intersect_update_needed = 1;
191 #ifdef OPENGL_TRACE
192 CHECK_GL_ERRORS();
193 #endif //OPENGL_TRACE
194 }
195
draw_3d_object_shadows(unsigned int object_type)196 void draw_3d_object_shadows(unsigned int object_type)
197 {
198 unsigned int start, stop;
199 unsigned int i, j, l;
200 int is_transparent;
201 #ifdef SIMPLE_LOD
202 int x, y;
203 int dist;
204
205 x= -camera_x;
206 y= -camera_y;
207 #endif //SIMPLE_LOD
208
209 cur_e3d= NULL;
210 #ifdef DEBUG
211 cur_e3d_count= 0;
212 #endif //DEBUG
213
214 get_intersect_start_stop(main_bbox_tree, object_type, &start, &stop);
215 // nothing to draw?
216 if(start >= stop){
217 return;
218 }
219
220 // find the modes we need
221 is_transparent= is_alpha_3d_object(object_type);
222 if(is_transparent)
223 {
224 glEnable(GL_ALPHA_TEST);//enable alpha filtering, so we have some alpha key
225 glAlphaFunc(GL_GREATER,0.05f);
226 // glEnableClientState(GL_TEXTURE_COORD_ARRAY);
227 }
228 // else glDisable(GL_TEXTURE_2D);//we don't need textures for non transparent objects
229
230 glEnable(GL_TEXTURE_2D);
231 // now loop through each object
232 for (i=start; i<stop; i++)
233 {
234 j = get_intersect_item_ID(main_bbox_tree, i);
235 l = get_3dobject_index(j);
236 if (objects_list[l] == NULL) continue;
237 //track the usage
238 cache_use(objects_list[l]->e3d_data->cache_ptr);
239 if(!objects_list[l]->display) continue; // not currently on the map, ignore it
240 #ifdef SIMPLE_LOD
241 // simple size/distance culling
242 dist= (x-objects_list[l]->x_pos)*(x-objects_list[l]->x_pos) + (y-objects_list[l]->y_pos)*(y-objects_list[l]->y_pos);
243 if(objects_list[l]->e3d_data->materials && (10000*objects_list[l]->e3d_data->materials[get_3dobject_material(j)].max_size)/(dist) < ((is_transparent)?15:10)) continue;
244 #endif //SIMPLE_LOD
245 draw_3d_object_detail(objects_list[l], get_3dobject_material(j), 0, is_transparent, 0);
246 }
247
248 if (use_compiled_vertex_array && (cur_e3d != NULL))
249 {
250 ELglUnlockArraysEXT();
251 }
252 if (use_vertex_buffers)
253 {
254 ELglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
255 ELglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
256 }
257 if(is_transparent)
258 {
259 glDisable(GL_ALPHA_TEST);
260 }
261 else glEnable(GL_TEXTURE_2D);
262
263 CHECK_GL_ERRORS();
264 #ifdef DEBUG
265 // final statistics
266 if(cur_e3d_count > 0){
267 e3d_count++;
268 e3d_total+= cur_e3d_count;
269 }
270 cur_e3d_count= 0;
271 #endif //DEBUG
272 cur_e3d= NULL;
273 }
274
display_shadows()275 void display_shadows()
276 {
277 glEnable(GL_POLYGON_OFFSET_FILL);
278 glPolygonOffset(1.05f, 2.0f);
279 glEnable(GL_CULL_FACE);
280 glEnableClientState(GL_VERTEX_ARRAY);
281 glDisable(GL_COLOR_MATERIAL);
282
283 draw_3d_object_shadows(TYPE_3D_NO_BLEND_NO_GROUND_ALPHA_SELF_LIT_OBJECT);
284 draw_3d_object_shadows(TYPE_3D_NO_BLEND_NO_GROUND_ALPHA_NO_SELF_LIT_OBJECT);
285 draw_3d_object_shadows(TYPE_3D_NO_BLEND_NO_GROUND_NO_ALPHA_SELF_LIT_OBJECT);
286 draw_3d_object_shadows(TYPE_3D_NO_BLEND_NO_GROUND_NO_ALPHA_NO_SELF_LIT_OBJECT);
287
288 if(!use_shadow_mapping)
289 {
290 draw_3d_object_shadows(TYPE_3D_NO_BLEND_GROUND_ALPHA_SELF_LIT_OBJECT);
291 draw_3d_object_shadows(TYPE_3D_NO_BLEND_GROUND_ALPHA_NO_SELF_LIT_OBJECT);
292 draw_3d_object_shadows(TYPE_3D_NO_BLEND_GROUND_NO_ALPHA_SELF_LIT_OBJECT);
293 draw_3d_object_shadows(TYPE_3D_NO_BLEND_GROUND_NO_ALPHA_NO_SELF_LIT_OBJECT);
294 }
295
296 glDisableClientState(GL_VERTEX_ARRAY);
297 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
298 glDisableClientState(GL_COLOR_ARRAY);
299 glDisableClientState(GL_NORMAL_ARRAY);
300 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
301 glDisable(GL_CULL_FACE);
302 glCullFace(GL_FRONT);
303
304 #ifndef MAP_EDITOR2
305 display_actors(0, DEPTH_RENDER_PASS);
306 #endif
307 glCullFace(GL_BACK);
308 glDisable(GL_POLYGON_OFFSET_FILL);
309 #ifdef OPENGL_TRACE
310 CHECK_GL_ERRORS();
311 #endif //OPENGL_TRACE
312 }
313
display_3d_ground_objects()314 void display_3d_ground_objects()
315 {
316 glEnable(GL_CULL_FACE);
317 glEnableClientState(GL_VERTEX_ARRAY);
318 glDisable(GL_COLOR_MATERIAL);
319
320 if (!dungeon && clouds_shadows)
321 {
322 //bind the detail texture
323 ELglActiveTextureARB(detail_unit);
324 glEnable(GL_TEXTURE_2D);
325 bind_texture_unbuffered(ground_detail_text);
326 ELglActiveTextureARB(base_unit);
327 glEnable(GL_TEXTURE_2D);
328 }
329
330 draw_3d_objects(TYPE_3D_NO_BLEND_GROUND_ALPHA_SELF_LIT_OBJECT);
331 draw_3d_objects(TYPE_3D_NO_BLEND_GROUND_ALPHA_NO_SELF_LIT_OBJECT);
332 draw_3d_objects(TYPE_3D_NO_BLEND_GROUND_NO_ALPHA_SELF_LIT_OBJECT);
333 draw_3d_objects(TYPE_3D_NO_BLEND_GROUND_NO_ALPHA_NO_SELF_LIT_OBJECT);
334
335 if (!dungeon && clouds_shadows)
336 {
337 //disable the second texture unit
338 ELglActiveTextureARB(detail_unit);
339 glDisable(GL_TEXTURE_2D);
340 ELglActiveTextureARB(base_unit);
341 }
342
343 glDisableClientState(GL_VERTEX_ARRAY);
344 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
345 glDisableClientState(GL_COLOR_ARRAY);
346 glDisableClientState(GL_NORMAL_ARRAY);
347 glDisable(GL_CULL_FACE);
348 #ifdef OPENGL_TRACE
349 CHECK_GL_ERRORS();
350 #endif //OPENGL_TRACE
351 }
352
display_3d_non_ground_objects()353 void display_3d_non_ground_objects()
354 {
355 //we don't want to be affected by 2d objects and shadows
356 anything_under_the_mouse(0,UNDER_MOUSE_NO_CHANGE);
357
358 glEnable(GL_CULL_FACE);
359 glEnable(GL_COLOR_MATERIAL);
360 glEnableClientState(GL_VERTEX_ARRAY);
361 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
362
363 if (!dungeon && clouds_shadows)
364 {
365 //bind the detail texture
366 ELglActiveTextureARB(detail_unit);
367 glEnable(GL_TEXTURE_2D);
368 bind_texture_unbuffered(ground_detail_text);
369 ELglActiveTextureARB(base_unit);
370 glEnable(GL_TEXTURE_2D);
371 }
372
373 draw_3d_objects(TYPE_3D_NO_BLEND_NO_GROUND_ALPHA_SELF_LIT_OBJECT);
374 draw_3d_objects( TYPE_3D_NO_BLEND_NO_GROUND_ALPHA_NO_SELF_LIT_OBJECT);
375 draw_3d_objects(TYPE_3D_NO_BLEND_NO_GROUND_NO_ALPHA_SELF_LIT_OBJECT);
376 draw_3d_objects(TYPE_3D_NO_BLEND_NO_GROUND_NO_ALPHA_NO_SELF_LIT_OBJECT);
377
378 if (!dungeon && clouds_shadows)
379 {
380 //disable the second texture unit
381 ELglActiveTextureARB(detail_unit);
382 glDisable(GL_TEXTURE_2D);
383 ELglActiveTextureARB(base_unit);
384 }
385 glDisable(GL_COLOR_MATERIAL);
386 glDisableClientState(GL_VERTEX_ARRAY);
387 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
388 glDisableClientState(GL_COLOR_ARRAY);
389 glDisableClientState(GL_NORMAL_ARRAY);
390 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
391 glDisable(GL_CULL_FACE);
392 #ifdef OPENGL_TRACE
393 CHECK_GL_ERRORS();
394 #endif //OPENGL_TRACE
395 }
396
render_light_view()397 void render_light_view()
398 {
399 unsigned int cur_intersect_type;
400 if(use_shadow_mapping)
401 {
402 if (!use_frame_buffer && !depth_map_id)
403 {
404 GLint depthbits=16;
405 GLenum internalformat=GL_DEPTH_COMPONENT16_ARB;
406
407 glGetIntegerv(GL_DEPTH_BITS,&depthbits);
408 if(depthbits==24)internalformat=GL_DEPTH_COMPONENT24_ARB;
409 else if(depthbits==32)internalformat=GL_DEPTH_COMPONENT32_ARB;
410
411 glGenTextures(1,&depth_map_id);
412 glBindTexture(depth_texture_target,depth_map_id);
413 CHECK_GL_ERRORS();
414 glTexImage2D(depth_texture_target,0,internalformat,
415 shadow_map_size,shadow_map_size,
416 0,GL_DEPTH_COMPONENT,GL_FLOAT,NULL);
417 glTexParameteri(depth_texture_target,GL_TEXTURE_COMPARE_MODE_ARB,
418 GL_COMPARE_R_TO_TEXTURE_ARB);
419 glTexParameteri(depth_texture_target,GL_TEXTURE_COMPARE_FUNC_ARB,GL_LEQUAL);
420
421 glTexParameteri(depth_texture_target,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
422 glTexParameteri(depth_texture_target,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
423 //TODO: Might want to use CLAMP_TO_BORDER for cards that support it?
424 glTexParameteri(depth_texture_target,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
425 glTexParameteri(depth_texture_target,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
426 CHECK_GL_ERRORS();
427 }
428
429 if (use_frame_buffer)
430 {
431 CHECK_GL_ERRORS();
432 CHECK_FBO_ERRORS();
433 ELglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shadow_fbo);
434 ELglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depth_map_id, 0);
435 glClear(GL_DEPTH_BUFFER_BIT);
436 glDrawBuffer(GL_NONE);
437 glReadBuffer(GL_NONE);
438 CHECK_GL_ERRORS();
439 CHECK_FBO_ERRORS();
440 }
441 CHECK_GL_ERRORS();
442
443 glPushAttrib(GL_ALL_ATTRIB_BITS);
444
445 glViewport(0,0,shadow_map_size,shadow_map_size);
446 CHECK_GL_ERRORS();
447
448 glEnable(GL_SCISSOR_TEST);
449 glScissor(1, 1, shadow_map_size-2, shadow_map_size-2);
450
451 glDisable(GL_LIGHTING);
452 glEnable(GL_DEPTH_TEST);
453 #ifndef MAP_EDITOR2
454 if (use_fog) glDisable(GL_FOG);
455 #endif
456 glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
457 CHECK_GL_ERRORS();
458 glMatrixMode(GL_PROJECTION);
459 glPushMatrix();
460 glLoadMatrixd(light_proj_mat);
461 glMatrixMode(GL_MODELVIEW);
462 glPushMatrix();
463 glLoadMatrixd(light_view_mat);
464 glTranslatef((int)camera_x,(int)camera_y,(int)camera_z);
465 cur_intersect_type = get_cur_intersect_type(main_bbox_tree);
466 set_cur_intersect_type(main_bbox_tree, INTERSECTION_TYPE_SHADOW);
467 calculate_shadow_frustum();
468 display_shadows();
469 set_cur_intersect_type(main_bbox_tree, cur_intersect_type);
470
471 if (!use_frame_buffer)
472 {
473 glBindTexture(depth_texture_target, depth_map_id);
474 glCopyTexSubImage2D(depth_texture_target, 0, 0, 0, 0, 0, shadow_map_size, shadow_map_size);
475 glClear(GL_DEPTH_BUFFER_BIT);
476 }
477
478 CHECK_GL_ERRORS();
479 glMatrixMode(GL_PROJECTION);
480 glPopMatrix();
481 glMatrixMode(GL_MODELVIEW);
482 glPopMatrix();
483 glPopAttrib();
484 glBindTexture(GL_TEXTURE_2D,0);
485 last_texture=-1;
486 CHECK_GL_ERRORS();
487 if (use_frame_buffer)
488 {
489 CHECK_GL_ERRORS();
490 CHECK_FBO_ERRORS();
491 ELglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
492 glDrawBuffer(GL_BACK);
493 glReadBuffer(GL_BACK);
494 CHECK_GL_ERRORS();
495 CHECK_FBO_ERRORS();
496 }
497 CHECK_GL_ERRORS();
498 }
499 }
500
setup_2d_texgen()501 void setup_2d_texgen()
502 {
503 GLfloat plane[4];
504
505 glEnable(GL_TEXTURE_GEN_S);
506 glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
507 plane[0]=shadow_texgen_mat[0];plane[1]=shadow_texgen_mat[4];plane[2]=shadow_texgen_mat[8];plane[3]=shadow_texgen_mat[12];
508 glTexGenfv(GL_S,GL_EYE_PLANE,plane);
509
510 glEnable(GL_TEXTURE_GEN_T);
511 glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
512 plane[0]=shadow_texgen_mat[1];plane[1]=shadow_texgen_mat[5];plane[2]=shadow_texgen_mat[9];plane[3]=shadow_texgen_mat[13];
513 glTexGenfv(GL_T,GL_EYE_PLANE,plane);
514
515 glEnable(GL_TEXTURE_GEN_R);
516 glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
517 plane[0]=shadow_texgen_mat[2];plane[1]=shadow_texgen_mat[6];plane[2]=shadow_texgen_mat[10];plane[3]=shadow_texgen_mat[14];
518 glTexGenfv(GL_R,GL_EYE_PLANE,plane);
519
520 glEnable(GL_TEXTURE_GEN_Q);
521 glTexGeni(GL_Q,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
522 plane[0]=shadow_texgen_mat[3];plane[1]=shadow_texgen_mat[7];plane[2]=shadow_texgen_mat[11];plane[3]=shadow_texgen_mat[15];
523 glTexGenfv(GL_Q,GL_EYE_PLANE,plane);
524 #ifdef OPENGL_TRACE
525 CHECK_GL_ERRORS();
526 #endif //OPENGL_TRACE
527 }
528
disable_texgen()529 void disable_texgen()
530 {
531 glDisable(GL_TEXTURE_GEN_S);
532 glDisable(GL_TEXTURE_GEN_T);
533 glDisable(GL_TEXTURE_GEN_R);
534 glDisable(GL_TEXTURE_GEN_Q);
535 #ifdef OPENGL_TRACE
536 CHECK_GL_ERRORS();
537 #endif //OPENGL_TRACE
538 }
539
setup_shadow_mapping()540 void setup_shadow_mapping()
541 {
542 GLfloat shadow_color[] = {ambient_light[0]+0.2,
543 ambient_light[1]+0.2,
544 ambient_light[2]+0.2,
545 1.0};
546
547 if (!is_day && lightning_falling)
548 {
549 if (lightning_ambient_color[0]+0.2 > shadow_color[0]) shadow_color[0] = lightning_ambient_color[0]+0.2;
550 if (lightning_ambient_color[1]+0.2 > shadow_color[1]) shadow_color[1] = lightning_ambient_color[1]+0.2;
551 if (lightning_ambient_color[2]+0.2 > shadow_color[2]) shadow_color[2] = lightning_ambient_color[2]+0.2;
552 }
553
554 glPushMatrix();
555 glLoadIdentity();
556 if (!first_person)
557 glTranslatef(0.0f, 0.0f, -zoom_level*camera_distance);
558 glRotatef(rx, 1.0f, 0.0f, 0.0f);
559 if (first_person)
560 {
561 float head_pos[3];
562 cal_get_actor_bone_local_position(get_our_actor(), get_actor_bone_id(get_our_actor(), head_bone), NULL, head_pos);
563 glTranslatef(head_pos[0], head_pos[1], 0.0);
564 }
565 glRotatef(rz, 0.0f, 0.0f, 1.0f);
566 glTranslatef(camera_x-(int)camera_x,camera_y-(int)camera_y,camera_z-(int)camera_z);
567
568 glBindTexture(depth_texture_target,depth_map_id);
569 setup_2d_texgen();
570
571 #ifdef OSX
572 glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB);
573 glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_INTERPOLATE_ARB);
574 glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB,GL_PREVIOUS_ARB);
575 glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_ARB,GL_SRC_COLOR);
576 glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB,GL_CONSTANT_ARB);
577 glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,shadow_color);
578 glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_ARB,GL_SRC_COLOR);
579 glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB_ARB,GL_TEXTURE);
580 glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB_ARB,GL_SRC_COLOR);
581 glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_ARB,GL_REPLACE);
582 glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_ARB,GL_PREVIOUS_ARB);
583 glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_ALPHA_ARB,GL_SRC_ALPHA);
584 #else
585 glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_EXT);
586 glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_EXT,GL_INTERPOLATE_EXT);
587 glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_EXT,GL_PREVIOUS_EXT);
588 glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_EXT,GL_SRC_COLOR);
589 glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_EXT,GL_CONSTANT_EXT);
590 glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,shadow_color);
591 glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_EXT,GL_SRC_COLOR);
592 glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB_EXT,GL_TEXTURE);
593 glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB_EXT,GL_SRC_COLOR);
594 glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_EXT,GL_REPLACE);
595 glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_EXT,GL_PREVIOUS_EXT);
596 glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_ALPHA_EXT,GL_SRC_ALPHA);
597 #endif
598 glPopMatrix();
599 #ifdef OPENGL_TRACE
600 CHECK_GL_ERRORS();
601 #endif //OPENGL_TRACE
602 }
603
setup_cloud_texturing(void)604 void setup_cloud_texturing(void)
605 {
606 ELglActiveTextureARB(detail_unit);
607 if (!dungeon && clouds_shadows)
608 {
609 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
610 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
611 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
612 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
613 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE);
614 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
615 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
616 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
617 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
618 }
619 else
620 {
621 glDisable(GL_TEXTURE_2D);
622 glBindTexture(GL_TEXTURE_2D, 0);
623 }
624 ELglActiveTextureARB(base_unit);
625 }
626
draw_sun_shadowed_scene(int any_reflection)627 void draw_sun_shadowed_scene(int any_reflection)
628 {
629 if(use_shadow_mapping)
630 {
631 reset_material();
632
633 shadow_unit=GL_TEXTURE0_ARB;
634 base_unit=GL_TEXTURE1_ARB;
635 detail_unit=GL_TEXTURE2_ARB;
636
637 #ifndef MAP_EDITOR2
638 if (use_fog) glDisable(GL_FOG);
639 #endif
640 ELglActiveTextureARB(shadow_unit);
641 glEnable(depth_texture_target);
642 setup_shadow_mapping();
643
644 setup_cloud_texturing();
645
646 ELglClientActiveTextureARB(base_unit);
647 ELglActiveTextureARB(base_unit);
648 glEnable(GL_TEXTURE_2D);
649 last_texture=-1;
650 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
651 CHECK_GL_ERRORS();
652 #ifndef MAP_EDITOR2
653 if (use_fog) glEnable(GL_FOG);
654 #endif
655 glNormal3f(0.0f,0.0f,1.0f);
656 if(any_reflection)draw_lake_tiles();
657 draw_tile_map();
658 #ifdef MAP_EDITOR2
659 get_world_x_y ();
660 display_mode();
661 #endif
662 CHECK_GL_ERRORS();
663 display_2d_objects();
664 CHECK_GL_ERRORS();
665 anything_under_the_mouse(0, UNDER_MOUSE_NOTHING);
666
667 display_objects();
668 display_ground_objects();
669 #ifndef MAP_EDITOR2
670 display_actors(1, SHADOW_RENDER_PASS); // Affects other textures ????????? (FPS etc., unless there's a particle system...)
671 #endif
672 display_alpha_objects();
673 display_blended_objects();
674
675 #ifndef MAP_EDITOR2
676 if (use_fog) glDisable(GL_FOG);
677 #endif
678
679 ELglActiveTextureARB(shadow_unit);
680 glDisable(depth_texture_target);
681 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
682 glBindTexture(GL_TEXTURE_2D,0);
683 disable_texgen();
684
685 ELglActiveTextureARB(detail_unit);
686 glDisable(GL_TEXTURE_2D);
687 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
688 glBindTexture(GL_TEXTURE_2D,0);
689 disable_texgen();
690
691 ELglActiveTextureARB(base_unit);
692 glDisable(GL_TEXTURE_2D);
693 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
694 glBindTexture(GL_TEXTURE_2D,0);
695 disable_texgen();
696
697 shadow_unit=GL_TEXTURE2_ARB;
698 base_unit=GL_TEXTURE0_ARB;
699 detail_unit=GL_TEXTURE1_ARB;
700 ELglActiveTextureARB(base_unit);
701 ELglClientActiveTextureARB(base_unit);
702 last_texture=-1;
703 glBindTexture(GL_TEXTURE_2D,0);
704 glEnable(GL_TEXTURE_2D);
705 }
706 else
707 {
708 glNormal3f(0.0f,0.0f,1.0f);
709 if(any_reflection)draw_lake_tiles();
710
711 setup_cloud_texturing();
712
713 draw_tile_map();
714 #ifdef MAP_EDITOR2
715 get_world_x_y ();
716 display_mode();
717 #endif
718 CHECK_GL_ERRORS();
719 display_2d_objects();
720 CHECK_GL_ERRORS();
721 anything_under_the_mouse(0, UNDER_MOUSE_NOTHING);
722 display_3d_ground_objects();
723 // turning off writing to the color buffer and depth buffer
724 glDisable(GL_DEPTH_TEST);
725
726 glDisable(GL_LIGHTING);
727 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
728
729 glEnable(GL_STENCIL_TEST);
730 // write a one to the stencil buffer everywhere we are about to draw
731 glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
732 // this is to always pass a one to the stencil buffer where we draw
733 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
734
735 display_shadows();
736
737 glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
738 // don't modify the contents of the stencil buffer
739 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
740
741 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
742
743 // Lachesis: drawing in 3D mode in order to get the fog correct
744 glDisable(GL_TEXTURE_2D);
745 glDisable(GL_LIGHTING);
746 glDepthMask(GL_FALSE);
747 glDisable(GL_DEPTH_TEST);
748
749 #ifndef MAP_EDITOR2
750 if (use_fog) glEnable(GL_FOG);
751 #endif
752
753 glEnable(GL_BLEND);
754 // need this function (or both flipped) for correctly working fog too
755 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
756
757 glColor4f(0.0f, 0.0f, 0.0f, 0.7f*((diffuse_light[0] + diffuse_light[1] + diffuse_light[2])/3.0 - 0.0f));
758
759 glBegin(GL_QUADS);
760 glVertex4f(-camera_x+20.0f,-camera_y+20.0f,0.0f,1.0f);
761 glVertex4f(-camera_x+20.0f,-camera_y-20.0f,0.0f,1.0f);
762 glVertex4f(-camera_x-20.0f,-camera_y-20.0f,0.0f,1.0f);
763 glVertex4f(-camera_x-20.0f,-camera_y+20.0f,0.0f,1.0f);
764 glEnd();
765
766 glDisable(GL_BLEND);
767
768 glEnable(GL_TEXTURE_2D);
769 glDepthMask(GL_TRUE);
770
771 glEnable(GL_DEPTH_TEST);
772 glColor4f(1.0f,1.0f,1.0f,1.0f);
773 glEnable(GL_LIGHTING);
774 glDisable(GL_STENCIL_TEST);
775
776 display_3d_non_ground_objects();
777 #ifndef MAP_EDITOR2
778 display_actors(1, DEFAULT_RENDER_PASS);
779 #endif
780 display_blended_objects();
781
782 }
783 #ifdef OPENGL_TRACE
784 CHECK_GL_ERRORS();
785 #endif //OPENGL_TRACE
786 }
787