From 6d4b70aa1c5097de626b265a7aa2f17bc388b54e Mon Sep 17 00:00:00 2001 From: Fries Date: Sun, 10 Mar 2024 18:13:28 -0700 Subject: [PATCH] Add a togglable rectangle and toggable wireframe. --- .vscode/settings.json | 5 ++ src/main.cc | 166 +++++++++++++++++++++++++++++++++--------- 2 files changed, 138 insertions(+), 33 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index e69de29..1f50700 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "clangd.arguments": [ + "-header-insertion=never" + ] +} diff --git a/src/main.cc b/src/main.cc index 6689eff..27abde7 100644 --- a/src/main.cc +++ b/src/main.cc @@ -4,6 +4,7 @@ void framebuffer_size_callback(GLFWwindow* window, int width, int height); void process_input(GLFWwindow* window); +void key_pressed(GLFWwindow *window, int key, int scancode, int action, int mods); int check_shader_compilation_status(unsigned int shaderId); const char* vertexShaderCode = R"( @@ -26,6 +27,98 @@ void main() { } )"; +bool wireframe; +bool rectangleToggled; + +struct GlRenderObjects { + unsigned int vertexBufferObject; + unsigned int vertexArrayObject; + unsigned int elementBufferObject; + void Destroy() { + glDeleteBuffers(1, &vertexBufferObject); + glDeleteVertexArrays(1, &vertexArrayObject); + glDeleteBuffers(1, &elementBufferObject); + } +}; + +GlRenderObjects triangle() { + // An array of verticies containing data for a triangle. + float vertices[] = { + -0.5f, -0.5f, 0.0f, + 0.5f, -0.5f, 0.0f, + 0.0f, 0.5f, 0.0f + }; + + unsigned int vertexBufferObject, vertexArrayObject; + // Create a Vertex Array Object. + glGenVertexArrays(1, &vertexArrayObject); + // Create a Vertex Buffer Object and write the id to the vertexBufferObject variable. + glGenBuffers(1, &vertexBufferObject); + // Bind the vertex array object so the attributes are stored in that object. + glBindVertexArray(vertexArrayObject); + + // Bind the GL_ARRAY_BUFFER target to the verterBufferObject object id. + glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); + // Copy the verticies data into the vertexBufferObject object and tell the GPU it will only be written once but read many times. + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + // Tell OpenGL how to process the Vertex attributes so it can pass it to the Vertex shader. + // This will pass the vertex to the location "0". We tell OpenGL the size of the array is 3 elements. + // We tell OpenGL that we're using floating point types. + // We tell OpenGL we don't want our data to be normalized as its already normalized. + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); + glEnableVertexAttribArray(0); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + + return {vertexBufferObject, vertexArrayObject, 0}; +} + +GlRenderObjects rectangle() { + float vertices[] = { + 0.5f, 0.5f, 0.0f, + 0.5f, -0.5f, 0.0f, + -0.5f, -0.5f, 0.0f, + -0.5f, 0.5f, 0.0f + }; + + unsigned int indices[] = { + 0, 1, 3, + 1, 2, 3 + }; + + unsigned int vertexBufferObject, vertexArrayObject, elementBufferObject; + + // Create a Vertex Array Object. + glGenVertexArrays(1, &vertexArrayObject); + // Create a Vertex Buffer Object. + glGenBuffers(1, &vertexBufferObject); + // Create a Element Buffer Object; + glGenBuffers(1, &elementBufferObject); + + // Bind the Vertex Array Object to the state. + glBindVertexArray(vertexArrayObject); + // Bind the Vertex Buffer Object to the GL_ARRAY_BUFFER target on the state. + glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); + // Copy verticies into the GPU's memory. + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + // Bind the Element Buffer Object to the GL_ELEMENT_ARRAY_BUFFER target on the state. + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBufferObject); + // Copy indicies into the GPU's memory. + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + // Tell OpenGL on how to process the verticies. + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0); + glEnableVertexAttribArray(0); + + // Unbind the current buffers and arrays from the state. + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + return {vertexBufferObject, vertexArrayObject, elementBufferObject}; +} + int main() { glfwInit(); @@ -103,40 +196,15 @@ int main() { glDeleteShader(vertexShader); glDeleteShader(fragmentShader); - // An array of verticies containing data for a triangle. - float vertices[] = { - -0.5f, -0.5f, 0.0f, - 0.5f, -0.5f, 0.0f, - 0.0f, 0.5f, 0.0f - }; - - unsigned int vertexBufferObject, vertexArrayObject; - // Create a Vertex Array Object. - glGenVertexArrays(1, &vertexArrayObject); - // Create a Vertex Buffer Object and write the id to the vertexBufferObject variable. - glGenBuffers(1, &vertexBufferObject); - // Bind the vertex array object so the attributes are stored in that object. - glBindVertexArray(vertexArrayObject); - - // Bind the GL_ARRAY_BUFFER target to the verterBufferObject object id. - glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); - // Copy the verticies data into the vertexBufferObject object and tell the GPU it will only be written once but read many times. - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - // Tell OpenGL how to process the Vertex attributes so it can pass it to the Vertex shader. - // This will pass the vertex to the location "0". We tell OpenGL the size of the array is 3 elements. - // We tell OpenGL that we're using floating point types. - // We tell OpenGL we don't want our data to be normalized as its already normalized. - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); - glEnableVertexAttribArray(0); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); + GlRenderObjects triangleRenderObjs = triangle(); + GlRenderObjects rectangleRenderObjs = rectangle(); // Create a render loop, which keeps the program open until glfw tells the loop that the window should close. while (!glfwWindowShouldClose(window)) { // Process input. process_input(window); + // Set a callback to trigger whenever a key is pressed. + glfwSetKeyCallback(window, key_pressed); // Set the GL state to use this color when clearing the screen. glClearColor(0.2f, 0.3f, 0.3f, 1.0f); @@ -145,10 +213,17 @@ int main() { // Use the shaderProgram shader program for drawing verticies. glUseProgram(shaderProgram); - // Bind the state to use the vertexArrayObject object so OpenGL knows what to do with the verticies. - glBindVertexArray(vertexArrayObject); - // Draw the verticies. - glDrawArrays(GL_TRIANGLES, 0, 3); + if (!rectangleToggled) { + // Bind the state to use the vertexArrayObject object so OpenGL knows what to do with the verticies. + glBindVertexArray(triangleRenderObjs.vertexArrayObject); + // Draw the verticies. + glDrawArrays(GL_TRIANGLES, 0, 3); + glBindVertexArray(0); + } else { + glBindVertexArray(rectangleRenderObjs.vertexArrayObject); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + glBindVertexArray(0); + } // This swaps completely drawn frames from the "second buffer" to the front one which is displayed on the screen. glfwSwapBuffers(window); @@ -156,6 +231,11 @@ int main() { glfwPollEvents(); } + // Clean up objects from memory. + triangleRenderObjs.Destroy(); + rectangleRenderObjs.Destroy(); + glDeleteProgram(shaderProgram); + glfwTerminate(); return 0; } @@ -176,3 +256,23 @@ int check_shader_compilation_status(unsigned int shaderId) { glGetShaderiv(shaderId, GL_COMPILE_STATUS, &success); return success; } + +void key_pressed(GLFWwindow *window, int key, int scancode, int action, int mods) { + // If the W key is pressed, toggle wireframe mode. + if (key == GLFW_KEY_W && action == GLFW_PRESS) { + if (!wireframe) { + // Render polygons in wireframe mode. + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + wireframe = true; + } else { + // Render polygons in fill mode. + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + wireframe = false; + } + } + + // Flip a boolean indicating the rectangle should be rendered. + if (key == GLFW_KEY_R && action == GLFW_PRESS) { + rectangleToggled = !rectangleToggled; + } +}