]> git.sesse.net Git - nageru/blobdiff - flow.cpp
Also calculate beta_0 when calculating derivatives.
[nageru] / flow.cpp
index d5e73eccf93c47a16d3ef943612873428bd80402..8250aa3a885e63c633988ad76c3015a142aa0767 100644 (file)
--- a/flow.cpp
+++ b/flow.cpp
@@ -153,10 +153,10 @@ GLuint load_texture(const char *filename, unsigned width, unsigned height)
 
 GLuint link_program(GLuint vs_obj, GLuint fs_obj)
 {
-        GLuint program = glCreateProgram();
-        glAttachShader(program, vs_obj);
-        glAttachShader(program, fs_obj);
-        glLinkProgram(program);
+       GLuint program = glCreateProgram();
+       glAttachShader(program, vs_obj);
+       glAttachShader(program, fs_obj);
+       glLinkProgram(program);
        GLint success;
        glGetProgramiv(program, GL_LINK_STATUS, &success);
        if (success == GL_FALSE) {
@@ -224,7 +224,7 @@ private:
        GLuint sobel_program;
        GLuint sobel_vao;
 
-       GLuint uniform_tex, uniform_image_size, uniform_inv_image_size;
+       GLuint uniform_tex, uniform_image_size;
 };
 
 Sobel::Sobel()
@@ -234,15 +234,14 @@ Sobel::Sobel()
        sobel_program = link_program(sobel_vs_obj, sobel_fs_obj);
 
        // Set up the VAO containing all the required position/texcoord data.
-        glCreateVertexArrays(1, &sobel_vao);
-        glBindVertexArray(sobel_vao);
+       glCreateVertexArrays(1, &sobel_vao);
+       glBindVertexArray(sobel_vao);
 
        GLint position_attrib = glGetAttribLocation(sobel_program, "position");
        glEnableVertexArrayAttrib(sobel_vao, position_attrib);
        glVertexAttribPointer(position_attrib, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
 
        uniform_tex = glGetUniformLocation(sobel_program, "tex");
-       uniform_inv_image_size = glGetUniformLocation(sobel_program, "inv_image_size");
 }
 
 void Sobel::exec(GLint tex0_view, GLint grad0_tex, int level_width, int level_height)
@@ -251,7 +250,6 @@ void Sobel::exec(GLint tex0_view, GLint grad0_tex, int level_width, int level_he
        glBindTextureUnit(0, tex0_view);
        glBindSampler(0, nearest_sampler);
        glProgramUniform1i(sobel_program, uniform_tex, 0);
-       glProgramUniform2f(sobel_program, uniform_inv_image_size, 1.0f / level_width, 1.0f / level_height);
 
        GLuint grad0_fbo;  // TODO: cleanup
        glCreateFramebuffers(1, &grad0_fbo);
@@ -259,7 +257,7 @@ void Sobel::exec(GLint tex0_view, GLint grad0_tex, int level_width, int level_he
 
        glViewport(0, 0, level_width, level_height);
        glBindFramebuffer(GL_FRAMEBUFFER, grad0_fbo);
-        glBindVertexArray(sobel_vao);
+       glBindVertexArray(sobel_vao);
        glUseProgram(sobel_program);
        glDisable(GL_BLEND);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
@@ -288,8 +286,8 @@ MotionSearch::MotionSearch()
        motion_search_program = link_program(motion_vs_obj, motion_fs_obj);
 
        // Set up the VAO containing all the required position/texcoord data.
-        glCreateVertexArrays(1, &motion_search_vao);
-        glBindVertexArray(motion_search_vao);
+       glCreateVertexArrays(1, &motion_search_vao);
+       glBindVertexArray(motion_search_vao);
        glBindBuffer(GL_ARRAY_BUFFER, vertex_vbo);
 
        GLint position_attrib = glGetAttribLocation(motion_search_program, "position");
@@ -322,7 +320,7 @@ void MotionSearch::exec(GLuint tex0_view, GLuint tex1_view, GLuint grad0_tex, GL
 
        glViewport(0, 0, width_patches, height_patches);
        glBindFramebuffer(GL_FRAMEBUFFER, flow_fbo);
-        glBindVertexArray(motion_search_vao);
+       glBindVertexArray(motion_search_vao);
        glUseProgram(motion_search_program);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 }
@@ -357,8 +355,8 @@ Densify::Densify()
        densify_program = link_program(densify_vs_obj, densify_fs_obj);
 
        // Set up the VAO containing all the required position/texcoord data.
-        glCreateVertexArrays(1, &densify_vao);
-        glBindVertexArray(densify_vao);
+       glCreateVertexArrays(1, &densify_vao);
+       glBindVertexArray(densify_vao);
        glBindBuffer(GL_ARRAY_BUFFER, vertex_vbo);
 
        GLint position_attrib = glGetAttribLocation(densify_program, "position");
@@ -399,7 +397,7 @@ void Densify::exec(GLuint tex0_view, GLuint tex1_view, GLuint flow_tex, GLuint d
        glViewport(0, 0, level_width, level_height);
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
-        glBindVertexArray(densify_vao);
+       glBindVertexArray(densify_vao);
        glBindFramebuffer(GL_FRAMEBUFFER, dense_flow_fbo);
        glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, width_patches * height_patches);
 }
@@ -430,7 +428,7 @@ Prewarp::Prewarp()
        prewarp_program = link_program(prewarp_vs_obj, prewarp_fs_obj);
 
        // Set up the VAO containing all the required position/texcoord data.
-        glCreateVertexArrays(1, &prewarp_vao);
+       glCreateVertexArrays(1, &prewarp_vao);
        glBindVertexArray(prewarp_vao);
        glBindBuffer(GL_ARRAY_BUFFER, vertex_vbo);
 
@@ -471,10 +469,12 @@ void Prewarp::exec(GLuint tex0_view, GLuint tex1_view, GLuint flow_tex, GLuint I
 // The coefficients come from
 //
 //   https://en.wikipedia.org/wiki/Finite_difference_coefficient
+//
+// Also computes β_0, since it depends only on I_x and I_y.
 class Derivatives {
 public:
        Derivatives();
-       void exec(GLuint input_tex, GLuint output_tex, int level_width, int level_height);
+       void exec(GLuint input_tex, GLuint I_x_y_tex, GLuint beta_0_tex, int level_width, int level_height);
 
 private:
        GLuint derivatives_vs_obj;
@@ -483,7 +483,6 @@ private:
        GLuint derivatives_vao;
 
        GLuint uniform_tex;
-       GLuint uniform_inv_image_size;
 };
 
 Derivatives::Derivatives()
@@ -502,19 +501,20 @@ Derivatives::Derivatives()
        glVertexAttribPointer(position_attrib, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
 
        uniform_tex = glGetUniformLocation(derivatives_program, "tex");
-       uniform_inv_image_size = glGetUniformLocation(derivatives_program, "inv_image_size");
 }
 
-void Derivatives::exec(GLuint input_tex, GLuint output_tex, int level_width, int level_height)
+void Derivatives::exec(GLuint input_tex, GLuint I_x_y_tex, GLuint beta_0_tex, int level_width, int level_height)
 {
        glUseProgram(derivatives_program);
 
        bind_sampler(derivatives_program, uniform_tex, 0, input_tex, nearest_sampler);
-       glProgramUniform2f(derivatives_program, uniform_inv_image_size, 1.0f / level_width, 1.0f / level_height);
 
        GLuint derivatives_fbo;  // TODO: cleanup
        glCreateFramebuffers(1, &derivatives_fbo);
-       glNamedFramebufferTexture(derivatives_fbo, GL_COLOR_ATTACHMENT0, output_tex, 0);
+       GLenum bufs[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
+       glNamedFramebufferDrawBuffers(derivatives_fbo, 2, bufs);
+       glNamedFramebufferTexture(derivatives_fbo, GL_COLOR_ATTACHMENT0, I_x_y_tex, 0);
+       glNamedFramebufferTexture(derivatives_fbo, GL_COLOR_ATTACHMENT1, beta_0_tex, 0);
 
        glViewport(0, 0, level_width, level_height);
        glDisable(GL_BLEND);
@@ -648,17 +648,17 @@ int main(void)
                glTextureStorage2D(I_t_tex, 1, GL_R16F, level_width, level_height);
                prewarp.exec(tex0_view, tex1_view, dense_flow_tex, I_tex, I_t_tex, level_width, level_height);
 
-               // Derivatives of the images. We're only calculating first derivatives;
+               // Calculate I_x and I_y. We're only calculating first derivatives;
                // the others will be taken on-the-fly in order to sample from fewer
                // textures overall, since sampling from the L1 cache is cheap.
                // (TODO: Verify that this is indeed faster than making separate
                // double-derivative textures.)
-
-               // Calculate I_x and I_y.
-               GLuint I_x_y_tex;
+               GLuint I_x_y_tex, beta_0_tex;
                glCreateTextures(GL_TEXTURE_2D, 1, &I_x_y_tex);
+               glCreateTextures(GL_TEXTURE_2D, 1, &beta_0_tex);
                glTextureStorage2D(I_x_y_tex, 1, GL_RG16F, level_width, level_height);
-               derivatives.exec(I_tex, I_x_y_tex, level_width, level_height);
+               glTextureStorage2D(beta_0_tex, 1, GL_R16F, level_width, level_height);
+               derivatives.exec(I_tex, I_x_y_tex, beta_0_tex, level_width, level_height);
 
                prev_level_flow_tex = dense_flow_tex;
        }