lens_flare.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "lens_flare.h"
  9. #ifndef IGL_NO_OPENGL
  10. #include "C_STR.h"
  11. #include "unproject.h"
  12. #include "project.h"
  13. #include "shine_textures.h"
  14. #include "flare_textures.h"
  15. #include <iostream>
  16. // http://www.opengl.org/archives/resources/features/KilgardTechniques/LensFlare/glflare.c
  17. IGL_INLINE void igl::lens_flare_load_textures(
  18. std::vector<GLuint> & shine_id,
  19. std::vector<GLuint> & flare_id)
  20. {
  21. const auto setup_texture =[](
  22. const uint8_t * texture,
  23. const int width,
  24. const int height,
  25. GLuint texobj,
  26. GLenum minFilter, GLenum maxFilter)
  27. {
  28. glBindTexture(GL_TEXTURE_2D, texobj);
  29. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  30. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
  31. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, maxFilter);
  32. glTexImage2D(GL_TEXTURE_2D, 0, 1, width, height, 0,
  33. GL_LUMINANCE, GL_UNSIGNED_BYTE, texture);
  34. };
  35. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  36. shine_id.resize(10);
  37. glGenTextures(10,&shine_id[0]);
  38. for (int i = 0; i < (int)shine_id.size(); i++) {
  39. setup_texture(
  40. SHINE_TEXTURES[i],
  41. SHINE_TEXTURE_WIDTHS[i],
  42. SHINE_TEXTURE_HEIGHTS[i],
  43. shine_id[i], GL_LINEAR, GL_LINEAR);
  44. }
  45. flare_id.resize(6);
  46. glGenTextures(6,&flare_id[0]);
  47. for (int i = 0; i < (int)flare_id.size(); i++) {
  48. setup_texture(
  49. FLARE_TEXTURES[i],
  50. FLARE_TEXTURE_WIDTHS[i],
  51. FLARE_TEXTURE_HEIGHTS[i],
  52. flare_id[i], GL_LINEAR, GL_LINEAR);
  53. }
  54. }
  55. IGL_INLINE void igl::lens_flare_create(
  56. const float * A,
  57. const float * B,
  58. const float * C,
  59. std::vector<igl::Flare> & flares)
  60. {
  61. using namespace igl;
  62. using namespace std;
  63. flares.resize(12);
  64. /* Shines */
  65. flares[0] = Flare(-1, 1.0f, 0.1f, C, 1.0);
  66. flares[1] = Flare(-1, 1.0f, 0.15f, B, 1.0);
  67. flares[2] = Flare(-1, 1.0f, 0.35f, A, 1.0);
  68. /* Flares */
  69. flares[3] = Flare(2, 1.3f, 0.04f, A, 0.6);
  70. flares[4] = Flare(3, 1.0f, 0.1f, A, 0.4);
  71. flares[5] = Flare(1, 0.5f, 0.2f, A, 0.3);
  72. flares[6] = Flare(3, 0.2f, 0.05f, A, 0.3);
  73. flares[7] = Flare(0, 0.0f, 0.04f, A, 0.3);
  74. flares[8] = Flare(5, -0.25f, 0.07f, A, 0.5);
  75. flares[9] = Flare(5, -0.4f, 0.02f, A, 0.6);
  76. flares[10] = Flare(5, -0.6f, 0.04f, A, 0.4);
  77. flares[11] = Flare(5, -1.0f, 0.03f, A, 0.2);
  78. }
  79. IGL_INLINE void igl::lens_flare_draw(
  80. const std::vector<igl::Flare> & flares,
  81. const std::vector<GLuint> & shine_ids,
  82. const std::vector<GLuint> & flare_ids,
  83. const Eigen::Vector3f & light,
  84. const float near_clip,
  85. int & shine_tic)
  86. {
  87. bool ot2 = glIsEnabled(GL_TEXTURE_2D);
  88. bool ob = glIsEnabled(GL_BLEND);
  89. bool odt = glIsEnabled(GL_DEPTH_TEST);
  90. bool ocm = glIsEnabled(GL_COLOR_MATERIAL);
  91. bool ol = glIsEnabled(GL_LIGHTING);
  92. int obsa,obda,odf,odwm;
  93. glGetIntegerv(GL_BLEND_SRC_ALPHA,&obsa);
  94. glGetIntegerv(GL_BLEND_DST_ALPHA,&obda);
  95. glGetIntegerv(GL_DEPTH_FUNC,&odf);
  96. glGetIntegerv(GL_DEPTH_WRITEMASK,&odwm);
  97. glDisable(GL_COLOR_MATERIAL);
  98. glEnable(GL_DEPTH_TEST);
  99. //glDepthFunc(GL_LEQUAL);
  100. glDepthMask(GL_FALSE);
  101. glEnable(GL_TEXTURE_2D);
  102. glDisable(GL_LIGHTING);
  103. glEnable(GL_BLEND);
  104. glBlendFunc(GL_ONE, GL_ONE);
  105. using namespace Eigen;
  106. using namespace igl;
  107. using namespace std;
  108. //// view_dir direction from eye to position is is looking at
  109. //const Vector3f view_dir = (at - from).normalized();
  110. //// near_clip distance from eye to near clipping plane along view_dir
  111. //// center position on near clipping plane along viewdir from eye
  112. //const Vector3f center = from + near_clip*view_dir;
  113. Vector3f plight = project(light);
  114. // Orthogonal vectors to view direction at light
  115. Vector3f psx = plight;
  116. psx(0) += 1;
  117. Vector3f psy = plight;
  118. psy(1) += 1;
  119. // axis toward center
  120. int vp[4];
  121. glGetIntegerv(GL_VIEWPORT,vp);
  122. Vector3f center = unproject(Vector3f(0.5*vp[2],0.5*vp[3],plight[2]-1e-3));
  123. //Vector3f center(0,0,1);
  124. Vector3f axis = light-center;
  125. //glLineWidth(4.);
  126. //glColor3f(1,0,0);
  127. //glBegin(GL_LINES);
  128. //glVertex3fv(center.data());
  129. //glVertex3fv(light.data());
  130. //glEnd();
  131. const Vector3f SX = unproject(psx).normalized();
  132. const Vector3f SY = unproject(psy).normalized();
  133. for(int i = 0; i < (int)flares.size(); i++)
  134. {
  135. const Vector3f sx = flares[i].scale * SX;
  136. const Vector3f sy = flares[i].scale * SY;
  137. glColor3fv(flares[i].color);
  138. if (flares[i].type < 0) {
  139. glBindTexture(GL_TEXTURE_2D, shine_ids[shine_tic]);
  140. shine_tic = (shine_tic + 1) % shine_ids.size();
  141. } else
  142. {
  143. glBindTexture(GL_TEXTURE_2D, flare_ids[flares[i].type]);
  144. }
  145. /* position = center + flare[i].loc * axis */
  146. const Vector3f position = center + flares[i].loc * axis;
  147. Vector3f tmp;
  148. glBegin(GL_QUADS);
  149. glTexCoord2f(0.0, 0.0);
  150. tmp = position + sx;
  151. tmp = tmp + sy;
  152. glVertex3fv(tmp.data());
  153. glTexCoord2f(1.0, 0.0);
  154. tmp = position - sx;
  155. tmp = tmp + sy;
  156. glVertex3fv(tmp.data());
  157. glTexCoord2f(1.0, 1.0);
  158. tmp = position - sx;
  159. tmp = tmp - sy;
  160. glVertex3fv(tmp.data());
  161. glTexCoord2f(0.0, 1.0);
  162. tmp = position + sx;
  163. tmp = tmp - sy;
  164. glVertex3fv(tmp.data());
  165. glEnd();
  166. }
  167. ot2?glEnable(GL_TEXTURE_2D):glDisable(GL_TEXTURE_2D);
  168. ob?glEnable(GL_BLEND):glDisable(GL_BLEND);
  169. odt?glEnable(GL_DEPTH_TEST):glDisable(GL_DEPTH_TEST);
  170. ocm?glEnable(GL_COLOR_MATERIAL):glDisable(GL_COLOR_MATERIAL);
  171. ol?glEnable(GL_LIGHTING):glDisable(GL_LIGHTING);
  172. glBlendFunc(obsa,obda);
  173. glDepthFunc(odf);
  174. glDepthMask(odwm);
  175. }
  176. #endif