Created
July 10, 2021 03:17
-
-
Save Pacheco95/86a4f4235f2ffbc705634226d8917b43 to your computer and use it in GitHub Desktop.
https://learnopengl.com/Getting-started/Hello-Triangle example adapted to toggle wireframe mode on W key press
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <glad/glad.h> | |
#include <GLFW/glfw3.h> | |
#include <iostream> | |
void framebuffer_size_callback(GLFWwindow* window, int width, int height); | |
void keyEventCallback(GLFWwindow* window, int key, int scancode, int action, int mods); | |
// settings | |
const unsigned int SCR_WIDTH = 800; | |
const unsigned int SCR_HEIGHT = 600; | |
const char* vertexShaderSource = R"( | |
#version 330 core | |
layout (location = 0) in vec3 aPos; | |
void main() | |
{ | |
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); | |
} | |
)"; | |
const char* fragmentShaderSource = R"( | |
#version 330 core | |
out vec4 FragColor; | |
void main() | |
{ | |
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); | |
} | |
)"; | |
int polygonMode = GL_LINE; | |
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); | |
#ifdef __APPLE__ | |
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); | |
#endif | |
// 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); | |
// glad: load all OpenGL function pointers | |
// --------------------------------------- | |
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) | |
{ | |
std::cout << "Failed to initialize GLAD" << std::endl; | |
return -1; | |
} | |
glfwSetKeyCallback(window, keyEventCallback); | |
// build and compile our shader program | |
// ------------------------------------ | |
// vertex shader | |
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER); | |
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); | |
glCompileShader(vertexShader); | |
// check for shader compile errors | |
int success; | |
char infoLog[512]; | |
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); | |
if (!success) | |
{ | |
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); | |
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; | |
} | |
// fragment shader | |
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); | |
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); | |
glCompileShader(fragmentShader); | |
// check for shader compile errors | |
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); | |
if (!success) | |
{ | |
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); | |
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; | |
} | |
// link shaders | |
unsigned int shaderProgram = glCreateProgram(); | |
glAttachShader(shaderProgram, vertexShader); | |
glAttachShader(shaderProgram, fragmentShader); | |
glLinkProgram(shaderProgram); | |
// check for linking errors | |
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); | |
if (!success) { | |
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); | |
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; | |
} | |
glDeleteShader(vertexShader); | |
glDeleteShader(fragmentShader); | |
// set up vertex data (and buffer(s)) and configure vertex attributes | |
// ------------------------------------------------------------------ | |
float vertices[] = { | |
0.5f, 0.5f, 0.0f, // top right | |
0.5f, -0.5f, 0.0f, // bottom right | |
-0.5f, -0.5f, 0.0f, // bottom left | |
-0.5f, 0.5f, 0.0f // top left | |
}; | |
unsigned int indices[] = { // note that we start from 0! | |
0, 1, 3, // first Triangle | |
1, 2, 3 // second Triangle | |
}; | |
unsigned int VBO, VAO, EBO; | |
glGenVertexArrays(1, &VAO); | |
glGenBuffers(1, &VBO); | |
glGenBuffers(1, &EBO); | |
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). | |
glBindVertexArray(VAO); | |
glBindBuffer(GL_ARRAY_BUFFER, VBO); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); | |
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); | |
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); | |
glEnableVertexAttribArray(0); | |
// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
// remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound. | |
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | |
// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other | |
// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary. | |
glBindVertexArray(0); | |
// uncomment this call to draw in wireframe polygons. | |
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | |
// render loop | |
// ----------- | |
while (!glfwWindowShouldClose(window)) | |
{ | |
// render | |
// ------ | |
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); | |
glClear(GL_COLOR_BUFFER_BIT); | |
// draw our first triangle | |
glUseProgram(shaderProgram); | |
glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized | |
//glDrawArrays(GL_TRIANGLES, 0, 6); | |
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); | |
// glBindVertexArray(0); // no need to unbind it every time | |
// 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); | |
glDeleteBuffers(1, &EBO); | |
glDeleteProgram(shaderProgram); | |
// glfw: terminate, clearing all previously allocated GLFW resources. | |
// ------------------------------------------------------------------ | |
glfwTerminate(); | |
return 0; | |
} | |
// 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); | |
} | |
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly | |
void keyEventCallback(GLFWwindow* window, int key, int scancode, int action, int mods) | |
{ | |
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) | |
glfwSetWindowShouldClose(window, true); | |
if (key == GLFW_KEY_W && action == GLFW_PRESS) | |
glPolygonMode(GL_FRONT_AND_BACK, polygonMode = polygonMode == GL_LINE ? GL_FILL : GL_LINE); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment