out vec2 derivatives;
uniform sampler2D tex;
-uniform vec2 inv_image_size;
void main()
{
- float x_m2 = texture(tex, vec2(tc.x - 2.0 * inv_image_size.x), tc.y).x;
- float x_m1 = texture(tex, vec2(tc.x - inv_image_size.x), tc.y).x;
- float x_p1 = texture(tex, vec2(tc.x + inv_image_size.x), tc.y).x;
- float x_p2 = texture(tex, vec2(tc.x + 2.0 * inv_image_size.x), tc.y).x;
+ float x_m2 = textureOffset(tex, tc, ivec2(-2, 0)).x;
+ float x_m1 = textureOffset(tex, tc, ivec2(-1, 0)).x;
+ float x_p1 = textureOffset(tex, tc, ivec2( 1, 0)).x;
+ float x_p2 = textureOffset(tex, tc, ivec2( 2, 0)).x;
- float y_m2 = texture(tex, vec2(tc.x, tc.y - 2.0 * inv_image_size.y)).x;
- float y_m1 = texture(tex, vec2(tc.x, tc.y - inv_image_size.y)).x;
- float y_p1 = texture(tex, vec2(tc.x, tc.y + inv_image_size.y)).x;
- float y_p2 = texture(tex, vec2(tc.x, tc.y + 2.0 * inv_image_size.y)).x;
+ float y_m2 = textureOffset(tex, tc, ivec2( 0, -2)).x;
+ float y_m1 = textureOffset(tex, tc, ivec2( 0, -1)).x;
+ float y_p1 = textureOffset(tex, tc, ivec2( 0, 1)).x;
+ float y_p2 = textureOffset(tex, tc, ivec2( 0, 2)).x;
derivatives.x = (x_p1 - x_m1) * (2.0/3.0) + (x_m2 - x_p2) * (1.0/12.0);
derivatives.y = (y_p1 - y_m1) * (2.0/3.0) + (y_m2 - y_p2) * (1.0/12.0);
GLuint sobel_program;
GLuint sobel_vao;
- GLuint uniform_tex, uniform_image_size, uniform_inv_image_size;
+ GLuint uniform_tex, uniform_image_size;
};
Sobel::Sobel()
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);
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)
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);
// Computing both directions at once allows us to get away with eight
// texture samples instead of twelve.
- float x_left = tc.x - inv_image_size.x;
- float x_mid = tc.x;
- float x_right = tc.x + inv_image_size.x;
-
- float y_top = tc.y + inv_image_size.y; // Note the bottom-left coordinate system.
- float y_mid = tc.y;
- float y_bottom = tc.y - inv_image_size.y;
-
- float top_left = texture(tex, vec2(x_left, y_top)).x;
- float left = texture(tex, vec2(x_left, y_mid)).x;
- float bottom_left = texture(tex, vec2(x_left, y_bottom)).x;
-
- float top = texture(tex, vec2(x_mid, y_top)).x;
- float bottom = texture(tex, vec2(x_mid, y_bottom)).x;
-
- float top_right = texture(tex, vec2(x_right, y_top)).x;
- float right = texture(tex, vec2(x_right, y_mid)).x;
- float bottom_right = texture(tex, vec2(x_right, y_bottom)).x;
+ float top_left = textureOffset(tex, tc, ivec2(-1, 1)).x; // Note the bottom-left coordinate system.
+ float left = textureOffset(tex, tc, ivec2(-1, 0)).x;
+ float bottom_left = textureOffset(tex, tc, ivec2(-1, -1)).x;
+
+ float top = textureOffset(tex, tc, ivec2( 0, 1)).x;
+ float bottom = textureOffset(tex, tc, ivec2( 0, -1)).x;
+
+ float top_right = textureOffset(tex, tc, ivec2( 1, 1)).x;
+ float right = textureOffset(tex, tc, ivec2( 1, 0)).x;
+ float bottom_right = textureOffset(tex, tc, ivec2( 1, -1)).x;
gradients.x = (top_right + 2.0f * right + bottom_right) - (top_left + 2.0f * left + bottom_left);
gradients.y = (top_left + 2.0 * top + top_right) - (bottom_left + 2.0f * bottom + bottom_right);