美文网首页
OpenGL的2D游戏教程中为什么要开启面剔除?

OpenGL的2D游戏教程中为什么要开启面剔除?

作者: constantine丶 | 来源:发表于2019-12-26 01:00 被阅读0次

    最近在学习OpenGL官方教程中的2D小游戏项目,发现官方在做2D游戏的时候居然开启了面剔除,让人非常费解,
    如下:

    glEnable(GL_CULL_FACE); //开启面剔除功能,所有背向面都将被丢弃
    

    这个功能开启之后,所有逆时针的面可以被渲染,而所有顺时针的面会被丢弃
    我们再来看看官方给的顶点数据

        GLfloat vertices[] = {
            // 位置     // 纹理
            0.0f, 1.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 0.0f, 0.0f,
    
            0.0f, 1.0f, 0.0f, 1.0f,
            1.0f, 1.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 0.0f
        };
    

    可以看到所有的点都是顺时针的,正常来说都要被剔除掉,那么是为什么它们最后都被正常渲染了呢?
    还有二个问题如下:

    第一个问题

    官方在写正射投影的时候是这样写的:

    
    glm::mat4 projection = glm::ortho(
    0.0f, static_cast<GLfloat>(this->Width), static_cast<GLfloat>(this->Height), 0.0f, -1.0f, 1.0f);
    
    

    ortho函数的顺序是left right bottom top 对应0 800 600 0
    然而一般来说应该会这么写left right bottom top 对应0 800 0 600
    似乎官方在这里把上下颠倒了

    第二个问题

    官方在处理2D贴图的时候,加载贴图过程中没有加入

    stbi_set_flip_vertically_on_load(true); 
    

    这条语句是用来翻转图片的Y轴坐标,防止图片出现上下颠倒
    虽然没有加这个语句,但是为什么最后渲染出来的纹理是正常的呢?
    把2个问题串起来想一想,相信大家可能已经懂了一半了...

    那么,我们首先试试按照正常思路

    1.我们把面剔除开启
    2.我们把 正射投影的形式写为 0 800 0 600,也就是没有颠倒bottom和top
    那么最后会渲染成什么样子呢?
    大概会成这样子,我设置的200*200像素,位置(0,0),正射投影后


    1.png

    如果按照官方的写法

    那么渲染的图可能如下:
    200*200像素,位置也是(0,0),正射投影后


    2.png

    看到这里,相信大家都懂了,官方这么做可能是为了把(0,0)的坐标对应到画面左上角,
    而且由于整个画面上下颠倒了,原本顺时针的图形变成了逆时针,开启了面剔除是可以被正常渲染的。
    纹理的问题也是一样,实际上Y轴上下颠倒的纹理,在经过Y轴颠倒的正射投影变换之后,变成了正的...

    也许可以理解为:
    图一 Y轴向上,原点在左下
    图二 Y轴向下,原点在左上

    官方文档感觉这一部分写的有点快,初看的时候这几个问题疑惑了很久。我觉得这个也许是OpenGL开发2D游戏的一个规范之类的?(0,0)坐标必须定义在左上角?

    这在2D图形以及/或GUI系统中广为接受,元素的位置定义为元素左上角的位置。

    参考文档:
    https://learnopengl-cn.github.io/06%20In%20Practice/2D-Game/03%20Rendering%20Sprites/

    相关文章

      网友评论

          本文标题:OpenGL的2D游戏教程中为什么要开启面剔除?

          本文链接:https://www.haomeiwen.com/subject/lwnhoctx.html