PageRenderTime 18ms CodeModel.GetById 1ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://github.com/xbmc/xbmc
C++ | 126 lines | 91 code | 10 blank | 25 comment | 11 complexity | e0097d5fc68f7f012c970f52b6ea91f6 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 <hyperspace.hh>
 26#include <particle.hh>
 27
 28StretchedParticle::StretchedParticle(
 29	const Vector& XYZ, float radius, const RGBColor& color, float fov) :
 30	_XYZ(XYZ), _lastXYZ(XYZ), _radius(radius),
 31	_color(color), _fov(fov), _moved(true) {
 32	_lastScreenPos[0] = _lastScreenPos[1] = 0.0f;
 33}
 34
 35void StretchedParticle::update() {
 36	Vector temp(_XYZ - Hack::camera);
 37	if (temp.x() > Hack::fogDepth) {
 38		_XYZ.x() = _XYZ.x() - Hack::fogDepth * 2.0f;
 39		_lastXYZ.x() = _lastXYZ.x() - Hack::fogDepth * 2.0f;
 40	}
 41	if (temp.x() < -Hack::fogDepth) {
 42		_XYZ.x() = _XYZ.x() + Hack::fogDepth * 2.0f;
 43		_lastXYZ.x() = _lastXYZ.x() + Hack::fogDepth * 2.0f;
 44	}
 45	if (temp.z() > Hack::fogDepth) {
 46		_XYZ.z() = _XYZ.z() - Hack::fogDepth * 2.0f;
 47		_lastXYZ.z() = _lastXYZ.z() - Hack::fogDepth * 2.0f;
 48	}
 49	if (temp.z() < -Hack::fogDepth) {
 50		_XYZ.z() = _XYZ.z() + Hack::fogDepth * 2.0f;
 51		_lastXYZ.z() = _lastXYZ.z() + Hack::fogDepth * 2.0f;
 52	}
 53}
 54
 55void StretchedParticle::draw() {
 56	double winX, winY, winZ;
 57	gluProject(
 58		_XYZ.x(), _XYZ.y(), _XYZ.z(),
 59		Hack::modelMat, Hack::projMat, Hack::viewport,
 60		&winX, &winY, &winZ
 61	);
 62
 63	double screenPos[2];
 64	if (winZ > 0.0f) {
 65		screenPos[0] = winX;
 66		screenPos[1] = winY;
 67	} else {
 68		screenPos[0] = _lastScreenPos[0];
 69		screenPos[1] = _lastScreenPos[1];
 70	}
 71
 72	Vector drawXYZ((_XYZ + _lastXYZ) * 0.5f);
 73	_lastXYZ = _XYZ;
 74
 75	if (_moved) {
 76		// Window co-ords are screwed, so skip it
 77		_moved = false;
 78	} else {
 79		float sd[2];  // screen difference, position difference
 80		sd[0] = float(screenPos[0] - _lastScreenPos[0]);
 81		sd[1] = float(screenPos[1] - _lastScreenPos[1]);
 82
 83		Vector pd(Hack::camera - drawXYZ);
 84		float n = pd.normalize();
 85		RotationMatrix bbMat = RotationMatrix::lookAt(pd, Vector(), Vector(0, 1, 0));
 86
 87		float stretch = 0.0015f * std::sqrt(sd[0] * sd[0] + sd[1] * sd[1]) * n / _radius;
 88		if (stretch < 1.0f) stretch = 1.0f;
 89		if (stretch > 0.5f / _radius) stretch = 0.5f / _radius;
 90		glPushMatrix();
 91			glTranslatef(drawXYZ.x(), drawXYZ.y(), drawXYZ.z());
 92			glMultMatrixf(bbMat.get());
 93			glRotatef(R2D * std::atan2(sd[1], sd[0]) + Hack::unroll, 0, 0, 1);
 94			glScalef(stretch, 1.0f, 1.0f);
 95			float darkener = stretch * 0.5f;
 96			if (darkener < 1.0f) darkener = 1.0f;
 97			// draw colored aura
 98			glColor3f(_color.r() / darkener, _color.g() / darkener, _color.b() / darkener);
 99			glBegin(GL_TRIANGLE_STRIP);
100				glTexCoord2f(0.0f, 0.0f);
101				glVertex3f(-_radius, -_radius, 0.0f);
102				glTexCoord2f(1.0f, 0.0f);
103				glVertex3f(_radius, -_radius, 0.0f);
104				glTexCoord2f(0.0f, 1.0f);
105				glVertex3f(-_radius, _radius, 0.0f);
106				glTexCoord2f(1.0f, 1.0f);
107				glVertex3f(_radius, _radius, 0.0f);
108			glEnd();
109			// draw white center
110			glColor3f(1.0f / darkener, 1.0f / darkener, 1.0f / darkener);
111			glBegin(GL_TRIANGLE_STRIP);
112				glTexCoord2f(0.0f, 0.0f);
113				glVertex3f(-_radius * 0.3f, -_radius * 0.3f, 0.0f);
114				glTexCoord2f(1.0f, 0.0f);
115				glVertex3f(_radius * 0.3f, -_radius * 0.3f, 0.0f);
116				glTexCoord2f(0.0f, 1.0f);
117				glVertex3f(-_radius * 0.3f, _radius * 0.3f, 0.0f);
118				glTexCoord2f(1.0f, 1.0f);
119				glVertex3f(_radius * 0.3f, _radius * 0.3f, 0.0f);
120			glEnd();
121		glPopMatrix();
122	}
123
124	_lastScreenPos[0] = screenPos[0];
125	_lastScreenPos[1] = screenPos[1];
126}