/* Simplified OpenGL 4.5 demo * Seth Long, Fall 2020 * This is a *very* short demo which displays a triangle * Many of these functions can fail, and return error values * I doubt it can be done much shorter without leaving vertices in only main memory or some such * If moving to C++, use GLM instead of cglm * * Building this: It requires OpenGL, glfw, and glew. If you don't have these, it won't build * On the MLH 310 lab, this should do it: * sudo apt install libglfw3-dev libglew-dev */ #include #include #include #include #include #include #include const float height =768; const float width = 1024; int main(int argc, char ** argv){ glfwInit(); GLFWwindow* window = glfwCreateWindow(width, height, "Simple OpenGL 4.0+ Demo", 0, 0); glfwMakeContextCurrent(window); glewInit(); // Initialization part float vertices[] = {0, 1, 0, -0.5, -1, 0, 0.5, -1, 0}; unsigned int vbuf; glGenBuffers(1, &vbuf); glBindBuffer(GL_SHADER_STORAGE_BUFFER, vbuf); glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); float colors[] = {1, .8, 0, 1, 1, 0, .5, 0, 0}; unsigned int cbuf; glGenBuffers(1, &cbuf); glBindBuffer(GL_SHADER_STORAGE_BUFFER, cbuf); glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW); int fd = open("vertex_shader.glsl", O_RDONLY); char *source = malloc(2048); size_t readlen = read(fd, source, 2048); if(2048 == readlen) printf("Warning: vertex shader is probably too long for this read routine\n"); source[readlen] = 0; puts(source); close(fd); unsigned int vs_reference = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vs_reference, 1, (const char**)&source, 0); glCompileShader(vs_reference); fd = open("fragment_shader.glsl", O_RDONLY); readlen = read(fd, source, 2048); source[readlen] = 0; puts(source); close(fd); unsigned int fs_reference = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fs_reference, 1, (const char**)&source, 0); glCompileShader(fs_reference); free(source); unsigned int program = glCreateProgram(); glAttachShader(program, vs_reference); glAttachShader(program, fs_reference); glLinkProgram(program); unsigned int v_attrib = glGetAttribLocation(program, "in_vertex"); unsigned int c_attrib = glGetAttribLocation(program, "in_color"); unsigned int mvp_uniform = glGetUniformLocation(program, "mvp"); int count = 0; glUseProgram(program); glEnableVertexAttribArray(v_attrib); glBindBuffer(GL_ARRAY_BUFFER, vbuf); glVertexAttribPointer(v_attrib, 3, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(c_attrib); glBindBuffer(GL_ARRAY_BUFFER, cbuf); glVertexAttribPointer(c_attrib, 3, GL_FLOAT, GL_FALSE, 0, 0); while(!glfwWindowShouldClose(window)){ count++; glfwPollEvents(); glClearColor(0, 0.2, 0, 1.0); glClear(GL_COLOR_BUFFER_BIT); mat4 model = GLM_MAT4_IDENTITY_INIT; // glm_rotate(model, 45, GLM_YUP); // glm_rotate(model, count / 1000.0f, GLM_XUP); glm_translate(model, ((vec3){count/300.0f, 0, 0})); glm_rotate(model, count / 100.0f, GLM_YUP); glm_scale(model, ((vec3){0.25 + count/100.0f, 1, 1})); mat4 view; glm_lookat(((vec3){0.0f, 0.0f, 2.0f}), GLM_FORWARD, GLM_YUP, view); mat4 projection; glm_perspective(45.0, width/height, 0.1, 1000.0, projection); mat4 mvp; glm_mul(projection, view, mvp); glm_mul(mvp, model, mvp); glUniformMatrix4fv(mvp_uniform, 1, 0, (float*)mvp); glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 2); glfwSwapBuffers(window); usleep(10000); } glDeleteProgram(program); glfwDestroyWindow(window); glfwTerminate(); }