Reputation: 1889
I have a texture that I can render in OpenGL-ES with an orthogonal identity matrix:
gst_gl_shader_set_uniform_matrix_4fv(shader, "u_transformation", 1, FALSE, identity_matrix);
I want to move "the pixels around": half of the top is going to the left, half of the bottom is going to the right as shown on the image below. Is there an "easy" way to do that? I'm on Android.
On this related answered question How to crop/clip in OpenGL using u_transformation, I was able to keep the top part 'a' or the bottom part 'e'. Would there be a way to do a "double gst_gl_shader_set_uniform_matrix_4fv" after "cutting" the scene in two?
Upvotes: 0
Views: 534
Reputation: 1889
The formula described in Reto answers 'semi' work as they only produce the "a" on the left or the "e" on the right but not both at the same time.
The solution I found is to double the number of vertices and indices and play around with the vertices coordinates like this:
static const GLfloat vertices[] = {
1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, -1.0f, 0.0f, 0.0f, 0.5f,
1.0f, -1.0f, 0.0f, 1.0f, 0.5f,
0.0f, 1.0f, 0.0f, 1.0f, 0.5f,
-1.0f, 1.0f, 0.0f, 0.0f, 0.5f,
-1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
0.0f, -1.0f, 0.0f, 1.0f, 1.0f
};
static const GLushort indices[] = { 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7 };
Upvotes: 0
Reputation: 54592
The transformation that you want here cannot be represented by a transformation matrix. Matrices can only represent certain classes of transformations. In 3D space:
The transformation in your sketch is none of the above. So applying a matrix to your vertices will not be able to do this.
So what can you do? Two options come to mind:
For option 2, you could do this either in the vertex or fragment shader. If you have no primitives that cross the boundary between the two parts, handling it in the vertex shader would be more efficient. Otherwise, similar logic can be used in the fragment shader.
Sketching the critical parts for the vertex shader case, let's say you currently have the following that gives you the arrangement in the left side of your sketch:
// Calculate output position and store it in variable "pos".
gl_Position = pos;
To get the second arrangement, the logic could look like this (completely untested...):
if (pos.y > 0.0) {
gl_Position = vec4(0.5 * pos.x - 0.5, 2.0 * pos.y - 1.0, pos.zw)
} else {
gl_Position = vec4(0.5 * pos.x + 0.5, 2.0 * pos.y + 1.0, pos.zw);
}
The idea is that you check whether the vertex is in the top or bottom half, and scale/shift it accordingly to map the top half of the coordinate space into the left half, and the bottom half of the coordinate space into the right half.
This could be streamlined some more by replacing the conditional with a sign
operation:
float s = sign(pos.y);
gl_Position = vec4(0.5 * pos.x - sign * 0.5, 2.0 * pos.y - sign, pos.zw);
Some more care will be needed if pos.w
is not 1.0, which happens if you e.g. applied a perspective projection to your vertices. In that case, you'll have to incorporate the division by w
in the calculations above.
Upvotes: 1