sách gpt4 ai đã đi

opengl - 了解 glVertexAttribPointer?

In lại 作者:行者123 更新时间:2023-12-04 05:18:02 28 4
mua khóa gpt4 Nike

private int vbo;
private int ibo;

vbo = glGenBuffers();
ibo = glGenBuffers();

glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, Util.createFlippedBuffer(vertices), GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, Util.createFlippedBuffer(indices), GL_STATIC_DRAW);




glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
//glEnableVertexAttribArray(2);

//glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, false, Vertex.SIZE * 4, 0);
glVertexAttribPointer(1, 2, GL_FLOAT, false, Vertex.SIZE * 4, 12);
//glVertexAttribPointer(2, 3, GL_FLOAT, false, Vertex.SIZE * 4, 20);

//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
//glDisableVertexAttribArray(2);

顶点着色器代码看起来像

#version 330

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoord;

out vec2 texCoord0;

uniform mat4 transform;

void main()
{
gl_Position = transform * vec4(position, 1.0);
texCoord0 = texCoord;
}

所以,这是我的理解。 glVertexAttribPointer 的目的是定义顶点缓冲区对象中数据的格式。因此,在 vbo 中,它存储数据如下

buffer.put(vertices[i].getPos().getX());
buffer.put(vertices[i].getPos().getY());
buffer.put(vertices[i].getPos().getZ());
buffer.put(vertices[i].getTexCoord().getX());
buffer.put(vertices[i].getTexCoord().getY());
buffer.put(vertices[i].getNormal().getX());
buffer.put(vertices[i].getNormal().getY());
buffer.put(vertices[i].getNormal().getZ());

因此,我们有两条 glVertexAttribPointer 行,因为我们在顶点着色器中定义了两个变量。所以基本上我们正在定义这两个变量指向什么。因此,第一个 glVertexAttribPointer 定义第一个变量“位置”是一个顶点,三个坐标均为浮点数。第二个 glVertexAttribPointer 将第二个变量“texCoord”定义为一对纹理坐标,每个坐标都是浮点数。所以,如果到目前为止我的理解是正确的,那么我假设我们首先需要先绑定(bind)顶点缓冲区对象,但即使在注释掉这一行之后

glBindBuffer(GL_ARRAY_BUFFER, vbo);

它仍然有效。我很困惑。既然有两个 vbo,它怎么知道我们在谈论哪个缓冲区对象?

1 Câu trả lời

@datenwolf 已经在上面的评论中介绍了关键方面。详细说明:

你做 KHÔNG 必须绑定(bind)GL_ARRAY_BUFFER再次在 glDrawElements() 之前称呼。重要的是,当您创建 glVertexAttribPointer() 时,您要从中获取给定属性的缓冲区是绑定(bind)的。调用该属性。

描绘这一点的最佳方式是,当您调用电话时:

glVertexAttribPointer(0, 3, GL_FLOAT, false, Vertex.SIZE * 4, 0);

您正在指定告诉 OpenGL 从何处获取属性 0(第一个参数)的数据所需的所有状态,以及如何读取它。大多数状态由参数直接给出:
  • 它有 3 个组件
  • 组件是浮点值
  • 以 20 字节的步长读取顶点...
  • ...并从缓冲区的字节 0
  • bắt đầu

    但是当您进行调用时,还有一个额外的隐含状态也存储在属性 0 中:
  • 从当前绑定(bind)到 GL_ARRAY_BUFFER 的缓冲区中读取数据

  • 换句话说,与每个属性相关联的状态包括属性数据来源的缓冲区的 id。这可以是多个/所有属性的相同缓冲区,也可以是每个属性的不同缓冲区。

    Xin lưu ý, GL_ELEMENT_ARRAY_BUFFER 的情况并非如此。 .那个需要在 glDrawElements()的时候绑定(bind)称呼。虽然看起来有些不一致,但这是必要的,因为没有与 glVertexAttribPointer() 等价的东西。对于索引数组。 API 可以被定义为具有这种调用,但是......它不是。原因很可能是根本没有必要,因为一次绘制调用只能使用一个索引数组,而可以使用多个顶点缓冲区。

    关于opengl - 了解 glVertexAttribPointer?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24876647/

    28 4 0
    行者123
    Hồ sơ cá nhân

    Tôi là một lập trình viên xuất sắc, rất giỏi!

    Nhận phiếu giảm giá Didi Taxi miễn phí
    Mã giảm giá Didi Taxi
    Giấy chứng nhận ICP Bắc Kinh số 000000
    Hợp tác quảng cáo: 1813099741@qq.com 6ren.com