2 * Copyright (C) 2003 Robert Kooima
4 * NEVERBALL is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
28 #include "solid_draw.h"
30 /*---------------------------------------------------------------------------*/
32 static struct s_full beam;
33 static struct s_full jump;
34 static struct s_full goal;
35 static struct s_full flag;
36 static struct s_full mark;
37 static struct s_full vect;
38 static struct s_full back;
40 static int back_state = 0;
42 /*---------------------------------------------------------------------------*/
46 sol_load_full(&beam, "geom/beam/beam.sol", 0);
47 sol_load_full(&jump, "geom/jump/jump.sol", 0);
48 sol_load_full(&goal, "geom/goal/goal.sol", 0);
49 sol_load_full(&flag, "geom/flag/flag.sol", 0);
50 sol_load_full(&mark, "geom/mark/mark.sol", 0);
51 sol_load_full(&vect, "geom/vect/vect.sol", 0);
64 /*---------------------------------------------------------------------------*/
66 void back_init(const char *name)
71 /* Load the background SOL and modify its material in-place to use the */
72 /* named gradient texture. */
74 sol_load_full(&back, "geom/back/back.sol", 0);
75 back.draw.mv[0].o = make_image_from_file(name);
77 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
90 /*---------------------------------------------------------------------------*/
92 static void jump_part_draw(struct s_rend *rend, GLfloat s, GLfloat a)
94 glMatrixMode(GL_TEXTURE);
95 glTranslatef(s, 0.0f, 0.0f);
96 glMatrixMode(GL_MODELVIEW);
98 glRotatef(a, 0.0f, 1.0f, 0.0f);
99 sol_draw(&jump.draw, rend, 1, 1);
100 glScalef(0.9f, 0.9f, 0.9f);
103 static void goal_part_draw(struct s_rend *rend, GLfloat s)
105 glMatrixMode(GL_TEXTURE);
106 glTranslatef(0.0f, -s, 0.0f);
107 glMatrixMode(GL_MODELVIEW);
109 sol_draw(&goal.draw, rend, 1, 1);
110 glScalef(0.8f, 1.1f, 0.8f);
113 /*---------------------------------------------------------------------------*/
115 void goal_draw(struct s_rend *rend, float t)
119 glScalef(1.0f, 3.0f, 1.0f);
120 glColor4f(1.0f, 1.0f, 0.0f, 0.5f);
122 sol_draw(&beam.draw, rend, 1, 1);
124 goal_part_draw(rend, t * 0.10f);
125 goal_part_draw(rend, t * 0.10f);
126 goal_part_draw(rend, t * 0.10f);
127 goal_part_draw(rend, t * 0.10f);
129 glMatrixMode(GL_TEXTURE);
131 glMatrixMode(GL_MODELVIEW);
133 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
138 void jump_draw(struct s_rend *rend, float t, int h)
140 static GLfloat c[4][4] = {
141 { 0.75f, 0.5f, 1.0f, 0.5f },
142 { 0.75f, 0.5f, 1.0f, 0.8f },
147 glColor4f(c[h][0], c[h][1], c[h][2], c[h][3]);
149 glScalef(1.0f, 2.0f, 1.0f);
151 sol_draw(&beam.draw, rend, 1, 1);
153 jump_part_draw(rend, t * 0.15f, t * 360.0f);
154 jump_part_draw(rend, t * 0.20f, t * 360.0f);
155 jump_part_draw(rend, t * 0.25f, t * 360.0f);
157 glMatrixMode(GL_TEXTURE);
159 glMatrixMode(GL_MODELVIEW);
161 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
166 void swch_draw(struct s_rend *rend, int b, int e)
168 static GLfloat c[4][4] = {
169 { 1.0f, 0.0f, 0.0f, 0.5f }, /* red out */
170 { 1.0f, 0.0f, 0.0f, 0.8f }, /* red in */
171 { 0.0f, 1.0f, 0.0f, 0.5f }, /* green out */
172 { 0.0f, 1.0f, 0.0f, 0.8f }, /* green in */
175 const int h = 2 * b + e;
179 glScalef(1.0f, 2.0f, 1.0f);
181 glColor4f(c[h][0], c[h][1], c[h][2], c[h][3]);
182 sol_draw(&beam.draw, rend, 1, 1);
183 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
188 void flag_draw(struct s_rend *rend)
190 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
191 sol_draw(&flag.draw, rend, 1, 1);
194 void mark_draw(struct s_rend *rend)
196 sol_draw(&mark.draw, rend, 1, 1);
199 void vect_draw(struct s_rend *rend)
201 sol_draw(&vect.draw, rend, 0, 1);
202 sol_draw(&vect.draw, rend, 0, 0);
205 void back_draw(struct s_rend *rend, float t)
209 GLfloat dx = 60.0f * fsinf(t / 10.0f);
210 GLfloat dz = 180.0f * fsinf(t / 12.0f);
212 glDisable(GL_DEPTH_TEST);
213 glDisable(GL_CULL_FACE);
214 glDisable(GL_LIGHTING);
215 glDepthMask(GL_FALSE);
217 glScalef(-BACK_DIST, BACK_DIST, -BACK_DIST);
218 if (t) glRotatef(dz, 0.0f, 0.0f, 1.0f);
219 if (t) glRotatef(dx, 1.0f, 0.0f, 0.0f);
221 sol_draw(&back.draw, rend, 1, 1);
223 glDepthMask(GL_TRUE);
224 glEnable(GL_LIGHTING);
225 glEnable(GL_CULL_FACE);
226 glEnable(GL_DEPTH_TEST);
231 void back_draw_easy(void)
233 struct s_rend rend = { NULL };
235 sol_draw_enable(&rend);
236 back_draw(&rend, 0.0f);
237 sol_draw_disable(&rend);
240 /*---------------------------------------------------------------------------*/
242 static GLuint clip_text;
244 static GLubyte clip_data[] = { 0xff, 0xff, 0x0, 0x0 };
248 if (!glActiveTexture_)
251 glActiveTexture_(GL_TEXTURE1);
253 glGenTextures(1, &clip_text);
254 glBindTexture(GL_TEXTURE_1D, clip_text);
256 glTexImage1D(GL_TEXTURE_1D, 0,
257 GL_LUMINANCE_ALPHA, 2, 0,
258 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, clip_data);
260 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
261 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
263 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
265 glActiveTexture_(GL_TEXTURE0);
270 if (glIsTexture(clip_text))
271 glDeleteTextures(1, &clip_text);
274 void clip_draw_set(void)
276 if (!glActiveTexture_)
279 glActiveTexture_(GL_TEXTURE1);
281 glBindTexture(GL_TEXTURE_1D, clip_text);
283 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
285 glEnable(GL_TEXTURE_GEN_S);
286 glEnable(GL_TEXTURE_1D);
288 glActiveTexture_(GL_TEXTURE0);
291 void clip_draw_clr(void)
293 if (!glActiveTexture_)
296 glActiveTexture_(GL_TEXTURE1);
298 glDisable(GL_TEXTURE_GEN_S);
299 glDisable(GL_TEXTURE_1D);
301 glActiveTexture_(GL_TEXTURE0);
304 /*---------------------------------------------------------------------------*/
307 * A note about lighting and shadow: technically speaking, it's wrong.
308 * The light position and shadow projection behave as if the
309 * light-source rotates with the floor. However, the skybox does not
310 * rotate, thus the light should also remain stationary.
312 * The correct behavior would eliminate a significant 3D cue: the
313 * shadow of the ball indicates the ball's position relative to the
314 * floor even when the ball is in the air. This was the motivating
315 * idea behind the shadow in the first place, so correct shadow
316 * projection would only magnify the problem.
319 static GLuint shad_text;
323 shad_text = make_image_from_file(IMG_SHAD);
325 if (config_get_d(CONFIG_SHADOW) == 2)
327 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
328 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
334 if (glIsTexture(shad_text))
335 glDeleteTextures(1, &shad_text);
338 void shad_draw_set(void)
340 glActiveTexture_(GL_TEXTURE1);
342 glEnable(GL_TEXTURE_2D);
343 glBindTexture(GL_TEXTURE_2D, shad_text);
344 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
346 glActiveTexture_(GL_TEXTURE0);
349 void shad_draw_clr(void)
351 glActiveTexture_(GL_TEXTURE1);
353 glBindTexture(GL_TEXTURE_2D, 0);
354 glDisable(GL_TEXTURE_2D);
356 glActiveTexture_(GL_TEXTURE0);
359 /*---------------------------------------------------------------------------*/