OpenGL - 使用非规范化的纹理坐标
OpenGL - Use non normalized texcoords
默认情况下,OpenGL 使用规范化的 TexCoords,这意味着该值必须介于 0 和 1 ([0..1]) 之间。 Vertex
的常见实现必须是这样的:
// Common Implementation of Vertex
Vertex v = new Vertex(
// Position
new Vector2(0f, 500f),
// 'Normalized' TexCoords [0..1]
new Vector2(0f, 1f),
// Color of Vertex
Color.White
);
// Or in immediate mode..
// It's the same, we still need to specify between 0 and 1 ([0..1])
GL.TexCoord2(1f, 0f);
但是,是否可以在 OpenGL 中使用非标准化的 texcoord(因此它以像素格式指定,这意味着该值必须介于 0 和大小 ([0..size]) 之间)?
我仍然不明白为什么 GL.Ortho
(在 MatrixMode.Texture
中)没有给我预期的结果..
最后,我手动计算了矩阵:
// Initialize identity matrix
Matrix4 matrix = new Matrix4
(1f, 0f, 0f, 0f,
0f, 1f, 0f, 0f,
0f, 0f, 1f, 0f,
0f, 0f, 0f, 1f);
// Or use Matrix4.Identity (in OpenTK case), that should be equal(?)
// Convert to normalized
matrix[0, 0] = 1f / textureWidth;
matrix[1, 1] = 1f / textureHeight;
// Apply the matrix to texture matrix
GL.MatrixMode(MatrixMode.Texture);
GL.LoadMatrix(ref matrix);
要为此案例设置纹理变换,请使用:
glMatrixMode(GL_TEXTURE);
glScalef(1.0f / textureWidth, 1.0f / textureHeight, 1.0f);
您似乎曾尝试对 glOrtho()
做同样的事情。虽然这是可能的,但以下 不会 给出所需的结果:
glOrtho(0.0, textureWidth, 0.0, textureHeight, ...);
glOrtho()
构建一个矩阵,在两个坐标方向上将给定范围转换为范围 [-1.0, 1.0]。这是有道理的,因为它主要用于需要转化为NDC space的顶点坐标,即[-1.0, 1.0].
但是,对于纹理坐标,您希望将 [0.0, textureWidth] 和 [0.0, textureHeight] 范围转换为 [0.0, 1.0] 范围。如果您完全使用 glOrtho()
,正确的调用将是:
glOrtho(-textureWidth, textureWidth, -textureHeight, textureHeight, 1.0, -1.0);
由于现在将 [-textureWidth, textureWidth] 映射到 [-1.0, 1.0],这意味着它将 [0.0, textureWidth] 映射到 [0.0, 1.0],这是所需的转换。
但是使用我回答开头显示的 glScalef()
调用更容易和更清晰。
默认情况下,OpenGL 使用规范化的 TexCoords,这意味着该值必须介于 0 和 1 ([0..1]) 之间。 Vertex
的常见实现必须是这样的:
// Common Implementation of Vertex
Vertex v = new Vertex(
// Position
new Vector2(0f, 500f),
// 'Normalized' TexCoords [0..1]
new Vector2(0f, 1f),
// Color of Vertex
Color.White
);
// Or in immediate mode..
// It's the same, we still need to specify between 0 and 1 ([0..1])
GL.TexCoord2(1f, 0f);
但是,是否可以在 OpenGL 中使用非标准化的 texcoord(因此它以像素格式指定,这意味着该值必须介于 0 和大小 ([0..size]) 之间)?
我仍然不明白为什么 GL.Ortho
(在 MatrixMode.Texture
中)没有给我预期的结果..
最后,我手动计算了矩阵:
// Initialize identity matrix
Matrix4 matrix = new Matrix4
(1f, 0f, 0f, 0f,
0f, 1f, 0f, 0f,
0f, 0f, 1f, 0f,
0f, 0f, 0f, 1f);
// Or use Matrix4.Identity (in OpenTK case), that should be equal(?)
// Convert to normalized
matrix[0, 0] = 1f / textureWidth;
matrix[1, 1] = 1f / textureHeight;
// Apply the matrix to texture matrix
GL.MatrixMode(MatrixMode.Texture);
GL.LoadMatrix(ref matrix);
要为此案例设置纹理变换,请使用:
glMatrixMode(GL_TEXTURE);
glScalef(1.0f / textureWidth, 1.0f / textureHeight, 1.0f);
您似乎曾尝试对 glOrtho()
做同样的事情。虽然这是可能的,但以下 不会 给出所需的结果:
glOrtho(0.0, textureWidth, 0.0, textureHeight, ...);
glOrtho()
构建一个矩阵,在两个坐标方向上将给定范围转换为范围 [-1.0, 1.0]。这是有道理的,因为它主要用于需要转化为NDC space的顶点坐标,即[-1.0, 1.0].
但是,对于纹理坐标,您希望将 [0.0, textureWidth] 和 [0.0, textureHeight] 范围转换为 [0.0, 1.0] 范围。如果您完全使用 glOrtho()
,正确的调用将是:
glOrtho(-textureWidth, textureWidth, -textureHeight, textureHeight, 1.0, -1.0);
由于现在将 [-textureWidth, textureWidth] 映射到 [-1.0, 1.0],这意味着它将 [0.0, textureWidth] 映射到 [0.0, 1.0],这是所需的转换。
但是使用我回答开头显示的 glScalef()
调用更容易和更清晰。