Learn OpenGL(二)——顶点输入(Vertex Input)

      开始绘制一些东西之前, 我们必须给OpenGL输入一些顶点数据。 OpenGL是一个3D图形库,所以我们在OpenGL中指定的所有坐标都是在3D坐标里(x、 y和z)。 OpenGL不是简单的把你所有的3D坐标变换为你屏幕上的2D像素; OpenGL只是在当它们的3个轴(x、 y和z)在特定的-1.0到1.0的范围内时才处理3D坐标。 所有在这个范围内的坐标叫做标准化设备坐标(Normalized Device Coordinates, NDC)会最终显示在你的屏幕上(所有出了这个范围的都不会显示)。
      由于我们希望渲染一个三角形, 我们指定所有的这三个顶点都有一个3D位置。 我们把它们以 GLfloat 数组的方式定义为标准化设备坐标(也就是在OpenGL的可见区域)中。

GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};

      上面数组可以理解为3x3的矩阵,对应NDC,为三角形三个顶点的坐标:
 A1=(-0.5,-0.5,0)  A2=(0.5,-0.5,0.0)  A3=(0.0,0.5,0.0)
       由于OpenGL是在3D空间中工作的, 我们渲染一个2D三角形, 它的每个顶点都要有同一个z坐标0.0。 在这样的方式中, 三角形的每一处的深度(Depth, 译注2)都一样, 从而使它看上去就像2D的。


注:
标准化设备坐标(Normalized Device Coordinates, NDC)
一旦你的顶点坐标已经在顶点着色器中处理过, 它们就应该是标准化设备坐标了, 标准化设备坐标是一个x、 y和z值在-1.0到1.0的与通常的屏幕坐标不同, y轴正方向上的点和(0,0)坐标是这个图像的中心, 而不是左上角。 最后你希望所有(变换过的)坐标都在这个坐标


      你的标准化设备坐标接着会变换为屏幕空间坐标(Screen-space Coordinates), 这是使用你通过`glViewport`函数提供的数据
有了这样的顶点数据, 我们会把它作为输入数据发送给图形渲染管线的第一个处理阶段: 顶点着色器。 它会在GPU上创建储存空间用于储存我们的顶点数据, 还要配置OpenGL如何解释这些内存, 并且指定如何发送给显卡。 顶点着色器接着会处理我们告诉它要处理内存中的顶点的数量。
      通过顶点缓冲对象(Vertex Buffer Objects, VBO)管理这个内存, 它会在GPU内存(通常被称为显存)中储存大批顶点。 使用这些缓冲对象的好处是我们可以一次性的发送一大批数据到显卡上, 而不是每个顶点发送一次。 从CPU把数据发送到显卡相对较慢, 所以无论何处我们都要尝试尽量一次性发送尽可能多的数据。 当数据到了显卡内存中时, 顶点着色器几乎立即就能获得顶点, 这非常快。
      顶点缓冲对象(VBO)是我们在OpenGL教程中第一个出现的OpenGL对象。 就像OpenGL中的其他对象一样, 这个缓冲有一个独一无二的ID, 所以我们可以使用 glGenBuffers 函数生成一个缓冲ID:

GLuint VBO;
glGenBuffers(1, &VBO);


OpenGL有很多缓冲对象类型, GL_ARRAY_BUFFER 是其中一个顶点缓冲对象的缓冲类型。
OpenGL允许我们同时绑定多个缓冲, 只要它们是不同的缓冲类型。 我们可以使用 glBindBuffer 函数把新创建的缓冲绑定到 GL_ARRAY_BUFFER 上:

glBindBuffer(GL_ARRAY_BUFFER, VBO);


从这一刻起, 我们使用的任何缓冲函数(在 GL_ARRAY_BUFFER 目标上)都会用来配置当前绑定的缓冲( VBO )。 然后我们可以调用 glBufferData 函数, 它会把之前定义的顶点数据复制到缓冲的内存中:

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);


glBufferData 是一个用来把用户定的义数据复制到当前绑定缓冲的函数。 它的第一个参数是我们希望把数据复制到上面的缓冲类型: 顶点缓冲对象当前绑定到 GL_ARRAY_BUFFER 目标上。第二个参数指定我们希望传递给缓冲的数据的大小(以字节为单位); 用一个简单的 sizeof 计算出顶点数据就行。 第三个参数是我们希望发送的真实数据。第四个参数指定了我们希望显卡如何管理给定的数据。 有三种形式:

  • GL_STATIC_DRAW : 数据不会或几乎不会改变。
  • GL_DYNAMIC_DRAW : 数据会被改变很多。
  • GL_STREAM_DRAW : 数据每次绘制时都会改变。

三角形的位置数据不会改变, 每次渲染调用时都保持原样, 所以它使用的类型最好是 GL_STATIC_DRAW 。 如果, 比如, 一个缓冲中的数据将频繁被改变, 那么使用的类型就是 GL_DYNAMIC_DRAW 或 GL_STREAM_DRAW 。 这样就能确保图形卡把数据放在高速写入的内存部分。

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值