gpt4 book ai didi

opengl - 了解 glVertexAttribPointer?

转载 作者:行者123 更新时间:2023-12-04 05:18:02 28 4
gpt4 key购买 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,它怎么知道我们在谈论哪个缓冲区对象?

最佳答案

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

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

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

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

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

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

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

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

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

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com