6 #define GLM_ENABLE_EXPERIMENTAL
\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
13 #include <SFML/OpenGL.hpp>
\r
14 #include <SFML/Graphics.hpp>
\r
17 #include <imgui-SFML.h>
\r
19 #include <assimp/Importer.hpp>
\r
20 #include <assimp/postprocess.h>
\r
21 #include <assimp/scene.h>
\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
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
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
68 float translucencySampleVariances[] = {
\r
77 float translucencySampleWeights[] = {
\r
78 0.233, 0.455, 0.649,
\r
79 0.100, 0.336, 0.344,
\r
81 0.113, 0.007, 0.007,
\r
87 std::vector<float> vertices;
\r
88 std::vector<GLuint> indices;
\r
91 if (VAO == 0) initVAO();
\r
92 glBindVertexArray(VAO);
\r
93 glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
\r
94 glBindVertexArray(0);
\r
100 glGenBuffers(1, &VBO);
\r
103 glGenBuffers(1, &EBO);
\r
105 glGenVertexArrays(1, &VAO);
\r
107 glBindVertexArray(VAO);
\r
109 glBindBuffer(GL_ARRAY_BUFFER, VBO);
\r
110 glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(),
\r
111 vertices.data(), GL_STATIC_DRAW);
\r
113 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
\r
114 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indices.size(),
\r
115 indices.data(), GL_STATIC_DRAW);
\r
117 glEnableVertexAttribArray(0);
\r
118 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (void*)(0));
\r
119 glEnableVertexAttribArray(1);
\r
120 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (void*)(sizeof(float) * 3));
\r
122 glBindVertexArray(0);
\r
128 glm::vec3 pos = glm::vec3(0, 0, -1);
\r
129 glm::vec2 rot = glm::vec2(0, 0);
\r
131 void update(sf::Window &window) {
\r
132 int mouseDeltaX = sf::Mouse::getPosition(window).x - window.getSize().x / 2;
\r
133 int mouseDeltaY = sf::Mouse::getPosition(window).y - window.getSize().y / 2;
\r
135 rot.x += mouseDeltaX;
\r
136 rot.y += mouseDeltaY;
\r
138 forward = glm::rotate(glm::vec3(0, 0, 1), rot.y / angleFactor, glm::vec3(1, 0, 0));
\r
139 forward = glm::rotate(forward, -rot.x / angleFactor, glm::vec3(0, 1, 0));
\r
141 glm::vec3 left = glm::rotate(glm::vec3(0, 0, 1), -rot.x / angleFactor + glm::radians(90.0f), glm::vec3(0, 1, 0));
\r
143 if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::LShift))
\r
148 if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
\r
149 pos += forward / moveFactor;
\r
150 if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
\r
151 pos -= forward / moveFactor;
\r
152 if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
\r
153 pos += left / moveFactor;
\r
154 if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
\r
155 pos -= left / moveFactor;
\r
161 rot.x = fmod(rot.x, glm::radians(360.0f) * angleFactor);
\r
162 rot.y = fmod(rot.y, glm::radians(360.0f) * angleFactor);
\r
165 glm::mat4 getViewMatrix() {
\r
166 forward = glm::rotate(glm::vec3(0, 0, 1), rot.y / angleFactor, glm::vec3(1, 0, 0));
\r
167 forward = glm::rotate(forward, -rot.x / angleFactor, glm::vec3(0, 1, 0));
\r
168 glm::mat4 result = glm::lookAt(pos, pos + forward, up);
\r
173 glm::vec3 forward = glm::vec3(0, 0, 1);
\r
174 glm::vec3 up = glm::vec3(0, 1, 0);
\r
176 const float angleFactor = 200;
\r
177 float moveFactor = 20;
\r
181 glm::vec2 rot = glm::vec2(0, 0);
\r
184 void update(sf::Window &window) {
\r
185 int mouseDeltaX = sf::Mouse::getPosition(window).x - window.getSize().x / 2;
\r
186 int mouseDeltaY = sf::Mouse::getPosition(window).y - window.getSize().y / 2;
\r
188 rot.x += mouseDeltaX;
\r
189 rot.y += mouseDeltaY;
\r
194 void limit(float minY, float maxY) {
\r
195 float angleX = rot.x / angleFactor;
\r
196 float angleY = rot.y / angleFactor;
\r
198 rot.x = fmod(rot.x, glm::radians(360.0f) * angleFactor);
\r
200 if (angleY > glm::radians(maxY))
\r
201 rot.y = glm::radians(maxY) * angleFactor;
\r
202 if (angleY < glm::radians(minY))
\r
203 rot.y = glm::radians(minY) * angleFactor;
\r
206 glm::vec3 getPos() {
\r
207 float angle = rot.y / angleFactor;
\r
209 float camY = sin(angle) * exp(radius);
\r
210 float camZ = cos(angle) * exp(radius);
\r
212 glm::vec3 result(0.0, camY, camZ);
\r
213 return glm::rotate(result, -rot.x / angleFactor, glm::vec3(0, 1, 0));
\r
216 glm::mat4 getViewMatrix() {
\r
217 float angle = rot.y / angleFactor;
\r
219 float camY = sin(angle) * exp(radius);
\r
220 float camZ = cos(angle) * exp(radius);
\r
221 glm::mat4 result = glm::lookAt(glm::vec3(0.0, camY, camZ), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
\r
222 result = glm::rotate(result, rot.x / angleFactor, glm::vec3(0, 1, 0));
\r
228 const float angleFactor = 200;
\r
231 std::string readFile(std::string filename) {
\r
232 std::ifstream ifs(filename, std::ios::binary);
\r
233 std::string result, line;
\r
234 while (std::getline(ifs, line))
\r
235 result += line + "\n";
\r
240 model loadModel(const std::string &filename) {
\r
241 Assimp::Importer importer;
\r
243 const aiScene *scene = importer.ReadFile(
\r
244 filename, aiProcess_CalcTangentSpace | aiProcess_Triangulate |
\r
245 aiProcess_SortByPType | aiProcess_GenSmoothNormals |
\r
246 aiProcess_GenUVCoords);
\r
250 printf("uv channels: %d\n", scene->mMeshes[0]->GetNumUVChannels());
\r
252 for (int i = 0; i < scene->mMeshes[0]->mNumVertices; i++) {
\r
253 aiVector3D v = scene->mMeshes[0]->mVertices[i];
\r
254 aiVector3D n = scene->mMeshes[0]->mNormals[i];
\r
255 result.vertices.push_back(v.x*100);
\r
256 result.vertices.push_back(v.y*100);
\r
257 result.vertices.push_back(v.z*100);
\r
258 result.vertices.push_back(n.x);
\r
259 result.vertices.push_back(n.y);
\r
260 result.vertices.push_back(n.z);
\r
263 for (int i = 0; i < scene->mMeshes[0]->mNumFaces; i++) {
\r
264 aiFace f = scene->mMeshes[0]->mFaces[i];
\r
265 for (int j = 0; j < f.mNumIndices; j++) {
\r
266 result.indices.push_back(f.mIndices[j]);
\r
273 GLuint compileShaders(const char *vertFilename, const char *fragFilename) {
\r
274 GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);
\r
275 std::string vertSource = readFile(vertFilename);
\r
276 const char *vertAddr = vertSource.c_str();
\r
277 glShaderSource(vertShader, 1, &vertAddr, NULL);
\r
278 glCompileShader(vertShader);
\r
282 glGetShaderiv(vertShader, GL_COMPILE_STATUS, &success);
\r
284 glGetShaderInfoLog(vertShader, 512, NULL, infoLog);
\r
285 printf("Error compiling vertex shader(%s): %s\n", vertFilename, infoLog);
\r
288 GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);
\r
289 std::string fragSource = readFile(fragFilename);
\r
290 const char *fragAddr = fragSource.c_str();
\r
291 glShaderSource(fragShader, 1, &fragAddr, NULL);
\r
292 glCompileShader(fragShader);
\r
294 glGetShaderiv(fragShader, GL_COMPILE_STATUS, &success);
\r
296 glGetShaderInfoLog(fragShader, 512, NULL, infoLog);
\r
297 printf("Error compiling fragment shader(%s): %s\n", fragFilename, infoLog);
\r
300 // Link Shader Program
\r
302 GLuint shaderProgram = glCreateProgram();
\r
303 glAttachShader(shaderProgram, vertShader);
\r
304 glAttachShader(shaderProgram, fragShader);
\r
305 glLinkProgram(shaderProgram);
\r
307 glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
\r
309 glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
\r
310 printf("Error linking shader program: %s\n", infoLog);
\r
313 glDeleteShader(vertShader);
\r
314 glDeleteShader(fragShader);
\r
316 return shaderProgram;
\r
319 struct framebuffer {
\r
320 framebuffer(const char *vertFilename, const char *fragFilename, int width, int height) {
\r
321 glGenFramebuffers(1, &fbo);
\r
322 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
\r
324 glGenTextures(1, &renderTexture);
\r
325 glBindTexture(GL_TEXTURE_2D, renderTexture);
\r
326 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
\r
327 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
328 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
329 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
\r
330 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
\r
331 //glBindTexture(GL_TEXTURE_2D, 0);
\r
332 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTexture, 0);
\r
334 glGenRenderbuffers(1, &rbo);
\r
335 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
\r
336 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
\r
337 //glBindRenderbuffer(GL_RENDERBUFFER, 0);
\r
338 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
\r
340 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) {
\r
341 printf("Successfully created framebuffer\n");
\r
343 glBindFramebuffer(GL_FRAMEBUFFER, 0);
\r
345 screenShaderProgram = compileShaders(vertFilename, fragFilename);
\r
346 glUseProgram(screenShaderProgram);
\r
347 glUniform1i(glGetUniformLocation(screenShaderProgram, "screenTexture"), 0);
\r
351 glGenBuffers(1, &screenVBO);
\r
353 glGenVertexArrays(1, &screenVAO);
\r
355 glBindVertexArray(screenVAO);
\r
357 float screenVerts[] = {
\r
358 -1.0f, +1.0f, +0.0f, +1.0f,
\r
359 -1.0f, -1.0f, +0.0f, +0.0f,
\r
360 +1.0f, -1.0f, +1.0f, +0.0f,
\r
362 -1.0f, +1.0f, +0.0f, +1.0f,
\r
363 +1.0f, -1.0f, +1.0f, +0.0f,
\r
364 +1.0f, +1.0f, +1.0f, +1.0f,
\r
367 glBindBuffer(GL_ARRAY_BUFFER, screenVBO);
\r
368 glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4,
\r
369 screenVerts, GL_STATIC_DRAW);
\r
371 glEnableVertexAttribArray(0);
\r
372 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (void*)(0));
\r
373 glEnableVertexAttribArray(1);
\r
374 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (void*)(sizeof(float) * 2));
\r
376 glBindVertexArray(0);
\r
379 glDeleteFramebuffers(1, &fbo);
\r
383 GLuint renderTexture;
\r
385 GLuint screenShaderProgram;
\r
393 const int width = 1600, height = 900;
\r
395 sf::ContextSettings settings;
\r
396 settings.depthBits = 24;
\r
397 settings.antialiasingLevel = 0;
\r
398 settings.majorVersion = 4;
\r
399 settings.minorVersion = 6;
\r
401 sf::RenderWindow window(sf::VideoMode(1600, 900), "Subsurface Scattering",
\r
402 sf::Style::Default, settings);
\r
403 window.setVerticalSyncEnabled(true);
\r
405 ImGui::SFML::Init(window);
\r
409 if (glewInit() != GLEW_OK) {
\r
412 GLuint shaderProgramShadowmap = compileShaders("shaders/vert_shadowmap.glsl", "shaders/frag_shadowmap.glsl");
\r
413 GLuint shaderProgramIrradiance = compileShaders("shaders/vert_irradiance.glsl", "shaders/frag_irradiance.glsl");
\r
415 //model m = loadModel("models/Isotrop-upperjaw.ply");
\r
416 model m = loadModel("models/african_head/african_head.obj");
\r
423 glm::mat4 model = glm::scale(glm::mat4(1.0f), glm::vec3(0.01f, 0.01f, 0.01f));
\r
425 glm::mat4 view, lightView;
\r
427 glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)window.getSize().x / window.getSize().y, 0.001f, 1000.0f);
\r
428 glm::mat4 lightProj = glm::perspective(glm::radians(90.0f), (float)window.getSize().x / window.getSize().y, 0.001f, 1000.0f);
\r
431 framebuffer fb_shadowmap("shaders/fbo_vert.glsl", "shaders/fbo_frag.glsl", width, height);
\r
432 framebuffer fb_irradiance("shaders/fbo_vert.glsl", "shaders/fbo_frag.glsl", width, height);
\r
437 bool wireframe = false;
\r
438 bool freecam = false;
\r
439 int renderState = 2;
\r
440 float color[3] = { 0.7f, 0.4f, 0.4f };
\r
441 glm::vec3 lightPos = glm::vec3(0.0f, 0.0f, 0.03f);
\r
442 float transmittanceScale = 0.005f;
\r
443 float powBase = 2.718;
\r
444 float powFactor = 1;
\r
447 auto options = DefaultOptions;
\r
449 sf::Clock deltaClock;
\r
451 bool prevMouse = false;
\r
453 bool running = true;
\r
458 while (window.pollEvent(event)) {
\r
459 ImGui::SFML::ProcessEvent(event);
\r
461 if (event.type == sf::Event::EventType::Closed) {
\r
463 } else if (event.type == sf::Event::EventType::Resized) {
\r
464 glViewport(0, 0, event.size.width, event.size.height);
\r
465 } else if (event.type == sf::Event::EventType::KeyReleased) {
\r
466 using keys = sf::Keyboard;
\r
467 switch (event.key.code) {
\r
472 } else if (event.type == sf::Event::EventType::MouseWheelScrolled) {
\r
473 if (! options.freecam) {
\r
474 arcCam.radius -= event.mouseWheelScroll.delta / 5.0f;
\r
481 if (sf::Mouse::isButtonPressed(sf::Mouse::Right)) {
\r
482 window.setMouseCursorVisible(false);
\r
485 if (options.freecam)
\r
486 freeCam.update(window);
\r
488 arcCam.update(window);
\r
492 sf::Mouse::setPosition(sf::Vector2i(
\r
493 window.getSize().x / 2,
\r
494 window.getSize().y / 2
\r
497 window.setMouseCursorVisible(true);
\r
500 prevMouse = sf::Mouse::isButtonPressed(sf::Mouse::Right);
\r
502 // Render Shadowmap
\r
504 glClampColor(GL_CLAMP_READ_COLOR, GL_FALSE);
\r
505 glClampColor(GL_CLAMP_VERTEX_COLOR, GL_FALSE);
\r
506 glClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
\r
508 glBindFramebuffer(GL_FRAMEBUFFER, fb_shadowmap.fbo);
\r
509 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
\r
510 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
\r
511 glEnable(GL_DEPTH_TEST);
\r
513 if (options.wireframe)
\r
514 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
\r
516 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
\r
518 glUseProgram(shaderProgramShadowmap);
\r
520 if (options.freecam)
\r
521 view = freeCam.getViewMatrix();
\r
523 view = arcCam.getViewMatrix();
\r
525 lightView = glm::lookAt(options.lightPos, glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
\r
527 glUniformMatrix4fv(
\r
528 glGetUniformLocation(shaderProgramShadowmap, "model"),
\r
529 1, GL_FALSE, glm::value_ptr(model));
\r
530 glUniformMatrix4fv(
\r
531 glGetUniformLocation(shaderProgramShadowmap, "lightView"),
\r
532 1, GL_FALSE, glm::value_ptr(lightView));
\r
533 glUniformMatrix4fv(
\r
534 glGetUniformLocation(shaderProgramShadowmap, "projection"),
\r
535 1, GL_FALSE, glm::value_ptr(lightProj));
\r
538 glGetUniformLocation(shaderProgramShadowmap, "lightPos"),
\r
539 1, glm::value_ptr(options.lightPos));
\r
543 // Render irradiance
\r
545 glBindFramebuffer(GL_FRAMEBUFFER, fb_irradiance.fbo);
\r
546 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
\r
547 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
\r
548 glEnable(GL_DEPTH_TEST);
\r
550 if (options.wireframe)
\r
551 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
\r
553 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
\r
555 glUseProgram(shaderProgramIrradiance);
\r
557 glUniformMatrix4fv(
\r
558 glGetUniformLocation(shaderProgramIrradiance, "model"),
\r
559 1, GL_FALSE, glm::value_ptr(model));
\r
560 glUniformMatrix4fv(
\r
561 glGetUniformLocation(shaderProgramIrradiance, "view"),
\r
562 1, GL_FALSE, glm::value_ptr(view));
\r
563 glUniformMatrix4fv(
\r
564 glGetUniformLocation(shaderProgramIrradiance, "lightView"),
\r
565 1, GL_FALSE, glm::value_ptr(lightView));
\r
566 glUniformMatrix4fv(
\r
567 glGetUniformLocation(shaderProgramIrradiance, "lightViewInv"),
\r
568 1, GL_FALSE, glm::value_ptr(glm::inverse(lightView)));
\r
569 glUniformMatrix4fv(
\r
570 glGetUniformLocation(shaderProgramIrradiance, "projection"),
\r
571 1, GL_FALSE, glm::value_ptr(proj));
\r
572 glUniformMatrix4fv(
\r
573 glGetUniformLocation(shaderProgramIrradiance, "lightProjection"),
\r
574 1, GL_FALSE, glm::value_ptr(lightProj));
\r
575 glUniform1i(glGetUniformLocation(shaderProgramIrradiance, "screenWidth"), window.getSize().x);
\r
576 glUniform1i(glGetUniformLocation(shaderProgramIrradiance, "screenHeight"), window.getSize().y);
\r
577 glUniform1fv(glGetUniformLocation(shaderProgramIrradiance, "samplePositions"), 13, samplePositions);
\r
578 glUniform3fv(glGetUniformLocation(shaderProgramIrradiance, "sampleWeights"), 13, sampleWeights);
\r
579 glUniform2fv(glGetUniformLocation(shaderProgramIrradiance, "translucencySampleVariances"), 6, translucencySampleVariances);
\r
580 glUniform3fv(glGetUniformLocation(shaderProgramIrradiance, "translucencySampleWeights"), 6, translucencySampleWeights);
\r
583 glGetUniformLocation(shaderProgramIrradiance, "transmittanceScale"),
\r
584 options.transmittanceScale);
\r
586 glGetUniformLocation(shaderProgramIrradiance, "renderState"),
\r
587 options.renderState);
\r
589 glGetUniformLocation(shaderProgramIrradiance, "powBase"),
\r
592 glGetUniformLocation(shaderProgramIrradiance, "powFactor"),
\r
593 options.powFactor);
\r
596 glGetUniformLocation(shaderProgramIrradiance, "objectColor"),
\r
599 glGetUniformLocation(shaderProgramIrradiance, "lightColor"),
\r
602 glGetUniformLocation(shaderProgramIrradiance, "lightPos"),
\r
603 1, glm::value_ptr(options.lightPos));
\r
605 glGetUniformLocation(shaderProgramIrradiance, "viewPos"),
\r
606 1, glm::value_ptr(options.freecam ? freeCam.pos : arcCam.getPos()));
\r
609 glUniform1i(glGetUniformLocation(shaderProgramIrradiance, "shadowmapTexture"), 0);
\r
610 glActiveTexture(GL_TEXTURE0 + 0);
\r
611 glBindTexture(GL_TEXTURE_2D, fb_shadowmap.renderTexture);
\r
615 // Render fbo to screen
\r
617 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
\r
619 glBindFramebuffer(GL_FRAMEBUFFER, 0);
\r
620 glDisable(GL_DEPTH_TEST);
\r
621 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
\r
622 glClear(GL_COLOR_BUFFER_BIT);
\r
623 glUseProgram(fb_irradiance.screenShaderProgram);
\r
625 glUniform1i(glGetUniformLocation(fb_irradiance.screenShaderProgram, "screenWidth"), window.getSize().x);
\r
626 glUniform1i(glGetUniformLocation(fb_irradiance.screenShaderProgram, "screenHeight"), window.getSize().y);
\r
627 glUniform1i(glGetUniformLocation(fb_irradiance.screenShaderProgram, "renderState"), options.renderState);
\r
628 glUniform2fv(glGetUniformLocation(fb_irradiance.screenShaderProgram, "samplePositions"), 13, samplePositions);
\r
629 glUniform3fv(glGetUniformLocation(fb_irradiance.screenShaderProgram, "sampleWeights"), 13, sampleWeights);
\r
631 glBindVertexArray(fb_irradiance.screenVAO);
\r
632 glUniform1i(glGetUniformLocation(fb_irradiance.screenShaderProgram, "shadowmapTexture"), 0);
\r
633 glUniform1i(glGetUniformLocation(fb_irradiance.screenShaderProgram, "irradianceTexture"), 1);
\r
634 glActiveTexture(GL_TEXTURE0 + 0);
\r
635 glBindTexture(GL_TEXTURE_2D, fb_shadowmap.renderTexture);
\r
636 glActiveTexture(GL_TEXTURE0 + 1);
\r
637 glBindTexture(GL_TEXTURE_2D, fb_irradiance.renderTexture);
\r
638 glDrawArrays(GL_TRIANGLES, 0, 6);
\r
639 glBindVertexArray(0);
\r
641 ImGui::SFML::Update(window, deltaClock.restart());
\r
643 ImGui::Begin("Options");
\r
644 ImGui::Checkbox("Wireframe", &options.wireframe);
\r
645 ImGui::Checkbox("Free Cam", &options.freecam);
\r
646 ImGui::InputInt("Render State", &options.renderState);
\r
647 ImGui::DragFloat3("Color", options.color, 0.01, 0, 1);
\r
648 ImGui::DragFloat("Transmittance Scale", &options.transmittanceScale, 0.0001f, 0, 0.3);
\r
649 ImGui::DragFloat("Pow Base", &options.powBase, 0.01f, 0, 4);
\r
650 ImGui::DragFloat("Pow Factor", &options.powFactor, 0.01f, 0, 3);
\r
651 ImGui::DragFloat3("Light Pos", glm::value_ptr(options.lightPos), 0.01, -5, 5);
\r
652 if (options.freecam) {
\r
653 ImGui::LabelText("Position", "%f %f %f", freeCam.pos.x, freeCam.pos.y, freeCam.pos.z);
\r
654 ImGui::LabelText("Rotation", "%f %f", freeCam.rot.x, freeCam.rot.y);
\r
655 if (ImGui::Button("Reset")) {
\r
656 freeCam.pos = glm::vec3(0, 0, -1);
\r
657 freeCam.rot = glm::vec2(0);
\r
658 options = DefaultOptions;
\r
661 ImGui::LabelText("Rotation", "%f %f", arcCam.rot.x, arcCam.rot.y);
\r
662 ImGui::DragFloat("Radius", &arcCam.radius, 0.01f, -1.0f, 1.0f);
\r
663 if (ImGui::Button("Reset")) {
\r
664 arcCam.rot = glm::vec2(0);
\r
666 options = DefaultOptions;
\r
671 ImGui::SFML::Render(window);
\r