DLGOPENGL-05

在我们开始直接绘制之前,我们首先需要删除图像,因为如前一课所述,我们会在每次循环运行时重新绘制场景。glClear函数删除包含图像信息的缓冲区。我们片段的颜色信息(片段与屏幕上的像素相似,但具有深度值等附加信息。当图像输出时,这些片段被转换为像素)存储在所谓的颜色缓冲区中。因此,我们将常量GL_COLOR_BUFFER_BIT传递给glClear函数。上述深度值在深度缓冲区中。该数据用于确定哪些像素被其他像素隐藏。因此,我们还应该删除深度缓冲区。此项的常量为GL_DEPTH_BUFFER_BIT。

//空颜色缓冲区和深度缓冲区

glClear(GL_color_buffer_BIT或GL_depth_buffer-BIT);

使用glClearColor命令,我们可以指定在调用glClear时应将哪些颜色信息写入颜色缓冲区。因此,如果我们准确地使用它,glClear不会删除颜色缓冲区,但会用定义的值填充它。默认情况下,碎片为黑色。(为了完整起见,深度缓冲区总是用零覆盖。)
因此,每次绘制过程(渲染过程)都不会删除图像存储器,而是由程序员决定何时发生。理论上,您也可以回放场景,然后在输出之前删除它……谁喜欢它:)。
如果决定不删除颜色缓冲区,还可以创建一些不错的效果。例如,如果你在反恐打击中穿过墙壁,你中间的骗子应该知道所取得的效果。在这两种情况下,模糊的原因是相同的:绘制新图像时没有从缓冲区中删除旧图像。

如果我们在监视器旁边侧视,我们会看到一条从左到右的线(如果你不应该这样做,不要担心,作者更经常出现这种癫痫发作)。这是X轴,它在负区域中延伸到监视器的左侧,在正区域中延伸至监视器的右侧。
现在我们上下看,我们已经看到了Y轴,它在监视器上方正运行,在监视器下方负运行。精彩的如果你已经在2D中工作过,此时你的脸上应该会露出傻笑,并且会有一种安慰的感觉,那就是这一切对你来说似乎已经很熟悉了。但让我们感到恐惧的是,我们可以远离屏幕,甚至更靠近屏幕(我们中所有近视的人都不应该这么个人,他们也生活在3D空间中)。
这种现象在3D空间中很常见,但当我们在Z轴上移动时,这种现象并非无法解释。如果我们把椅子从显示器上移开,我们就到达了Z轴的正区域,如果我们朝着它移动,我们就达到了负区域。任何已经用D3D编程的人都应该很快记住,这是D3D和OpenGL之间的巨大区别。如果你不知道,这可能会导致一些非常严重的错误。

这段没有看懂,我的理解是OPENGL的视觉是由视觉的位置决定的,我原理显示器,意味着我的Z纵深为正值,靠近显示器移动,Z深度就变成了负值?


特别是如果你已经编程了2D游戏,你应该很快将自己与以下想法分开:你看到和指定的坐标通常与屏幕的像素不对应,而是所谓的世界坐标。这些世界坐标没有定义,因为它们的大小取决于程序员。如果你把物体放在你前面一个单位,右边0.1个单位,或者你前面100个单位,旁边10个单位,这都无关紧要。你可以支配的世界是无限的;)。理论上可以将场景表示为无限小或无限大。唯一真正阻止您执行此操作的是可用类型的大小和分辨率,如整数或单个;)。物体的实际尺寸印象是由观察者和其他物体在世界上移动的速度产生的。

 

 

为了使用OpenGL渲染某些东西,我们需要了解模型矩阵是什么以及为什么需要它。此矩阵记录对象的绘制方式和位置。这听起来可能很奇怪,但很容易说明。
人们应该想象,实际上存在两个坐标系,毫无疑问,这很简单……;)。我用一张示例图向您解释:

 

 

左侧的是OPENGL的世界坐标系,始终保持不变。右侧的是模型的坐标系,可以修改,由用户进行修改。

所以在3D编程中,你实际上不是移动物体而是移动坐标系。由于您无法在世界坐标系中如此轻松地移动和旋转对象(尝试自己计算任意旋转立方体的新坐标),因此您正在寻找可以代替世界坐标系移动的对象,并且与坐标系原点中的非旋转表示一样容易处理。读过书的人已经知道了…对!模型坐标系是自己产生的?太棒了
模型坐标系与第一次调用之前的世界坐标系平行,即基本向量(x,y,z轴)“指向”相同方向,并具有相同的原始斜率(0点)。如果我们现在调用OpenGL函数来修改(例如glTralate、glRotate…)我们的对象,我们实际上不会更改对象,而是只更改模型坐标系。此外,在编程时,我们首先定义位置(即模型坐标系),然后绘制对象,这真的很难理解吗?

德文翻译过来,听得有点儿费劲。

 

 

 

左图:模型坐标系位于世界坐标系原点的起点(或调用glLoadldentity之后) 右图:调用glRotate和glTranslate后的模型坐标系

 上图中的立方体实际上是不必要的,仅用于说明。


所以一开始我们把模型坐标系放在世界坐标系的中心。举上面的例子:屏幕。这是通过命令glLoadIdentity完成的,并对应于模型矩阵的重置。理论上,我们现在可以在这一点上画出一些东西。然而,这会导致物体非常大或根本不可见,因为我们观察物体的点(也称为眼点坐标)正好位于物体所在的位置,在原点(假设我们在原点周围或对着原点绘制一个物体,并且正好在x/y平面上,而不是在上面或下面)。让我们向后移动6个单位,向左移动1.5个单位!
一个小示例图形应该有助于:

 

 

 经过移动,有可能人的视界就不一定能够看到这个小方块了。

为此,我们应该意识到,在OpenGL中,我们实际上被绑在椅子上,也就是说,我们根本无法移动。我不想这样阻止我们。我们只需要移动整个世界,让它看起来像我们在移动。因为如果除了我们以外的所有人都向左移动,我们会觉得我们已经向右移动了,对吗?但现在来看看我们第一个物体的运动:

 
glTranslatef(0, 0,-6);
glTranslatef(-1.5,0,0);
这导致我们的铅笔向后移动6个单位(Y轴的负面积),然后向左移动1.5个单位(X轴的负区域)。我故意分两步来说明这个问题。毫无疑问,只需glTranslate*的一次调用就可以轻松完成所有操作:
glTranslatef(-1.5, 0,-6);
请注意,在这种情况下,向后6步是必要的,以便与物体保持一定距离,而不是直接站在其中!
完成!我们已经将“绘图笔”放置在那里,现在正在等待我们发出进一步的绘图命令。这听起来可能有点令人困惑……尽可能使用参数并识别其含义。
glBegin(GL_TRIANGLES);
  glVertex3f(-1,-1, 0);  
  glVertex3f( 1,-1, 0);
  glVertex3f( 0, 1, 0);
glEnd;

 

 

 从例子可以看出Z的坐标与模型坐标的关系。此处为2D图像,如果Z>=0,则渲染出来什么也看不见,因为你的眼睛已经在模型的背后了。

 

 

我们在glBegin的帮助下告诉OpenGL我们想要绘制一个对象。在本例中,我们传递参数GL_TRIANGLE,它向OpenGL指示以下点应被解释为三角形。
接下来是对glVertex3f的三重调用。现在,每次调用都会在我们的3D空间中创建一个顶点。由于我们在glBegin上告诉OpenGL,这些点应该合并为三角形,所以这是这样做的。
正如我们在图片中所看到的,我们的三角形如预期的那样向左移动,并且与相机的距离也很小,即沿Z轴移动了4个单位。

 在任何人开始逐像素绘制屏幕或甚至打开PaintShop创建第一个纹理之前,请停止!在OpenGL中有一种更好的简单着色方法。我们只需为每个角点定义一种颜色,OpenGL甚至可以独立地为其创建颜色渐变。我们现在要做的就是告诉OpenGL使用不同的颜色。OpenGL将对以下所有顶点使用此颜色,直到我们发出另一个命令。我一直在挥舞的神秘命令是glColor*:

glColor3f(1,0,0);
给三个顶点赋予不同的颜色形成渐变色。
glBegin(GL_TRIANGLES);
  glColor3f(1, 0, 0); glVertex3f(-1,-1, 0);  
  glColor3f(0, 0, 1); glVertex3f( 1,-1, 0);
  glColor3f(0, 1, 0); glVertex3f( 0, 1, 0);
glEnd;

 

 


总结下,这次的学习,我们初始化了OpenGL,在屏幕上尝试了Z视觉的坐标调试,绘制出了第一个三角形,并进行了着色!

 



posted @ 2022-11-20 21:07  下雨天不爱打伞  阅读(38)  评论(0编辑  收藏  举报