// Copyright (C) 2021 Emilio J. PadrĂ³n // Released as Free Software under the X11 License // https://spdx.org/licenses/X11.html #include #include #include int main() { // start GL context and O/S window using the GLFW helper library if (!glfwInit()) { fprintf(stderr, "ERROR: could not start GLFW3\n"); return 1; } // glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); GLFWwindow* window = glfwCreateWindow(640, 480, "Hello Triangle", NULL, NULL); if (!window) { fprintf(stderr, "ERROR: could not open window with GLFW3\n"); glfwTerminate(); return 1; } glfwMakeContextCurrent(window); // start GLEW extension handler // glewExperimental = GL_TRUE; glewInit(); // get version info const GLubyte* vendor = glGetString(GL_VENDOR); // get vendor string const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string const GLubyte* glversion = glGetString(GL_VERSION); // version as a string const GLubyte* glslversion = glGetString(GL_SHADING_LANGUAGE_VERSION); // version as a string printf("Vendor: %s\n", vendor); printf("Renderer: %s\n", renderer); printf("OpenGL version supported %s\n", glversion); printf("GLSL version supported %s\n", glslversion); // Vertex Shader const char* vertex_shader = "#version 130\n" "in vec3 v_pos;" "void main() {" " gl_Position = vec4(v_pos, 1.0);" "}"; // Fragment Shader const char* fragment_shader = "#version 130\n" "out vec4 frag_col;" "void main() {" " frag_col = vec4(0.54, 0.73, 0.1, 1.0);" "}"; // Shaders compilation GLuint vs = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vs, 1, &vertex_shader, NULL); glCompileShader(vs); GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fs, 1, &fragment_shader, NULL); glCompileShader(fs); // Create program, attach shaders to it and link it GLuint shader_program = glCreateProgram(); glAttachShader(shader_program, fs); glAttachShader(shader_program, vs); glLinkProgram(shader_program); // Release shader objects glDeleteShader(vs); glDeleteShader(fs); // Vertex Array Object GLuint vao = 0; glGenVertexArrays(1, &vao); glBindVertexArray(vao); // Triangle to be rendered (NDC) float points[] = { 0.0f, 0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, -0.5f, 0.0f }; // Vertex Buffer Object GLuint vbo = 0; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW); // Vertex attributes // 0: vertex position glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray(0); // Unbind vbo (it was conveniently registered by VertexAttribPointer) glBindBuffer(GL_ARRAY_BUFFER, 0); // Unbind vao glBindVertexArray(0); // Render loop while(!glfwWindowShouldClose(window)) { // wipe the drawing surface clear glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shader_program); glBindVertexArray(vao); // use 3 points to render a triangle from the currently bound VAO // with current in-use shader glDrawArrays(GL_TRIANGLES, 0, 3); // put the stuff we've been drawing onto the display glfwSwapBuffers(window); // update other events like input handling glfwPollEvents(); } // close GL context and any other GLFW resources glfwTerminate(); return 0; }