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