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