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