/* 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 #include "scolor.h" const float height =768; const float width = 1024; GLuint make_shader(char *filename, GLenum shaderType); #define GBLEN (1024*32) char *general_buffer; int main(int argc, char ** argv){ general_buffer = malloc(GBLEN); 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); unsigned int vs_reference = make_shader("vertex_shader.glsl", GL_VERTEX_SHADER); unsigned int fs_reference = make_shader("fragment_shader.glsl", GL_FRAGMENT_SHADER); if(!(vs_reference && fs_reference)) return 0; 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"); unsigned int count_uniform = glGetUniformLocation(program, "count"); 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); 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, 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 + count/100.0}), 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); glUniform1i(count_uniform, count); glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 2); glfwSwapBuffers(window); usleep(10000); } glDeleteProgram(program); glfwDestroyWindow(window); glfwTerminate(); } GLuint make_shader(char *filename, GLenum shaderType){ int fd = open(filename, O_RDONLY); size_t readlen = read(fd, general_buffer, GBLEN); close(fd); if(readlen == GBLEN){ printf(RED("Buffer Length of %d bytes Inadequate for File %s\n"), GBLEN, filename); return 0; } general_buffer[readlen] = 0; printf(DGREEN("Read shader in file %s (%lu bytes)\n"), filename, readlen); puts(general_buffer); unsigned int s_reference = glCreateShader(shaderType); glShaderSource(s_reference, 1, (const char**)&general_buffer, 0); glCompileShader(s_reference); glGetShaderInfoLog(s_reference, GBLEN, NULL, general_buffer); puts(general_buffer); GLint compile_ok; glGetShaderiv(s_reference, GL_COMPILE_STATUS, &compile_ok); if(compile_ok){ printf(GREEN("Compile Success\n")); return s_reference; } puts(RED("Compile Failed\n")); return 0; }