#include <stdio.h>\r
+#include <fstream>\r
\r
#include <GL/glew.h>\r
\r
#include <assimp/postprocess.h>\r
#include <assimp/scene.h>\r
\r
-const char *vertexShaderSource = R"(\r
-#version 330 core\r
+/*\r
+\r
+TODO:\r
+- ShadowMap to fbo\r
+- Save Depth to fbo\r
+\r
+*/\r
+\r
+float samplePositions[] = {\r
+ 0.000000f, 0.000000f,\r
+ 1.633992f, 0.036795f,\r
+ 0.177801f, 1.717593f,\r
+ -0.194906f, 0.091094f,\r
+ -0.239737f, -0.220217f,\r
+ -0.003530f, -0.118219f,\r
+ 1.320107f, -0.181542f,\r
+ 5.970690f, 0.253378f,\r
+ -1.089250f, 4.958349f,\r
+ -4.015465f, 4.156699f,\r
+ -4.063099f, -4.110150f,\r
+ -0.638605f, -6.297663f,\r
+ 2.542348f, -3.245901f\r
+};\r
+\r
+float sampleWeights[] = {\r
+ 0.220441f, 0.487000f, 0.635000f,\r
+ 0.076356f, 0.064487f, 0.039097f,\r
+ 0.116515f, 0.103222f, 0.064912f,\r
+ 0.064844f, 0.086388f, 0.062272f,\r
+ 0.131798f, 0.151695f, 0.103676f,\r
+ 0.025690f, 0.042728f, 0.033003f,\r
+ 0.048593f, 0.064740f, 0.046131f,\r
+ 0.048092f, 0.003042f, 0.000400f,\r
+ 0.048845f, 0.005406f, 0.001222f,\r
+ 0.051322f, 0.006034f, 0.001420f,\r
+ 0.061428f, 0.009152f, 0.002511f,\r
+ 0.030936f, 0.002868f, 0.000652f,\r
+ 0.073580f, 0.023239f, 0.009703f\r
+};\r
+\r
+struct model {\r
+ std::vector<float> vertices;\r
+ std::vector<GLuint> indices;\r
+\r
+ void draw() {\r
+ if (VAO == 0) initVAO();\r
+ glBindVertexArray(VAO);\r
+ glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);\r
+ glBindVertexArray(0);\r
+ }\r
\r
-layout (location = 0) in vec3 pos;\r
-layout (location = 1) in vec3 normal;\r
+private:\r
+ void initVAO() {\r
+ GLuint VBO;\r
+ glGenBuffers(1, &VBO);\r
\r
-out vec3 FragPos;\r
-out vec3 Normal;\r
+ GLuint EBO;\r
+ glGenBuffers(1, &EBO);\r
\r
-uniform mat4 model;\r
-uniform mat4 view;\r
-uniform mat4 projection;\r
+ glGenVertexArrays(1, &VAO);\r
\r
-void main()\r
-{\r
- gl_Position = projection * view * model * vec4(pos, 1.0);\r
- FragPos = vec3(model * vec4(pos, 1));\r
- Normal = normal;\r
-}\r
-)";\r
+ glBindVertexArray(VAO);\r
\r
-const char *fragmentShaderSource = R"(\r
-#version 330 core\r
+ glBindBuffer(GL_ARRAY_BUFFER, VBO);\r
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(),\r
+ vertices.data(), GL_STATIC_DRAW);\r
\r
-in vec3 FragPos;\r
-in vec3 Normal;\r
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);\r
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indices.size(),\r
+ indices.data(), GL_STATIC_DRAW);\r
\r
-out vec4 FragColor;\r
+ glEnableVertexAttribArray(0);\r
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (void*)(0));\r
+ glEnableVertexAttribArray(1);\r
+ glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (void*)(sizeof(float) * 3));\r
\r
-uniform vec3 objectColor;\r
-uniform vec3 lightColor;\r
-uniform vec3 lightPos;\r
+ glBindVertexArray(0);\r
+ }\r
+ GLuint VAO = 0;\r
+};\r
\r
-void main()\r
-{\r
- vec3 norm = normalize(Normal);\r
- vec3 lightDir = normalize(lightPos - FragPos);\r
\r
- float diff = max(dot(norm, lightDir), 0.0);\r
- vec3 diffuse = diff * lightColor;\r
+struct freecam {\r
+ glm::vec3 pos = glm::vec3(0, 0, -1);\r
+ glm::vec2 rot = glm::vec2(0, 0);\r
\r
- float ambientStrength = 0.1;\r
- vec3 ambient = ambientStrength * lightColor;\r
+ void update(sf::Window &window) {\r
+ int mouseDeltaX = sf::Mouse::getPosition(window).x - window.getSize().x / 2;\r
+ int mouseDeltaY = sf::Mouse::getPosition(window).y - window.getSize().y / 2;\r
\r
- vec3 result = (ambient + diffuse) * objectColor;\r
- FragColor = vec4(result, 1.0f);\r
-}\r
-)";\r
+ rot.x += mouseDeltaX;\r
+ rot.y += mouseDeltaY;\r
+\r
+ forward = glm::rotate(glm::vec3(0, 0, 1), rot.y / angleFactor, glm::vec3(1, 0, 0));\r
+ forward = glm::rotate(forward, -rot.x / angleFactor, glm::vec3(0, 1, 0));\r
+\r
+ glm::vec3 left = glm::rotate(glm::vec3(0, 0, 1), -rot.x / angleFactor + glm::radians(90.0f), glm::vec3(0, 1, 0));\r
\r
-std::vector<float> vertices;\r
-std::vector<GLuint> indices;\r
+ if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::LShift))\r
+ moveFactor = 200;\r
+ else\r
+ moveFactor = 20;\r
+\r
+ if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))\r
+ pos += forward / moveFactor;\r
+ if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))\r
+ pos -= forward / moveFactor;\r
+ if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))\r
+ pos += left / moveFactor;\r
+ if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))\r
+ pos -= left / moveFactor;\r
+\r
+ limit();\r
+ }\r
+\r
+ void limit() {\r
+ rot.x = fmod(rot.x, glm::radians(360.0f) * angleFactor);\r
+ rot.y = fmod(rot.y, glm::radians(360.0f) * angleFactor);\r
+ }\r
+\r
+ glm::mat4 getViewMatrix() {\r
+ forward = glm::rotate(glm::vec3(0, 0, 1), rot.y / angleFactor, glm::vec3(1, 0, 0));\r
+ forward = glm::rotate(forward, -rot.x / angleFactor, glm::vec3(0, 1, 0));\r
+ glm::mat4 result = glm::lookAt(pos, pos + forward, up);\r
+ return result;\r
+ }\r
\r
-glm::vec3 lightPos(1.2f, 5.0f, 2.0f);\r
+private:\r
+ glm::vec3 forward = glm::vec3(0, 0, 1);\r
+ glm::vec3 up = glm::vec3(0, 1, 0);\r
\r
-void load(const std::string &filename, std::vector<float> &vertices,\r
- std::vector<GLuint> &indices) {\r
+ const float angleFactor = 200;\r
+ float moveFactor = 20;\r
+};\r
+\r
+\r
+struct arccam {\r
+ glm::vec2 rot = glm::vec2(0, 0);\r
+ float radius = 1;\r
+\r
+ void update(sf::Window &window) {\r
+ int mouseDeltaX = sf::Mouse::getPosition(window).x - window.getSize().x / 2;\r
+ int mouseDeltaY = sf::Mouse::getPosition(window).y - window.getSize().y / 2;\r
+\r
+ rot.x += mouseDeltaX;\r
+ rot.y += mouseDeltaY;\r
+\r
+ limit(-89, 89);\r
+ }\r
+\r
+ void limit(float minY, float maxY) {\r
+ float angleX = rot.x / angleFactor;\r
+ float angleY = rot.y / angleFactor;\r
+\r
+ rot.x = fmod(rot.x, glm::radians(360.0f) * angleFactor);\r
+\r
+ if (angleY > glm::radians(maxY))\r
+ rot.y = glm::radians(maxY) * angleFactor;\r
+ if (angleY < glm::radians(minY))\r
+ rot.y = glm::radians(minY) * angleFactor;\r
+ }\r
+\r
+ glm::vec3 getPos() {\r
+ float angle = rot.y / angleFactor;\r
+ \r
+ float camY = sin(angle) * exp(radius);\r
+ float camZ = cos(angle) * exp(radius);\r
+\r
+ glm::vec3 result(0.0, camY, camZ);\r
+ return glm::rotate(result, -rot.x / angleFactor, glm::vec3(0, 1, 0));\r
+ }\r
+\r
+ glm::mat4 getViewMatrix() {\r
+ float angle = rot.y / angleFactor;\r
+ \r
+ float camY = sin(angle) * exp(radius);\r
+ float camZ = cos(angle) * exp(radius);\r
+ glm::mat4 result = glm::lookAt(glm::vec3(0.0, camY, camZ), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));\r
+ result = glm::rotate(result, rot.x / angleFactor, glm::vec3(0, 1, 0));\r
+\r
+ return result;\r
+ }\r
+\r
+private:\r
+ const float angleFactor = 200;\r
+};\r
+\r
+\r
+std::string readFile(std::string filename) {\r
+ std::ifstream ifs(filename, std::ios::binary);\r
+ std::string result, line;\r
+ while (std::getline(ifs, line))\r
+ result += line + "\n";\r
+\r
+ return result;\r
+}\r
+\r
+model loadModel(const std::string &filename) {\r
Assimp::Importer importer;\r
\r
const aiScene *scene = importer.ReadFile(\r
filename, aiProcess_CalcTangentSpace | aiProcess_Triangulate |\r
aiProcess_SortByPType | aiProcess_GenSmoothNormals);\r
\r
+ model result;\r
+\r
for (int i = 0; i < scene->mMeshes[0]->mNumVertices; i++) {\r
aiVector3D v = scene->mMeshes[0]->mVertices[i];\r
aiVector3D n = scene->mMeshes[0]->mNormals[i];\r
- vertices.push_back(v.x);\r
- vertices.push_back(v.y);\r
- vertices.push_back(v.z);\r
- vertices.push_back(n.x);\r
- vertices.push_back(n.y);\r
- vertices.push_back(n.z);\r
+ result.vertices.push_back(v.x);\r
+ result.vertices.push_back(v.y);\r
+ result.vertices.push_back(v.z);\r
+ result.vertices.push_back(n.x);\r
+ result.vertices.push_back(n.y);\r
+ result.vertices.push_back(n.z);\r
}\r
\r
for (int i = 0; i < scene->mMeshes[0]->mNumFaces; i++) {\r
aiFace f = scene->mMeshes[0]->mFaces[i];\r
for (int j = 0; j < f.mNumIndices; j++) {\r
- indices.push_back(f.mIndices[j]);\r
+ result.indices.push_back(f.mIndices[j]);\r
}\r
}\r
-}\r
-\r
-int main() {\r
- // Window Setup\r
-\r
- sf::ContextSettings settings;\r
- settings.depthBits = 24;\r
- settings.antialiasingLevel = 0;\r
- settings.majorVersion = 4;\r
- settings.minorVersion = 6;\r
-\r
- sf::RenderWindow window(sf::VideoMode(1600, 900), "Subsurface Scattering",\r
- sf::Style::Default, settings);\r
- window.setVerticalSyncEnabled(true);\r
- window.setMouseCursorGrabbed(true);\r
- window.setMouseCursorVisible(false);\r
-\r
- ImGui::SFML::Init(window);\r
-\r
- // Initialize GLEW\r
-\r
- if (glewInit() != GLEW_OK) {\r
- }\r
-\r
- load("models/Isotrop-upperjaw.ply", vertices, indices);\r
\r
- // Compile Shaders\r
+ return result;\r
+}\r
\r
- GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);\r
- glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);\r
- glCompileShader(vertexShader);\r
+GLuint compileShaders(const char *vertFilename, const char *fragFilename) {\r
+ GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);\r
+ std::string vertSource = readFile(vertFilename);\r
+ const char *vertAddr = vertSource.c_str();\r
+ glShaderSource(vertShader, 1, &vertAddr, NULL);\r
+ glCompileShader(vertShader);\r
\r
int success;\r
char infoLog[512];\r
- glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);\r
+ glGetShaderiv(vertShader, GL_COMPILE_STATUS, &success);\r
if (!success) {\r
- glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);\r
- printf("Error compiling vertex shader: %s\n", infoLog);\r
+ glGetShaderInfoLog(vertShader, 512, NULL, infoLog);\r
+ printf("Error compiling vertex shader(%s): %s\n", vertFilename, infoLog);\r
}\r
\r
- GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);\r
- glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);\r
- glCompileShader(fragmentShader);\r
+ GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);\r
+ std::string fragSource = readFile(fragFilename);\r
+ const char *fragAddr = fragSource.c_str();\r
+ glShaderSource(fragShader, 1, &fragAddr, NULL);\r
+ glCompileShader(fragShader);\r
\r
- glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);\r
+ glGetShaderiv(fragShader, GL_COMPILE_STATUS, &success);\r
if (!success) {\r
- glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);\r
- printf("Error compiling fragment shader: %s\n", infoLog);\r
+ glGetShaderInfoLog(fragShader, 512, NULL, infoLog);\r
+ printf("Error compiling fragment shader(%s): %s\n", fragFilename, infoLog);\r
}\r
\r
// Link Shader Program\r
\r
GLuint shaderProgram = glCreateProgram();\r
- glAttachShader(shaderProgram, vertexShader);\r
- glAttachShader(shaderProgram, fragmentShader);\r
+ glAttachShader(shaderProgram, vertShader);\r
+ glAttachShader(shaderProgram, fragShader);\r
glLinkProgram(shaderProgram);\r
\r
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);\r
printf("Error linking shader program: %s\n", infoLog);\r
}\r
\r
- glDeleteShader(vertexShader);\r
- glDeleteShader(fragmentShader);\r
+ glDeleteShader(vertShader);\r
+ glDeleteShader(fragShader);\r
+\r
+ return shaderProgram;\r
+}\r
+\r
+\r
+struct framebuffer {\r
+ framebuffer(const char *vertFilename, const char *fragFilename, int width, int height) {\r
+ glGenFramebuffers(1, &fbo);\r
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);\r
+ \r
+ glGenTextures(1, &renderTexture);\r
+ glBindTexture(GL_TEXTURE_2D, renderTexture);\r
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);\r
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);\r
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);\r
+ //glBindTexture(GL_TEXTURE_2D, 0);\r
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTexture, 0);\r
+\r
+ glGenRenderbuffers(1, &rbo);\r
+ glBindRenderbuffer(GL_RENDERBUFFER, rbo);\r
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);\r
+ //glBindRenderbuffer(GL_RENDERBUFFER, 0);\r
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);\r
+\r
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) {\r
+ printf("Successfully created framebuffer\n");\r
+ }\r
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);\r
+ \r
+ screenShaderProgram = compileShaders(vertFilename, fragFilename);\r
+ glUseProgram(screenShaderProgram);\r
+ glUniform1i(glGetUniformLocation(screenShaderProgram, "screenTexture"), 0);\r
+\r
+ // Screen VAO\r
+ \r
+ glGenBuffers(1, &screenVBO);\r
\r
- // Create VBO\r
+ glGenVertexArrays(1, &screenVAO);\r
\r
- GLuint VBO;\r
- glGenBuffers(1, &VBO);\r
+ glBindVertexArray(screenVAO);\r
\r
- // Create EBO\r
+ float screenVerts[] = {\r
+ -1.0f, +1.0f, +0.0f, +1.0f,\r
+ -1.0f, -1.0f, +0.0f, +0.0f,\r
+ +1.0f, -1.0f, +1.0f, +0.0f,\r
+ \r
+ -1.0f, +1.0f, +0.0f, +1.0f,\r
+ +1.0f, -1.0f, +1.0f, +0.0f,\r
+ +1.0f, +1.0f, +1.0f, +1.0f,\r
+ };\r
\r
- GLuint EBO;\r
- glGenBuffers(1, &EBO);\r
+ glBindBuffer(GL_ARRAY_BUFFER, screenVBO);\r
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4,\r
+ screenVerts, GL_STATIC_DRAW);\r
\r
- // Create VAO\r
+ glEnableVertexAttribArray(0);\r
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (void*)(0));\r
+ glEnableVertexAttribArray(1);\r
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (void*)(sizeof(float) * 2));\r
\r
- GLuint VAO;\r
- glGenVertexArrays(1, &VAO);\r
+ glBindVertexArray(0);\r
+ }\r
+ ~framebuffer() {\r
+ glDeleteFramebuffers(1, &fbo);\r
+ }\r
+ \r
+ GLuint fbo;\r
+ GLuint renderTexture;\r
+ GLuint rbo;\r
+ GLuint screenShaderProgram;\r
+ GLuint screenVBO;\r
+ GLuint screenVAO;\r
+};\r
\r
- glBindVertexArray(VAO);\r
+int main() {\r
+ // Window Setup\r
\r
- glBindBuffer(GL_ARRAY_BUFFER, VBO);\r
- glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(),\r
- vertices.data(), GL_STATIC_DRAW);\r
+ const int width = 1600, height = 900;\r
\r
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);\r
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indices.size(),\r
- indices.data(), GL_STATIC_DRAW);\r
+ sf::ContextSettings settings;\r
+ settings.depthBits = 24;\r
+ settings.antialiasingLevel = 0;\r
+ settings.majorVersion = 4;\r
+ settings.minorVersion = 6;\r
\r
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (void*)(0));\r
- glEnableVertexAttribArray(0);\r
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (void*)(sizeof(float) * 3));\r
- glEnableVertexAttribArray(1);\r
+ sf::RenderWindow window(sf::VideoMode(1600, 900), "Subsurface Scattering",\r
+ sf::Style::Default, settings);\r
+ window.setVerticalSyncEnabled(true);\r
\r
- glBindVertexArray(0);\r
+ ImGui::SFML::Init(window);\r
\r
- // Perspective\r
+ // Initialize GLEW\r
\r
- glm::mat4 model = glm::scale(glm::mat4(1.0f), glm::vec3(0.01f, 0.01f, 0.01f));\r
+ if (glewInit() != GLEW_OK) {\r
+ }\r
\r
- struct {\r
- float camX = 0;\r
- float camZ = -5;\r
- int mouseX = 0;\r
- int mouseY = 0;\r
- } arcball;\r
+ GLuint shaderProgramShadowmap = compileShaders("shaders/vert.glsl", "shaders/frag_shadowmap.glsl");\r
+ GLuint shaderProgramIrradiance = compileShaders("shaders/vert.glsl", "shaders/frag_irradiance.glsl");\r
\r
- struct {\r
- int mouseX = 0;\r
- int mouseY = 0;\r
- } freecam;\r
+ model m = loadModel("models/Isotrop-upperjaw.ply");\r
+\r
+ arccam arcCam;\r
+ freecam freeCam;\r
+ \r
+ glm::vec3 lightPos(1.2f, 5.0f, 2.0f);\r
+\r
+ // MVP\r
+\r
+ glm::mat4 model = glm::scale(glm::mat4(1.0f), glm::vec3(0.01f, 0.01f, 0.01f));\r
+\r
+ glm::mat4 view;\r
\r
- glm::vec3 camPos = glm::vec3(0, 0, -3);\r
- glm::vec3 camForward = glm::vec3(0, 0, 1);\r
- glm::vec3 camUp = glm::vec3(0, 1, 0);\r
+ glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)window.getSize().x / window.getSize().y, 0.001f, 1000.0f);\r
\r
- glm::mat4 view =\r
- glm::lookAt(glm::vec3(arcball.camX, 0.0, arcball.camZ), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));\r
+ // Framebuffer\r
+ framebuffer fb_shadowmap("shaders/fbo_vert.glsl", "shaders/fbo_frag.glsl", width, height);\r
+ framebuffer fb_irradiance("shaders/fbo_vert.glsl", "shaders/fbo_frag.glsl", width, height);\r
\r
- glm::mat4 proj =\r
- glm::perspective(glm::radians(45.0f), (float)window.getSize().x / window.getSize().y, 0.001f, 1000.0f);\r
+ // Config\r
\r
struct {\r
- bool catchMouse = false;\r
bool wireframe = false;\r
bool freecam = false;\r
- float radius = 1.0f;\r
+ int renderState = 0;\r
+ float color[3] = { 0.7f, 0.4f, 0.4f };\r
} options;\r
\r
sf::Clock deltaClock;\r
\r
+ bool prevMouse = false;\r
+\r
bool running = true;\r
while (running) {\r
+ // Events\r
+\r
sf::Event event;\r
while (window.pollEvent(event)) {\r
ImGui::SFML::ProcessEvent(event);\r
case keys::Escape:\r
running = false;\r
break;\r
- case keys::C:\r
- options.catchMouse = !options.catchMouse;\r
- break;\r
- case keys::R:\r
- freecam.mouseX = freecam.mouseY = 0;\r
- break;\r
}\r
} else if (event.type == sf::Event::EventType::MouseWheelScrolled) {\r
- options.radius -= event.mouseWheelScroll.delta / 5.0f;\r
+ if (! options.freecam) {\r
+ arcCam.radius -= event.mouseWheelScroll.delta / 5.0f;\r
+ }\r
}\r
}\r
\r
- int mouseDeltaX = sf::Mouse::getPosition(window).x - window.getSize().x / 2;\r
- int mouseDeltaY = sf::Mouse::getPosition(window).y - window.getSize().y / 2;\r
+ // Update\r
\r
- if (options.catchMouse) {\r
- sf::Mouse::setPosition(sf::Vector2i(\r
- window.getSize().x / 2,\r
- window.getSize().y / 2\r
- ), window);\r
+ if (sf::Mouse::isButtonPressed(sf::Mouse::Right)) {\r
+ window.setMouseCursorVisible(false);\r
\r
- if (options.freecam) {\r
- freecam.mouseX += mouseDeltaX;\r
- freecam.mouseY += mouseDeltaY;\r
+ if (prevMouse) {\r
+ if (options.freecam)\r
+ freeCam.update(window);\r
+ else\r
+ arcCam.update(window);\r
+ }\r
\r
- camForward = glm::rotate(glm::vec3(0, 0, 1), freecam.mouseY / 500.0f, glm::vec3(1, 0, 0));\r
- camForward = glm::rotate(camForward, -freecam.mouseX / 500.0f, glm::vec3(0, 1, 0));\r
\r
- if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {\r
- camPos += camForward / 20.0f;\r
- }\r
- if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) {\r
- camPos -= camForward / 20.0f;\r
- }\r
- if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {\r
- glm::vec3 camLeft = glm::rotate(glm::vec3(0, 0, 1), -freecam.mouseX / 500.0f + glm::radians(90.0f), glm::vec3(0, 1, 0));\r
- camPos += camLeft / 20.0f;\r
- }\r
- if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {\r
- glm::vec3 camRight = glm::rotate(glm::vec3(0, 0, 1), -freecam.mouseX / 500.0f - glm::radians(90.0f), glm::vec3(0, 1, 0));\r
- camPos += camRight / 20.0f;\r
- }\r
- } else {\r
- if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {\r
- arcball.mouseX += mouseDeltaX;\r
- arcball.mouseY += mouseDeltaY;\r
- }\r
- }\r
+ sf::Mouse::setPosition(sf::Vector2i(\r
+ window.getSize().x / 2,\r
+ window.getSize().y / 2\r
+ ), window); \r
+ } else {\r
+ window.setMouseCursorVisible(true);\r
}\r
\r
+ prevMouse = sf::Mouse::isButtonPressed(sf::Mouse::Right);\r
\r
+ // Render Shadowmap\r
\r
+ glBindFramebuffer(GL_FRAMEBUFFER, fb_shadowmap.fbo);\r
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);\r
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);\r
-\r
glEnable(GL_DEPTH_TEST);\r
\r
if (options.wireframe)\r
else\r
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);\r
\r
- glUseProgram(shaderProgram);\r
-\r
- //rotate\r
- //model = glm::rotate(model, glm::radians(0.2f), glm::vec3(0.0f, 1.0f, 0.0f));\r
-\r
- if (options.freecam) {\r
- view = glm::lookAt(camPos, camPos + camForward, camUp);\r
- } else {\r
- float angle = arcball.mouseY / 200.0f;\r
- if (angle > glm::radians(89.0f)) {\r
- angle = glm::radians(89.0f);\r
- arcball.mouseY = angle * 200.0f;\r
- }\r
- if (angle < glm::radians(-89.0f)) {\r
- angle = glm::radians(-89.0f);\r
- arcball.mouseY = angle * 200.0f;\r
- }\r
- arcball.camX = sin(angle) * exp(options.radius);\r
- arcball.camZ = cos(angle) * exp(options.radius);\r
- view = glm::lookAt(glm::vec3(0.0, arcball.camX, arcball.camZ), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));\r
- view = glm::rotate(view, arcball.mouseX / 100.0f, glm::vec3(0, 1, 0));\r
- }\r
-\r
- glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1,\r
- GL_FALSE, glm::value_ptr(model));\r
- glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "view"), 1, GL_FALSE,\r
- glm::value_ptr(view));\r
- glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1,\r
- GL_FALSE, glm::value_ptr(proj));\r
+ glUseProgram(shaderProgramShadowmap);\r
+ \r
+ if (options.freecam)\r
+ view = freeCam.getViewMatrix();\r
+ else\r
+ view = arcCam.getViewMatrix();\r
+ \r
+ glUniformMatrix4fv(\r
+ glGetUniformLocation(shaderProgramShadowmap, "model"),\r
+ 1, GL_FALSE, glm::value_ptr(model));\r
+ glUniformMatrix4fv(\r
+ glGetUniformLocation(shaderProgramShadowmap, "view"),\r
+ 1, GL_FALSE, glm::value_ptr(view));\r
+ glUniformMatrix4fv(\r
+ glGetUniformLocation(shaderProgramShadowmap, "projection"),\r
+ 1, GL_FALSE, glm::value_ptr(proj));\r
+\r
+ glUniform3fv(\r
+ glGetUniformLocation(shaderProgramShadowmap, "lightPos"),\r
+ 1, glm::value_ptr(lightPos));\r
+\r
+ m.draw();\r
+\r
+ // Render irradiance\r
+\r
+ glBindFramebuffer(GL_FRAMEBUFFER, fb_irradiance.fbo);\r
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);\r
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);\r
+ glEnable(GL_DEPTH_TEST);\r
\r
- glUniform3f(glGetUniformLocation(shaderProgram, "objectColor"), 1.0f, 0.5f,\r
- 0.31f);\r
- glUniform3f(glGetUniformLocation(shaderProgram, "lightColor"), 1.0f, 1.0f,\r
- 1.0f);\r
- glUniform3fv(glGetUniformLocation(shaderProgram, "lightPos"), 1, glm::value_ptr(lightPos));\r
+ if (options.wireframe)\r
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);\r
+ else\r
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);\r
\r
- glBindVertexArray(VAO);\r
- glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);\r
- glBindVertexArray(0);\r
+ glUseProgram(shaderProgramIrradiance);\r
+ \r
+ if (options.freecam)\r
+ view = freeCam.getViewMatrix();\r
+ else\r
+ view = arcCam.getViewMatrix();\r
+ \r
+ glUniformMatrix4fv(\r
+ glGetUniformLocation(shaderProgramIrradiance, "model"),\r
+ 1, GL_FALSE, glm::value_ptr(model));\r
+ glUniformMatrix4fv(\r
+ glGetUniformLocation(shaderProgramIrradiance, "view"),\r
+ 1, GL_FALSE, glm::value_ptr(view));\r
+ glUniformMatrix4fv(\r
+ glGetUniformLocation(shaderProgramIrradiance, "projection"),\r
+ 1, GL_FALSE, glm::value_ptr(proj));\r
+\r
+ glUniform3fv(\r
+ glGetUniformLocation(shaderProgramIrradiance, "objectColor"),\r
+ 1, options.color);\r
+ glUniform3f(\r
+ glGetUniformLocation(shaderProgramIrradiance, "lightColor"),\r
+ 1.0f, 1.0f, 1.0f);\r
+ glUniform3fv(\r
+ glGetUniformLocation(shaderProgramIrradiance, "lightPos"),\r
+ 1, glm::value_ptr(lightPos));\r
+ glUniform3fv(\r
+ glGetUniformLocation(shaderProgramIrradiance, "viewPos"),\r
+ 1, glm::value_ptr(options.freecam ? freeCam.pos : arcCam.getPos()));\r
+ \r
+ glUniform1i(glGetUniformLocation(shaderProgramIrradiance, "shadowmapTexture"), 0);\r
+ glActiveTexture(GL_TEXTURE0 + 0);\r
+ glBindTexture(GL_TEXTURE_2D, fb_shadowmap.renderTexture);\r
+\r
+ m.draw();\r
+\r
+ // Render fbo to screen\r
\r
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);\r
\r
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);\r
+ glDisable(GL_DEPTH_TEST);\r
+ glClearColor(1.0f, 1.0f, 1.0f, 1.0f);\r
+ glClear(GL_COLOR_BUFFER_BIT);\r
+ glUseProgram(fb_irradiance.screenShaderProgram);\r
+\r
+ glUniform1i(glGetUniformLocation(fb_irradiance.screenShaderProgram, "screenWidth"), window.getSize().x);\r
+ glUniform1i(glGetUniformLocation(fb_irradiance.screenShaderProgram, "screenHeight"), window.getSize().y);\r
+ glUniform1i(glGetUniformLocation(fb_irradiance.screenShaderProgram, "renderState"), options.renderState);\r
+ glUniform2fv(glGetUniformLocation(fb_irradiance.screenShaderProgram, "samplePositions"), 13, samplePositions);\r
+ glUniform3fv(glGetUniformLocation(fb_irradiance.screenShaderProgram, "sampleWeights"), 13, sampleWeights);\r
+\r
+ glBindVertexArray(fb_irradiance.screenVAO);\r
+ glUniform1i(glGetUniformLocation(fb_irradiance.screenShaderProgram, "shadowmapTexture"), 0);\r
+ glUniform1i(glGetUniformLocation(fb_irradiance.screenShaderProgram, "irradianceTexture"), 1);\r
+ glActiveTexture(GL_TEXTURE0 + 0);\r
+ glBindTexture(GL_TEXTURE_2D, fb_shadowmap.renderTexture);\r
+ glActiveTexture(GL_TEXTURE0 + 1);\r
+ glBindTexture(GL_TEXTURE_2D, fb_irradiance.renderTexture);\r
+ glDrawArrays(GL_TRIANGLES, 0, 6);\r
+ glBindVertexArray(0);\r
+\r
ImGui::SFML::Update(window, deltaClock.restart());\r
\r
ImGui::Begin("Options");\r
- ImGui::LabelText("Cursor Locked", "%d", options.catchMouse);\r
ImGui::Checkbox("Wireframe", &options.wireframe);\r
ImGui::Checkbox("Free Cam", &options.freecam);\r
+ ImGui::InputInt("Render State", &options.renderState);\r
+ ImGui::InputFloat3("Color", options.color, 2);\r
if (options.freecam) {\r
- ImGui::LabelText("Position", "%f %f %f", camPos.x, camPos.y, camPos.z);\r
- ImGui::LabelText("Forward", "%f %f %f", camForward.x, camForward.y, camForward.z);\r
- ImGui::LabelText("Mouse", "%d %d", freecam.mouseX, freecam.mouseY);\r
+ ImGui::LabelText("Position", "%f %f %f", freeCam.pos.x, freeCam.pos.y, freeCam.pos.z);\r
+ ImGui::LabelText("Rotation", "%f %f", freeCam.rot.x, freeCam.rot.y);\r
+ if (ImGui::Button("Reset")) {\r
+ freeCam.pos = glm::vec3(0, 0, -1);\r
+ freeCam.rot = glm::vec2(0);\r
+ }\r
} else {\r
- ImGui::LabelText("Rotation", "%f %f", arcball.camX, arcball.camZ);\r
- ImGui::InputFloat("Radius", &options.radius);\r
+ ImGui::LabelText("Rotation", "%f %f", arcCam.rot.x, arcCam.rot.y);\r
+ ImGui::DragFloat("Radius", &arcCam.radius, 0.01f, -1.0f, 1.0f);\r
+ if (ImGui::Button("Reset")) {\r
+ arcCam.rot = glm::vec2(0);\r
+ arcCam.radius = 1;\r
+ }\r
}\r
ImGui::End();\r
\r