3 Copyright (C) 2003 Nuno Subtil
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 static const char cvsid
[] =
21 "$Id: render_map.c,v 1.4 2003/11/30 17:43:55 nsubtil Exp $";
46 prepara-se para desenhar um tile do mapa
48 void map_setup_wall(struct game
*game
, int x
, int y
)
52 static struct image_rgba32
*rocket_lightmap
= NULL
;
55 if(rocket_lightmap
== NULL
)
57 rocket_lightmap
= gfx_get("gfx/rocket-highlight.tga");
58 gfx_alpha_from_intensity("gfx/rocket-highlight.tga");
59 gfx_upload_texture("gfx/rocket-highlight.tga");
65 glMatrixMode(GL_MODELVIEW
);
68 glTranslatef((GLfloat
)x
+ 0.5, -0.5, (GLfloat
)y
+ 0.5);
70 glEnable(GL_DEPTH_TEST
);
72 // glDisable(GL_TEXTURE_2D);
73 // glDisable(GL_BLEND);
75 glColorMaterial(GL_FRONT_AND_BACK
, GL_AMBIENT_AND_DIFFUSE
);
76 glEnable(GL_COLOR_MATERIAL
);
79 /* compute lightmaps */
80 for(c
= 0; c
< game
->n_shots
; c
++)
82 if(game
->shots
[c
].type
== SHOT_TYPE_ROCKET
&& game
->shots
[c
].state
== SHOT_STATE_ACTIVE
)
86 rx
= (int)game
->shots
[c
].position
[X
];
87 ry
= (int)game
->shots
[c
].position
[Z
];
89 switch(MAP(game
->map
, x
, y
).wall
)
91 case MAP_WALL_HORIZONTAL
:
92 if(rx
== x
&& (ry
== y
- 1 || ry
== y
+ 1))
96 /* XXX - multitexturing! */
97 glActiveTexture(GL_TEXTURE0_ARB
);
98 glDisable(GL_TEXTURE_2D
);
100 glActiveTexture(GL_TEXTURE1_ARB
);
101 glBindTexture(GL_TEXTURE_2D
, rocket_lightmap
->id
);
102 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_REPEAT
);
103 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_REPEAT
);
104 glEnable(GL_TEXTURE_2D
);
106 map_lightmap_param_rocket(params
, game
, x
, y
, c
);
112 glTexGenfv(GL_S
, GL_OBJECT_PLANE
, params
);
113 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_OBJECT_LINEAR
);
114 glEnable(GL_TEXTURE_GEN_S
);
120 glTexGenfv(GL_T
, GL_OBJECT_PLANE
, params
);
121 glTexGeni(GL_T
, GL_TEXTURE_GEN_MODE
, GL_OBJECT_LINEAR
);
122 glEnable(GL_TEXTURE_GEN_T
);
124 glBlendFunc(GL_ONE
, GL_ONE
);
138 computes lightmap parameters for wall at x, y and rocket n
140 void map_lightmap_param_rocket(GLfloat params
[4], struct game
*game
, int x
, int y
, int r
)
146 rocket
= &game
->shots
[r
];
148 /* xxx - do something nice */
156 desenha uma parede vertical em x, y
158 void map_draw_vertical_wall(struct game
*game
, int x
, int y
)
160 static struct object
*wall
= NULL
;
162 map_setup_wall(game
, x
, y
);
168 wall
= object_read_file("gfx/wall-vertical.3d", &nframes
);
171 render_dlist(wall
, NULL
);
175 desenha uma parede horizontal em (x, y)
177 void map_draw_horizontal_wall(struct game
*game
, int x
, int y
)
179 static struct object
*wall
= NULL
;
181 map_setup_wall(game
, x
, y
);
187 wall
= object_read_file("gfx/wall-horizontal.3d", &nframes
);
188 render_compile_dlist(wall
);
191 render_dlist(wall
, NULL
);
195 canto inferior esquerdo
197 void map_draw_ll_wall(struct game
*game
, int x
, int y
)
199 static struct object
*wall
= NULL
;
201 map_setup_wall(game
, x
, y
);
207 wall
= object_read_file("gfx/wall-ll.3d", &nframes
);
208 render_compile_dlist(wall
);
211 render_dlist(wall
, NULL
);
215 canto inferior direito
217 void map_draw_lr_wall(struct game
*game
, int x
, int y
)
219 static struct object
*wall
= NULL
;
221 map_setup_wall(game
, x
, y
);
227 wall
= object_read_file("gfx/wall-lr.3d", &nframes
);
228 render_compile_dlist(wall
);
231 render_dlist(wall
, NULL
);
235 canto superior direito
237 void map_draw_ur_wall(struct game
*game
, int x
, int y
)
239 static struct object
*wall
= NULL
;
241 map_setup_wall(game
, x
, y
);
247 wall
= object_read_file("gfx/wall-ur.3d", &nframes
);
248 render_compile_dlist(wall
);
251 render_dlist(wall
, NULL
);
255 canto superior esquerdo
257 void map_draw_ul_wall(struct game
*game
, int x
, int y
)
259 static struct object
*wall
= NULL
;
261 map_setup_wall(game
, x
, y
);
267 wall
= object_read_file("gfx/wall-ul.3d", &nframes
);
268 render_compile_dlist(wall
);
271 render_dlist(wall
, NULL
);
275 desenha comida do pacman em (x,y) no mapa
277 void map_draw_pacman_food(struct map
*map
, int x
, int y
)
279 static struct image_rgba32
*food
= NULL
;
283 food
= gfx_get("gfx/dot-yellow.tga");
284 gfx_alpha_from_intensity("gfx/dot-yellow.tga");
285 gfx_upload_texture("gfx/dot-yellow.tga");
288 glDisable(GL_LIGHTING
);
289 glEnable(GL_DEPTH_TEST
);
291 // glBlendFunc(GL_ONE, GL_ONE);
292 // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
293 glEnable(GL_TEXTURE_2D
);
294 glBindTexture(GL_TEXTURE_2D
, food
->id
);
296 glDepthMask(GL_FALSE
);
298 switch(MAP_FOOD(map
, x
, y
).type
)
300 case FOOD_TYPE_NORMAL
:
301 if(MAP_FOOD(map
, x
, y
).status
== FOOD_STATUS_ACTIVE
)
302 render_draw_plane((GLfloat
)x
+ 0.5, -0.5, (GLfloat
)y
+ 0.5, 1.0);
306 case FOOD_TYPE_RESPAWN
:
307 if(MAP_FOOD(map
, x
, y
).status
== FOOD_STATUS_EATEN
)
309 if(MAP_FOOD(map
, x
, y
).time
<= MAP_FOOD(map
, x
, y
).fade_in
)
310 render_draw_plane((GLfloat
)x
+ 0.5, -0.5, (GLfloat
)y
+ 0.5,
311 1.0 - (MAP_FOOD(map
, x
, y
).time
/
312 MAP_FOOD(map
, x
, y
).fade_in
));
315 render_draw_plane((GLfloat
)x
+ 0.5, -0.5, (GLfloat
)y
+ 0.5, 1.0);
319 case FOOD_TYPE_INTERMITTENT
:
320 if(MAP_FOOD(map
, x
, y
).status
== FOOD_STATUS_ACTIVE
)
322 if(MAP_FOOD(map
, x
, y
).time
<= MAP_FOOD(map
, x
, y
).fade_out
)
323 render_draw_plane((GLfloat
)x
+ 0.5, -0.5, (GLfloat
)y
+ 0.5,
324 (MAP_FOOD(map
, x
, y
).time
/
325 MAP_FOOD(map
, x
, y
).fade_out
));
327 render_draw_plane((GLfloat
)x
+ 0.5, -0.5, (GLfloat
)y
+ 0.5, 1.0);
329 if(MAP_FOOD(map
, x
, y
).time
<= MAP_FOOD(map
, x
, y
).fade_in
)
330 render_draw_plane((GLfloat
)x
+ 0.5, -0.5, (GLfloat
)y
+ 0.5,
331 1.0 - (MAP_FOOD(map
, x
, y
).time
/
332 MAP_FOOD(map
, x
, y
).fade_in
));
338 glDepthMask(GL_TRUE
);
341 void map_draw_pacman_pill(struct map
*map
, int x
, int y
)
343 static GLUquadricObj
*sphere
= NULL
;
347 sphere
= gluNewQuadric();
348 gluQuadricNormals(sphere
, GLU_SMOOTH
);
349 gluQuadricTexture(sphere
, GLU_FALSE
);
350 gluQuadricOrientation(sphere
, GLU_OUTSIDE
);
351 gluQuadricDrawStyle(sphere
, GLU_FILL
);
354 glMatrixMode(GL_MODELVIEW
);
357 /* XXX - isto a mexer fica mais giro */
358 // glTranslatef((GLfloat)x + 0.5, pill_height, (GLfloat)y + 0.5);
359 // glTranslatef((GLfloat)x + 0.5, MAP(map, x, y).c_data.pill.height, (GLfloat)y + 0.5);
360 glTranslatef((GLfloat
)x
+ 0.5,
361 -0.5 + 0.25 * sin(PILL_BOB_FREQUENCY
* (float)SDL_GetTicks() / 1000.0 +
362 MAP(map
, x
, y
).c_data
.pill
.phase
),
365 glEnable(GL_DEPTH_TEST
);
366 glDepthMask(GL_TRUE
);
367 glDisable(GL_TEXTURE_2D
);
370 glColor4f(0.91, 0.88, 0.28, 1.0);
371 gluSphere(sphere
, 0.2, 15, 15);
374 void map_draw_wall(struct game
*game
, int x
, int y
)
380 switch(MAP(map
, x
, y
).wall
)
382 case MAP_WALL_HORIZONTAL
:
383 map_draw_horizontal_wall(game
, x
, y
);
386 case MAP_WALL_VERTICAL
:
387 map_draw_vertical_wall(game
, x
, y
);
391 map_draw_ll_wall(game
, x
, y
);
395 map_draw_ul_wall(game
, x
, y
);
399 map_draw_lr_wall(game
, x
, y
);
403 map_draw_ur_wall(game
, x
, y
);
411 void map_render_opaque_objects(struct game
*game
)
418 /* pass 1: untextured geometry */
421 glDisable(GL_TEXTURE_2D
);
423 for(x
= 0; x
< map
->width
; x
++)
424 for(y
= 0; y
< map
->height
; y
++)
426 map_draw_wall(game
, x
, y
);
429 glDisable(GL_TEXTURE_2D
);
430 glDisable(GL_TEXTURE_GEN_S
);
431 glDisable(GL_TEXTURE_GEN_T
);
433 switch(MAP(map
, x
, y
).content
)
435 case MAP_CONTENT_PILL
:
436 if(MAP(map
, x
, y
).c_data
.pill
.status
== PILL_STATUS_ACTIVE
)
437 map_draw_pacman_pill(map
, x
, y
);
442 #ifdef UGLY_LIGHTMAPS
443 /* pass 2: additive lightmaps */
444 for(c
= 0; c
< game
->n_shots
; c
++)
445 switch(game
->shots
[c
].type
)
447 case SHOT_TYPE_ROCKET
:
448 if(game
->shots
[c
].state
!= SHOT_STATE_ACTIVE
)
451 map_draw_rocket_lightmap(game
, c
);
457 void map_draw_rocket_lightmap(struct game
*game
, int c
)
459 static struct image_rgba32
*texture
= NULL
;
463 /* object plane coefficients (s, t, r, q) */
468 texture
= gfx_get("gfx/rocket-highlight.tga");
469 gfx_upload_texture("gfx/rocket-highlight.tga");
472 rocket
= &game
->shots
[c
];
474 /* set up texturing */
475 glBindTexture(GL_TEXTURE_2D
, texture
->id
);
476 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP
);
477 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP
);
478 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
479 glEnable(GL_TEXTURE_2D
);
481 /* texture coordinate generation */
482 switch(rocket
->direction
)
491 case DIRECTION_RIGHT
:
513 glTexGenfv(GL_S
, GL_OBJECT_PLANE
, params
);
514 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_OBJECT_LINEAR
);
515 glEnable(GL_TEXTURE_GEN_S
);
521 glTexGenfv(GL_T
, GL_OBJECT_PLANE
, params
);
522 glTexGeni(GL_T
, GL_TEXTURE_GEN_MODE
, GL_OBJECT_LINEAR
);
523 glEnable(GL_TEXTURE_GEN_T
);
525 /* additive alpha blending */
526 glBlendFunc(GL_ONE
, GL_ONE
);
529 glColor4f(1.0, 1.0, 1.0, 1.0);
531 /* draw map squares */
532 x
= (int)rocket
->position
[X
];
533 y
= (int)rocket
->position
[Z
];
535 switch(rocket
->direction
)
538 /* up right square */
540 /* glPolygonOffset and glDepthFunc(GL_LESS) might be a better idea
541 instead of messing with the projection matrix */
542 glMatrixMode(GL_PROJECTION
);
544 glTranslatef(0.0, 0.0, -0.01);
546 glMatrixMode(GL_TEXTURE
);
548 glTranslatef(-(rocket
->position
[X
] - (float)x
) + 1.0, -0.5, 0.3);
551 switch(MAP(game
->map
, x
+ 1, y
+ 1).wall
)
554 /* fix texturing for LL corners */
555 printf("fixing LL corner for UR\n");
570 glTexGenfv(GL_S
, GL_OBJECT_PLANE
, params
);
572 map_draw_wall(game
, x
+ 1, y
+ 1);
575 glMatrixMode(GL_TEXTURE
);
577 glTranslatef(-(rocket
->position
[X
] - (float)x
), -0.5, 0.3);
580 switch(MAP(game
->map
, x
, y
+ 1).wall
)
583 /* fix texturing for LL corners */
584 printf("fixing LL corner for UP\n");
599 glTexGenfv(GL_S
, GL_OBJECT_PLANE
, params
);
601 map_draw_wall(game
, x
, y
+ 1);
604 /* down right square */
605 glMatrixMode(GL_PROJECTION
);
608 glTranslatef(0.0, 0.0, 0.01);
610 glMatrixMode(GL_TEXTURE
);
612 glTranslatef(-(rocket
->position
[X
] - (float)x
), -0.5, 0.3);
614 map_draw_wall(game
, x
+ 1, y
- 1);
617 glMatrixMode(GL_TEXTURE
);
619 glTranslatef(-(rocket
->position
[X
] - (float)x
) - 1.0, -0.5, 0.3);
621 map_draw_wall(game
, x
, y
- 1);
623 glMatrixMode(GL_PROJECTION
);
628 case DIRECTION_RIGHT
:
630 glMatrixMode(GL_PROJECTION
);
632 glTranslatef(0.0, 0.0, -0.01);
634 glMatrixMode(GL_TEXTURE
);
636 glTranslatef(-(rocket
->position
[X
] - (float)x
), -0.5, 0.0);
638 map_draw_wall(game
, x
- 1, y
+ 1);
641 glMatrixMode(GL_TEXTURE
);
643 glTranslatef(-(rocket
->position
[X
] - (float)x
) + 1.0, -0.5, 0.0);
645 map_draw_wall(game
, x
, y
+ 1);
648 /* down left square */
649 glMatrixMode(GL_PROJECTION
);
652 glTranslatef(0.0, 0.0, 0.01);
654 glMatrixMode(GL_TEXTURE
);
656 glTranslatef(-(rocket
->position
[X
] - (float)x
) - 1.0, -0.5, 0.0);
658 map_draw_wall(game
, x
- 1, y
- 1);
661 glMatrixMode(GL_TEXTURE
);
663 glTranslatef(-(rocket
->position
[X
] - (float)x
), -0.5, 0.0);
665 map_draw_wall(game
, x
, y
- 1);
667 glMatrixMode(GL_PROJECTION
);
673 /* left down square */
674 glMatrixMode(GL_PROJECTION
);
676 glTranslatef(0.01, 0.0, 0.0);
678 glMatrixMode(GL_TEXTURE
);
680 glTranslatef(0.0, -0.5, -(rocket
->position
[Z
] - (float)y
));
682 map_draw_wall(game
, x
- 1, y
- 1);
685 glMatrixMode(GL_TEXTURE
);
687 glTranslatef(0.0, -0.5, -(rocket
->position
[Z
] - (float)y
) + 1.0);
689 map_draw_wall(game
, x
- 1, y
);
691 /* right down square */
692 glMatrixMode(GL_PROJECTION
);
695 glTranslatef(-0.01, 0.0, 0.0);
697 glMatrixMode(GL_TEXTURE
);
699 glTranslatef(0.0, -0.5, -(rocket
->position
[Z
] - (float)y
));
701 map_draw_wall(game
, x
+ 1, y
- 1);
704 glMatrixMode(GL_TEXTURE
);
706 glTranslatef(0.0, -0.5, -(rocket
->position
[Z
] - (float)y
) + 1.0);
708 map_draw_wall(game
, x
+ 1, y
);
710 glMatrixMode(GL_PROJECTION
);
717 glMatrixMode(GL_PROJECTION
);
719 glTranslatef(0.01, 0.0, 0.0);
721 glMatrixMode(GL_TEXTURE
);
723 glTranslatef(0.0, -0.5, -(rocket
->position
[Z
] - (float)y
) + 1.0);
725 map_draw_wall(game
, x
- 1, y
+ 1);
728 glMatrixMode(GL_TEXTURE
);
730 glTranslatef(0.0, -0.5, -(rocket
->position
[Z
] - (float)y
));
732 map_draw_wall(game
, x
- 1, y
);
734 /* right up square */
735 glMatrixMode(GL_PROJECTION
);
738 glTranslatef(-0.01, 0.0, 0.0);
740 glMatrixMode(GL_TEXTURE
);
742 glTranslatef(0.0, -0.5, -(rocket
->position
[Z
] - (float)y
) + 1.0);
744 map_draw_wall(game
, x
+ 1, y
+ 1);
747 glMatrixMode(GL_TEXTURE
);
749 glTranslatef(0.0, -0.5, -(rocket
->position
[Z
] - (float)y
));
751 map_draw_wall(game
, x
+ 1, y
);
753 glMatrixMode(GL_PROJECTION
);
760 glDisable(GL_TEXTURE_GEN_S
);
761 glDisable(GL_TEXTURE_GEN_T
);
762 glDisable(GL_TEXTURE_2D
);
763 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
765 glMatrixMode(GL_TEXTURE
);
767 glMatrixMode(GL_MODELVIEW
);
770 void map_render_translucent_objects(struct game
*game
, int player_no
)
777 cam
= game
->demo_camera
;
779 cam
= game
->players
[player_no
].camera
;
781 render_setup_plane_geometry(cam
, 1.0);
784 for(x
= 0; x
< map
->width
; x
++)
785 for(y
= 0; y
< map
->height
; y
++)
786 switch(MAP(map
, x
, y
).content
)
788 case MAP_CONTENT_FOOD
:
789 /* comidinha do pacman */
790 map_draw_pacman_food(map
, x
, y
);