/* 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 */ #include #include #include #include #include #include #include #include #include #include #include "scolor.hpp" const float height = 2560; const float width = 1600; // Will be used for a lot of stuff throughout the demo // NOTE: general_buffer is NOT thread safe. Don't try to load shaders in parallel! // NOTE on the NOTE: You probably shouldn't do that anyway! #define GBLEN (1024*32) char *general_buffer; GLuint make_shader(const 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").c_str(), GBLEN, filename); return 0; } general_buffer[readlen] = 0; printf(DGREEN("Read shader in file %s (%d bytes)\n").c_str(), 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){ puts(GREEN("Compile Success").c_str()); return s_reference; } puts(RED("Compile Failed\n").c_str()); return 0; } int main(int argc, char ** argv){ general_buffer = (char*)malloc(GBLEN); glfwInit(); GLFWwindow* window = glfwCreateWindow(width, height, "Simple OpenGL 4.0+ Demo", 0, 0); glfwMakeContextCurrent(window); glewInit(); GLuint program = glCreateProgram(); GLuint shader = make_shader("image_filter.glsl", GL_COMPUTE_SHADER); glAttachShader(program, shader); glLinkProgram(program); GLint link_ok; glGetProgramiv(program, GL_LINK_STATUS, &link_ok); if(!link_ok){ glGetProgramInfoLog(program, GBLEN, NULL, general_buffer); puts(general_buffer); puts(RED("Link Failed").c_str()); return 1; } glUseProgram(program); int width, height; unsigned char* image = SOIL_load_image("brick.jpg", &width, &height, 0, SOIL_LOAD_RGBA); if(!image) puts(RED("No image, giving up!").c_str()); else printf(PURPLE("Image size: %d by %d\n").c_str(), width, height); unsigned int image_buffer; glGenBuffers(1, &image_buffer); glBindBuffer(GL_SHADER_STORAGE_BUFFER, image_buffer); glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * width * height, image, GL_STATIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, image_buffer); glDispatchCompute(width*height, 1, 1); glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, width*height*sizeof(int), image); // write image SOIL_save_image("done.bmp", SOIL_SAVE_TYPE_BMP, width, height, 4, image); puts(GREEN("Saved image as done.bmp").c_str()); glDeleteProgram(program); glfwDestroyWindow(window); glfwTerminate(); free(general_buffer); } // g++ load_object.cpp -lGL -lglfw -lGLEW