OpenGL -使用非规格化纹理坐标

yruzcnhs  于 2022-11-04  发布在  其他
关注(0)|答案(3)|浏览(141)

默认情况下,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和size([0..size])之间)?

093gszye

093gszye1#

若要为此情况设置纹理变换,请用途:

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空间的顶点坐标,即[-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]Map到[-1.0,1.0],这意味着它将[0.0,textureWidth]Map到[0.0,1.0],这是所需的变换。
但是,使用我的答案开头所示的glScalef()调用要简单得多。

fcipmucu

fcipmucu2#

我仍然不明白为什么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);
k4emjkb1

k4emjkb13#

由于glMatrixMode和glLoadMatrix在现代OpenGL中已弃用,因此可能需要重新考虑以下事实:您可以使用GL_TEXTURE_RECTANGLE而不是GL_TEXTURE_2D。您不能使用mipmap,并且需要在着色器中使用sampler2DRect而不是sampler2D()或texture(),但您可以通过这种方式直接进行非规格化纹理元素查找。
该功能是安全的(核心)所有的方式回到OpenGL 3.1,所以它将运行在您的10岁的英特尔高清图形。

相关问题