最近在学习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/
网友评论