了解用于在 OpenGL 3.3 中绘制四边形的代码使用三角形的核心

发布于 2024-11-03 20:13:54 字数 1667 浏览 1 评论 0原文

我正在尝试使用 OpenGL 3.x+ 绘制一个四边形作为背景(2D)。四边形已被弃用,因此目标是使用两个三角形来制作一个填充屏幕的矩形。它有效,但我并不是 100% 清楚这里的一切。

  1. 设置

    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,它怎么知道要上传呢?
  2. 画画

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 5);
    glDisableVertexAttribArray(0);
    
    • glEnableVertexAttribArray() 只是说我要使用数组 0 进行绘制?
    • glDrawArrays() - 如果我想绘制两个顶点数组怎么办?它如何知道要渲染哪些?它从上面的命令知道这一点吗?
    • 不确定 glVertexAttribPointer() 的作用是什么?
    • glDrawArrays() 很清楚。
  3. 清理一下,我认为这是对的吗?

    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.

  1. 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 the vertexPositions to the GPU's memory; but how does it know were to upload it since I didn't give it an ID?
  2. 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.
  3. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最初的梦 2024-11-10 20:13:54

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, and positionBufferObject is its ID."

glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject); says "positionBufferObject is now the current GL_ARRAY_BUFFER."

glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW); says "upload vertexPositions to the ID currently bound to GL_ARRAY_BUFFER (which is positionBufferObject)."

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."

晚雾 2024-11-10 20:13:54

回答user697111关于多个数组的问题,非常简单。

每个顶点属性需要与一个缓冲区对象关联。关联不是通过 glVertexAttribPointer 指定缓冲区对象,而是通过 GL_ARRAY_BUFFER 完成。当您调用 glVertexAttribPointer(或任何 gl*Pointer 调用)时,当前绑定到 GL_ARRAY_BUFFER 的缓冲区将用作该属性的源。因此,请考虑以下情况:

glBindBuffer(GL_ARRAY_BUFFER, myPositionData);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, ..., 0);
glBindBuffer(GL_ARRAY_BUFFER, myColorData);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, ..., 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDrawArrays(...);

属性 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:

glBindBuffer(GL_ARRAY_BUFFER, myPositionData);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, ..., 0);
glBindBuffer(GL_ARRAY_BUFFER, myColorData);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, ..., 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDrawArrays(...);

Attribute 0 will come from the buffer object myPositionData, and attribute 1 will come from the buffer object myColorData. The fact that I undid the binding to GL_ARRAY_BUFFER before calling glDrawArrays does not change where the data for those attributes comes from.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文