【问题标题】:How to achieve glOrthof in OpenGL ES 2.0如何在 OpenGL ES 2.0 中实现 glOrthof
【发布时间】:2011-09-06 08:40:08
【问题描述】:

我正在尝试将我的OpenGL ES 1 应用程序转换为OpenGL ES 2 应用程序以便能够使用着色器。现在我使用 glOrthof 函数来获得“真实大小的视口”,这样我就可以将顶点放置在 OpenGL 视图中的“实际”像素处。

glOrthof(0, _frame.size.width, _frame.size.height, 0, -1, 1);

我在OpenGL ES 2 中找不到如何实现这一点,有没有人可以告诉我如何做到这一点?

如果没有,有没有人有一个好的OpenGL ES 1 to OpenGL ES 2 教程/说明的链接?

【问题讨论】:

    标签: ios opengl-es opengl-es-2.0


    【解决方案1】:

    glOrtho 方法只是创建一个新矩阵并将当前投影矩阵乘以该矩阵。使用 OpenGL ES 2.0,您必须自己管理矩阵。为了复制glOrtho 行为,您需要在顶点着色器中为投影矩阵设置一个统一,然后将其与顶点相乘。通常你还有一个模型和一个视图矩阵(或一个组合的模型视图矩阵,比如在 OpenGL ES 1 中),你可以在投影变换之前用它们来变换你的顶点:

    uniform mat4 projection;
    uniform mat4 modelview;
    
    attribute vec4 vertex;
    
    void main()
    {
        gl_Position = projection * (modelview * vertex);
    }
    

    glOrtho构造的具体投影矩阵可以在here找到。

    【讨论】:

    • 你能告诉我如何创建/加载投影和模型视图吗?
    • @MrThys 如果您对此不确定,您应该首先真正参考一些有关 OpenGL ES 2.0 和 GLSL 着色器的学习资源。基本上,一旦你有相应的统一位置并且着色器程序被绑定/使用,你可以使用许多 glUniform... 调用之一来设置它们的值,在矩阵的情况下你会使用 glUniformMatrix4fv
    • @HaukeStrasdat 什么...你是对的!这样的规范参考怎么会死?好吧,现在我们只剩下愚蠢的 ES 参考页面了。但是好的,至少对于这个答案,它们很合适。
    • 更新的链接:khronos.org/opengles/sdk/1.1/docs/man/glOrtho.xml 但看起来文档到 HTML 的转换丢失了基本的 '/'s 和 '()'s。与 Brad Larson 的回答相比,医生可能想说2/(right-left) 0 0 tx 0 2/(top-bottom) 0 ty 0 0 -2/(far-near) tz 0 0 0 1。其中tx = -(right+left)/(right-left)ty = -(top+bottom)/(top-bottom)tz = -(far+near)/(far-near)。这与拉尔森的回答有一点不同:矩阵[10] 是-2/(far-near),但拉尔森的答案没有减号2 / f_n。所以 z 是倒置的。尝试两种方式...
    • @ToolmakerSteve 不过应该有减号。 Z 必须倒置,因为眼睛空间的相机朝向 -Z,但在 NDC/窗口空间中,我们有 +1 = 远。
    【解决方案2】:

    正如 Christian 所描述的,用于处理顶点的所有矩阵数学都取决于您,因此您必须复制 glOrthof() 创建的矩阵。在我的回答here 中,我提供了以下Objective-C 方法来生成这样的正交投影矩阵:

    - (void)loadOrthoMatrix:(GLfloat *)matrix left:(GLfloat)left right:(GLfloat)right bottom:(GLfloat)bottom top:(GLfloat)top near:(GLfloat)near far:(GLfloat)far;
    {
        GLfloat r_l = right - left;
        GLfloat t_b = top - bottom;
        GLfloat f_n = far - near;
        GLfloat tx = - (right + left) / (right - left);
        GLfloat ty = - (top + bottom) / (top - bottom);
        GLfloat tz = - (far + near) / (far - near);
    
        matrix[0] = 2.0f / r_l;
        matrix[1] = 0.0f;
        matrix[2] = 0.0f;
        matrix[3] = tx;
    
        matrix[4] = 0.0f;
        matrix[5] = 2.0f / t_b;
        matrix[6] = 0.0f;
        matrix[7] = ty;
    
        matrix[8] = 0.0f;
        matrix[9] = 0.0f;
        matrix[10] = 2.0f / f_n;
        matrix[11] = tz;
    
        matrix[12] = 0.0f;
        matrix[13] = 0.0f;
        matrix[14] = 0.0f;
        matrix[15] = 1.0f;
    }
    

    这里使用的矩阵定义为

    GLfloat orthographicMatrix[16];
    

    然后我在我的顶点着色器中应用矩阵,如下所示:

    gl_Position = modelViewProjMatrix * position * orthographicMatrix;
    

    我的乘法顺序与 Christian 的不同,所以我在这里做的可能有点落后,但这是我在我的 OpenGL ES 2.0 应用程序中用来处理这个问题的方法(可以找到源代码@ 987654322@).

    【讨论】:

    • 您的方法似乎与 glOrthof 手册页给出的公式完全匹配(例如 opengl.org/sdk/docs/man/xhtml/glOrtho.xml
    • 正交矩阵其实就是投影矩阵,但是modelViewProjMatrix这个名字暗示你有另一个投影矩阵,这在概念上有点奇怪(虽然有效,但着色器无法实现)。但真正奇怪的是,您将矩阵变换的左应用与右应用混合到向量中。这就是您在 loadOrthoMatrix 例程中实际创建转置矩阵的原因(以及此着色器代码应该对不深入矩阵转换的任何人造成完全混淆的原因)。
    • @Christian - 你真的可以看出矩阵数学不是我的强项之一。着色器的命名是从另一个实现中遗留下来的,实际上应该只是第一个组件的模型视图矩阵。我认为这是两个左手组成右手的情况,但当我尝试时它已经奏效了,所以我从来没有质疑过为什么。感谢您指出这里的奇怪之处。
    • matrix[10] = -2.0f / f_n; // 纠正缺失的减号 — 参见文档
    猜你喜欢
    • 2013-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-20
    • 2013-07-08
    • 2015-08-08
    • 1970-01-01
    相关资源
    最近更新 更多