- // Set up an output texture.
- GLuint dense_flow_tex;
- glCreateTextures(GL_TEXTURE_2D, 1, &dense_flow_tex);
- //glTextureStorage2D(dense_flow_tex, 1, GL_RGB16F, level_width, level_height);
- glTextureStorage2D(dense_flow_tex, 1, GL_RGBA32F, level_width, level_height);
-
- // And draw.
- densify.exec(tex0_view, tex1_view, flow_out_tex, dense_flow_tex, level_width, level_height, width_patches, height_patches);
-
- // TODO: Variational refinement.
+ for (int level = coarsest_level; level >= int(finest_level); --level) {
+ int level_width = WIDTH >> level;
+ int level_height = HEIGHT >> level;
+ float patch_spacing_pixels = patch_size_pixels * (1.0f - patch_overlap_ratio);
+ int width_patches = 1 + lrintf((level_width - patch_size_pixels) / patch_spacing_pixels);
+ int height_patches = 1 + lrintf((level_height - patch_size_pixels) / patch_spacing_pixels);
+
+ // Make sure we always read from the correct level; the chosen
+ // mipmapping could otherwise be rather unpredictable, especially
+ // during motion search.
+ // TODO: create these beforehand, and stop leaking them.
+ GLuint tex0_view, tex1_view;
+ glGenTextures(1, &tex0_view);
+ glTextureView(tex0_view, GL_TEXTURE_2D, tex0, GL_R8, level, 1, 0, 1);
+ glGenTextures(1, &tex1_view);
+ glTextureView(tex1_view, GL_TEXTURE_2D, tex1, GL_R8, level, 1, 0, 1);
+
+ // Create a new texture; we could be fancy and render use a multi-level
+ // texture, but meh.
+ GLuint grad0_tex;
+ glCreateTextures(GL_TEXTURE_2D, 1, &grad0_tex);
+ glTextureStorage2D(grad0_tex, 1, GL_RG16F, level_width, level_height);
+
+ // Find the derivative.
+ sobel.exec(tex0_view, grad0_tex, level_width, level_height);
+
+ // Motion search to find the initial flow. We use the flow from the previous
+ // level (sampled bilinearly; no fancy tricks) as a guide, then search from there.
+
+ // Create an output flow texture.
+ GLuint flow_out_tex;
+ glCreateTextures(GL_TEXTURE_2D, 1, &flow_out_tex);
+ glTextureStorage2D(flow_out_tex, 1, GL_RG16F, width_patches, height_patches);
+
+ // And draw.
+ motion_search.exec(tex0_view, tex1_view, grad0_tex, prev_level_flow_tex, flow_out_tex, level_width, level_height, width_patches, height_patches);
+
+ // Densification.
+
+ // Set up an output texture.
+ GLuint dense_flow_tex;
+ glCreateTextures(GL_TEXTURE_2D, 1, &dense_flow_tex);
+ //glTextureStorage2D(dense_flow_tex, 1, GL_RGB16F, level_width, level_height);
+ glTextureStorage2D(dense_flow_tex, 1, GL_RGBA32F, level_width, level_height);
+
+ // And draw.
+ densify.exec(tex0_view, tex1_view, flow_out_tex, dense_flow_tex, level_width, level_height, width_patches, height_patches);
+
+ // TODO: Variational refinement.
+
+ prev_level_flow_tex = dense_flow_tex;
+ }