PageRenderTime 47ms CodeModel.GetById 19ms app.highlight 24ms RepoModel.GetById 1ms app.codeStats 0ms

/xbmc/screensavers/rsxs-0.9/src/hyperspace/flares.cc

http://github.com/xbmc/xbmc
C++ | 282 lines | 204 code | 36 blank | 42 comment | 26 complexity | 0303b56933569a63f66898f35919ac2a MD5 | raw file
  1/*
  2 * Really Slick XScreenSavers
  3 * Copyright (C) 2002-2006  Michael Chapman
  4 *
  5 * This program 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 * This program 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 *
 20 * This is a Linux port of the Really Slick Screensavers,
 21 * Copyright (C) 2005 Terence M. Welsh, available from www.reallyslick.com
 22 */
 23#include <common.hh>
 24
 25#include <color.hh>
 26#include <hyperspace.hh>
 27#include <flares.hh>
 28
 29#define FLARESIZE 64
 30
 31namespace Flares {
 32	GLuint blob;
 33};
 34
 35namespace Flares {
 36	GLuint _lists;
 37	GLuint _flare[4];
 38};
 39
 40void Flares::init() {
 41	stdx::dim3<GLubyte, 4, FLARESIZE> flareMap[4];
 42	for (unsigned int i = 0; i < 4; ++i)
 43		flareMap[i].resize(FLARESIZE);
 44
 45	for (unsigned int i = 0; i < FLARESIZE; ++i) {
 46		float x = float(int(i) - FLARESIZE / 2) / float(FLARESIZE / 2);
 47		for (unsigned int j = 0; j < FLARESIZE; ++j) {
 48			float y = float(int(j) - FLARESIZE / 2) / float(FLARESIZE / 2);
 49			float temp;
 50
 51			// Basic flare
 52			flareMap[0](i, j, 0) = 255;
 53			flareMap[0](i, j, 1) = 255;
 54			flareMap[0](i, j, 2) = 255;
 55			temp = 1.0f - ((x * x) + (y * y));
 56			if (temp > 1.0f) temp = 1.0f;
 57			if (temp < 0.0f) temp = 0.0f;
 58			flareMap[0](i, j, 3) = GLubyte(255.0f * temp * temp);
 59
 60			// Flattened sphere
 61			flareMap[1](i, j, 0) = 255;
 62			flareMap[1](i, j, 1) = 255;
 63			flareMap[1](i, j, 2) = 255;
 64			temp = 2.5f * (1.0f - ((x * x) + (y * y)));
 65			if (temp > 1.0f) temp = 1.0f;
 66			if (temp < 0.0f) temp = 0.0f;
 67			flareMap[1](i, j, 3) = GLubyte(255.0f * temp);
 68
 69			// Torus
 70			flareMap[2](i, j, 0) = 255;
 71			flareMap[2](i, j, 1) = 255;
 72			flareMap[2](i, j, 2) = 255;
 73			temp = 4.0f * ((x * x) + (y * y)) * (1.0f - ((x * x) + (y * y)));
 74			if (temp > 1.0f) temp = 1.0f;
 75			if (temp < 0.0f) temp = 0.0f;
 76			temp = temp * temp * temp * temp;
 77			flareMap[2](i, j, 3) = GLubyte(255.0f * temp);
 78
 79			// Kick-ass!
 80			x = std::abs(x);
 81			y = std::abs(y);
 82			float xy = x * y;
 83			flareMap[3](i, j, 0) = 255;
 84			flareMap[3](i, j, 1) = 255;
 85			temp = 0.14f * (1.0f - ((x > y) ? x : y)) / ((xy > 0.05f) ? xy : 0.05f);
 86			if (temp > 1.0f) temp = 1.0f;
 87			if (temp < 0.0f) temp = 0.0f;
 88			flareMap[3](i, j, 2) = GLubyte(255.0f * temp);
 89			temp = 0.1f * (1.0f - ((x > y) ? x : y)) / ((xy > 0.1f) ? xy : 0.1f);
 90			if (temp > 1.0f) temp = 1.0f;
 91			if (temp < 0.0f) temp = 0.0f;
 92			flareMap[3](i, j, 3) = GLubyte(255.0f * temp);
 93		}
 94	}
 95
 96	for (unsigned int i = 0; i < 4; ++i)
 97		_flare[i] = Common::resources->genTexture(
 98			GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT,
 99			4, FLARESIZE, FLARESIZE, GL_RGBA, GL_UNSIGNED_BYTE,
100			&flareMap[i].front(), false
101		);
102
103	_lists = Common::resources->genLists(4);
104	for (unsigned int i = 0; i < 4; ++i) {
105		glNewList(_lists + i, GL_COMPILE);
106			glBindTexture(GL_TEXTURE_2D, _flare[i]);
107			glBegin(GL_TRIANGLE_STRIP);
108				glTexCoord2f(0.0f, 0.0f);
109				glVertex3f(-0.5f, -0.5f, 0.0f);
110				glTexCoord2f(1.0f, 0.0f);
111				glVertex3f(0.5f, -0.5f, 0.0f);
112				glTexCoord2f(0.0f, 1.0f);
113				glVertex3f(-0.5f, 0.5f, 0.0f);
114				glTexCoord2f(1.0f, 1.0f);
115				glVertex3f(0.5f, 0.5f, 0.0f);
116			glEnd();
117		glEndList();
118	}
119
120	blob = _flare[0];
121}
122
123// Draw a flare at a specified (x,y) location on the screen
124// Screen corners are at (0,0) and (1,1)
125void Flares::draw(const Vector& XYZ, const RGBColor& RGB, float alpha) {
126	double winX, winY, winZ;
127	gluProject(
128		XYZ.x(), XYZ.y(), XYZ.z(),
129		Hack::modelMat, Hack::projMat, Hack::viewport,
130		&winX, &winY, &winZ
131	);
132	if (winZ > 1.0f)
133		return;
134
135	// Fade alpha if source is off edge of screen
136	float fadeWidth = float(Common::width) * 0.1f;
137	if (winY < 0.0f) {
138		float temp = fadeWidth + winY;
139		if (temp < 0.0f) return;
140		alpha *= temp / fadeWidth;
141	}
142	if (winY > Common::height) {
143		float temp = fadeWidth - winY + Common::height;
144		if (temp < 0.0f) return;
145		alpha *= temp / fadeWidth;
146	}
147	if (winX < 0) {
148		float temp = fadeWidth + winX;
149		if (temp < 0.0f) return;
150		alpha *= temp / fadeWidth;
151	}
152	if (winX > Common::width) {
153		float temp = fadeWidth - winX + Common::width;
154		if (temp < 0.0f) return;
155		alpha *= temp / fadeWidth;
156	}
157
158	float x = (float(winX) / float(Common::width)) * Common::aspectRatio;
159	float y = float(winY) / float(Common::height);
160
161	// Find lens flare vector
162	// This vector runs from the light source through the screen's center
163	float dx = 0.5f * Common::aspectRatio - x;
164	float dy = 0.5f - y;
165
166	glPushAttrib(GL_ENABLE_BIT);
167	glBlendFunc(GL_SRC_ALPHA, GL_ONE);
168	glEnable(GL_BLEND);
169	glEnable(GL_TEXTURE_2D);
170
171	// Setup projection matrix
172	glMatrixMode(GL_PROJECTION);
173	glPushMatrix();
174	glLoadIdentity();
175	gluOrtho2D(0, Common::aspectRatio, 0, 1.0f);
176
177	// Update fractal flickering
178	static float flicker = 0.95f;
179	flicker += Common::elapsedSecs * (Common::randomFloat(2.0f) - 1.0f);
180	if (flicker < 0.9f) flicker = 0.9f;
181	if (flicker > 1.1f) flicker = 1.1f;
182	alpha *= flicker;
183
184	// Draw stuff
185	glMatrixMode(GL_MODELVIEW);
186	glPushMatrix();
187
188	glLoadIdentity();
189	glTranslatef(x, y, 0.0f);
190	glScalef(0.1f * flicker, 0.1f * flicker, 1.0f);
191	glColor4f(RGB.r(), RGB.g(), RGB.b() * 0.8f, alpha);
192	glCallList(_lists + 0);
193
194	// wide flare
195	glLoadIdentity();
196	glTranslatef(x, y, 0.0f);
197	glScalef(5.0f * alpha, 0.05f * alpha, 1.0f);
198	glColor4f(RGB.r() * 0.3f, RGB.g() * 0.3f, RGB.b(), alpha);
199	glCallList(_lists + 0);
200
201	// torus
202	glLoadIdentity();
203	glTranslatef(x, y, 0.0f);
204	glScalef(0.5f, 0.2f, 1.0f);
205	glColor4f(RGB.r(), RGB.g() * 0.5f, RGB.b() * 0.5f, alpha * 0.4f);
206	glCallList(_lists + 2);
207
208	// 3 blueish dots
209	glLoadIdentity();
210	glTranslatef(x + dx * 0.35f, y + dy * 0.35f, 0.0f);
211	glScalef(0.06f, 0.06f, 1.0f);
212	glColor4f(RGB.r() * 0.85f, RGB.g() * 0.85f, RGB.b(), alpha * 0.5f);
213	glCallList(_lists + 1);
214
215	glLoadIdentity();
216	glTranslatef(x + dx * 0.45f, y + dy * 0.45f, 0.0f);
217	glScalef(0.09f, 0.09f, 1.0f);
218	glColor4f(RGB.r() * 0.7f, RGB.g() * 0.7f, RGB.b(), alpha * 0.4f);
219	glCallList(_lists + 1);
220
221	glLoadIdentity();
222	glTranslatef(x + dx * 0.55f, y + dy * 0.55f, 0.0f);
223	glScalef(0.12f, 0.12f, 1.0f);
224	glColor4f(RGB.r() * 0.55f, RGB.g() * 0.55f, RGB.b(), alpha * 0.3f);
225	glCallList(_lists + 1);
226
227	// 4 more dots
228	glLoadIdentity();
229	glTranslatef(x + dx * 0.75f, y + dy * 0.75f, 0.0f);
230	glScalef(0.14f, 0.07f, 1.0f);
231	glColor4f(RGB.r() * 0.3f, RGB.g() * 0.3f, RGB.b() * 0.3f, alpha);
232	glCallList(_lists + 3);
233
234	glLoadIdentity();
235	glTranslatef(x + dx * 0.78f, y + dy * 0.78f, 0.0f);
236	glScalef(0.06f, 0.06f, 1.0f);
237	glColor4f(RGB.r() * 0.3f, RGB.g() * 0.4f, RGB.b() * 0.4f, alpha * 0.5f);
238	glCallList(_lists + 1);
239
240	glLoadIdentity();
241	glTranslatef(x + dx * 1.25f, y + dy * 1.25f, 0.0f);
242	glScalef(0.1f, 0.1f, 1.0f);
243	glColor4f(RGB.r() * 0.3f, RGB.g() * 0.4f, RGB.b() * 0.3f, alpha * 0.5f);
244	glCallList(_lists + 1);
245
246	glLoadIdentity();
247	glTranslatef(x + dx * 1.3f, y + dy * 1.3f, 0.0f);
248	glScalef(0.07f, 0.07f, 1.0f);
249	glColor4f(RGB.r() * 0.6f, RGB.g() * 0.45f, RGB.b() * 0.3f, alpha * 0.5f);
250	glCallList(_lists + 1);
251
252	// stretched weird flare
253	glLoadIdentity();
254	glTranslatef(x + dx * 1.45f, y + dy * 1.45f, 0.0f);
255	glScalef(0.8f, 0.2f, 1.0f);
256	glRotatef(x * 70.0f, 0, 0, 1);
257	glColor4f(RGB.r(), RGB.g(), RGB.b(), alpha * 0.4f);
258	glCallList(_lists + 3);
259
260	// circle
261	glLoadIdentity();
262	glTranslatef(x + dx * 2.0f, y + dy * 2.0f, 0.0f);
263	glScalef(0.3f, 0.3f, 1.0f);
264	glColor4f(RGB.r(), RGB.g(), RGB.b(), alpha * 0.2f);
265	glCallList(_lists + 1);
266
267	// big weird flare
268	glLoadIdentity();
269	glTranslatef(x + dx * 2.4f, y + dy * 2.4f, 0.0f);
270	glRotatef(y * 40.0f, 0, 0, 1);
271	glScalef(0.7f, 0.7f, 1.0f);
272	glColor4f(RGB.r(), RGB.g(), RGB.b(), alpha * 0.3f);
273	glCallList(_lists + 3);
274
275	// Unsetup projection matrix
276	glPopMatrix();
277	glMatrixMode(GL_PROJECTION);
278	glPopMatrix();
279	glMatrixMode(GL_MODELVIEW);
280
281	glPopAttrib();
282}