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