在 OpenGL-ES 中四处移动像素 (Android)
Move pixels around in OpenGL-ES (Android)
我有一个可以在 OpenGL-ES 中使用正交单位矩阵渲染的纹理:
gst_gl_shader_set_uniform_matrix_4fv(shader, "u_transformation", 1, FALSE, identity_matrix);
我要移动"the pixels around": 上面的一半向左移动,底部的一半向右移动,如下图所示。有 "easy" 方法吗?我在 Android.
在这个相关的已回答问题 上,我能够保留顶部 'a' 或底部 'e'。有没有办法在 "cutting" 场景之后将 "double gst_gl_shader_set_uniform_matrix_4fv" 一分为二?
这里你想要的变换不能用变换矩阵来表示。矩阵只能表示某些 类 的变换。 3D space:
- 一个 3x3 矩阵表示一个线性变换。典型示例包括旋转、缩放、镜像、剪切。
- 一个 4x3 矩阵表示一个仿射变换。除上述内容外,还包括翻译。
- 如果将 3D space 扩展到具有 4 个分量的齐次坐标,则 4x4 矩阵可以表示额外的 类 变换,例如投影。
你草图中的变换是上面的none。所以对你的顶点应用矩阵将无法做到这一点。
那你能做什么?我想到了两个选项:
- 如果您可以轻松地分别绘制两个部分 (top/bottom、left/right),您显然可以做到这一点,只需更改渲染两个部分之间的变换即可。
- 在着色器代码中应用逻辑。
对于选项 2,您可以在顶点着色器或片段着色器中执行此操作。如果您没有跨越两个部分之间边界的基元,则在顶点着色器中处理它会更有效。否则,可以在片段着色器中使用类似的逻辑。
绘制顶点着色器情况下的关键部分,假设您目前有以下内容可以在草图的左侧进行排列:
// Calculate output position and store it in variable "pos".
gl_Position = pos;
要获得第二种排列,逻辑可能如下所示(完全未经测试...):
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);
}
想法是检查顶点是在上半部分还是下半部分,然后scale/shift相应地将坐标space的上半部分映射到左半部分,然后坐标的下半部分space变成右半部分。
这可以通过用 sign
操作替换条件来进一步简化:
float s = sign(pos.y);
gl_Position = vec4(0.5 * pos.x - sign * 0.5, 2.0 * pos.y - sign, pos.zw);
如果 pos.w
不是 1.0,则需要多加注意,例如,将透视投影应用于您的顶点。在这种情况下,您必须在上面的计算中包含 w
的除法。
Reto 回答 'semi' 中描述的公式起作用,因为它们只产生左侧的 "a" 或右侧的 "e",但不会同时产生两者。
我找到的解决方案是将顶点和索引的数量加倍,然后像这样处理顶点坐标:
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 };
我有一个可以在 OpenGL-ES 中使用正交单位矩阵渲染的纹理:
gst_gl_shader_set_uniform_matrix_4fv(shader, "u_transformation", 1, FALSE, identity_matrix);
我要移动"the pixels around": 上面的一半向左移动,底部的一半向右移动,如下图所示。有 "easy" 方法吗?我在 Android.
在这个相关的已回答问题
这里你想要的变换不能用变换矩阵来表示。矩阵只能表示某些 类 的变换。 3D space:
- 一个 3x3 矩阵表示一个线性变换。典型示例包括旋转、缩放、镜像、剪切。
- 一个 4x3 矩阵表示一个仿射变换。除上述内容外,还包括翻译。
- 如果将 3D space 扩展到具有 4 个分量的齐次坐标,则 4x4 矩阵可以表示额外的 类 变换,例如投影。
你草图中的变换是上面的none。所以对你的顶点应用矩阵将无法做到这一点。
那你能做什么?我想到了两个选项:
- 如果您可以轻松地分别绘制两个部分 (top/bottom、left/right),您显然可以做到这一点,只需更改渲染两个部分之间的变换即可。
- 在着色器代码中应用逻辑。
对于选项 2,您可以在顶点着色器或片段着色器中执行此操作。如果您没有跨越两个部分之间边界的基元,则在顶点着色器中处理它会更有效。否则,可以在片段着色器中使用类似的逻辑。
绘制顶点着色器情况下的关键部分,假设您目前有以下内容可以在草图的左侧进行排列:
// Calculate output position and store it in variable "pos".
gl_Position = pos;
要获得第二种排列,逻辑可能如下所示(完全未经测试...):
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);
}
想法是检查顶点是在上半部分还是下半部分,然后scale/shift相应地将坐标space的上半部分映射到左半部分,然后坐标的下半部分space变成右半部分。
这可以通过用 sign
操作替换条件来进一步简化:
float s = sign(pos.y);
gl_Position = vec4(0.5 * pos.x - sign * 0.5, 2.0 * pos.y - sign, pos.zw);
如果 pos.w
不是 1.0,则需要多加注意,例如,将透视投影应用于您的顶点。在这种情况下,您必须在上面的计算中包含 w
的除法。
Reto 回答 'semi' 中描述的公式起作用,因为它们只产生左侧的 "a" 或右侧的 "e",但不会同时产生两者。
我找到的解决方案是将顶点和索引的数量加倍,然后像这样处理顶点坐标:
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 };