diff --git a/src/8.guest/2021/4.dsa/hello_triangle_dsa.cpp b/src/8.guest/2021/4.dsa/hello_triangle_dsa.cpp new file mode 100644 index 0000000..92d9c02 --- /dev/null +++ b/src/8.guest/2021/4.dsa/hello_triangle_dsa.cpp @@ -0,0 +1,147 @@ +#include +#include + +#include + +void framebuffer_size_callback(GLFWwindow* window, int width, int height); +void processInput(GLFWwindow *window); + +const char* vertexShaderSource = "#version 330 core\n" +"layout (location = 0) in vec3 aPos;\n" +"void main()\n" +"{\n" +" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" +"}\0"; +const char* fragmentShaderSource = "#version 330 core\n" +"out vec4 FragColor;\n" +"void main()\n" +"{\n" +" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" +"}\n\0"; + +int main() +{ + const unsigned int SCR_WIDTH = 800; + const unsigned int SCR_HEIGHT = 600; + + glfwInit(); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + +#ifdef __APPLE__ + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); +#endif + + 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); + + if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) + { + std::cout << "Failed to initialize GLAD" << std::endl; + return -1; + } + + unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); + glCompileShader(vertexShader); + 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; + } + unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); + glCompileShader(fragmentShader); + glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; + } + unsigned int shaderProgram = glCreateProgram(); + glAttachShader(shaderProgram, vertexShader); + glAttachShader(shaderProgram, fragmentShader); + glLinkProgram(shaderProgram); + 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); + + 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 + }; + // Here we create the VBO with DSA. + GLuint vbo = 0; + // Note how we do not have to call glBindBuffer() after the create call. + glCreateBuffers(1, &vbo); + glNamedBufferStorage(vbo, sizeof(vertices), vertices, 0x0); + + unsigned int indices[] = { + 0, 1, 3, + 1, 2, 3 + }; + // Here we create the EBO with DSA while also specifying that the buffer is mutable from the client side. + GLuint ebo = 0; + glCreateBuffers(1, &ebo); + glNamedBufferStorage(ebo, sizeof(indices), nullptr, GL_DYNAMIC_STORAGE_BIT); + glNamedBufferSubData(ebo, 0, sizeof(indices), indices); + + // Here we create the VAO with DSA and specify its format. + GLuint vao = 0; + glCreateVertexArrays(1, &vao); + + // Specifying our vertex layout with the VAO. + glEnableVertexArrayAttrib(vao, 0); + glVertexArrayAttribFormat(vao, 0, 3, GL_FLOAT, GL_FALSE, 0); + glVertexArrayAttribBinding(vao, 0, 0); + + // Binding the VBO and Element Buffer to the VAO. + glVertexArrayVertexBuffer(vao, 0, vbo, 0, sizeof(float) * 3); + glVertexArrayElementBuffer(vao, ebo); + + while (!glfwWindowShouldClose(window)) + { + processInput(window); + glClearColor(0.2f, 0.3f, 0.3f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + glUseProgram(shaderProgram); + glBindVertexArray(vao); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + glfwSwapBuffers(window); + glfwPollEvents(); + } + glDeleteVertexArrays(1, &vao); + glDeleteBuffers(1, &vbo); + glDeleteBuffers(1, &ebo); + glDeleteProgram(shaderProgram); + glfwTerminate(); + return 0; +} + +void processInput(GLFWwindow* window) +{ + if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) + glfwSetWindowShouldClose(window, true); +} + +void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +}