1 /*
2 * Copyright (C) 2002 Terence M. Welsh
3 * Ported to Linux by Tugrul Galatali <tugrul@galatali.com>
4 *
5 * Skyrocket is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Skyrocket is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 #include <GL/gl.h>
20 #include <GL/glu.h>
21
22 #include "skyrocket_flare.h"
23
24 #define FLARESIZE 128
25
26 #define max(x, y) ((x > y) ? x : y)
27
28 unsigned int flarelist[4];
29
30 extern int xsize, ysize;
31 extern float aspectRatio;
32
33 // Generate textures for lens flares
34 // then applies textures to geometry in display lists
initFlares()35 void initFlares ()
36 {
37 int i, j;
38 float x, y;
39 float temp;
40 unsigned char flare[FLARESIZE][FLARESIZE][4];
41 unsigned int flaretex[4];
42
43 glGenTextures (4, flaretex);
44
45 // First flare: basic sphere
46 for (i = 0; i < FLARESIZE; i++) {
47 for (j = 0; j < FLARESIZE; j++) {
48 flare[i][j][0] = 255;
49 flare[i][j][1] = 255;
50 flare[i][j][2] = 255;
51 x = float (i - FLARESIZE / 2) / float (FLARESIZE / 2);
52 y = float (j - FLARESIZE / 2) / float (FLARESIZE / 2);
53
54 temp = 1.0f - ((x * x) + (y * y));
55 if (temp > 1.0f)
56 temp = 1.0f;
57 if (temp < 0.0f)
58 temp = 0.0f;
59 flare[i][j][3] = char (255.0f * temp * temp);
60 }
61 }
62 glBindTexture (GL_TEXTURE_2D, flaretex[0]);
63 //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
64 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
65 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
66 glTexImage2D (GL_TEXTURE_2D, 0, 4, FLARESIZE, FLARESIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, flare);
67
68 // Second flare: flattened sphere
69 for (i = 0; i < FLARESIZE; i++) {
70 for (j = 0; j < FLARESIZE; j++) {
71 flare[i][j][0] = 255;
72 flare[i][j][1] = 255;
73 flare[i][j][2] = 255;
74 x = float (i - FLARESIZE / 2) / float (FLARESIZE / 2);
75 y = float (j - FLARESIZE / 2) / float (FLARESIZE / 2);
76
77 temp = 2.5f * (1.0f - ((x * x) + (y * y)));
78 if (temp > 1.0f)
79 temp = 1.0f;
80 if (temp < 0.0f)
81 temp = 0.0f;
82 //temp = temp * temp * temp * temp;
83 flare[i][j][3] = char (255.0f * temp);
84 }
85 }
86 glBindTexture (GL_TEXTURE_2D, flaretex[1]);
87 //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
88 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
89 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
90 glTexImage2D (GL_TEXTURE_2D, 0, 4, FLARESIZE, FLARESIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, flare);
91
92 // Third flare: torus
93 for (i = 0; i < FLARESIZE; i++) {
94 for (j = 0; j < FLARESIZE; j++) {
95 flare[i][j][0] = 255;
96 flare[i][j][1] = 255;
97 flare[i][j][2] = 255;
98 x = float (i - FLARESIZE / 2) / float (FLARESIZE / 2);
99 y = float (j - FLARESIZE / 2) / float (FLARESIZE / 2);
100
101 temp = 4.0f * ((x * x) + (y * y)) * (1.0f - ((x * x) + (y * y)));
102 if (temp > 1.0f)
103 temp = 1.0f;
104 if (temp < 0.0f)
105 temp = 0.0f;
106 temp = temp * temp * temp * temp;
107 flare[i][j][3] = char (255.0f * temp);
108 }
109 }
110 glBindTexture (GL_TEXTURE_2D, flaretex[2]);
111 //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
112 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
113 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
114 glTexImage2D (GL_TEXTURE_2D, 0, 4, FLARESIZE, FLARESIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, flare);
115
116 // Fourth flare: kick-ass flare
117 for (i = 0; i < FLARESIZE; i++) {
118 for (j = 0; j < FLARESIZE; j++) {
119 x = float (i - FLARESIZE / 2) / float (FLARESIZE / 2);
120
121 if (x < 0.0f)
122 x = -x;
123 y = float (j - FLARESIZE / 2) / float (FLARESIZE / 2);
124
125 if (y < 0.0f)
126 y = -y;
127 flare[i][j][0] = 255;
128 flare[i][j][1] = 255;
129 temp = 0.14f * (1.0f - max (x, y)) / max ((x * y), 0.05f);
130 if (temp > 1.0f)
131 temp = 1.0f;
132 if (temp < 0.0f)
133 temp = 0.0f;
134 flare[i][j][2] = char (255.0f * temp);
135
136 temp = 0.1f * (1.0f - max (x, y)) / max ((x * y), 0.1f);
137 if (temp > 1.0f)
138 temp = 1.0f;
139 if (temp < 0.0f)
140 temp = 0.0f;
141 flare[i][j][3] = char (255.0f * temp);
142 }
143 }
144 glBindTexture (GL_TEXTURE_2D, flaretex[3]);
145 //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
146 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
147 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
148 glTexImage2D (GL_TEXTURE_2D, 0, 4, FLARESIZE, FLARESIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, flare);
149
150 // Build display lists
151 flarelist[0] = glGenLists (4);
152 flarelist[1] = flarelist[0] + 1;
153 flarelist[2] = flarelist[0] + 2;
154 flarelist[3] = flarelist[0] + 3;
155 for (i = 0; i < 4; i++) {
156 glNewList (flarelist[i], GL_COMPILE);
157 glBindTexture (GL_TEXTURE_2D, flaretex[i]);
158 glBegin (GL_TRIANGLE_STRIP);
159 glTexCoord2f (0.0f, 0.0f);
160 glVertex3f (-0.5f, -0.5f, 0.0f);
161 glTexCoord2f (1.0f, 0.0f);
162 glVertex3f (0.5f, -0.5f, 0.0f);
163 glTexCoord2f (0.0f, 1.0f);
164 glVertex3f (-0.5f, 0.5f, 0.0f);
165 glTexCoord2f (1.0f, 1.0f);
166 glVertex3f (0.5f, 0.5f, 0.0f);
167 glEnd ();
168 glEndList ();
169 }
170 }
171
cleanupFlares()172 void cleanupFlares ()
173 {
174 glDeleteLists (flarelist[0], 4);
175 }
176
177 // Draw a flare at a specified (x,y) location on the screen
178 // Screen corners are at (0,0) and (1,1)
179 // alpha = 0.0 for lowest intensity; alpha = 1.0 for highest intensity
flare(float x,float y,float red,float green,float blue,float alpha)180 void flare (float x, float y, float red, float green, float blue, float alpha)
181 {
182 float dx, dy;
183 float fadewidth, temp;
184
185 glBlendFunc (GL_SRC_ALPHA, GL_ONE);
186 glEnable (GL_BLEND);
187
188 // Fade alpha if source is off edge of screen
189 fadewidth = float (xsize) / 10.0f;
190
191 if (y < 0) {
192 temp = fadewidth + y;
193 if (temp < 0.0f)
194 return;
195 alpha *= temp / fadewidth;
196 }
197 if (y > ysize) {
198 temp = fadewidth - y + ysize;
199 if (temp < 0.0f)
200 return;
201 alpha *= temp / fadewidth;
202 }
203 if (x < 0) {
204 temp = fadewidth + x;
205 if (temp < 0.0f)
206 return;
207 alpha *= temp / fadewidth;
208 }
209 if (x > xsize) {
210 temp = fadewidth - x + xsize;
211 if (temp < 0.0f)
212 return;
213 alpha *= temp / fadewidth;
214 }
215 // Find lens flare vector
216 // This vector runs from the light source through the screen's center
217 dx = 0.5f * aspectRatio - x;
218 dy = 0.5f - y;
219
220 // Setup projection matrix
221 glMatrixMode (GL_PROJECTION);
222 glPushMatrix ();
223 glLoadIdentity ();
224 gluOrtho2D (0, aspectRatio, 0, 1.0f);
225
226 // Draw stuff
227 glMatrixMode (GL_MODELVIEW);
228 glPushMatrix ();
229
230 glLoadIdentity ();
231 glTranslatef (x + dx * 0.05f, y + dy * 0.05f, 0.0f);
232 glScalef (0.065f, 0.065f, 0.065f);
233 glColor4f (red, green, blue, alpha * 0.4f);
234 glCallList (flarelist[2]);
235
236 glLoadIdentity ();
237 glTranslatef (x + dx * 0.15f, y + dy * 0.15f, 0.0f);
238 glScalef (0.04f, 0.04f, 0.04f);
239 glColor4f (red * 0.9f, green * 0.9f, blue, alpha * 0.9f);
240 glCallList (flarelist[1]);
241
242 glLoadIdentity ();
243 glTranslatef (x + dx * 0.25f, y + dy * 0.25f, 0.0f);
244 glScalef (0.06f, 0.06f, 0.06f);
245 glColor4f (red * 0.8f, green * 0.8f, blue, alpha * 0.9f);
246 glCallList (flarelist[1]);
247
248 glLoadIdentity ();
249 glTranslatef (x + dx * 0.35f, y + dy * 0.35f, 0.0f);
250 glScalef (0.08f, 0.08f, 0.08f);
251 glColor4f (red * 0.7f, green * 0.7f, blue, alpha * 0.9f);
252 glCallList (flarelist[1]);
253
254 glLoadIdentity ();
255 glTranslatef (x + dx * 1.25f, y + dy * 1.25f, 0.0f);
256 glScalef (0.05f, 0.05f, 0.05f);
257 glColor4f (red, green * 0.6f, blue * 0.6f, alpha * 0.9f);
258 glCallList (flarelist[1]);
259
260 glLoadIdentity ();
261 glTranslatef (x + dx * 1.65f, y + dy * 1.65f, 0.0f);
262 glRotatef (x, 0, 0, 1);
263 glScalef (0.3f, 0.3f, 0.3f);
264 glColor4f (red, green, blue, alpha);
265 glCallList (flarelist[3]);
266
267 glLoadIdentity ();
268 glTranslatef (x + dx * 1.85f, y + dy * 1.85f, 0.0f);
269 glScalef (0.04f, 0.04f, 0.04f);
270 glColor4f (red, green * 0.6f, blue * 0.6f, alpha * 0.9f);
271 glCallList (flarelist[1]);
272
273 glLoadIdentity ();
274 glTranslatef (x + dx * 2.2f, y + dy * 2.2f, 0.0f);
275 glScalef (0.3f, 0.3f, 0.3f);
276 glColor4f (red, green, blue, alpha * 0.7f);
277 glCallList (flarelist[1]);
278
279 glLoadIdentity ();
280 glTranslatef (x + dx * 2.5f, y + dy * 2.5f, 0.0f);
281 glScalef (0.6f, 0.6f, 0.6f);
282 glColor4f (red, green, blue, alpha * 0.8f);
283 glCallList (flarelist[3]);
284
285 glPopMatrix ();
286
287 // Unsetup projection matrix
288 glMatrixMode (GL_PROJECTION);
289 glPopMatrix ();
290 glMatrixMode (GL_MODELVIEW);
291 }
292
293 // super bright elongated glow for sucker, shockwave, stretcher, and bigmama
superFlare(float x,float y,float red,float green,float blue,float alpha)294 void superFlare (float x, float y, float red, float green, float blue, float alpha)
295 {
296 float fadewidth, temp;
297
298 glBlendFunc (GL_SRC_ALPHA, GL_ONE);
299 glEnable (GL_BLEND);
300
301 // Fade alpha if source is off edge of screen
302 fadewidth = float (xsize) / 10.0f;
303
304 if (y < 0) {
305 temp = fadewidth + y;
306 if (temp < 0.0f)
307 return;
308 alpha *= temp / fadewidth;
309 }
310 if (y > ysize) {
311 temp = fadewidth - y + ysize;
312 if (temp < 0.0f)
313 return;
314 alpha *= temp / fadewidth;
315 }
316 if (x < 0) {
317 temp = fadewidth + x;
318 if (temp < 0.0f)
319 return;
320 alpha *= temp / fadewidth;
321 }
322 if (x > xsize) {
323 temp = fadewidth - x + xsize;
324 if (temp < 0.0f)
325 return;
326 alpha *= temp / fadewidth;
327 }
328 // Setup projection matrix
329 glMatrixMode (GL_PROJECTION);
330 glPushMatrix ();
331 glLoadIdentity ();
332 gluOrtho2D (0, aspectRatio, 0, 1.0f);
333
334 // Draw stuff
335 glMatrixMode (GL_MODELVIEW);
336 glPushMatrix ();
337
338 glLoadIdentity ();
339 glTranslatef (x, y, 0.0f);
340 glScalef (2.0f * alpha, 0.08f, 0.0f);
341 glColor4f (red, green, blue, alpha);
342 glCallList (flarelist[0]);
343
344 glLoadIdentity ();
345 glTranslatef (x, y, 0.0f);
346 glScalef (0.4f, 0.35f * alpha + 0.05f, 1.0f);
347 glColor4f (red, green, blue, alpha * 0.4f);
348 glCallList (flarelist[2]);
349
350 glPopMatrix ();
351
352 // Unsetup projection matrix
353 glMatrixMode (GL_PROJECTION);
354 glPopMatrix ();
355 glMatrixMode (GL_MODELVIEW);
356 }
357