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