diff --git a/src/4.advanced_opengl/9.1.geometry_shader_houses/9.1.geometry_shader.fs b/src/4.advanced_opengl/9.1.geometry_shader_houses/9.1.geometry_shader.fs index 6249a54..aa8966d 100644 --- a/src/4.advanced_opengl/9.1.geometry_shader_houses/9.1.geometry_shader.fs +++ b/src/4.advanced_opengl/9.1.geometry_shader_houses/9.1.geometry_shader.fs @@ -1,8 +1,9 @@ #version 330 core +out vec4 FragColor; + in vec3 fColor; -out vec4 color; void main() { - color = vec4(fColor, 1.0f); + FragColor = vec4(fColor, 1.0); } \ No newline at end of file diff --git a/src/4.advanced_opengl/9.1.geometry_shader_houses/9.1.geometry_shader.vs b/src/4.advanced_opengl/9.1.geometry_shader_houses/9.1.geometry_shader.vs index d07b142..d899a8e 100644 --- a/src/4.advanced_opengl/9.1.geometry_shader_houses/9.1.geometry_shader.vs +++ b/src/4.advanced_opengl/9.1.geometry_shader_houses/9.1.geometry_shader.vs @@ -1,6 +1,6 @@ #version 330 core -layout (location = 0) in vec2 position; -layout (location = 1) in vec3 color; +layout (location = 0) in vec2 aPos; +layout (location = 1) in vec3 aColor; out VS_OUT { vec3 color; @@ -8,6 +8,6 @@ out VS_OUT { void main() { - gl_Position = vec4(position.x, position.y, 0.0f, 1.0f); - vs_out.color = color; + vs_out.color = aColor; + gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0); } \ No newline at end of file diff --git a/src/4.advanced_opengl/9.1.geometry_shader_houses/geometry_shader_houses.cpp b/src/4.advanced_opengl/9.1.geometry_shader_houses/geometry_shader_houses.cpp index 56dd846..c3be032 100644 --- a/src/4.advanced_opengl/9.1.geometry_shader_houses/geometry_shader_houses.cpp +++ b/src/4.advanced_opengl/9.1.geometry_shader_houses/geometry_shader_houses.cpp @@ -1,101 +1,107 @@ -// GLEW -#define GLEW_STATIC -#include - -// GLFW +#include #include -// GL includes +#include #include -// Properties -GLuint screenWidth = 800, screenHeight = 600; +#include -bool keys[1024]; -void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode); +void framebuffer_size_callback(GLFWwindow* window, int width, int height); + +// settings +const unsigned int SCR_WIDTH = 1280; +const unsigned int SCR_HEIGHT = 720; -// 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); + if (window == NULL) + { + std::cout << "Failed to create GLFW window" << std::endl; + glfwTerminate(); + return -1; + } - // Options - 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; + } - // Set the required callback functions - glfwSetKeyCallback(window, key_callback); + // configure global opengl state + // ----------------------------- + glEnable(GL_DEPTH_TEST); - // Initialize GLEW to setup the OpenGL Function pointers - glewExperimental = GL_TRUE; - glewInit(); + // build and compile shaders + // ------------------------- + Shader shader("9.1.geometry_shader.vs", "9.1.geometry_shader.fs", "9.1.geometry_shader.gs"); - // Define the viewport dimensions - glViewport(0, 0, screenWidth, screenHeight); - - // Setup and compile our shaders - Shader shader("geometry_shader.vs", "geometry_shader.frag", "geometry_shader.gs"); - - // Vertex data - GLfloat points[] = { - -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // Top-left - 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right - 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-right - -0.5f, -0.5f, 1.0f, 1.0f, 0.0f // Bottom-left + // set up vertex data (and buffer(s)) and configure vertex attributes + // ------------------------------------------------------------------ + float points[] = { + -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // top-left + 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // top-right + 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // bottom-right + -0.5f, -0.5f, 1.0f, 1.0f, 0.0f // bottom-left }; - GLuint VBO, VAO; + unsigned int VBO, VAO; glGenBuffers(1, &VBO); glGenVertexArrays(1, &VAO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(points), &points, GL_STATIC_DRAW); glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), 0); glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(GLfloat))); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2 * sizeof(float))); glBindVertexArray(0); - //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - // Game loop - while(!glfwWindowShouldClose(window)) + // render loop + // ----------- + while (!glfwWindowShouldClose(window)) { - // Check and call events - glfwPollEvents(); - - // Clear buffers + // render + // ------ glClearColor(0.1f, 0.1f, 0.1f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - // Draw points - shader.Use(); + // draw points + shader.use(); glBindVertexArray(VAO); glDrawArrays(GL_POINTS, 0, 4); - glBindVertexArray(0); - - // Swap the buffers + + // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) + // ------------------------------------------------------------------------------- glfwSwapBuffers(window); + glfwPollEvents(); } + // optional: de-allocate all resources once they've outlived their purpose: + // ------------------------------------------------------------------------ + glDeleteVertexArrays(1, &VAO); + glDeleteBuffers(1, &VBO); + glfwTerminate(); return 0; } -// 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); +} \ No newline at end of file diff --git a/src/4.advanced_opengl/9.2.geometry_shader_exploding/9.2.geometry_shader.fs b/src/4.advanced_opengl/9.2.geometry_shader_exploding/9.2.geometry_shader.fs index 6249a54..7d157ae 100644 --- a/src/4.advanced_opengl/9.2.geometry_shader_exploding/9.2.geometry_shader.fs +++ b/src/4.advanced_opengl/9.2.geometry_shader_exploding/9.2.geometry_shader.fs @@ -1,8 +1,12 @@ #version 330 core -in vec3 fColor; -out vec4 color; +out vec4 FragColor; + +in vec2 TexCoords; + +uniform sampler2D texture_diffuse1; void main() { - color = vec4(fColor, 1.0f); -} \ No newline at end of file + FragColor = texture(texture_diffuse1, TexCoords); +} + diff --git a/src/4.advanced_opengl/9.2.geometry_shader_exploding/9.2.geometry_shader.gs b/src/4.advanced_opengl/9.2.geometry_shader_exploding/9.2.geometry_shader.gs index 4f24075..1e23bd2 100644 --- a/src/4.advanced_opengl/9.2.geometry_shader_exploding/9.2.geometry_shader.gs +++ b/src/4.advanced_opengl/9.2.geometry_shader_exploding/9.2.geometry_shader.gs @@ -1,30 +1,40 @@ #version 330 core -layout (points) in; -layout (triangle_strip, max_vertices = 5) out; +layout (triangles) in; +layout (triangle_strip, max_vertices = 3) out; in VS_OUT { - vec3 color; + vec2 texCoords; } gs_in[]; -out vec3 fColor; +out vec2 TexCoords; -void build_house(vec4 position) -{ - fColor = gs_in[0].color; // gs_in[0] since there's only one input vertex - gl_Position = position + vec4(-0.2f, -0.2f, 0.0f, 0.0f); // 1:bottom-left - EmitVertex(); - gl_Position = position + vec4( 0.2f, -0.2f, 0.0f, 0.0f); // 2:bottom-right - EmitVertex(); - gl_Position = position + vec4(-0.2f, 0.2f, 0.0f, 0.0f); // 3:top-left - EmitVertex(); - gl_Position = position + vec4( 0.2f, 0.2f, 0.0f, 0.0f); // 4:top-right - EmitVertex(); - gl_Position = position + vec4( 0.0f, 0.4f, 0.0f, 0.0f); // 5:top - fColor = vec3(1.0f, 1.0f, 1.0f); - EmitVertex(); - EndPrimitive(); +uniform float time; + +vec4 explode(vec4 position, vec3 normal) +{ + float magnitude = 2.0f; + vec3 direction = normal * ((sin(time) + 1.0f) / 2.0f) * magnitude; + return position + vec4(direction, 0.0f); +} + +vec3 GetNormal() +{ + vec3 a = vec3(gl_in[0].gl_Position) - vec3(gl_in[1].gl_Position); + vec3 b = vec3(gl_in[2].gl_Position) - vec3(gl_in[1].gl_Position); + return normalize(cross(a, b)); } void main() { - build_house(gl_in[0].gl_Position); + vec3 normal = GetNormal(); + + gl_Position = explode(gl_in[0].gl_Position, normal); + TexCoords = gs_in[0].texCoords; + EmitVertex(); + gl_Position = explode(gl_in[1].gl_Position, normal); + TexCoords = gs_in[1].texCoords; + EmitVertex(); + gl_Position = explode(gl_in[2].gl_Position, normal); + TexCoords = gs_in[2].texCoords; + EmitVertex(); + EndPrimitive(); } \ No newline at end of file diff --git a/src/4.advanced_opengl/9.2.geometry_shader_exploding/9.2.geometry_shader.vs b/src/4.advanced_opengl/9.2.geometry_shader_exploding/9.2.geometry_shader.vs index d07b142..0e70aad 100644 --- a/src/4.advanced_opengl/9.2.geometry_shader_exploding/9.2.geometry_shader.vs +++ b/src/4.advanced_opengl/9.2.geometry_shader_exploding/9.2.geometry_shader.vs @@ -1,13 +1,17 @@ #version 330 core -layout (location = 0) in vec2 position; -layout (location = 1) in vec3 color; +layout (location = 0) in vec3 aPos; +layout (location = 2) in vec2 aTexCoords; out VS_OUT { - vec3 color; + vec2 texCoords; } vs_out; +uniform mat4 projection; +uniform mat4 view; +uniform mat4 model; + void main() { - gl_Position = vec4(position.x, position.y, 0.0f, 1.0f); - vs_out.color = color; + vs_out.texCoords = aTexCoords; + gl_Position = projection * view * model * vec4(aPos, 1.0); } \ No newline at end of file diff --git a/src/4.advanced_opengl/9.2.geometry_shader_exploding/geometry_shader_exploding.cpp b/src/4.advanced_opengl/9.2.geometry_shader_exploding/geometry_shader_exploding.cpp index 56dd846..215a1b7 100644 --- a/src/4.advanced_opengl/9.2.geometry_shader_exploding/geometry_shader_exploding.cpp +++ b/src/4.advanced_opengl/9.2.geometry_shader_exploding/geometry_shader_exploding.cpp @@ -1,101 +1,178 @@ -// GLEW -#define GLEW_STATIC -#include - -// GLFW +#include #include +#include -// GL includes +#include +#include +#include + +#include #include +#include +#include -// Properties -GLuint screenWidth = 800, screenHeight = 600; +#include -bool keys[1024]; -void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode); +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 processInput(GLFWwindow *window); + +// settings +const unsigned int SCR_WIDTH = 1280; +const unsigned int SCR_HEIGHT = 720; + +// camera +Camera camera(glm::vec3(0.0f, 0.0f, 3.0f)); +float lastX = (float)SCR_WIDTH / 2.0; +float lastY = (float)SCR_HEIGHT / 2.0; +bool firstMouse = true; + +// 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); - - // Options - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - - // Set the required callback functions - glfwSetKeyCallback(window, key_callback); - - // Initialize GLEW to setup the OpenGL Function pointers - glewExperimental = GL_TRUE; - glewInit(); - - // Define the viewport dimensions - glViewport(0, 0, screenWidth, screenHeight); - - // Setup and compile our shaders - Shader shader("geometry_shader.vs", "geometry_shader.frag", "geometry_shader.gs"); - - // Vertex data - GLfloat points[] = { - -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // Top-left - 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right - 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-right - -0.5f, -0.5f, 1.0f, 1.0f, 0.0f // Bottom-left - }; - GLuint VBO, VAO; - glGenBuffers(1, &VBO); - glGenVertexArrays(1, &VAO); - glBindVertexArray(VAO); - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(points), &points, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(GLfloat))); - glBindVertexArray(0); - - //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - // Game loop - while(!glfwWindowShouldClose(window)) + if (window == NULL) { - // Check and call events - glfwPollEvents(); + 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); - // Clear buffers + // 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); + + // build and compile shaders + // ------------------------- + Shader shader("9.2.geometry_shader.vs", "9.2.geometry_shader.fs", "9.2.geometry_shader.gs"); + + // load models + // ----------- + Model nanosuit(FileSystem::getPath("resources/objects/nanosuit/nanosuit.obj")); + + // render loop + // ----------- + while (!glfwWindowShouldClose(window)) + { + // per-frame time logic + // -------------------- + float currentFrame = glfwGetTime(); + deltaTime = currentFrame - lastFrame; + lastFrame = currentFrame; + + // input + // ----- + processInput(window); + + // render + // ------ glClearColor(0.1f, 0.1f, 0.1f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - // Draw points - shader.Use(); - glBindVertexArray(VAO); - glDrawArrays(GL_POINTS, 0, 4); - glBindVertexArray(0); - - // Swap the buffers + // configure transformation matrices + glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 1.0f, 100.0f); + glm::mat4 view = camera.GetViewMatrix();; + glm::mat4 model; + shader.use(); + shader.setMat4("projection", projection); + shader.setMat4("view", view); + shader.setMat4("model", model); + + // add time component to geometry shader in the form of a uniform + shader.setFloat("time", glfwGetTime()); + + // draw model + nanosuit.Draw(shader); + + // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) + // ------------------------------------------------------------------------------- glfwSwapBuffers(window); + glfwPollEvents(); } glfwTerminate(); return 0; } -// Is called whenever a key is pressed/released via GLFW -void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) +// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly +// --------------------------------------------------------------------------------------------------------- +void processInput(GLFWwindow *window) { - if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) - glfwSetWindowShouldClose(window, GL_TRUE); + if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) + glfwSetWindowShouldClose(window, true); - if(action == GLFW_PRESS) - keys[key] = true; - else if(action == GLFW_RELEASE) - keys[key] = false; + float cameraSpeed = 2.5 * deltaTime; + if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) + camera.ProcessKeyboard(FORWARD, deltaTime); + if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) + camera.ProcessKeyboard(BACKWARD, deltaTime); + if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) + camera.ProcessKeyboard(LEFT, deltaTime); + if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) + camera.ProcessKeyboard(RIGHT, deltaTime); } + +// 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) +{ + // 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) + { + lastX = xpos; + lastY = ypos; + firstMouse = false; + } + + 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); +} \ No newline at end of file diff --git a/src/4.advanced_opengl/9.3.geometry_shader_normal_visualization/9.3.default.fs b/src/4.advanced_opengl/9.3.geometry_shader_normal_visualization/9.3.default.fs deleted file mode 100644 index 6249a54..0000000 --- a/src/4.advanced_opengl/9.3.geometry_shader_normal_visualization/9.3.default.fs +++ /dev/null @@ -1,8 +0,0 @@ -#version 330 core -in vec3 fColor; -out vec4 color; - -void main() -{ - color = vec4(fColor, 1.0f); -} \ No newline at end of file diff --git a/src/4.advanced_opengl/9.3.geometry_shader_normal_visualization/9.3.default.vs b/src/4.advanced_opengl/9.3.geometry_shader_normal_visualization/9.3.default.vs deleted file mode 100644 index d07b142..0000000 --- a/src/4.advanced_opengl/9.3.geometry_shader_normal_visualization/9.3.default.vs +++ /dev/null @@ -1,13 +0,0 @@ -#version 330 core -layout (location = 0) in vec2 position; -layout (location = 1) in vec3 color; - -out VS_OUT { - vec3 color; -} vs_out; - -void main() -{ - gl_Position = vec4(position.x, position.y, 0.0f, 1.0f); - vs_out.color = color; -} \ No newline at end of file diff --git a/src/4.advanced_opengl/9.3.geometry_shader_normal_visualization/9.3.geometry_shader_normal_visualization.fs b/src/4.advanced_opengl/9.3.geometry_shader_normal_visualization/9.3.geometry_shader_normal_visualization.fs deleted file mode 100644 index 6249a54..0000000 --- a/src/4.advanced_opengl/9.3.geometry_shader_normal_visualization/9.3.geometry_shader_normal_visualization.fs +++ /dev/null @@ -1,8 +0,0 @@ -#version 330 core -in vec3 fColor; -out vec4 color; - -void main() -{ - color = vec4(fColor, 1.0f); -} \ No newline at end of file diff --git a/src/4.advanced_opengl/9.3.geometry_shader_normal_visualization/9.3.geometry_shader_normal_visualization.gs b/src/4.advanced_opengl/9.3.geometry_shader_normal_visualization/9.3.geometry_shader_normal_visualization.gs deleted file mode 100644 index 4f24075..0000000 --- a/src/4.advanced_opengl/9.3.geometry_shader_normal_visualization/9.3.geometry_shader_normal_visualization.gs +++ /dev/null @@ -1,30 +0,0 @@ -#version 330 core -layout (points) in; -layout (triangle_strip, max_vertices = 5) out; - -in VS_OUT { - vec3 color; -} gs_in[]; - -out vec3 fColor; - -void build_house(vec4 position) -{ - fColor = gs_in[0].color; // gs_in[0] since there's only one input vertex - gl_Position = position + vec4(-0.2f, -0.2f, 0.0f, 0.0f); // 1:bottom-left - EmitVertex(); - gl_Position = position + vec4( 0.2f, -0.2f, 0.0f, 0.0f); // 2:bottom-right - EmitVertex(); - gl_Position = position + vec4(-0.2f, 0.2f, 0.0f, 0.0f); // 3:top-left - EmitVertex(); - gl_Position = position + vec4( 0.2f, 0.2f, 0.0f, 0.0f); // 4:top-right - EmitVertex(); - gl_Position = position + vec4( 0.0f, 0.4f, 0.0f, 0.0f); // 5:top - fColor = vec3(1.0f, 1.0f, 1.0f); - EmitVertex(); - EndPrimitive(); -} - -void main() { - build_house(gl_in[0].gl_Position); -} \ No newline at end of file diff --git a/src/4.advanced_opengl/9.3.geometry_shader_normal_visualization/9.3.geometry_shader_normal_visualization.vs b/src/4.advanced_opengl/9.3.geometry_shader_normal_visualization/9.3.geometry_shader_normal_visualization.vs deleted file mode 100644 index d07b142..0000000 --- a/src/4.advanced_opengl/9.3.geometry_shader_normal_visualization/9.3.geometry_shader_normal_visualization.vs +++ /dev/null @@ -1,13 +0,0 @@ -#version 330 core -layout (location = 0) in vec2 position; -layout (location = 1) in vec3 color; - -out VS_OUT { - vec3 color; -} vs_out; - -void main() -{ - gl_Position = vec4(position.x, position.y, 0.0f, 1.0f); - vs_out.color = color; -} \ No newline at end of file diff --git a/src/4.advanced_opengl/9.3.geometry_shader_normal_visualization/geometry_shader_normal_visualization.cpp b/src/4.advanced_opengl/9.3.geometry_shader_normal_visualization/geometry_shader_normal_visualization.cpp deleted file mode 100644 index 56dd846..0000000 --- a/src/4.advanced_opengl/9.3.geometry_shader_normal_visualization/geometry_shader_normal_visualization.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// GLEW -#define GLEW_STATIC -#include - -// GLFW -#include - -// GL includes -#include - -// Properties -GLuint screenWidth = 800, screenHeight = 600; - -bool keys[1024]; -void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode); - -// 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(screenWidth, screenHeight, "LearnOpenGL", nullptr, nullptr); // Windowed - glfwMakeContextCurrent(window); - - // Options - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - - // Set the required callback functions - glfwSetKeyCallback(window, key_callback); - - // Initialize GLEW to setup the OpenGL Function pointers - glewExperimental = GL_TRUE; - glewInit(); - - // Define the viewport dimensions - glViewport(0, 0, screenWidth, screenHeight); - - // Setup and compile our shaders - Shader shader("geometry_shader.vs", "geometry_shader.frag", "geometry_shader.gs"); - - // Vertex data - GLfloat points[] = { - -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // Top-left - 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right - 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-right - -0.5f, -0.5f, 1.0f, 1.0f, 0.0f // Bottom-left - }; - GLuint VBO, VAO; - glGenBuffers(1, &VBO); - glGenVertexArrays(1, &VAO); - glBindVertexArray(VAO); - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(points), &points, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(GLfloat))); - glBindVertexArray(0); - - //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - // Game loop - while(!glfwWindowShouldClose(window)) - { - // Check and call events - glfwPollEvents(); - - // Clear buffers - glClearColor(0.1f, 0.1f, 0.1f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - - // Draw points - shader.Use(); - glBindVertexArray(VAO); - glDrawArrays(GL_POINTS, 0, 4); - glBindVertexArray(0); - - // Swap the buffers - glfwSwapBuffers(window); - } - - glfwTerminate(); - return 0; -} - -// Is called whenever a key is pressed/released via GLFW -void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) -{ - 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; -} diff --git a/src/4.advanced_opengl/9.3.geometry_shader_normals/9.3.default.fs b/src/4.advanced_opengl/9.3.geometry_shader_normals/9.3.default.fs new file mode 100644 index 0000000..7d157ae --- /dev/null +++ b/src/4.advanced_opengl/9.3.geometry_shader_normals/9.3.default.fs @@ -0,0 +1,12 @@ +#version 330 core +out vec4 FragColor; + +in vec2 TexCoords; + +uniform sampler2D texture_diffuse1; + +void main() +{ + FragColor = texture(texture_diffuse1, TexCoords); +} + diff --git a/src/4.advanced_opengl/9.3.geometry_shader_normals/9.3.default.vs b/src/4.advanced_opengl/9.3.geometry_shader_normals/9.3.default.vs new file mode 100644 index 0000000..f7c5c9c --- /dev/null +++ b/src/4.advanced_opengl/9.3.geometry_shader_normals/9.3.default.vs @@ -0,0 +1,15 @@ +#version 330 core +layout (location = 0) in vec3 aPos; +layout (location = 2) in vec2 aTexCoords; + +out vec2 TexCoords; + +uniform mat4 projection; +uniform mat4 view; +uniform mat4 model; + +void main() +{ + TexCoords = aTexCoords; + gl_Position = projection * view * model * vec4(aPos, 1.0f); +} \ No newline at end of file diff --git a/src/4.advanced_opengl/9.3.geometry_shader_normals/9.3.normal_visualization.fs b/src/4.advanced_opengl/9.3.geometry_shader_normals/9.3.normal_visualization.fs new file mode 100644 index 0000000..86b6535 --- /dev/null +++ b/src/4.advanced_opengl/9.3.geometry_shader_normals/9.3.normal_visualization.fs @@ -0,0 +1,8 @@ +#version 330 core +out vec4 FragColor; + +void main() +{ + FragColor = vec4(1.0, 1.0, 0.0, 1.0); +} + diff --git a/src/4.advanced_opengl/9.3.geometry_shader_normals/9.3.normal_visualization.gs b/src/4.advanced_opengl/9.3.geometry_shader_normals/9.3.normal_visualization.gs new file mode 100644 index 0000000..e4bba23 --- /dev/null +++ b/src/4.advanced_opengl/9.3.geometry_shader_normals/9.3.normal_visualization.gs @@ -0,0 +1,25 @@ +#version 330 core +layout (triangles) in; +layout (line_strip, max_vertices = 6) out; + +in VS_OUT { + vec3 normal; +} gs_in[]; + +const float MAGNITUDE = 0.2; + +void GenerateLine(int index) +{ + gl_Position = gl_in[index].gl_Position; + EmitVertex(); + gl_Position = gl_in[index].gl_Position + vec4(gs_in[index].normal, 0.0) * MAGNITUDE; + EmitVertex(); + EndPrimitive(); +} + +void main() +{ + GenerateLine(0); // First vertex normal + GenerateLine(1); // Second vertex normal + GenerateLine(2); // Third vertex normal +} \ No newline at end of file diff --git a/src/4.advanced_opengl/9.3.geometry_shader_normals/9.3.normal_visualization.vs b/src/4.advanced_opengl/9.3.geometry_shader_normals/9.3.normal_visualization.vs new file mode 100644 index 0000000..435399b --- /dev/null +++ b/src/4.advanced_opengl/9.3.geometry_shader_normals/9.3.normal_visualization.vs @@ -0,0 +1,18 @@ +#version 330 core +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aNormal; + +out VS_OUT { + vec3 normal; +} vs_out; + +uniform mat4 projection; +uniform mat4 view; +uniform mat4 model; + +void main() +{ + mat3 normalMatrix = mat3(transpose(inverse(view * model))); + vs_out.normal = vec3(projection * vec4(normalMatrix * aNormal, 1.0)); + gl_Position = projection * view * model * vec4(aPos, 1.0); +} \ No newline at end of file diff --git a/src/4.advanced_opengl/9.3.geometry_shader_normals/normal_visualization.cpp b/src/4.advanced_opengl/9.3.geometry_shader_normals/normal_visualization.cpp new file mode 100644 index 0000000..bcc19a1 --- /dev/null +++ b/src/4.advanced_opengl/9.3.geometry_shader_normals/normal_visualization.cpp @@ -0,0 +1,184 @@ +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#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 processInput(GLFWwindow *window); + +// settings +const unsigned int SCR_WIDTH = 1280; +const unsigned int SCR_HEIGHT = 720; + +// camera +Camera camera(glm::vec3(0.0f, 0.0f, 3.0f)); +float lastX = (float)SCR_WIDTH / 2.0; +float lastY = (float)SCR_HEIGHT / 2.0; +bool firstMouse = true; + +// timing +float deltaTime = 0.0f; +float lastFrame = 0.0f; + +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); + + // glfw window creation + // -------------------- + GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL); + glfwMakeContextCurrent(window); + 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); + + // 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); + + // build and compile shaders + // ------------------------- + Shader shader("9.3.default.vs", "9.3.default.fs"); + Shader normalShader("9.3.normal_visualization.vs", "9.3.normal_visualization.fs", "9.3.normal_visualization.gs"); + + // load models + // ----------- + Model nanosuit(FileSystem::getPath("resources/objects/nanosuit/nanosuit.obj")); + + // render loop + // ----------- + while (!glfwWindowShouldClose(window)) + { + // per-frame time logic + // -------------------- + float currentFrame = glfwGetTime(); + deltaTime = currentFrame - lastFrame; + lastFrame = currentFrame; + + // input + // ----- + processInput(window); + + // render + // ------ + glClearColor(0.1f, 0.1f, 0.1f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // configure transformation matrices + glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 1.0f, 100.0f); + glm::mat4 view = camera.GetViewMatrix();; + glm::mat4 model; + shader.use(); + shader.setMat4("projection", projection); + shader.setMat4("view", view); + shader.setMat4("model", model); + + // draw model as usual + nanosuit.Draw(shader); + + // then draw model with normal visualizing geometry shader + normalShader.use(); + normalShader.setMat4("projection", projection); + normalShader.setMat4("view", view); + normalShader.setMat4("model", model); + + nanosuit.Draw(normalShader); + + // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) + // ------------------------------------------------------------------------------- + glfwSwapBuffers(window); + glfwPollEvents(); + } + + glfwTerminate(); + return 0; +} + +// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly +// --------------------------------------------------------------------------------------------------------- +void processInput(GLFWwindow *window) +{ + if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) + glfwSetWindowShouldClose(window, true); + + float cameraSpeed = 2.5 * deltaTime; + if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) + camera.ProcessKeyboard(FORWARD, deltaTime); + if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) + camera.ProcessKeyboard(BACKWARD, deltaTime); + if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) + camera.ProcessKeyboard(LEFT, deltaTime); + if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) + camera.ProcessKeyboard(RIGHT, deltaTime); +} + +// 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) +{ + // 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) + { + lastX = xpos; + lastY = ypos; + firstMouse = false; + } + + 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); +} \ No newline at end of file