#include #include #include #include "shader.h" #include "die.h" #include "uniform.h" #include "fill_vert.h" #include "visuals_frag.h" #include "output_frag.h" void resize_handler(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); } GLFWwindow* init_window() { glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // creating a non-resizable floating window makes the window float with i3 glfwWindowHint(GLFW_FLOATING, GL_TRUE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // initialize window int width = 800, height = 600; // default size GLFWwindow* window = glfwCreateWindow(width, height, "vis", NULL, NULL); if (window == NULL) die("error: could not create window\n"); glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, resize_handler); // but i still want a resizable window glfwSetWindowAttrib(window, GLFW_RESIZABLE, GL_TRUE); return window; } void init_tri() { const float vertices[] = { 0, 1, 0, 1, -1, 0, -1, -1, 0, }; // initialize vertex {buffer,attribute} object buffers GLuint VBO, VAO; glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glGenVertexArrays(1, &VAO); glBindVertexArray(VAO); // copy vertex data into VBO glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // set VAO pointers glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); // draw (only) this triangle glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(VAO); } int main(int argc, char** argv) { glfwInit(); GLFWwindow* window = init_window(); glewInit(); init_tri(); GLuint visuals = link_shaders( vert_shader(fill_vert, fill_vert_size), frag_shader(visuals_frag, visuals_frag_size) ); uniforms_t * visuals_uniforms = init_uniforms(visuals, window); GLuint output = link_shaders( vert_shader(fill_vert, fill_vert_size), frag_shader(output_frag, output_frag_size) ); uniforms_t * output_uniforms = init_uniforms(output, window); GLuint fbo; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); GLuint last_frame; glGenTextures(1, &last_frame); glBindTexture(GL_TEXTURE_2D, last_frame); // todo: what to do when the size changes? glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, last_frame, 0); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) die("can't initialize framebuffer??\n"); glBindFramebuffer(GL_FRAMEBUFFER, 0); glUseProgram(visuals); // main draw loop while (!glfwWindowShouldClose(window)) { glfwPollEvents(); update_uniforms(visuals_uniforms); // glBindFramebuffer(GL_FRAMEBUFFER, fbo); glDrawArrays(GL_TRIANGLES, 0, 3); // glBindFramebuffer(GL_FRAMEBUFFER, 0); glfwSwapBuffers(window); } return EXIT_SUCCESS; }