当前位置: 首页 > 知识库问答 >
问题:

为什么索引缓冲区对象没有GlvertexAttribute指针?

牧璞
2023-03-14

我来这里是为了消除专家们对opengl的一些困惑。我感谢你的帮助!

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);

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);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);


glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

顶点着色器代码看起来像

#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;
}

所以,这是我的理解。GLVertexAttributePointer的目的是定义顶点缓冲区对象中的数据格式。因此,在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());

所以,我们有两条glVertex AttribPointer线,因为我们在顶点着色器中定义了两个变量。所以基本上我们定义了这两个变量指向什么。因此,第一个glVertex AttribPointer定义了第一个变量“位置”是一个顶点,每个顶点有三个坐标是浮动的。第二个glVertex AttribPointer定义了第二个变量"tex Cood"是一对纹理坐标,每个坐标都是浮动的。

现在让我困惑的是,我们正在使用glVertex AttribPointer来理解存储在vbo到opengl中的数据。现在,我们为什么不使用另一个glVertex AttribPointer或类似的代码来理解ibo中的数据呢?为什么这个缓冲对象被单独留下?

我感谢任何帮助。非常感谢!

共有1个答案

莫乐
2023-03-14

原因是,在绘制调用中只能有一个活动的索引缓冲区。索引缓冲区的格式在绘制调用中指定(参见glDrawElements,第3个参数)。

您还可以看到对glVertex AttribPointer的调用作为vbo到着色器中的in变量的绑定。由于index-Buffer永远不会附加到统一项,因此不必调用glVertex AttribPointer。

 类似资料:
  • 我读到FileWriter和BufferedWriter的区别在于FileWriter直接写入文件(逐字符),white BufferedReader使用缓冲区。如果是,为什么FileWriter有缓冲区?例如,如果我创建一个FileWriter对象,如下所示: 而且,如果我在程序结束时不刷新或关闭写入器,它将不会向文件写入任何内容。这意味着它也使用缓冲区。拜托,解释一下?

  • 我有一个JSON对象,我正在将它转换成一个,并在这里进行一些处理。稍后,我想将相同的缓冲区数据转换为有效的JSON对象。 我的工作节点V6.9.1 下面是我尝试过的代码,但当我转换回JSON并且无法打开此对象时,我得到了。 所以我试着用检查的方式打印整个物体 如果我试着像数组一样读取它 我试图解析它也抛出SynTaxError:意外令牌o在JSON在位置2 我需要像我创建的那样将其视为真实对象(我

  • 两者都是序列化库,由谷歌开发人员开发。他们之间有什么大的区别吗?将使用协议缓冲区的代码转换为使用FlatBuffers需要大量工作吗?

  • 我正在学习Java I/O。因此,使用缓冲流可以减少读取或写入所需的时间,因为如果使用普通的FileInputStream,每次调用读取时都会获取一个字节,但如果使用缓冲区,则会获取指定大小的数据并将其存储在内存中。所以我试着在实践中看到这一点。 我已将BufferedInputStream的缓冲区大小设置为512,8192,65536。每次需要87秒才能完成执行。所以我尝试使用FileInput

  • 关于IO,我有两个问题。 A.在一个教程和一些StackOverflow答案中,他们声称没有被修复。是真的吗? 以下代码使用将数据读入字节数组(1024字节) 从API,有一行: 公共整数读取(字节b[])引发IOException @参数b:将数据读入的缓冲区 B.如果它们都是缓冲的,它们都将数据放入缓冲区,并从缓冲区中获取数据,那么使BufferedInputStream比FileInputS

  • 根据digitalocean教程,我用我的ELK节点作为RedHat服务器设置了ELK stack和filebeat。Kibana已启动并运行,但当我将索引模式配置为logstash-*时,我看不到任何logstash索引: 当我做卷曲以查看我的索引时,它们只是filebeat索引。Filebeat应该将数据推送到正在监听5044的logstash 您可以看到我只有filebeat索引。我检查了我