/* Simplified OpenGL 4.5 demo * Seth Long, Fall 2020 * Simple demo, C++ version * Note operator overloading for matrix multiplication! * * Linux build: g++ simple_demo.cpp -lglfw -lGLEW -lGL -lGLU */ #include #include #include #include #include #include #include #include #include using namespace glm; const float height = 1280; const float width = 800; void GLAPIENTRY debug_callback(GLenum, GLenum type, GLuint, GLenum severity, GLsizei, const GLchar* message, const void*){ if(severity != GL_DEBUG_SEVERITY_HIGH && severity != GL_DEBUG_SEVERITY_MEDIUM ) return; fprintf( stderr, "GL ERROR MESSAGE: %s type = 0x%x, severity = 0x%x, message = %s\n", ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ), type, severity, message ); } int main(int argc, char ** argv){ glfwInit(); GLFWwindow* window = glfwCreateWindow(width, height, "Simple OpenGL 4.0+ Demo", 0, 0); glfwMakeContextCurrent(window); glewInit(); // During init, enable debug output glEnable ( GL_DEBUG_OUTPUT ); glDebugMessageCallback( debug_callback, 0 ); // Initialization part float vertices[] = {0, 1, 0, -0.5, 0, 0, 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, 0, 0.5, 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 = (char*)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); // glEnable(GL_DEPTH_TEST); while(!glfwWindowShouldClose(window)){ count++; glfwPollEvents(); glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); mat4 model = rotate(mat4(1.0), count / 100.0f, vec3(0, 1, 0)); mat4 view = lookAt(((vec3){0.0f, 0.0f, 9.0f}), vec3(0, 0, -1), vec3(0, 1, 0)); mat4 projection = perspective(radians(45.0f), width/height, 0.1f, 1000.0f); mat4 mvp = projection * view * model; glUniformMatrix4fv(mvp_uniform, 1, 0, value_ptr(mvp)); glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 10); glfwSwapBuffers(window); // usleep(10000); } glDeleteProgram(program); glfwDestroyWindow(window); glfwTerminate(); }