/* 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 * Compile with: gcc simple_demo.c -Icglm/include -lGL -lm -lglfw -lGLEW */ #include #include #include #include #include #include #include const float height = 800; const float width = 1280; #define SBLEN 4096 char shader_buffer[SBLEN]; 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.5, 0, 0, -0.5, 0, 1, 0.5, 0, 0, -0.5, 0, 0, -0.5, 0, 1, 0, 1, 0, -0.5, 0, 0, 0, 1, 0, 0.5, 0, 0, 0, 1, 0, -0.5, 0, 1, 0.5, 0, 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, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; 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); // TODO: Give up if it failed glGetProgramInfoLog(program, SBLEN, 0, shader_buffer); printf("Log: \n%s\n", shader_buffer); 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); glEnable(GL_DEPTH_TEST); // Per-frame part while(!glfwWindowShouldClose(window)){ count++; glfwPollEvents(); glClearColor(0, 0.2, 0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); mat4 model = GLM_MAT4_IDENTITY_INIT; glm_rotate(model, count / 100.0f, GLM_YUP); glm_rotate(model, count / 1000.0f, GLM_XUP); mat4 view; glm_lookat(((vec3){0.0f, 0.0f, 1.5f}), GLM_FORWARD, GLM_YUP, view); mat4 projection; glm_perspective(90.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, sizeof(vertices)/sizeof(float)/3, 2); glfwSwapBuffers(window); usleep(10000); } glDeleteProgram(program); glfwDestroyWindow(window); glfwTerminate(); }