diff --git a/CMakeLists.txt b/CMakeLists.txt index bbdd7a4..4402538 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,9 +122,10 @@ set(4.advanced_opengl 8.advanced_glsl_ubo 9.1.geometry_shader_houses 9.2.geometry_shader_exploding - 9.3.geometry_shader_normal_visualization + 9.3.geometry_shader_normals 10.1.instancing_quads - 10.2.instancing_asteroids + 10.2.asteroids + 10.3.asteroids_instanced 11.anti_aliasing_offscreen ) diff --git a/src/4.advanced_opengl/11.anti_aliasing_offscreen/11.1.anti_aliasing.fs b/src/4.advanced_opengl/11.anti_aliasing_offscreen/11.1.anti_aliasing.fs new file mode 100644 index 0000000..fce61e0 --- /dev/null +++ b/src/4.advanced_opengl/11.anti_aliasing_offscreen/11.1.anti_aliasing.fs @@ -0,0 +1,7 @@ +#version 330 core +out vec4 FragColor; + +void main() +{ + FragColor = vec4(0.0, 1.0, 0.0, 1.0); +} \ No newline at end of file diff --git a/src/4.advanced_opengl/11.anti_aliasing_offscreen/11.1.anti_aliasing.vs b/src/4.advanced_opengl/11.anti_aliasing_offscreen/11.1.anti_aliasing.vs new file mode 100644 index 0000000..4a80ebb --- /dev/null +++ b/src/4.advanced_opengl/11.anti_aliasing_offscreen/11.1.anti_aliasing.vs @@ -0,0 +1,11 @@ +#version 330 core +layout (location = 0) in vec3 aPos; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main() +{ + gl_Position = projection * view * model * vec4(aPos, 1.0f); +} \ No newline at end of file diff --git a/src/4.advanced_opengl/11.anti_aliasing_offscreen/11.2.aa_post.fs b/src/4.advanced_opengl/11.anti_aliasing_offscreen/11.2.aa_post.fs new file mode 100644 index 0000000..1846180 --- /dev/null +++ b/src/4.advanced_opengl/11.anti_aliasing_offscreen/11.2.aa_post.fs @@ -0,0 +1,13 @@ +#version 330 core +out vec4 FragColor; + +in vec2 TexCoords; + +uniform sampler2D screenTexture; + +void main() +{ + vec3 col = texture(screenTexture, TexCoords).rgb; + float grayscale = 0.2126 * col.r + 0.7152 * col.g + 0.0722 * col.b; + FragColor = vec4(vec3(grayscale), 1.0); +} \ No newline at end of file diff --git a/src/4.advanced_opengl/11.anti_aliasing_offscreen/11.2.aa_post.vs b/src/4.advanced_opengl/11.anti_aliasing_offscreen/11.2.aa_post.vs new file mode 100644 index 0000000..1376b62 --- /dev/null +++ b/src/4.advanced_opengl/11.anti_aliasing_offscreen/11.2.aa_post.vs @@ -0,0 +1,11 @@ +#version 330 core +layout (location = 0) in vec2 aPos; +layout (location = 1) in vec2 aTexCoords; + +out vec2 TexCoords; + +void main() +{ + TexCoords = aTexCoords; + gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0); +} \ No newline at end of file diff --git a/src/4.advanced_opengl/11.anti_aliasing_offscreen/11.anti_aliasing.fs b/src/4.advanced_opengl/11.anti_aliasing_offscreen/11.anti_aliasing.fs deleted file mode 100644 index 692a6a3..0000000 --- a/src/4.advanced_opengl/11.anti_aliasing_offscreen/11.anti_aliasing.fs +++ /dev/null @@ -1,7 +0,0 @@ -#version 330 core -out vec4 color; - -void main() -{ - color = vec4(0.0, 1.0, 0.0, 1.0); -} \ No newline at end of file diff --git a/src/4.advanced_opengl/11.anti_aliasing_offscreen/11.anti_aliasing.vs b/src/4.advanced_opengl/11.anti_aliasing_offscreen/11.anti_aliasing.vs deleted file mode 100644 index 9cdccd8..0000000 --- a/src/4.advanced_opengl/11.anti_aliasing_offscreen/11.anti_aliasing.vs +++ /dev/null @@ -1,11 +0,0 @@ -#version 330 core -layout (location = 0) in vec3 position; - -uniform mat4 model; -uniform mat4 view; -uniform mat4 projection; - -void main() -{ - gl_Position = projection * view * model * vec4(position, 1.0f); -} \ No newline at end of file diff --git a/src/4.advanced_opengl/11.anti_aliasing_offscreen/anti_aliasing_offscreen.cpp b/src/4.advanced_opengl/11.anti_aliasing_offscreen/anti_aliasing_offscreen.cpp index debce4b..12da46a 100644 --- a/src/4.advanced_opengl/11.anti_aliasing_offscreen/anti_aliasing_offscreen.cpp +++ b/src/4.advanced_opengl/11.anti_aliasing_offscreen/anti_aliasing_offscreen.cpp @@ -1,255 +1,318 @@ -// GLEW -#define GLEW_STATIC -#include - -// GLFW +#include #include +#include -// GL includes -#include -#include - -// GLM Mathemtics #include #include #include -// Properties -GLuint screenWidth = 800, screenHeight = 600; +#include +#include +#include +#include -// Function prototypes -void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode); +#include + +void framebuffer_size_callback(GLFWwindow* window, int width, int height); void mouse_callback(GLFWwindow* window, double xpos, double ypos); void scroll_callback(GLFWwindow* window, double xoffset, double yoffset); -void Do_Movement(); -GLuint generateMultiSampleTexture(GLuint samples); +void processInput(GLFWwindow *window); -// Camera +// settings +const unsigned int SCR_WIDTH = 1280; +const unsigned int SCR_HEIGHT = 720; + +// camera Camera camera(glm::vec3(0.0f, 0.0f, 3.0f)); -bool keys[1024]; -GLfloat lastX = 400, lastY = 300; +float lastX = (float)SCR_WIDTH / 2.0; +float lastY = (float)SCR_HEIGHT / 2.0; bool firstMouse = true; -GLfloat deltaTime = 0.0f; -GLfloat lastFrame = 0.0f; +// timing +float deltaTime = 0.0f; +float lastFrame = 0.0f; -// The MAIN function, from here we start our application and run our Game loop int main() { - // Init GLFW + // 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_RESIZABLE, GL_FALSE); - GLFWwindow* window = glfwCreateWindow(screenWidth, screenHeight, "LearnOpenGL", nullptr, nullptr); // Windowed + // glfw window creation + // -------------------- + GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL); glfwMakeContextCurrent(window); - - // Set the required callback functions - glfwSetKeyCallback(window, key_callback); + if (window == NULL) + { + std::cout << "Failed to create GLFW window" << std::endl; + glfwTerminate(); + return -1; + } + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glfwSetCursorPosCallback(window, mouse_callback); glfwSetScrollCallback(window, scroll_callback); - // Options - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + // tell GLFW to capture our mouse + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - // Initialize GLEW to setup the OpenGL Function pointers - glewExperimental = GL_TRUE; - glewInit(); + // glad: load all OpenGL function pointers + // --------------------------------------- + if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) + { + std::cout << "Failed to initialize GLAD" << std::endl; + return -1; + } - // Define the viewport dimensions - glViewport(0, 0, screenWidth, screenHeight); - - // Setup OpenGL options - glEnable(GL_MULTISAMPLE); // Enabled by default on some drivers, but not all so always enable to make sure + // configure global opengl state + // ----------------------------- glEnable(GL_DEPTH_TEST); - // Setup and compile our shaders - Shader shader("anti_aliasing.vs", "anti_aliasing.frag"); + // build and compile shaders + // ------------------------- + Shader shader("11.1.anti_aliasing.vs", "11.1.anti_aliasing.fs"); + Shader screenShader("11.2.aa_post.vs", "11.2.aa_post.fs"); - #pragma region "object_initialization" - // Set the object data (buffers, vertex attributes) - GLfloat cubeVertices[] = { - // Positions - -0.5f, -0.5f, -0.5f, - 0.5f, -0.5f, -0.5f, - 0.5f, 0.5f, -0.5f, - 0.5f, 0.5f, -0.5f, - -0.5f, 0.5f, -0.5f, - -0.5f, -0.5f, -0.5f, - - -0.5f, -0.5f, 0.5f, - 0.5f, -0.5f, 0.5f, - 0.5f, 0.5f, 0.5f, - 0.5f, 0.5f, 0.5f, - -0.5f, 0.5f, 0.5f, - -0.5f, -0.5f, 0.5f, - - -0.5f, 0.5f, 0.5f, - -0.5f, 0.5f, -0.5f, - -0.5f, -0.5f, -0.5f, - -0.5f, -0.5f, -0.5f, - -0.5f, -0.5f, 0.5f, - -0.5f, 0.5f, 0.5f, - - 0.5f, 0.5f, 0.5f, - 0.5f, 0.5f, -0.5f, - 0.5f, -0.5f, -0.5f, - 0.5f, -0.5f, -0.5f, - 0.5f, -0.5f, 0.5f, - 0.5f, 0.5f, 0.5f, - - -0.5f, -0.5f, -0.5f, - 0.5f, -0.5f, -0.5f, - 0.5f, -0.5f, 0.5f, - 0.5f, -0.5f, 0.5f, - -0.5f, -0.5f, 0.5f, - -0.5f, -0.5f, -0.5f, - - -0.5f, 0.5f, -0.5f, + // set up vertex data (and buffer(s)) and configure vertex attributes + // ------------------------------------------------------------------ + float cubeVertices[] = { + // positions + -0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, - 0.5f, 0.5f, 0.5f, - 0.5f, 0.5f, 0.5f, - -0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, -0.5f, + -0.5f, 0.5f, -0.5f, + -0.5f, -0.5f, -0.5f, + + -0.5f, -0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, + -0.5f, -0.5f, 0.5f, + + -0.5f, 0.5f, 0.5f, + -0.5f, 0.5f, -0.5f, + -0.5f, -0.5f, -0.5f, + -0.5f, -0.5f, -0.5f, + -0.5f, -0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, + + 0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + + -0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + -0.5f, -0.5f, 0.5f, + -0.5f, -0.5f, -0.5f, + + -0.5f, 0.5f, -0.5f, + 0.5f, 0.5f, -0.5f, + 0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f }; - // Setup cube VAO - GLuint cubeVAO, cubeVBO; + float quadVertices[] = { // vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates. + // positions // texCoords + -1.0f, 1.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 0.0f, + + -1.0f, 1.0f, 0.0f, 1.0f, + 1.0f, -1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 1.0f + }; + // setup cube VAO + unsigned int cubeVAO, cubeVBO; glGenVertexArrays(1, &cubeVAO); glGenBuffers(1, &cubeVBO); glBindVertexArray(cubeVAO); glBindBuffer(GL_ARRAY_BUFFER, cubeVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); - glBindVertexArray(0); - #pragma endregion + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); + // setup screen VAO + unsigned int quadVAO, quadVBO; + glGenVertexArrays(1, &quadVAO); + glGenBuffers(1, &quadVBO); + glBindVertexArray(quadVAO); + glBindBuffer(GL_ARRAY_BUFFER, quadVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))); - // Framebuffers - GLuint framebuffer; + // configure MSAA framebuffer + // -------------------------- + unsigned int framebuffer; glGenFramebuffers(1, &framebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); - // Create a multisampled color attachment texture - GLuint textureColorBufferMultiSampled = generateMultiSampleTexture(4); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + // create a multisampled color attachment texture + unsigned int textureColorBufferMultiSampled; + glGenTextures(1, &textureColorBufferMultiSampled); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureColorBufferMultiSampled); + glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGB, SCR_WIDTH, SCR_HEIGHT, GL_TRUE); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, textureColorBufferMultiSampled, 0); - // Create a renderbuffer object for depth and stencil attachments - GLuint rbo; + // create a (also multisampled) renderbuffer object for depth and stencil attachments + unsigned int rbo; glGenRenderbuffers(1, &rbo); - glBindRenderbuffer(GL_RENDERBUFFER, rbo); - glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, screenWidth, screenHeight); + glBindRenderbuffer(GL_RENDERBUFFER, rbo); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, SCR_WIDTH, SCR_HEIGHT); glBindRenderbuffer(GL_RENDERBUFFER, 0); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); - if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << std::endl; + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << endl; glBindFramebuffer(GL_FRAMEBUFFER, 0); - - // Game loop - while(!glfwWindowShouldClose(window)) + // configure second post-processing framebuffer + unsigned int intermediateFBO; + glGenFramebuffers(1, &intermediateFBO); + glBindFramebuffer(GL_FRAMEBUFFER, intermediateFBO); + // create a color attachment texture + unsigned int screenTexture; + glGenTextures(1, &screenTexture); + glBindTexture(GL_TEXTURE_2D, screenTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, screenTexture, 0); // we only need a color buffer + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + cout << "ERROR::FRAMEBUFFER:: Intermediate framebuffer is not complete!" << endl; + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + // shader configuration + // -------------------- + shader.use(); + screenShader.setInt("screenTexture", 0); + + // render loop + // ----------- + while (!glfwWindowShouldClose(window)) { - // Set frame time - GLfloat currentFrame = glfwGetTime(); + // per-frame time logic + // -------------------- + float currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; - // Check and call events - glfwPollEvents(); - Do_Movement(); - - // 1. Draw scene as normal in multisampled buffers - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + // input + // ----- + processInput(window); + + // render + // ------ glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // 1. draw scene as normal in multisampled buffers + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + glClearColor(0.1f, 0.1f, 0.1f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + // Set transformation matrices - shader.Use(); - glm::mat4 projection = glm::perspective(camera.Zoom, (GLfloat)screenWidth/(GLfloat)screenHeight, 0.1f, 1000.0f); - glUniformMatrix4fv(glGetUniformLocation(shader.Program, "projection"), 1, GL_FALSE, glm::value_ptr(projection)); - glUniformMatrix4fv(glGetUniformLocation(shader.Program, "view"), 1, GL_FALSE, glm::value_ptr(camera.GetViewMatrix())); - glUniformMatrix4fv(glGetUniformLocation(shader.Program, "model"), 1, GL_FALSE, glm::value_ptr(glm::mat4())); - + shader.use(); + glm::mat4 projection = glm::perspective(camera.Zoom, (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 1000.0f); + shader.setMat4("projection", projection); + shader.setMat4("view", camera.GetViewMatrix()); + shader.setMat4("model", glm::mat4()); + glBindVertexArray(cubeVAO); glDrawArrays(GL_TRIANGLES, 0, 36); - glBindVertexArray(0); - // 2. Now blit multisampled buffer(s) to default framebuffers + // 2. now blit multisampled buffer(s) to normal colorbuffer of intermediate FBO. Image is stored in screenTexture glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - glBlitFramebuffer(0, 0, screenWidth, screenHeight, 0, 0, screenWidth, screenHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); - - // Swap the buffers - glfwSwapBuffers(window); - } + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, intermediateFBO); + glBlitFramebuffer(0, 0, SCR_WIDTH, SCR_HEIGHT, 0, 0, SCR_WIDTH, SCR_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST); + // 3. now render quad with scene's visuals as its texture image + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_DEPTH_TEST); + + // Draw Screen quad + screenShader.use(); + glBindVertexArray(quadVAO); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, screenTexture); // use the now resolved color attachment as the quad's texture + glDrawArrays(GL_TRIANGLES, 0, 6); + + // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) + // ------------------------------------------------------------------------------- + glfwSwapBuffers(window); + glfwPollEvents(); + } glfwTerminate(); return 0; } -GLuint generateMultiSampleTexture(GLuint samples) +// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly +// --------------------------------------------------------------------------------------------------------- +void processInput(GLFWwindow *window) { - GLuint texture; - glGenTextures(1, &texture); + if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) + glfwSetWindowShouldClose(window, true); - glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture); - glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGB, screenWidth, screenHeight, GL_TRUE); - glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); - - return texture; -} - -#pragma region "User input" - -// Moves/alters the camera positions based on user input -void Do_Movement() -{ - // Camera controls - if(keys[GLFW_KEY_W]) + float cameraSpeed = 2.5 * deltaTime; + if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) camera.ProcessKeyboard(FORWARD, deltaTime); - if(keys[GLFW_KEY_S]) + if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) camera.ProcessKeyboard(BACKWARD, deltaTime); - if(keys[GLFW_KEY_A]) + if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) camera.ProcessKeyboard(LEFT, deltaTime); - if(keys[GLFW_KEY_D]) + if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) camera.ProcessKeyboard(RIGHT, deltaTime); } -// Is called whenever a key is pressed/released via GLFW -void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) +// glfw: whenever the window size changed (by OS or user resize) this callback function executes +// --------------------------------------------------------------------------------------------- +void framebuffer_size_callback(GLFWwindow* window, int width, int height) { - if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) - glfwSetWindowShouldClose(window, GL_TRUE); - - if(action == GLFW_PRESS) - keys[key] = true; - else if(action == GLFW_RELEASE) - keys[key] = false; + // make sure the viewport matches the new window dimensions; note that width and + // height will be significantly larger than specified on retina displays. + glViewport(0, 0, width, height); } + +// glfw: whenever the mouse moves, this callback is called +// ------------------------------------------------------- void mouse_callback(GLFWwindow* window, double xpos, double ypos) { - if(firstMouse) + if (firstMouse) { lastX = xpos; lastY = ypos; firstMouse = false; } - GLfloat xoffset = xpos - lastX; - GLfloat yoffset = lastY - ypos; - + float xoffset = xpos - lastX; + float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top + lastX = xpos; lastY = ypos; camera.ProcessMouseMovement(xoffset, yoffset); -} +} +// glfw: whenever the mouse scroll wheel scrolls, this callback is called +// ---------------------------------------------------------------------- void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) { camera.ProcessMouseScroll(yoffset); -} - -#pragma endregion \ No newline at end of file +} \ No newline at end of file