]> gitweb.ps.run Git - subsurface_scattering/blob - src/main2.cpp
SSSSS comments
[subsurface_scattering] / src / main2.cpp
1 #include <stdio.h>\r
2 #include <fstream>\r
3 \r
4 #include <GL/glew.h>\r
5 \r
6 #define GLM_ENABLE_EXPERIMENTAL\r
7 \r
8 #include <glm/glm.hpp>\r
9 #include <glm/gtx/rotate_vector.hpp>\r
10 #include <glm/gtc/matrix_transform.hpp>\r
11 #include <glm/gtc/type_ptr.hpp>\r
12 \r
13 #include <SFML/OpenGL.hpp>\r
14 #include <SFML/Graphics.hpp>\r
15 \r
16 #include <imgui.h>\r
17 #include <imgui-SFML.h>\r
18 \r
19 #include <assimp/Importer.hpp>\r
20 #include <assimp/postprocess.h>\r
21 #include <assimp/scene.h>\r
22 \r
23 float samplePositions[] = {\r
24   0.000000f,  0.000000f,\r
25   1.633992f,  0.036795f,\r
26   0.177801f,  1.717593f,\r
27   -0.194906f,  0.091094f,\r
28   -0.239737f, -0.220217f,\r
29   -0.003530f, -0.118219f,\r
30   1.320107f, -0.181542f,\r
31   5.970690f,  0.253378f,\r
32   -1.089250f,  4.958349f,\r
33   -4.015465f,  4.156699f,\r
34   -4.063099f, -4.110150f,\r
35   -0.638605f, -6.297663f,\r
36   2.542348f, -3.245901f\r
37 };\r
38 \r
39 float sampleWeights[] = {\r
40   0.220441f,  0.487000f, 0.635000f,\r
41   0.076356f,  0.064487f, 0.039097f,\r
42   0.116515f,  0.103222f, 0.064912f,\r
43   0.064844f,  0.086388f, 0.062272f,\r
44   0.131798f,  0.151695f, 0.103676f,\r
45   0.025690f,  0.042728f, 0.033003f,\r
46   0.048593f,  0.064740f, 0.046131f,\r
47   0.048092f,  0.003042f, 0.000400f,\r
48   0.048845f,  0.005406f, 0.001222f,\r
49   0.051322f,  0.006034f, 0.001420f,\r
50   0.061428f,  0.009152f, 0.002511f,\r
51   0.030936f,  0.002868f, 0.000652f,\r
52   0.073580f,  0.023239f, 0.009703f\r
53 };\r
54 \r
55 struct model {\r
56   std::vector<float> vertices;\r
57   std::vector<GLuint> indices;\r
58 \r
59   void draw() {\r
60     if (VAO == 0) initVAO();\r
61     glBindVertexArray(VAO);\r
62     glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);\r
63     glBindVertexArray(0);\r
64   }\r
65 \r
66 private:\r
67   void initVAO() {\r
68     GLuint VBO;\r
69     glGenBuffers(1, &VBO);\r
70 \r
71     GLuint EBO;\r
72     glGenBuffers(1, &EBO);\r
73 \r
74     glGenVertexArrays(1, &VAO);\r
75 \r
76     glBindVertexArray(VAO);\r
77 \r
78     glBindBuffer(GL_ARRAY_BUFFER, VBO);\r
79     glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(),\r
80                 vertices.data(), GL_STATIC_DRAW);\r
81 \r
82     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);\r
83     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indices.size(),\r
84                 indices.data(), GL_STATIC_DRAW);\r
85 \r
86     glEnableVertexAttribArray(0);\r
87     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 8, (void*)(0));\r
88     glEnableVertexAttribArray(1);\r
89     glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 8, (void*)(sizeof(float) * 3));\r
90     glEnableVertexAttribArray(2);\r
91     glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 8, (void*)(sizeof(float) * 6));\r
92 \r
93     glBindVertexArray(0);\r
94   }\r
95   GLuint VAO = 0;\r
96 };\r
97 \r
98 struct freecam {\r
99   glm::vec3 pos = glm::vec3(0, 0, -1);\r
100   glm::vec2 rot = glm::vec2(0, 0);\r
101 \r
102   void update(sf::Window &window) {\r
103     int mouseDeltaX = sf::Mouse::getPosition(window).x - window.getSize().x / 2;\r
104     int mouseDeltaY = sf::Mouse::getPosition(window).y - window.getSize().y / 2;\r
105 \r
106     rot.x += mouseDeltaX;\r
107     rot.y += mouseDeltaY;\r
108 \r
109     forward = glm::rotate(glm::vec3(0, 0, 1), rot.y / angleFactor, glm::vec3(1, 0, 0));\r
110     forward = glm::rotate(forward, -rot.x / angleFactor, glm::vec3(0, 1, 0));\r
111 \r
112     glm::vec3 left = glm::rotate(glm::vec3(0, 0, 1), -rot.x / angleFactor + glm::radians(90.0f), glm::vec3(0, 1, 0));\r
113 \r
114     if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::LShift))\r
115       moveFactor = 200;\r
116     else\r
117       moveFactor = 20;\r
118 \r
119     if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))\r
120       pos += forward / moveFactor;\r
121     if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))\r
122       pos -= forward / moveFactor;\r
123     if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))\r
124       pos += left / moveFactor;\r
125     if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))\r
126       pos -= left / moveFactor;\r
127 \r
128     limit();\r
129   }\r
130 \r
131   void limit() {\r
132     rot.x = fmod(rot.x, glm::radians(360.0f) * angleFactor);\r
133     rot.y = fmod(rot.y, glm::radians(360.0f) * angleFactor);\r
134   }\r
135 \r
136   glm::mat4 getViewMatrix() {\r
137     forward = glm::rotate(glm::vec3(0, 0, 1), rot.y / angleFactor, glm::vec3(1, 0, 0));\r
138     forward = glm::rotate(forward, -rot.x / angleFactor, glm::vec3(0, 1, 0));\r
139     glm::mat4 result = glm::lookAt(pos, pos + forward, up);\r
140     return result;\r
141   }\r
142 \r
143 private:\r
144   glm::vec3 forward = glm::vec3(0, 0, 1);\r
145   glm::vec3 up = glm::vec3(0, 1, 0);\r
146 \r
147   const float angleFactor = 200;\r
148   float moveFactor = 20;\r
149 };\r
150 \r
151 struct arccam {\r
152   glm::vec2 rot = glm::vec2(0, 0);\r
153   float radius = 1;\r
154 \r
155   void update(sf::Window &window) {\r
156     int mouseDeltaX = sf::Mouse::getPosition(window).x - window.getSize().x / 2;\r
157     int mouseDeltaY = sf::Mouse::getPosition(window).y - window.getSize().y / 2;\r
158 \r
159     rot.x += mouseDeltaX;\r
160     rot.y += mouseDeltaY;\r
161 \r
162     limit(-89, 89);\r
163   }\r
164 \r
165   void limit(float minY, float maxY) {\r
166     float angleX = rot.x / angleFactor;\r
167     float angleY = rot.y / angleFactor;\r
168 \r
169     rot.x = fmod(rot.x, glm::radians(360.0f) * angleFactor);\r
170 \r
171     if (angleY > glm::radians(maxY))\r
172       rot.y = glm::radians(maxY) * angleFactor;\r
173     if (angleY < glm::radians(minY))\r
174       rot.y = glm::radians(minY) * angleFactor;\r
175   }\r
176 \r
177   glm::vec3 getPos() {\r
178     float angle = rot.y / angleFactor;\r
179   \r
180     float camY = sin(angle) * exp(radius);\r
181     float camZ = cos(angle) * exp(radius);\r
182 \r
183     glm::vec3 result(0.0, camY, camZ);\r
184     return glm::rotate(result, -rot.x / angleFactor, glm::vec3(0, 1, 0));\r
185   }\r
186 \r
187   glm::mat4 getViewMatrix() {\r
188     float angle = rot.y / angleFactor;\r
189   \r
190     float camY = sin(angle) * exp(radius);\r
191     float camZ = cos(angle) * exp(radius);\r
192     glm::mat4 result = glm::lookAt(glm::vec3(0.0, camY, camZ), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));\r
193     result = glm::rotate(result, rot.x / angleFactor, glm::vec3(0, 1, 0));\r
194 \r
195     return result;\r
196   }\r
197 \r
198 private:\r
199   const float angleFactor = 200;\r
200 };\r
201 \r
202 std::string readFile(std::string filename) {\r
203   std::ifstream ifs(filename, std::ios::binary);\r
204   std::string result, line;\r
205   while (std::getline(ifs, line))\r
206     result += line + "\n";\r
207 \r
208   return result;\r
209 }\r
210 \r
211 model loadModel(const std::string &filename) {\r
212   Assimp::Importer importer;\r
213 \r
214   const aiScene *scene = importer.ReadFile(\r
215       filename, aiProcess_CalcTangentSpace | aiProcess_Triangulate |\r
216                     aiProcess_SortByPType | aiProcess_GenSmoothNormals);\r
217 \r
218   model result;\r
219 \r
220   for (int i = 0; i < scene->mMeshes[0]->mNumVertices; i++) {\r
221     aiVector3D v = scene->mMeshes[0]->mVertices[i];\r
222     aiVector3D n = scene->mMeshes[0]->mNormals[i];\r
223     aiVector3D t = scene->mMeshes[0]->mTextureCoords[0][i];\r
224     result.vertices.push_back(v.x * 100);\r
225     result.vertices.push_back(v.y * 100);\r
226     result.vertices.push_back(v.z * 100);\r
227     result.vertices.push_back(n.x);\r
228     result.vertices.push_back(n.y);\r
229     result.vertices.push_back(n.z);\r
230     result.vertices.push_back(t.x);\r
231     result.vertices.push_back(t.y);\r
232   }\r
233 \r
234   for (int i = 0; i < scene->mMeshes[0]->mNumFaces; i++) {\r
235     aiFace f = scene->mMeshes[0]->mFaces[i];\r
236     for (int j = 0; j < f.mNumIndices; j++) {\r
237       result.indices.push_back(f.mIndices[j]);\r
238     }\r
239   }\r
240 \r
241   return result;\r
242 }\r
243 \r
244 GLuint compileShaders(const char *vertFilename, const char *fragFilename) {\r
245   GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);\r
246   std::string vertSource = readFile(vertFilename);\r
247   const char *vertAddr = vertSource.c_str();\r
248   glShaderSource(vertShader, 1, &vertAddr, NULL);\r
249   glCompileShader(vertShader);\r
250 \r
251   int success;\r
252   char infoLog[512];\r
253   glGetShaderiv(vertShader, GL_COMPILE_STATUS, &success);\r
254   if (!success) {\r
255     glGetShaderInfoLog(vertShader, 512, NULL, infoLog);\r
256     printf("Error compiling vertex shader(%s): %s\n", vertFilename, infoLog);\r
257   }\r
258 \r
259   GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);\r
260   std::string fragSource = readFile(fragFilename);\r
261   const char *fragAddr = fragSource.c_str();\r
262   glShaderSource(fragShader, 1, &fragAddr, NULL);\r
263   glCompileShader(fragShader);\r
264 \r
265   glGetShaderiv(fragShader, GL_COMPILE_STATUS, &success);\r
266   if (!success) {\r
267     glGetShaderInfoLog(fragShader, 512, NULL, infoLog);\r
268     printf("Error compiling fragment shader(%s): %s\n", fragFilename, infoLog);\r
269   }\r
270 \r
271   // Link Shader Program\r
272 \r
273   GLuint shaderProgram = glCreateProgram();\r
274   glAttachShader(shaderProgram, vertShader);\r
275   glAttachShader(shaderProgram, fragShader);\r
276   glLinkProgram(shaderProgram);\r
277 \r
278   glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);\r
279   if (!success) {\r
280     glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);\r
281     printf("Error linking shader program: %s\n", infoLog);\r
282   }\r
283 \r
284   glDeleteShader(vertShader);\r
285   glDeleteShader(fragShader);\r
286 \r
287   return shaderProgram;\r
288 }\r
289 \r
290 struct framebuffer {\r
291   framebuffer(const char *vertFilename, const char *fragFilename, int width, int height) {\r
292     glGenFramebuffers(1, &fbo);\r
293     glBindFramebuffer(GL_FRAMEBUFFER, fbo);\r
294     \r
295     glGenTextures(1, &renderTexture);\r
296     glBindTexture(GL_TEXTURE_2D, renderTexture);\r
297     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);\r
298     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
299     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
300     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);\r
301     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);\r
302     //glBindTexture(GL_TEXTURE_2D, 0);\r
303     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTexture, 0);\r
304 \r
305     glGenRenderbuffers(1, &rbo);\r
306     glBindRenderbuffer(GL_RENDERBUFFER, rbo);\r
307     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);\r
308     //glBindRenderbuffer(GL_RENDERBUFFER, 0);\r
309     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);\r
310 \r
311     if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) {\r
312       printf("Successfully created framebuffer\n");\r
313     }\r
314     glBindFramebuffer(GL_FRAMEBUFFER, 0);\r
315     \r
316     screenShaderProgram = compileShaders(vertFilename, fragFilename);\r
317     glUseProgram(screenShaderProgram);\r
318     glUniform1i(glGetUniformLocation(screenShaderProgram, "screenTexture"), 0);\r
319 \r
320     // Screen VAO\r
321     \r
322     glGenBuffers(1, &screenVBO);\r
323 \r
324     glGenVertexArrays(1, &screenVAO);\r
325 \r
326     glBindVertexArray(screenVAO);\r
327 \r
328     float screenVerts[] = {\r
329       -1.0f, +1.0f, +0.0f, +1.0f,\r
330       -1.0f, -1.0f, +0.0f, +0.0f,\r
331       +1.0f, -1.0f, +1.0f, +0.0f,\r
332   \r
333       -1.0f, +1.0f, +0.0f, +1.0f,\r
334       +1.0f, -1.0f, +1.0f, +0.0f,\r
335       +1.0f, +1.0f, +1.0f, +1.0f,\r
336     };\r
337 \r
338     glBindBuffer(GL_ARRAY_BUFFER, screenVBO);\r
339     glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4,\r
340                 screenVerts, GL_STATIC_DRAW);\r
341 \r
342     glEnableVertexAttribArray(0);\r
343     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (void*)(0));\r
344     glEnableVertexAttribArray(1);\r
345     glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (void*)(sizeof(float) * 2));\r
346 \r
347     glBindVertexArray(0);\r
348   }\r
349   ~framebuffer() {\r
350     glDeleteFramebuffers(1, &fbo);\r
351   }\r
352   \r
353   GLuint fbo;\r
354   GLuint renderTexture;\r
355   GLuint rbo;\r
356   GLuint screenShaderProgram;\r
357   GLuint screenVBO;\r
358   GLuint screenVAO;\r
359 };\r
360 \r
361 int main() {\r
362   // Window Setup\r
363 \r
364   const int width = 1600, height = 900;\r
365 \r
366   sf::ContextSettings settings;\r
367   settings.depthBits = 24;\r
368   settings.antialiasingLevel = 0;\r
369   settings.majorVersion = 4;\r
370   settings.minorVersion = 6;\r
371 \r
372   sf::RenderWindow window(sf::VideoMode(1600, 900), "Subsurface Scattering",\r
373                     sf::Style::Default, settings);\r
374   window.setVerticalSyncEnabled(true);\r
375 \r
376   ImGui::SFML::Init(window);\r
377 \r
378   // Initialize GLEW\r
379 \r
380   if (glewInit() != GLEW_OK) {\r
381   }\r
382 \r
383   GLuint shaderProgramIrradiance = compileShaders("shaders/ts_vert_irradiance.glsl", "shaders/ts_frag_irradiance.glsl");\r
384   GLuint shaderProgramCombine = compileShaders("shaders/ts_vert.glsl", "shaders/ts_frag.glsl");\r
385 \r
386   //model m = loadModel("models/Isotrop-upperjaw.ply");\r
387   model m = loadModel("models/african_head/african_head.obj");\r
388 \r
389   arccam arcCam;\r
390   freecam freeCam;\r
391 \r
392   // MVP\r
393 \r
394   glm::mat4 model = glm::scale(glm::mat4(1.0f), glm::vec3(0.01f, 0.01f, 0.01f));\r
395 \r
396   glm::mat4 view, lightView;\r
397 \r
398   glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)window.getSize().x / window.getSize().y, 0.001f, 1000.0f);\r
399   glm::mat4 lightProj = glm::perspective(glm::radians(90.0f), (float)window.getSize().x / window.getSize().y, 0.001f, 1000.0f);\r
400 \r
401   // Framebuffer\r
402   framebuffer fb_shadowmap("shaders/fbo_vert.glsl", "shaders/fbo_frag.glsl", width, height);\r
403   framebuffer fb_irradiance("shaders/fbo_vert.glsl", "shaders/fbo_frag.glsl", width, height);\r
404 \r
405   // Config\r
406 \r
407   const struct {\r
408     bool wireframe = false;\r
409     bool freecam = false;\r
410     int renderState = 1;\r
411     float color[3] = { 0.7f, 0.4f, 0.4f };\r
412     glm::vec3 lightPos = glm::vec3(0.0f, 0.0f, 0.25f);\r
413     float transmittanceScale = 0.005f;\r
414     float powBase = 2.718;\r
415     float powFactor = 1;\r
416   } DefaultOptions;\r
417 \r
418   auto options = DefaultOptions;\r
419 \r
420   sf::Clock deltaClock;\r
421 \r
422   bool prevMouse = false;\r
423 \r
424   bool running = true;\r
425   while (running) {\r
426     // Events\r
427 \r
428     sf::Event event;\r
429     while (window.pollEvent(event)) {\r
430       ImGui::SFML::ProcessEvent(event);\r
431 \r
432       if (event.type == sf::Event::EventType::Closed) {\r
433         running = false;\r
434       } else if (event.type == sf::Event::EventType::Resized) {\r
435         glViewport(0, 0, event.size.width, event.size.height);\r
436       } else if (event.type == sf::Event::EventType::KeyReleased) {\r
437         using keys = sf::Keyboard;\r
438         switch (event.key.code) {\r
439         case keys::Escape:\r
440           running = false;\r
441           break;\r
442         }\r
443       } else if (event.type == sf::Event::EventType::MouseWheelScrolled) {\r
444         if (! options.freecam) {\r
445           arcCam.radius -= event.mouseWheelScroll.delta / 5.0f;\r
446         }\r
447       }\r
448     }\r
449 \r
450     // Update\r
451 \r
452     if (sf::Mouse::isButtonPressed(sf::Mouse::Right)) {\r
453       window.setMouseCursorVisible(false);\r
454 \r
455       if (prevMouse) {\r
456         if (options.freecam)\r
457           freeCam.update(window);\r
458         else\r
459           arcCam.update(window);\r
460       }\r
461 \r
462 \r
463       sf::Mouse::setPosition(sf::Vector2i(\r
464           window.getSize().x / 2,\r
465           window.getSize().y / 2\r
466         ), window);  \r
467     } else {\r
468       window.setMouseCursorVisible(true);\r
469     }\r
470 \r
471     prevMouse = sf::Mouse::isButtonPressed(sf::Mouse::Right);\r
472 \r
473     // Render Shadowmap\r
474 \r
475     glBindFramebuffer(GL_FRAMEBUFFER, fb_irradiance.fbo);\r
476     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);\r
477     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);\r
478     glEnable(GL_DEPTH_TEST);\r
479 \r
480     if (options.wireframe)\r
481       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);\r
482     else\r
483       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);\r
484 \r
485     glUseProgram(shaderProgramIrradiance);\r
486     \r
487     if (options.freecam)\r
488       view = freeCam.getViewMatrix();\r
489     else\r
490       view = arcCam.getViewMatrix();\r
491     \r
492     glUniformMatrix4fv(\r
493       glGetUniformLocation(shaderProgramIrradiance, "model"),\r
494       1, GL_FALSE, glm::value_ptr(model));\r
495     glUniformMatrix4fv(\r
496       glGetUniformLocation(shaderProgramIrradiance, "view"),\r
497       1, GL_FALSE, glm::value_ptr(view));\r
498     glUniformMatrix4fv(\r
499       glGetUniformLocation(shaderProgramIrradiance, "projection"),\r
500       1, GL_FALSE, glm::value_ptr(proj));\r
501 \r
502     glUniform3fv(\r
503       glGetUniformLocation(shaderProgramIrradiance, "objectColor"),\r
504       1, options.color);\r
505     glUniform3f(\r
506       glGetUniformLocation(shaderProgramIrradiance, "lightColor"),\r
507       1.0f, 1.0f, 1.0f);\r
508     glUniform3fv(\r
509       glGetUniformLocation(shaderProgramIrradiance, "lightPos"),\r
510       1, glm::value_ptr(options.lightPos));\r
511     glUniform3fv(\r
512       glGetUniformLocation(shaderProgramIrradiance, "viewPos"),\r
513       1, glm::value_ptr(options.freecam ? freeCam.pos : arcCam.getPos()));\r
514 \r
515     m.draw();\r
516 \r
517     \r
518 \r
519     // Render fbo to screen\r
520 \r
521     glBindFramebuffer(GL_FRAMEBUFFER, 0);\r
522     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);\r
523     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);\r
524     glEnable(GL_DEPTH_TEST);\r
525 \r
526     if (options.wireframe)\r
527       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);\r
528     else\r
529       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);\r
530 \r
531     glUseProgram(shaderProgramCombine);\r
532     \r
533     if (options.freecam)\r
534       view = freeCam.getViewMatrix();\r
535     else\r
536       view = arcCam.getViewMatrix();\r
537     \r
538     glUniformMatrix4fv(\r
539       glGetUniformLocation(shaderProgramCombine, "model"),\r
540       1, GL_FALSE, glm::value_ptr(model));\r
541     glUniformMatrix4fv(\r
542       glGetUniformLocation(shaderProgramCombine, "view"),\r
543       1, GL_FALSE, glm::value_ptr(view));\r
544     glUniformMatrix4fv(\r
545       glGetUniformLocation(shaderProgramCombine, "projection"),\r
546       1, GL_FALSE, glm::value_ptr(proj));\r
547 \r
548     glUniform3fv(\r
549       glGetUniformLocation(shaderProgramCombine, "objectColor"),\r
550       1, options.color);\r
551     glUniform3f(\r
552       glGetUniformLocation(shaderProgramCombine, "lightColor"),\r
553       1.0f, 1.0f, 1.0f);\r
554     glUniform3fv(\r
555       glGetUniformLocation(shaderProgramCombine, "lightPos"),\r
556       1, glm::value_ptr(options.lightPos));\r
557     glUniform3fv(\r
558       glGetUniformLocation(shaderProgramCombine, "viewPos"),\r
559       1, glm::value_ptr(options.freecam ? freeCam.pos : arcCam.getPos()));\r
560 \r
561     glUniform1i(glGetUniformLocation(shaderProgramCombine, "screenWidth"), window.getSize().x);\r
562     glUniform1i(glGetUniformLocation(shaderProgramCombine, "screenHeight"), window.getSize().y);\r
563     glUniform1i(glGetUniformLocation(shaderProgramCombine, "renderState"), options.renderState);\r
564     glUniform2fv(glGetUniformLocation(shaderProgramCombine, "samplePositions"), 13, samplePositions);\r
565     glUniform3fv(glGetUniformLocation(shaderProgramCombine, "sampleWeights"), 13, sampleWeights);\r
566     glUniform1f(glGetUniformLocation(shaderProgramCombine, "transmittanceScale"), options.transmittanceScale);\r
567       \r
568     glUniform1i(glGetUniformLocation(shaderProgramCombine, "irradianceTexture"), 0);\r
569     glActiveTexture(GL_TEXTURE0 + 0);\r
570     glBindTexture(GL_TEXTURE_2D, fb_irradiance.renderTexture);\r
571 \r
572     // glBindVertexArray(fb_irradiance.screenVAO);\r
573     // glUniform1i(glGetUniformLocation(fb_irradiance.screenShaderProgram, "shadowmapTexture"), 0);\r
574     // glActiveTexture(GL_TEXTURE0 + 0);\r
575     // glBindTexture(GL_TEXTURE_2D, fb_irradiance.renderTexture);\r
576     // glDrawArrays(GL_TRIANGLES, 0, 6);\r
577     // glBindVertexArray(0);\r
578 \r
579     m.draw();\r
580 \r
581 \r
582 \r
583     ImGui::SFML::Update(window, deltaClock.restart());\r
584 \r
585     ImGui::Begin("Options");\r
586     ImGui::Checkbox("Wireframe", &options.wireframe);\r
587     ImGui::Checkbox("Free Cam", &options.freecam);\r
588     ImGui::InputInt("Render State", &options.renderState);\r
589     ImGui::DragFloat3("Color", options.color, 0.01, 0, 1);\r
590     ImGui::DragFloat("Transmittance Scale", &options.transmittanceScale, 0.0001f, 0, 0.3);\r
591     ImGui::DragFloat("Pow Base", &options.powBase, 0.01f, 0, 4);\r
592     ImGui::DragFloat("Pow Factor", &options.powFactor, 0.01f, 0, 3);\r
593     ImGui::DragFloat3("Light Pos", glm::value_ptr(options.lightPos), 0.01, -5, 5);\r
594     if (options.freecam) {\r
595       ImGui::LabelText("Position", "%f %f %f", freeCam.pos.x, freeCam.pos.y, freeCam.pos.z);\r
596       ImGui::LabelText("Rotation", "%f %f", freeCam.rot.x, freeCam.rot.y);\r
597       if (ImGui::Button("Reset")) {\r
598         freeCam.pos = glm::vec3(0, 0, -1);\r
599         freeCam.rot = glm::vec2(0);\r
600         options = DefaultOptions;\r
601       }\r
602     } else {\r
603       ImGui::LabelText("Rotation", "%f %f", arcCam.rot.x, arcCam.rot.y);\r
604       ImGui::DragFloat("Radius", &arcCam.radius, 0.01f, -1.0f, 1.0f);\r
605       if (ImGui::Button("Reset")) {\r
606         arcCam.rot = glm::vec2(0);\r
607         arcCam.radius = 1;\r
608         options = DefaultOptions;\r
609       }\r
610     }\r
611     ImGui::End();\r
612 \r
613     ImGui::SFML::Render(window);\r
614 \r
615     window.display();\r
616   }\r
617 \r
618   return 0;\r
619 }\r