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 const struct d_mtrl *jump_part_draw(const struct d_mtrl *mq,
95 glMatrixMode(GL_TEXTURE);
96 glTranslatef(s, 0.0f, 0.0f);
97 glMatrixMode(GL_MODELVIEW);
99 glRotatef(a, 0.0f, 1.0f, 0.0f);
100 mq = sol_draw(&jump.draw, mq, 1, 1);
101 glScalef(0.9f, 0.9f, 0.9f);
106 static const struct d_mtrl *goal_part_draw(const struct d_mtrl *mq, GLfloat s)
108 glMatrixMode(GL_TEXTURE);
109 glTranslatef(0.0f, -s, 0.0f);
110 glMatrixMode(GL_MODELVIEW);
112 mq = sol_draw(&goal.draw, mq, 1, 1);
113 glScalef(0.8f, 1.1f, 0.8f);
118 /*---------------------------------------------------------------------------*/
120 const struct d_mtrl *goal_draw(const struct d_mtrl *mq, float t)
124 glScalef(1.0f, 3.0f, 1.0f);
125 glColor4f(1.0f, 1.0f, 0.0f, 0.5f);
127 mq = sol_draw(&beam.draw, mq, 1, 1);
129 mq = goal_part_draw(mq, t * 0.10f);
130 mq = goal_part_draw(mq, t * 0.10f);
131 mq = goal_part_draw(mq, t * 0.10f);
132 mq = goal_part_draw(mq, t * 0.10f);
134 glMatrixMode(GL_TEXTURE);
136 glMatrixMode(GL_MODELVIEW);
138 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
145 const struct d_mtrl *jump_draw(const struct d_mtrl *mq, float t, int h)
147 static GLfloat c[4][4] = {
148 { 0.75f, 0.5f, 1.0f, 0.5f },
149 { 0.75f, 0.5f, 1.0f, 0.8f },
154 glColor4f(c[h][0], c[h][1], c[h][2], c[h][3]);
156 glScalef(1.0f, 2.0f, 1.0f);
158 mq = sol_draw(&beam.draw, mq, 1, 1);
160 mq = jump_part_draw(mq, t * 0.15f, t * 360.0f);
161 mq = jump_part_draw(mq, t * 0.20f, t * 360.0f);
162 mq = jump_part_draw(mq, t * 0.25f, t * 360.0f);
164 glMatrixMode(GL_TEXTURE);
166 glMatrixMode(GL_MODELVIEW);
168 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
175 const struct d_mtrl *swch_draw(const struct d_mtrl *mq, int b, int e)
177 static GLfloat c[4][4] = {
178 { 1.0f, 0.0f, 0.0f, 0.5f }, /* red out */
179 { 1.0f, 0.0f, 0.0f, 0.8f }, /* red in */
180 { 0.0f, 1.0f, 0.0f, 0.5f }, /* green out */
181 { 0.0f, 1.0f, 0.0f, 0.8f }, /* green in */
184 const int h = 2 * b + e;
188 glScalef(1.0f, 2.0f, 1.0f);
190 glColor4f(c[h][0], c[h][1], c[h][2], c[h][3]);
191 mq = sol_draw(&beam.draw, mq, 1, 1);
192 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
199 const struct d_mtrl *flag_draw(const struct d_mtrl *mq)
201 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
202 return sol_draw(&flag.draw, mq, 1, 1);
205 const struct d_mtrl *mark_draw(const struct d_mtrl *mq)
207 return sol_draw(&mark.draw, mq, 1, 1);
210 const struct d_mtrl *vect_draw(const struct d_mtrl *mq)
212 mq = sol_draw(&vect.draw, mq, 0, 1);
213 mq = sol_draw(&vect.draw, mq, 0, 0);
217 const struct d_mtrl *back_draw(const struct d_mtrl *mq, float t)
221 GLfloat dx = 60.0f * fsinf(t / 10.0f);
222 GLfloat dz = 180.0f * fsinf(t / 12.0f);
224 glDisable(GL_DEPTH_TEST);
225 glDisable(GL_CULL_FACE);
226 glDisable(GL_LIGHTING);
227 glDepthMask(GL_FALSE);
229 glScalef(-BACK_DIST, BACK_DIST, -BACK_DIST);
230 if (t) glRotatef(dz, 0.0f, 0.0f, 1.0f);
231 if (t) glRotatef(dx, 1.0f, 0.0f, 0.0f);
233 mq = sol_draw(&back.draw, mq, 1, 1);
235 glDepthMask(GL_TRUE);
236 glEnable(GL_LIGHTING);
237 glEnable(GL_CULL_FACE);
238 glEnable(GL_DEPTH_TEST);
245 void back_draw_easy(void)
247 sol_draw_disable(back_draw(sol_draw_enable(), 0.0f));
250 /*---------------------------------------------------------------------------*/
252 static GLuint clip_text;
254 static GLubyte clip_data[] = { 0xff, 0xff, 0x0, 0x0 };
258 if (!glActiveTexture_)
261 glActiveTexture_(GL_TEXTURE1);
263 glGenTextures(1, &clip_text);
264 glBindTexture(GL_TEXTURE_1D, clip_text);
266 glTexImage1D(GL_TEXTURE_1D, 0,
267 GL_LUMINANCE_ALPHA, 2, 0,
268 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, clip_data);
270 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
271 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
273 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
275 glActiveTexture_(GL_TEXTURE0);
280 if (glIsTexture(clip_text))
281 glDeleteTextures(1, &clip_text);
284 void clip_draw_set(void)
286 if (!glActiveTexture_)
289 glActiveTexture_(GL_TEXTURE1);
291 glBindTexture(GL_TEXTURE_1D, clip_text);
293 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
295 glEnable(GL_TEXTURE_GEN_S);
296 glEnable(GL_TEXTURE_1D);
298 glActiveTexture_(GL_TEXTURE0);
301 void clip_draw_clr(void)
303 if (!glActiveTexture_)
306 glActiveTexture_(GL_TEXTURE1);
308 glDisable(GL_TEXTURE_GEN_S);
309 glDisable(GL_TEXTURE_1D);
311 glActiveTexture_(GL_TEXTURE0);
314 /*---------------------------------------------------------------------------*/
317 * A note about lighting and shadow: technically speaking, it's wrong.
318 * The light position and shadow projection behave as if the
319 * light-source rotates with the floor. However, the skybox does not
320 * rotate, thus the light should also remain stationary.
322 * The correct behavior would eliminate a significant 3D cue: the
323 * shadow of the ball indicates the ball's position relative to the
324 * floor even when the ball is in the air. This was the motivating
325 * idea behind the shadow in the first place, so correct shadow
326 * projection would only magnify the problem.
329 static GLuint shad_text;
333 shad_text = make_image_from_file(IMG_SHAD);
335 if (config_get_d(CONFIG_SHADOW) == 2)
337 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
338 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
344 if (glIsTexture(shad_text))
345 glDeleteTextures(1, &shad_text);
348 void shad_draw_set(void)
350 glActiveTexture_(GL_TEXTURE1);
352 glEnable(GL_TEXTURE_2D);
353 glBindTexture(GL_TEXTURE_2D, shad_text);
354 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
356 glActiveTexture_(GL_TEXTURE0);
359 void shad_draw_clr(void)
361 glActiveTexture_(GL_TEXTURE1);
363 glBindTexture(GL_TEXTURE_2D, 0);
364 glDisable(GL_TEXTURE_2D);
366 glActiveTexture_(GL_TEXTURE0);
369 /*---------------------------------------------------------------------------*/