// The MAIN function, from here we start our application and run our Game loop int main() { // Init GLFW glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", nullptr, nullptr); // Windowed glfwMakeContextCurrent(window); // Set the required callback functions glfwSetKeyCallback(window, key_callback); glfwSetCursorPosCallback(window, mouse_callback); glfwSetScrollCallback(window, scroll_callback); // Options glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // Initialize GLEW to setup the OpenGL Function pointers glewExperimental = GL_TRUE; glewInit(); // Define the viewport dimensions glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT); // Setup some OpenGL options glEnable(GL_DEPTH_TEST); // Setup and compile our shaders ////Shader shader("shadow_mapping.vs", "shadow_mapping.frag"); Shader simpleDepthShader("shadow_mapping_depth.vs", "shadow_mapping_depth.frag"); Shader shaderGeometryPass("g_buffer.vs", "g_buffer.frag"); Shader shaderLightingPass("deferred_shading.vs", "deferred_shading.frag"); // Set texture samples ////shader.Use(); ////glUniform1i(glGetUniformLocation(shader.Program, "diffuseTexture"), 0); ////glUniform1i(glGetUniformLocation(shader.Program, "shadowMap"), 1); // Set samplers shaderLightingPass.Use(); glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "gPosition"), 0); glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "gNormal"), 1); glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "gAlbedoSpec"), 2); glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "gDepthViewer"), 3); glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "gShadowMap"), 4); shaderGeometryPass.Use(); glUniform1i(glGetUniformLocation(shaderGeometryPass.Program, "texture_diffuse1"), 0); glUniform1i(glGetUniformLocation(shaderGeometryPass.Program, "texture_specular1"), 1); GLfloat planeVertices[] = { // Positions // Normals // Texture Coords 25.0f, -0.5f, 25.0f, 0.0f, 1.0f, 0.0f, 25.0f, 0.0f, -25.0f, -0.5f, -25.0f, 0.0f, 1.0f, 0.0f, 0.0f, 25.0f, -25.0f, -0.5f, 25.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 25.0f, -0.5f, 25.0f, 0.0f, 1.0f, 0.0f, 25.0f, 0.0f, 25.0f, -0.5f, -25.0f, 0.0f, 1.0f, 0.0f, 25.0f, 25.0f, -25.0f, -0.5f, -25.0f, 0.0f, 1.0f, 0.0f, 0.0f, 25.0f }; // Setup plane VAO GLuint planeVBO; glGenVertexArrays(1, &planeVAO); glGenBuffers(1, &planeVBO); glBindVertexArray(planeVAO); glBindBuffer(GL_ARRAY_BUFFER, planeVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(planeVertices), &planeVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); glBindVertexArray(0); // Light source glm::vec3 lightPos(-2.0f, 4.0f, -1.0f); // Load textures woodTexture = loadTexture(FileSystem::getPath("resources/textures/wood.png").c_str()); // Configure depth map FBO const GLuint SHADOW_WIDTH = 1024, SHADOW_HEIGHT = 1024; GLuint depthMapFBO; glGenFramebuffers(1, &depthMapFBO); // - Create depth texture GLuint gShadowMap; glGenTextures(1, &gShadowMap); glBindTexture(GL_TEXTURE_2D, gShadowMap); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, gShadowMap, 0); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); glBindFramebuffer(GL_FRAMEBUFFER, 0); // Set up G-Buffer // 3 textures: // 1. Positions (RGB) // 2. Color (RGB) + Specular (A) // 3. Normals (RGB) //// 4. gDepthViewer (DEPTH) GLuint gBuffer; glGenFramebuffers(1, &gBuffer); glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); GLuint gPosition, gNormal, gAlbedoSpec, gDepthViewer; // - Position color buffer glGenTextures(1, &gPosition); glBindTexture(GL_TEXTURE_2D, gPosition); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gPosition, 0); // - Normal color buffer glGenTextures(1, &gNormal); glBindTexture(GL_TEXTURE_2D, gNormal); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gNormal, 0); // - Color + Specular color buffer glGenTextures(1, &gAlbedoSpec); glBindTexture(GL_TEXTURE_2D, gAlbedoSpec); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gAlbedoSpec, 0); // - Depth Map from viewer buffer glGenTextures(1, &gDepthViewer); glBindTexture(GL_TEXTURE_2D, gDepthViewer); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, gDepthViewer, 0); // - Tell OpenGL which color attachments we'll use (of this framebuffer) for rendering GLuint attachments[4] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; //////check! glDrawBuffers(4, attachments); glClearColor(0.1f, 0.1f, 0.1f, 1.0f); // Game loop while (!glfwWindowShouldClose(window)) { // Set frame time GLfloat currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; // Check and call events glfwPollEvents(); Do_Movement(); // Change light position over time lightPos.z = cos(glfwGetTime()) * 2.0f; // 1. Render depth of scene to texture (from light's perspective) // - Get light projection/view matrix. glm::mat4 lightProjection, lightView; glm::mat4 lightSpaceMatrix; GLfloat near_plane = 1.0f, far_plane = 9.5f; //lightProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane); lightProjection = glm::perspective(65.0f, (GLfloat)SHADOW_WIDTH / (GLfloat)SHADOW_HEIGHT, near_plane, far_plane); // Note that if you use a perspective projection matrix you'll have to change the light position as the current light position isn't enough to reflect the whole scene. lightView = glm::lookAt(lightPos, glm::vec3(0.0f), glm::vec3(1.0)); lightSpaceMatrix = lightProjection * lightView; // - now render scene from light's point of view simpleDepthShader.Use(); glUniformMatrix4fv(glGetUniformLocation(simpleDepthShader.Program, "lightSpaceMatrix"), 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix)); glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT); glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); glClear(GL_DEPTH_BUFFER_BIT); RenderScene(simpleDepthShader); glBindFramebuffer(GL_FRAMEBUFFER, 0); /* // 2. Render scene as normal glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); shader.Use(); glm::mat4 projection = glm::perspective(camera.Zoom, (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f); glm::mat4 view = camera.GetViewMatrix(); glUniformMatrix4fv(glGetUniformLocation(shader.Program, "projection"), 1, GL_FALSE, glm::value_ptr(projection)); glUniformMatrix4fv(glGetUniformLocation(shader.Program, "view"), 1, GL_FALSE, glm::value_ptr(view)); // Set light uniforms glUniform3fv(glGetUniformLocation(shader.Program, "lightPos"), 1, &lightPos[0]); glUniform3fv(glGetUniformLocation(shader.Program, "viewPos"), 1, &camera.Position[0]); glUniformMatrix4fv(glGetUniformLocation(shader.Program, "lightSpaceMatrix"), 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix)); // Enable/Disable shadows by pressing 'SPACE' glUniform1i(glGetUniformLocation(shader.Program, "shadows"), shadows); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, woodTexture); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, depthMap); RenderScene(shader); */ glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); shaderGeometryPass.Use(); glm::mat4 projection = glm::perspective(camera.Zoom, (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f); glm::mat4 view = camera.GetViewMatrix(); glUniformMatrix4fv(glGetUniformLocation(shaderGeometryPass.Program, "projection"), 1, GL_FALSE, glm::value_ptr(projection)); glUniformMatrix4fv(glGetUniformLocation(shaderGeometryPass.Program, "view"), 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(glGetUniformLocation(shaderGeometryPass.Program, "lightSpaceMatrix"), 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix)); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, woodTexture); RenderScene(shaderGeometryPass); glBindFramebuffer(GL_FRAMEBUFFER, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); shaderLightingPass.Use(); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, gPosition); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, gNormal); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, gAlbedoSpec); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, gDepthViewer); glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_2D, gShadowMap); // Also send light relevant uniforms glUniform3fv(glGetUniformLocation(shaderLightingPass.Program, "lightPos"), 1, &lightPos[0]); glUniform3fv(glGetUniformLocation(shaderLightingPass.Program, "viewPos"), 1, &camera.Position[0]); glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "draw_mode"), draw_mode); RenderQuad(); // Swap the buffers glfwSwapBuffers(window); } glfwTerminate(); return 0; }
int main() { // glfw: initialize and configure // ------------------------------ glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X // glfw window creation // -------------------- GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL); if (window == NULL) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glfwSetCursorPosCallback(window, mouse_callback); glfwSetScrollCallback(window, scroll_callback); // tell GLFW to capture our mouse glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // glad: load all OpenGL function pointers // --------------------------------------- if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cout << "Failed to initialize GLAD" << std::endl; return -1; } // configure global opengl state // ----------------------------- glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); // build and compile shaders // ------------------------- Shader shader("3.2.2.point_shadows.vs", "3.2.2.point_shadows.fs"); Shader simpleDepthShader("3.2.2.point_shadows_depth.vs", "3.2.2.point_shadows_depth.fs", "3.2.2.point_shadows_depth.gs"); // load textures // ------------- unsigned int woodTexture = loadTexture(FileSystem::getPath("resources/textures/wood.png").c_str()); // configure depth map FBO // ----------------------- const unsigned int SHADOW_WIDTH = 1024, SHADOW_HEIGHT = 1024; unsigned int depthMapFBO; glGenFramebuffers(1, &depthMapFBO); // create depth cubemap texture unsigned int depthCubemap; glGenTextures(1, &depthCubemap); glBindTexture(GL_TEXTURE_CUBE_MAP, depthCubemap); for (unsigned int i = 0; i < 6; ++i) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); // attach depth texture as FBO's depth buffer glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthCubemap, 0); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); glBindFramebuffer(GL_FRAMEBUFFER, 0); // shader configuration // -------------------- shader.use(); shader.setInt("diffuseTexture", 0); shader.setInt("depthMap", 1); // lighting info // ------------- glm::vec3 lightPos(0.0f, 0.0f, 0.0f); // render loop // ----------- while (!glfwWindowShouldClose(window)) { // per-frame time logic // -------------------- float currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; // input // ----- processInput(window); // move light position over time lightPos.z = sin(glfwGetTime() * 0.5) * 3.0; // render // ------ glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 0. create depth cubemap transformation matrices // ----------------------------------------------- float near_plane = 1.0f; float far_plane = 25.0f; glm::mat4 shadowProj = glm::perspective(glm::radians(90.0f), (float)SHADOW_WIDTH / (float)SHADOW_HEIGHT, near_plane, far_plane); std::vector<glm::mat4> shadowTransforms; shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f))); shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f))); shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f))); shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f))); shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f))); shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f))); // 1. render scene to depth cubemap // -------------------------------- glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT); glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); glClear(GL_DEPTH_BUFFER_BIT); simpleDepthShader.use(); for (unsigned int i = 0; i < 6; ++i) simpleDepthShader.setMat4("shadowMatrices[" + std::to_string(i) + "]", shadowTransforms[i]); simpleDepthShader.setFloat("far_plane", far_plane); simpleDepthShader.setVec3("lightPos", lightPos); renderScene(simpleDepthShader); glBindFramebuffer(GL_FRAMEBUFFER, 0); // 2. render scene as normal // ------------------------- glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); shader.use(); glm::mat4 projection = glm::perspective(camera.Zoom, (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f); glm::mat4 view = camera.GetViewMatrix(); shader.setMat4("projection", projection); shader.setMat4("view", view); // set lighting uniforms shader.setVec3("lightPos", lightPos); shader.setVec3("viewPos", camera.Position); shader.setInt("shadows", shadows); // enable/disable shadows by pressing 'SPACE' shader.setFloat("far_plane", far_plane); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, woodTexture); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_CUBE_MAP, depthCubemap); renderScene(shader); // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) // ------------------------------------------------------------------------------- glfwSwapBuffers(window); glfwPollEvents(); } glfwTerminate(); return 0; }
// The MAIN function, from here we start our application and run our Game loop int main() { // Init GLFW glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Windowed GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", nullptr, nullptr); glfwMakeContextCurrent(window); // Set the required callback functions glfwSetKeyCallback(window, key_callback); glfwSetCursorPosCallback(window, mouse_callback); glfwSetScrollCallback(window, scroll_callback); // Options glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // Initialize GLEW to setup the OpenGL Function pointers glewExperimental = GL_TRUE; glewInit(); // Define the viewport dimensions glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT); // Setup some OpenGL options glEnable(GL_DEPTH_TEST); // Setup and compile our shaders Shader shader("Shaders/shader.vert", "Shaders/shader.frag"); Shader simpleDepthShader("Shaders/shadow_mapping_depth.vs", "Shaders/shadow_mapping_depth.frag"); Shader lampShader("Shaders/lamp.vs", "Shaders/lamp.frag"); // Load models Model ourModel("Obj/nanosuit.obj"); Model lightBulb("Obj/geodesic_dome.obj"); GLfloat planeVertices[] = { // Positions // Normals // Texture Coords 25.0f, -0.5f, 25.0f, 0.0f, 1.0f, 0.0f, 25.0f, 0.0f, -25.0f, -0.5f, -25.0f, 0.0f, 1.0f, 0.0f, 0.0f, 25.0f, -25.0f, -0.5f, 25.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 25.0f, -0.5f, 25.0f, 0.0f, 1.0f, 0.0f, 25.0f, 0.0f, 25.0f, -0.5f, -25.0f, 0.0f, 1.0f, 0.0f, 25.0f, 25.0f, -25.0f, -0.5f, -25.0f, 0.0f, 1.0f, 0.0f, 0.0f, 25.0f }; glm::vec3 pointLightPositions[] = { glm::vec3(-2.0f, 4.0f, 0.0f), glm::vec3(-2.0f, 4.0f, 0.0f) }; // Setup plane VAO GLuint planeVBO; glGenVertexArrays(1, &planeVAO); glGenBuffers(1, &planeVBO); glBindVertexArray(planeVAO); glBindBuffer(GL_ARRAY_BUFFER, planeVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(planeVertices), &planeVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); glBindVertexArray(0); // Light source glm::vec3 lightPos(-2.0f, 4.0f, -1.0f); // Load textures woodTexture = loadTexture("Textures/wood.png"); rockTexture = loadTexture("Textures/rock.jpg"); glCullFace(GL_FRONT); // Configure depth map FBO const GLuint SHADOW_WIDTH = 1024, SHADOW_HEIGHT = 1024; GLuint depthMapFBO; glGenFramebuffers(1, &depthMapFBO); // - Create depth texture GLuint depthMap; glGenTextures(1, &depthMap); glBindTexture(GL_TEXTURE_2D, depthMap); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); GLfloat borderColor[] = { 1.0, 1.0, 1.0, 1.0 }; glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); glBindFramebuffer(GL_FRAMEBUFFER, 0); glCullFace(GL_BACK); glClearColor(0.1f, 0.1f, 0.1f, 1.0f); // Game loop while (!glfwWindowShouldClose(window)) { // Set frame time GLfloat currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; // Check and call events glfwPollEvents(); Do_Movement(); // Set texture samples shader.Use(); glUniform1i(glGetUniformLocation(shader.Program, "material.texture_diffuse1"), 0); glUniform1i(glGetUniformLocation(shader.Program, "shadowMap"), 1); // Change light position over time lightPos.x = sin(glfwGetTime() * 0.5f) * 6.0f; lightPos.z = 0; lightPos.y = cos(glfwGetTime() * 0.5f) * 6.0f; // 1. Render depth of scene to texture (from light's perspective) // - Get light projection/view matrix. glm::mat4 lightProjection, lightView; glm::mat4 lightSpaceMatrix; GLfloat near_plane = 0.5f, far_plane = 20.0f; lightProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane); //lightProjection = glm::perspective(45.0f, (GLfloat)SHADOW_WIDTH / (GLfloat)SHADOW_HEIGHT, near_plane, far_plane); // Note that if you use a perspective projection matrix you'll have to change the light position as the current light position isn't enough to reflect the whole scene. lightView = glm::lookAt(lightPos, glm::vec3(0.0f), glm::vec3(1.0)); lightSpaceMatrix = lightProjection * lightView; // - now render scene from light's point of view simpleDepthShader.Use(); glUniformMatrix4fv(glGetUniformLocation(simpleDepthShader.Program, "lightSpaceMatrix"), 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix)); glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT); glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); glClear(GL_DEPTH_BUFFER_BIT); RenderScene(simpleDepthShader); glm::mat4 model; model = glm::translate(model, glm::vec3(0.1f, -0.5f, 1.0f)); // Translate it down a bit so it's at the center of the scene model = glm::scale(model, glm::vec3(0.15f, 0.15f, 0.15f)); glUniformMatrix4fv(glGetUniformLocation(simpleDepthShader.Program, "model"), 1, GL_FALSE, glm::value_ptr(model)); ourModel.Draw(simpleDepthShader); glBindFramebuffer(GL_FRAMEBUFFER, 0); // 2. Render scene as normal glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); shader.Use(); glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f); glm::mat4 view = camera.GetViewMatrix(); glUniformMatrix4fv(glGetUniformLocation(shader.Program, "projection"), 1, GL_FALSE, glm::value_ptr(projection)); glUniformMatrix4fv(glGetUniformLocation(shader.Program, "view"), 1, GL_FALSE, glm::value_ptr(view)); // Set light uniforms glUniform3f(glGetUniformLocation(shader.Program, "viewPos"), camera.Position.x, camera.Position.y, camera.Position.z); // Point light 1 glUniform3f(glGetUniformLocation(shader.Program, "pointLights[0].position"), pointLightPositions[0].x, pointLightPositions[0].y, pointLightPositions[0].z); glUniform3f(glGetUniformLocation(shader.Program, "pointLights[0].ambient"), 0.05f, 0.05f, 0.05f); glUniform3f(glGetUniformLocation(shader.Program, "pointLights[0].diffuse"), 1.0f, 1.0f, 1.0f); glUniform3f(glGetUniformLocation(shader.Program, "pointLights[0].specular"), 0.5f, 0.5f, 0.5f); glUniform1f(glGetUniformLocation(shader.Program, "pointLights[0].constant"), 1.0f); glUniform1f(glGetUniformLocation(shader.Program, "pointLights[0].linear"), 0.009); glUniform1f(glGetUniformLocation(shader.Program, "pointLights[0].quadratic"), 0.0032); // Point light 2 glUniform3f(glGetUniformLocation(shader.Program, "pointLights[1].position"), pointLightPositions[1].x, pointLightPositions[1].y, pointLightPositions[1].z); glUniform3f(glGetUniformLocation(shader.Program, "pointLights[1].ambient"), 0.05f, 0.05f, 0.05f); glUniform3f(glGetUniformLocation(shader.Program, "pointLights[1].diffuse"), 1.0f, 1.0f, 1.0f); glUniform3f(glGetUniformLocation(shader.Program, "pointLights[1].specular"), 0.5f, 0.5f, 0.5f); glUniform1f(glGetUniformLocation(shader.Program, "pointLights[1].constant"), 1.0f); glUniform1f(glGetUniformLocation(shader.Program, "pointLights[1].linear"), 0.009); glUniform1f(glGetUniformLocation(shader.Program, "pointLights[1].quadratic"), 0.0032); glUniform3fv(glGetUniformLocation(shader.Program, "ViewPos"), 1, &camera.Position[0]); glUniformMatrix4fv(glGetUniformLocation(shader.Program, "lightSpaceMatrix"), 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix)); // Enable/Disable shadows by pressing 'SPACE' glUniform1i(glGetUniformLocation(shader.Program, "shadows"), shadows); glUniform1i(glGetUniformLocation(shader.Program, "pointLightCount"), 2); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, woodTexture); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, depthMap); RenderScene(shader); glActiveTexture(GL_TEXTURE15); glBindTexture(GL_TEXTURE_2D, woodTexture); glUniform1i(glGetUniformLocation(shader.Program, "material.texture_diffuse1"), 1); glActiveTexture(GL_TEXTURE16); glBindTexture(GL_TEXTURE_2D, depthMap); glUniform1i(glGetUniformLocation(shader.Program, "shadowMap"), 16); glUniformMatrix4fv(glGetUniformLocation(shader.Program, "model"), 1, GL_FALSE, glm::value_ptr(model)); ourModel.Draw(shader); // Draw the lamps lampShader.Use(); glUniformMatrix4fv(glGetUniformLocation(lampShader.Program, "projection"), 1, GL_FALSE, glm::value_ptr(projection)); glUniformMatrix4fv(glGetUniformLocation(lampShader.Program, "view"), 1, GL_FALSE, glm::value_ptr(view)); for (GLuint i = 0; i < 2; i++) { model = glm::mat4(); model = glm::translate(model, pointLightPositions[i]); if (i == 1) model = glm::rotate(model, glm::radians(180.0f), glm::vec3(1.0f, 0.0f, 0.0f)); model = glm::scale(model, glm::vec3(0.3f, 0.3f, 0.3f)); // Downscale lamp object (a bit too large) glUniformMatrix4fv(glGetUniformLocation(lampShader.Program, "model"), 1, GL_FALSE, glm::value_ptr(model)); GLfloat camX = sin(glfwGetTime() * 0.5f) * 10.0f; GLfloat camZ = 0; GLfloat camY = cos(glfwGetTime() * 0.5f) * 10.0f; glm::vec4 light; if (camY <= 0.0) light = glm::vec4(1.0f, 1.0f, 0.0f, 1.0f); else light = glm::vec4(1.0f); glUniform4f(glGetUniformLocation(lampShader.Program, "light"), light.x, light.y, light.z, light.w); GLint modelLoc = glGetUniformLocation(lampShader.Program, "model"); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); pointLightPositions[i] = glm::vec3(camX, camY, camZ); lightBulb.Draw(lampShader); } // Swap the buffers glfwSwapBuffers(window); } glfwTerminate(); return 0; }
int main() { // msaa glfwWindowHint(GLFW_SAMPLES, 4); GLFWwindow * window = initWindow(windowWidth, windowHeight); if (!window) { glfwTerminate(); return -1; } glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetKeyCallback(window, key_callback); glfwSetCursorPosCallback(window, cursor_callback); glfwSetScrollCallback(window, scroll_callback); glEnable(GL_DEPTH_TEST); // prepare texture loading library(devil) init_texture_loading(); //plane Shader simpleDepthShader("data/shaders/shadow_mapping_depth.vs", "data/shaders/shadow_mapping_depth.frag"); Model ourModel("data/models/nanosuit/nanosuit.obj"); GLfloat planeVertices[] = { // Positions // Normals // Texture Coords 2.0f, 0.0f, 2.0f, 0.0f, 1.0f, 0.0f, 2.0f, 0.0f, -2.0f, 0.0f, -2.0f, 0.0f, 1.0f, 0.0f, 0.0f, 2.0f, -2.0f, 0.0f, 2.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 2.0f, 0.0f, 2.0f, 0.0f, 1.0f, 0.0f, 2.0f, 0.0f, 2.0f, 0.0f, -2.0f, 0.0f, 1.0f, 0.0f, 2.0f, 2.0f, -2.0f, 0.0f, -2.0f, 0.0f, 1.0f, 0.0f, 0.0f, 2.0f }; // Setup plane VAO xzhs GLuint planeVBO; GLuint woodTexture; GLuint rockTexture; glGenVertexArrays(1, &planeVAO); glGenBuffers(1, &planeVBO); glBindVertexArray(planeVAO); glBindBuffer(GL_ARRAY_BUFFER, planeVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(planeVertices), &planeVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); glBindVertexArray(0); // Load textures woodTexture = load_texture("data/textures/wood.png"); rockTexture = load_texture("data/textures/rock.jpg"); // Configure depth map FBO const GLuint SHADOW_WIDTH = 1024, SHADOW_HEIGHT = 1024; GLuint depthMapFBO; glGenFramebuffers(1, &depthMapFBO); // - Create depth texture GLuint depthMap; glGenTextures(1, &depthMap); glBindTexture(GL_TEXTURE_2D, depthMap); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); GLfloat borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f }; glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); glBindFramebuffer(GL_FRAMEBUFFER, 0); glClearColor(0.1f, 0.1f, 0.1f, 1.0f); //xzhe Shader shaders("data/shaders/shader.vert", "data/shaders/shader.frag"); Shader colorShaders("data/shaders/shaderColorUniform.vert", "data/shaders/shaderColorUniform.frag"); Shader domeShaders("data/shaders/dome.vert", "data/shaders/dome.frag"); Shader lightShaders("data/shaders/lightShader.vert", "data/shaders/lightShader.frag"); Shader spriteShaders("data/shaders/spriteShader.vert", "data/shaders/spriteShader.frag"); Shader starShaders("data/shaders/spriteShader.vert", "data/shaders/stars.frag"); std::cout << "Loading models..." << std::endl; Model dome("data/models/geodesic_dome.obj"); Model landscape("data/models/landscape.obj"); std::cout << "Models loaded!" << std::endl; std::cout << "Loading extra textures..." << std::endl; GLuint domeColor = load_texture("data/textures/sky.png", true, GL_MIRRORED_REPEAT, GL_MIRRORED_REPEAT); GLuint domeGlow = load_texture("data/textures/glow.png", true, GL_MIRRORED_REPEAT, GL_MIRRORED_REPEAT); Sprite sun("data/textures/sun.png"); Sprite moon("data/textures/moon.png"); Sprite star("data/textures/star.png"); // enable blending! glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // enable msaa(multisample anti-aliasing) glEnable(GL_MULTISAMPLE); std::vector<glm::mat4> starModels(256); for (auto& m : starModels) { m = glm::rotate(m, glm::radians(rand_rotate()), glm::vec3(1.0f, 0.0f, 0.0f)); m = glm::rotate(m, glm::radians(rand_rotate()), glm::vec3(0.0f, 1.0f, 0.0f)); m = glm::rotate(m, glm::radians(rand_rotate()), glm::vec3(0.0f, 0.0f, 1.0f)); m = glm::translate(m, glm::vec3(5.0f, 0.0f, 0.0f)); m = glm::rotate(m, glm::radians(rand_rotate()), glm::vec3(1.0f, 0.0f, 0.0f)); m = glm::rotate(m, glm::radians(rand_rotate()), glm::vec3(0.0f, 1.0f, 0.0f)); } double last_frame = glfwGetTime(); while (!glfwWindowShouldClose(window)) { double current_frame = glfwGetTime(); double delta_time = current_frame - last_frame; last_frame = current_frame; glfwPollEvents(); do_movement(delta_time); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glViewport(0, 0, windowWidth, windowHeight); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)windowWidth / (float)windowHeight, 0.1f, 100.0f); glm::mat4 view = camera.GetViewMatrix(); // sun float sunAngle = current_frame * 30.0f; glm::mat4 sunModel; sunModel = glm::rotate(sunModel, glm::radians(sunAngle), glm::vec3(0.0f, 0.0f, 1.0f)); sunModel = glm::translate(sunModel, glm::vec3(3.5f, 0.0f, 0.0f)); glm::vec3 sunPos = glm::vec3(sunModel * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); // moon float moonAngle = sunAngle + 180.0f; glm::mat4 moonModel; moonModel = glm::rotate(moonModel, glm::radians(moonAngle), glm::vec3(0.0f, 0.0f, 1.0f)); moonModel = glm::translate(moonModel, glm::vec3(3.5f, 0.0f, 0.0f)); // directional light DirLight dirLight(-sunPos, glm::vec3(0.8f, 0.8f, 0.8f)); // point light GLfloat light_pos_angle = glm::radians(60.0f * current_frame); glm::vec3 light_pos(1.2f + sin(light_pos_angle), 0.0f, 2.0f + cos(light_pos_angle)); glm::vec3 lightColor(1.0f, 1.0f, 1.0f); lightColor.r = sin(current_frame * 2.0f); lightColor.g = sin(current_frame * 0.7f); lightColor.b = sin(current_frame * 1.3f); PointLight pointLight(light_pos, lightColor * 0.5f); // spot light SpotLight spotLight(camera.Position, camera.Front, glm::vec3((GLfloat)flash_light_on)); shaders.Use(); shaders.SetUniform("view", view); shaders.SetUniform("projection", projection); shaders.SetUniform("ViewPos", camera.Position); dirLight.SetUniforms(shaders, "dirLight"); pointLight.SetUniforms(shaders, "pointLights[0]"); shaders.SetUniform("pointLightCount", 0); spotLight.SetUniforms(shaders, "spotLight"); shaders.SetUniform("material.shininess", 16.0f); colorShaders.Use(); colorShaders.SetUniform("view", view); colorShaders.SetUniform("projection", projection); colorShaders.SetUniform("ViewPos", camera.Position); dirLight.SetUniforms(colorShaders, "dirLight"); //pointLight.SetUniforms(colorShaders, "pointLights[0]"); colorShaders.SetUniform("pointLightCount", 0); spotLight.SetUniforms(colorShaders, "spotLight"); colorShaders.SetUniform("material.shininess", 1.8f); // make the dome and landscape pinned glm::mat4 pinnedView = glm::lookAt(glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f) + camera.Front, glm::vec3(0.0f, 1.0f, 0.0f)); if (enable_stars) { // stars starShaders.Use(); starShaders.SetUniform("view", view); starShaders.SetUniform("projection", projection); starShaders.SetUniform("groundBases[0]", 1.0f, 0.0f, 0.0f); starShaders.SetUniform("groundBases[1]", 0.0f, 0.0f, 1.0f); starShaders.SetUniform("groundUp", 0.0f, 1.0f, 0.0f); starShaders.SetUniform("sunPos", sunPos); for (const auto& m : starModels) { glm::mat4 model = glm::rotate(glm::mat4(), glm::radians(sunAngle), glm::vec3(0.0f, 0.0f, 1.0f)) * m; starShaders.SetUniform("model", model); star.Draw(starShaders); } } colorShaders.Use(); glm::mat4 lmodel; lmodel = glm::scale(lmodel, glm::vec3(3.0f, 3.0f, 3.0f)); lmodel = glm::translate(lmodel, glm::vec3(0.0f, 0.1f, 0.0f)); lmodel = glm::rotate(lmodel, glm::radians(30.0f), glm::vec3(0.0f, 1.0f, 0.0f)); glm::mat3 normalMatrix = glm::mat3(glm::transpose(glm::inverse(lmodel))); colorShaders.SetUniform("view", view); colorShaders.SetUniform("model", lmodel); colorShaders.SetUniform("normalMatrix", normalMatrix); colorShaders.SetUniform("Color", glm::vec4(0.93f, 0.79f, 0.69f, 1.0f)); landscape.Draw(colorShaders, false); domeShaders.Use(); domeShaders.SetUniform("view", view); domeShaders.SetUniform("projection", projection); glActiveTexture(GL_TEXTURE7); glBindTexture(GL_TEXTURE_2D, domeColor); glActiveTexture(GL_TEXTURE8); glBindTexture(GL_TEXTURE_2D, domeGlow); domeShaders.SetUniform("domeColor", 7); domeShaders.SetUniform("glow", 8); glm::mat4 dmodel; dmodel = glm::scale(dmodel, glm::vec3(4.0f, 4.0f, 4.0f)); domeShaders.SetUniform("model", dmodel); domeShaders.SetUniform("sunPos", sunPos); dome.Draw(domeShaders, false); // cheating billboarding to make the sun and moon always face the camera glm::mat4 sunModelView = view * sunModel; for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) sunModelView[i][j] = (GLfloat)(i == j); sunModelView = glm::scale(sunModelView, glm::vec3(0.5f, 0.5f, 0.5f)); glm::mat4 moonModelView = view * moonModel; for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) moonModelView[i][j] = (GLfloat)(i == j); moonModelView = glm::scale(moonModelView, glm::vec3(0.5f, 0.5f, 0.5f)); spriteShaders.Use(); spriteShaders.SetUniform("view", glm::mat4()); spriteShaders.SetUniform("projection", projection); spriteShaders.SetUniform("model", sunModelView); sun.Draw(spriteShaders); spriteShaders.SetUniform("model", moonModelView); moon.Draw(spriteShaders); //xzhs // Set texture samples shaders.Use(); glActiveTexture(GL_TEXTURE13); glBindTexture(GL_TEXTURE_2D, woodTexture); glActiveTexture(GL_TEXTURE14); glBindTexture(GL_TEXTURE_2D, rockTexture); glActiveTexture(GL_TEXTURE15); glBindTexture(GL_TEXTURE_2D, depthMap); shaders.SetUniform("material.texture_diffuse1", 14); shaders.SetUniform("material.texture_specular1", 14); shaders.SetUniform("shadowMap", 15); // 1. Render depth of scene to texture (from light's perspective) // - Get light projection/view matrix. glm::mat4 lightProjection, lightView; glm::mat4 lightSpaceMatrix; GLfloat near_plane = 1.0f, far_plane = 7.5f; lightProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane); lightView = glm::lookAt(sunPos, glm::vec3(0.0f), glm::vec3(1.0)); lightSpaceMatrix = lightProjection * lightView; // - now render scene from light's point of view simpleDepthShader.Use(); simpleDepthShader.SetUniform("lightSpaceMatrix", lightSpaceMatrix); glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT); glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); glClear(GL_DEPTH_BUFFER_BIT); RenderFloor(simpleDepthShader); RenderCubes(simpleDepthShader); glm::mat4 nmodel; nmodel = glm::translate(nmodel, glm::vec3(0.1f, 0.3f, -0.5f)); nmodel = glm::rotate(nmodel, glm::radians(70.0f), glm::vec3(0.0f, 1.0f, 0.0f)); nmodel = glm::scale(nmodel, glm::vec3(0.05f, 0.05f, 0.05f)); simpleDepthShader.SetUniform("model", nmodel); ourModel.Draw(simpleDepthShader); glBindFramebuffer(GL_FRAMEBUFFER, 0); // 2. Render scene as normal glViewport(0, 0, windowWidth, windowHeight); //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); shaders.Use(); shaders.SetUniform("projection", projection); shaders.SetUniform("view", view); shaders.SetUniform("ViewPos", camera.Position); // Set light uniforms // PointLight sunPointLight(sunPos, glm::vec3(0.02f, 0.02f, 0.02f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(0.5f, 0.5f, 0.5f)); // sunPointLight.SetUniforms(shaders, "pointLights[0]"); // shaders.SetUniform("pointLightCount", 0); dirLight.SetUniforms(shaders, "dirLight"); shaders.SetUniform("pointLightCount", 0); shaders.SetUniform("lightSpaceMatrix", lightSpaceMatrix); shaders.SetUniform("material.texture_diffuse1", 14); shaders.SetUniform("material.texture_specular1", 14); shaders.SetUniform("shadowMap", 15); RenderFloor(shaders); shaders.SetUniform("material.texture_diffuse1", 13); shaders.SetUniform("material.texture_specular1", 13); RenderCubes(shaders); shaders.SetUniform("model", nmodel); ourModel.Draw(shaders); //xzhe glfwSwapBuffers(window); } glfwTerminate(); return 0; }
// The MAIN function, from here we start our application and run our Game loop int main() { // Init GLFW glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", nullptr, nullptr); // Windowed glfwMakeContextCurrent(window); // Set the required callback functions glfwSetKeyCallback(window, key_callback); glfwSetCursorPosCallback(window, mouse_callback); glfwSetScrollCallback(window, scroll_callback); // Options glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // Initialize GLEW to setup the OpenGL Function pointers glewExperimental = GL_TRUE; glewInit(); // Define the viewport dimensions glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT); // Setup some OpenGL options glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); // Setup and compile our shaders Shader shader("point_shadows.vs", "point_shadows.frag"); Shader simpleDepthShader("point_shadows_depth.vs", "point_shadows_depth.frag", "point_shadows_depth.gs"); // Set texture samples shader.Use(); glUniform1i(glGetUniformLocation(shader.Program, "diffuseTexture"), 0); glUniform1i(glGetUniformLocation(shader.Program, "depthMap"), 1); // Light source glm::vec3 lightPos(0.0f, 0.0f, 0.0f); // Load textures woodTexture = loadTexture(FileSystem::getPath("resources/textures/wood.png").c_str()); // Configure depth map FBO const GLuint SHADOW_WIDTH = 1024, SHADOW_HEIGHT = 1024; GLuint depthMapFBO; glGenFramebuffers(1, &depthMapFBO); // Create depth cubemap texture GLuint depthCubemap; glGenTextures(1, &depthCubemap); glBindTexture(GL_TEXTURE_CUBE_MAP, depthCubemap); for (GLuint i = 0; i < 6; ++i) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); // Attach cubemap as depth map FBO's color buffer glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthCubemap, 0); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) std::cout << "Framebuffer not complete!" << std::endl; glBindFramebuffer(GL_FRAMEBUFFER, 0); glClearColor(0.1f, 0.1f, 0.1f, 1.0f); // Game loop while (!glfwWindowShouldClose(window)) { // Set frame time GLfloat currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; // Check and call events glfwPollEvents(); Do_Movement(); // Move light position over time //lightPos.z = sin(glfwGetTime() * 0.5) * 3.0; // 0. Create depth cubemap transformation matrices GLfloat aspect = (GLfloat)SHADOW_WIDTH / (GLfloat)SHADOW_HEIGHT; GLfloat near = 1.0f; GLfloat far = 25.0f; glm::mat4 shadowProj = glm::perspective(90.0f, aspect, near, far); std::vector<glm::mat4> shadowTransforms; shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3( 1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0))); shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(-1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0))); shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3( 0.0, 1.0, 0.0), glm::vec3(0.0, 0.0, 1.0))); shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3( 0.0, -1.0, 0.0), glm::vec3(0.0, 0.0, -1.0))); shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3( 0.0, 0.0, 1.0), glm::vec3(0.0, -1.0, 0.0))); shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3( 0.0, 0.0, -1.0), glm::vec3(0.0, -1.0, 0.0))); // 1. Render scene to depth cubemap glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT); glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); glClear(GL_DEPTH_BUFFER_BIT); simpleDepthShader.Use(); for (GLuint i = 0; i < 6; ++i) glUniformMatrix4fv(glGetUniformLocation(simpleDepthShader.Program, ("shadowTransforms[" + std::to_string(i) + "]").c_str()), 1, GL_FALSE, glm::value_ptr(shadowTransforms[i])); glUniform1f(glGetUniformLocation(simpleDepthShader.Program, "far_plane"), far); glUniform3fv(glGetUniformLocation(simpleDepthShader.Program, "lightPos"), 1, &lightPos[0]); RenderScene(simpleDepthShader); glBindFramebuffer(GL_FRAMEBUFFER, 0); // 2. Render scene as normal glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); shader.Use(); glm::mat4 projection = glm::perspective(camera.Zoom, (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f); glm::mat4 view = camera.GetViewMatrix(); glUniformMatrix4fv(glGetUniformLocation(shader.Program, "projection"), 1, GL_FALSE, glm::value_ptr(projection)); glUniformMatrix4fv(glGetUniformLocation(shader.Program, "view"), 1, GL_FALSE, glm::value_ptr(view)); // Set light uniforms glUniform3fv(glGetUniformLocation(shader.Program, "lightPos"), 1, &lightPos[0]); glUniform3fv(glGetUniformLocation(shader.Program, "viewPos"), 1, &camera.Position[0]); // Enable/Disable shadows by pressing 'SPACE' glUniform1i(glGetUniformLocation(shader.Program, "shadows"), shadows); glUniform1f(glGetUniformLocation(shader.Program, "far_plane"), far); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, woodTexture); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_CUBE_MAP, depthCubemap); RenderScene(shader); // Swap the buffers glfwSwapBuffers(window); } glfwTerminate(); return 0; }