了解用于在 OpenGL 3.3 中绘制四边形的代码使用三角形的核心
我正在尝试使用 OpenGL 3.x+ 绘制一个四边形作为背景(2D)。四边形已被弃用,因此目标是使用两个三角形来制作一个填充屏幕的矩形。它有效,但我并不是 100% 清楚这里的一切。
设置
GLuintpositionBufferObject; GLfloat 顶点位置[] = { -1.0f、-1.0f、0.0f、1.0f、 -1.0f、1.0f、0.0f、1.0f、 1.0f、1.0f、0.0f、1.0f、 1.0f、-1.0f、0.0f、1.0f、 -1.0f、-1.0f、0.0f、1.0f、 }; glGenBuffers(1, &positionBufferObject); glBindBuffer(GL_ARRAY_BUFFER,positionBufferObject); glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
- 我理解
vertexPositions
,它是一个顶点数组。 glGenBuffers()
是说,我想要 1 个缓冲区并将 id 分配给&positionBufferObject
?glBufferData()
将vertexPositions
上传到 GPU 内存;但既然我没有给它 ID,它怎么知道要上传呢?
- 我理解
画画
glEnableVertexAttribArray(0); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 5); glDisableVertexAttribArray(0);
glEnableVertexAttribArray()
只是说我要使用数组 0 进行绘制?glDrawArrays()
- 如果我想绘制两个顶点数组怎么办?它如何知道要渲染哪些?它从上面的命令知道这一点吗?- 不确定
glVertexAttribPointer()
的作用是什么? glDrawArrays()
很清楚。
清理一下,我认为这是对的吗?
glBindBuffer(GL_ARRAY_BUFFER, 0); glDeleteBuffers(1, &positionBufferObject);
我只进行一次设置/清理。
加分点:
- 这是渲染此内容的最有效方法吗?我读到我应该“批量”提交和渲染[?],因为 3.x+ 不再使用立即模式。而且只有一个数组,因此在这种情况下批次不会提高性能,但如果我说要绘制“非常大量”的 vertxArray,这会是相同的过程吗?
- 在设置中,他们将数组 id 存储为positionBufferObject,但在渲染循环中将其硬编码。似乎在十几个数组之后会变得混乱,为什么使用变量而不是对其进行硬编码不是一个好习惯呢?
I'm trying to draw a quad for a background (2D) using OpenGL 3.x+. Quads are deprecated, so the goal is to use two triangles to make a rectangle that fills the screen. It's working, but I'm not 100% clear on everything here.
Setup
GLuint positionBufferObject; GLfloat vertexPositions[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.0f, 1.0f, }; glGenBuffers(1, &positionBufferObject); glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject); glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
- I understand the
vertexPositions
, it's an array of vertices. glGenBuffers()
is saying, I want 1 buffer and assign id to&positionBufferObject
?glBufferData()
uploads thevertexPositions
to the GPU's memory; but how does it know were to upload it since I didn't give it an ID?
- I understand the
Draw
glEnableVertexAttribArray(0); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 5); glDisableVertexAttribArray(0);
glEnableVertexAttribArray()
just says I'm going to be drawing with array 0?glDrawArrays()
- what if I want to draw two vertex arrays? How does it know which ones to render? It knows that from the above command?- Not sure what
glVertexAttribPointer()
does? glDrawArrays()
is clear.
Clean up, I think this is right?
glBindBuffer(GL_ARRAY_BUFFER, 0); glDeleteBuffers(1, &positionBufferObject);
I only do the setup/cleanup once.
Bonus points:
- Is this the most effective way to render this? I read that I'm suppose to be submitting and be rendering in "batches" [?] since 3.x+ doesn't do immediate mode any more. There is also only one array, so batches won't help performance in this case, but if I had say "a very large number" of vertxArrays to draw, would it be the same process?
- In setup they are storing the array id as positionBufferObject, but have it hardcoded in the rendering loop. Seems like it would get confusing after a dozen or so arrays, why isn't it good practice to use the variable instead of hardcode it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
glGenBuffers(1, &positionBufferObject);
表示“创建一个顶点缓冲区对象,positionBufferObject
是它的 ID。”glBindBuffer(GL_ARRAY_BUFFER,positionBufferObject);
表示“positionBufferObject
现在是当前的GL_ARRAY_BUFFER
”。glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
表示“将vertexPositions
上传到当前绑定到GL_ARRAY_BUFFER
的 ID(即 <代码>positionBufferObject)。”glEnableVertexAttribArray(0);
表示“顶点属性数组 0 现在可供使用。”glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
表示“顶点属性数组 0 将被解释为由 4 个浮点数组成的组”。glDrawArrays(GL_TRIANGLE_STRIP, 0, 5);
表示“从每个启用的数组中绘制一个具有五个索引的三角形带”。glDisableVertexAttribArray(0);
表示“我们暂时完成了顶点属性数组 0”。glGenBuffers(1, &positionBufferObject);
says "make a vertex buffer object, andpositionBufferObject
is its ID."glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
says "positionBufferObject
is now the currentGL_ARRAY_BUFFER
."glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
says "uploadvertexPositions
to the ID currently bound toGL_ARRAY_BUFFER
(which ispositionBufferObject
)."glEnableVertexAttribArray(0);
says "vertex attribute array 0 is now available for use."glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
says "vertex attribute array 0 is to be interpreted as consisting of groups of 4 floats."glDrawArrays(GL_TRIANGLE_STRIP, 0, 5);
says "draw a triangle strip with five indices from every enabled array."glDisableVertexAttribArray(0);
says "we're done for the time being with vertex attribute array 0."回答user697111关于多个数组的问题,非常简单。
每个顶点属性需要与一个缓冲区对象关联。关联不是通过 glVertexAttribPointer 指定缓冲区对象,而是通过 GL_ARRAY_BUFFER 完成。当您调用 glVertexAttribPointer(或任何 gl*Pointer 调用)时,当前绑定到 GL_ARRAY_BUFFER 的缓冲区将用作该属性的源。因此,请考虑以下情况:
属性 0 将来自缓冲区对象
myPositionData
,属性 1 将来自缓冲区对象myColorData
。事实上,我在调用glDrawArrays之前取消了与GL_ARRAY_BUFFER的绑定,这并没有改变这些属性的数据的来源。In answer to user697111's question about multiple arrays, it's quite simple.
Each vertex attribute needs to be associated with a buffer object. Rather than specifying the buffer object with glVertexAttribPointer, the association is done through GL_ARRAY_BUFFER. When you call glVertexAttribPointer (or any gl*Pointer call), the buffer that is currently bound to GL_ARRAY_BUFFER will be used as the source for that attribute. So, consider the following:
Attribute 0 will come from the buffer object
myPositionData
, and attribute 1 will come from the buffer objectmyColorData
. The fact that I undid the binding to GL_ARRAY_BUFFER before callingglDrawArrays
does not change where the data for those attributes comes from.