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) {
GLuint sobel_program;
GLuint sobel_vao;
- GLuint uniform_tex, uniform_image_size, uniform_inv_image_size;
+ GLuint uniform_tex, uniform_image_size;
};
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)
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);
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);
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");
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);
}
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");
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);
}
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);
// 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;
GLuint derivatives_vao;
GLuint uniform_tex;
- GLuint uniform_inv_image_size;
};
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);
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;
}