标签: vertex-buffer

VBO何时比"简单"OpenGL原语(glBegin())更快?

经过多年关于顶点缓冲对象(VBO)的讨论,我终于决定尝试它们(我的东西通常不是性能关键,显然......)

我将在下面描述我的实验,但总而言之,我看到"简单"直接模式(glBegin()/ glEnd()),顶点数组(CPU端)和VBO(GPU端)之间无法区分性能渲染模式.我试图理解为什么会这样,并且在什么条件下我可以期待看到VBO明显优于他们原始(双关语)的祖先.

实验细节

对于实验,我生成了一个具有大量点的(静态)3D高斯云.每个点都有与之关联的顶点和颜色信息.然后我在连续的帧中围绕云旋转相机,这是一种"轨道"行为.同样,这些点是静态的,只有眼睛移动(通过gluLookAt()).数据在任何渲染之前生成一次并存储在两个数组中以用于渲染循环.

对于直接渲染,整个数据集在单个glBegin()/ glEnd()块中呈现,其中包含一个循环,每个循环包含glColor3fv()和glVertex3fv().

对于顶点数组和VBO渲染,整个数据集使用单个glDrawArrays()调用进行渲染.

然后,我只需在紧凑的循环中运行一分钟左右,并使用高性能计时器测量平均FPS.

表现结果##

如上所述,我的台式机(XP x64,8GB RAM,512 MB Quadro 1700)和笔记本电脑(XP32,4GB RAM,256 MB Quadro NVS 110)的性能难以区分.然而,它确实按照预期的点数进行了扩展.显然,我也禁用了vsync.

笔记本电脑运行的具体结果(使用GL_POINTS渲染):

在glBegin()/ glEnd():

  • 1K分 - > 603 FPS
  • 10K分 - > 401 FPS
  • 100K分 - > 97 FPS
  • 1M点 - > 14 FPS

顶点阵列(CPU端):

  • 1K分 - > 603 FPS
  • 10K分 - > 402 FPS
  • 100K分 - > 97 FPS
  • 1M点 - > 14 FPS

顶点缓冲对象(GPU端):

  • 1K分 - > 604 FPS
  • 10K分 - > 399 FPS
  • 100K分 - > 95 …

opengl graphics performance vbo vertex-buffer

36
推荐指数
2
解决办法
2万
查看次数

OpenGL顶点缓冲区混乱

有人会关心解释VertexBuffer,VertexArray,VertexBufferObjectVertexArrayObject之间的区别吗?我甚至不确定这些是否是针对不同事物的所有术语,但我已经看到它们都出现在OpenGL规范中.

我知道VertexBuffer只包含顶点而没有其他任何东西,一旦绑定,一旦我设置了顶点指针,我就可以使用DrawArrays来绘制它.我已经多次这样做了.

我正在使用我认为的VertexArray,它存储所设置的任何顶点缓冲区的状态,以及任何顶点指针.绑定VertexArray会自动绑定顶点缓冲区并设置顶点指针.我也成功地使用了这个(大部分).

但什么是VertexBufferObjectVertexArrayObject?他们更好吗?VertexArray不能给我我需要的一切吗?

opengl vertex-buffer vertexdata vertex-array

17
推荐指数
2
解决办法
3937
查看次数

OpenGL的.使用glBufferData更新顶点缓冲区

我正在使用OpenGL某种批量绘图.为此,我创建了一个vertex buffer存储数据.

注意:此缓冲区通常会在每个帧上更新,但永远不会减小大小(但仍然可以增加).

我的问题是:使用glBufferData(用s treaming write-only mode)更新它(而不是例如glMapBuffer)在技​​术上是否正确?我想没有必要映射它,因为更新了完整的数据,所以我只需要立即发送一个完整的数据包.如果当前的缓冲区大小比我发送的少,它会自动增加,不是吗?我现在才确定它的实际工作方式(也许它会在每次调用时重新创建缓冲区,不是吗?).

opengl streaming vertex-buffer

15
推荐指数
2
解决办法
1万
查看次数

更新VBO中的顶点数据(glBufferSubData vs glMapBuffer)

我想在创建VBO后更新对象的顶点列表.我已经看到了两者glBufferSubData并且glMapBuffer它们似乎都做了类似的事情,这意味着我现在不确定使用哪一个.

我的伪工作流程是:

创建对象
开始顶点更新(使用data = nullptr调用glBufferData)
更新对象的顶点
结束顶点更新(采用更新的顶点和调用glBufferSubDataglMapBuffer)

opengl vertex-buffer

14
推荐指数
1
解决办法
1万
查看次数

在使用VAO时,VBO中的交错是否会加快性能

当您使用交错的VBO而不是使用多个VBO时,通常会加快速度.这在使用VAO时也有效吗?

因为对于位置有一个VBO,对于法线等有一个VBO更方便.你可以在多个VAO中使用一个VBO.

opengl vertex-buffer arraybuffer

14
推荐指数
1
解决办法
6714
查看次数

C++:OpenGL,glm和struct padding

我可以安全地使用glm ::*类型(例如vec4,mat4)来填充顶点缓冲区对象吗?

std::vector<glm::vec3> vertices;    
glBufferData(GL_ARRAY_BUFFER,  sizeof(glm::vec3) * vertices.size(), &vertices[0], GL_STATIC_DRAW);
Run Code Online (Sandbox Code Playgroud)

我不太确定,因为在我看来,struct padding(成员对齐)可能会导致一些麻烦,尽管我测试的所有编译器都会返回预期的大小.

我正在为C++ 11编译器开发(也许这会有所不同).

c++ opengl vertex-buffer c++11

12
推荐指数
1
解决办法
3831
查看次数

GLES2 glBindAttribLocation()是否必要?

这可能是一个菜鸟问题.据我了解,只要AAA是唯一的,glBindAttribLocation(...,AAA,...)就会将程序中的属性绑定到AAA的位置ID.如果我有以下代码:

glBindAttribLocation(..., 0, "XXX");
glBindAttribLocation(..., 1, "YYY");
Run Code Online (Sandbox Code Playgroud)

这会将我的两个变量绑定到位置ID 0和1.然后我会调用:

glBindBuffer(GL_ARRAY_BUFFER, VBId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBId);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (void *) 0 + sizeof(float) * 3);
glEnableVertexAttribArray(1);

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
Run Code Online (Sandbox Code Playgroud)

到目前为止,我理解0和1的ID作为第一个参数传递给glVertexAttribPointer().

如果我通过glGetAttribLocation()调用获得属性的位置ID(如上所述),以便返回的ID是5和6而不是0和1,我是否可以安全地将5和6传递给glVertexAttribPointer( )和glEnableVertexAttribArray()而不是0和1 ??

shader vertex-buffer opengl-es-2.0

11
推荐指数
1
解决办法
3395
查看次数

如何在OpenGL Es 2.0中正确更新顶点数组?

当我在OpenGL 2.0中更新iOS上的顶点数组时,原始顶点数据停留在屏幕上 - 即第一次刷新是持久的(我向下发送到GPU的初始点集每帧渲染),但是第二次,第3,第4,...第n次冲洗似乎都覆盖了相同的记忆.

所以我在做:

vector<VertexType> rawDynamicData ;

glGenVertexArraysOES( 1, &va ) ;        CHECK_GL ;
glBindVertexArrayOES( va ) ;            CHECK_GL ;
glGenBuffers( 1, &vb ) ;                CHECK_GL ;
glBindBuffer( GL_ARRAY_BUFFER, vb ) ;   CHECK_GL ;

glBufferData( glBufferData(
  GL_ARRAY_BUFFER, //Specifies the target buffer object.
  rawDynamicData.size() * sizeof( VertexType ),
  &rawDynamicData[0],
  GL_DYNAMIC_DRAW  // I plan to update the data every frame
) ;  CHECK_GL ; 
Run Code Online (Sandbox Code Playgroud)

在随后的帧中,我只是再次打电话:

// update the data
glBufferData( glBufferData(
  GL_ARRAY_BUFFER, //Specifies the target buffer object.
  rawDynamicData.size() * sizeof( VertexType …
Run Code Online (Sandbox Code Playgroud)

vertex-buffer ios opengl-es-2.0

11
推荐指数
1
解决办法
5939
查看次数

使用布局限定符时,未缓冲的顶点属性的OpenGL默认值

我假设这将是"未定义"的事情之一,但我似乎无法从谷歌找到具体的答案.

让我们在我的顶点着色器中说:

layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec3 vNormal;
layout(location = 2) in vec4 vColour;
Run Code Online (Sandbox Code Playgroud)

但是没有任何缓冲到位置2的glEnableVertexAttribArray()或glVertexAttribPointer().我可以期待价值是什么特别的吗?

我假设vec4它将沿着{0,0,0,0},{0,0,0,1}或{1,1,1,1}的线,但在我的情况下,它是{0,0,1,1}.

当我之前使用glBindAttribLocation()指定位置时,它使用3种不同的操作系统(ubuntu 12.04,windows 7和ubuntu 10.04)在4台不同的机器上默认为{1,1,1,1}.

假设机器上的值为{0,0,1,1}是否安全?或者这简直是巧合?

opengl shader attributes vertex-buffer

10
推荐指数
1
解决办法
2079
查看次数

顶点数组对象 - 关于当前绑定的顶点缓冲区的确切状态信息的确切混淆

我在构建图形引擎时正在研究arcsynthesis的优秀教程,并发现我不像我想象的那样理解VAO.

从教程第5章深入的对象

缓冲区绑定和属性关联

您可能会注意到glBindBuffer(GL_ARRAY_BUFFER)不在该列表中,即使它是用于渲染的属性设置的一部分.对GL_ARRAY_BUFFER的绑定不是VAO的一部分,因为当调用glBindBuffer(GL_ARRAY_BUFFER)时,缓冲区对象和顶点属性之间的关联不会发生.调用glVertexAttribPointer时会发生此关联.

当您调用glVertexAttribPointer时,OpenGL会将此调用时的任何缓冲区绑定到GL_ARRAY_BUFFER,并将其与给定的顶点属性相关联.将GL_ARRAY_BUFFER绑定视为glVertexAttribPointer读取的全局指针.因此,在进行glVertexAttribPointer调用之后,您可以自由地将任何您想要的内容绑定到GL_ARRAY_BUFFER; 它会影响最终渲染中的任何内容.因此VAO确实存储哪些缓冲区对象与哪些属性相关联; 但它们不存储GL_ARRAY_BUFFER绑定本身.

我最初错过了最后一行"......但他们没有存储GL_ARRAY_BUFFER绑定本身".在我注意到这一行之前,我认为一旦调用了glVertexAttribPointer,就会保存当前绑定的缓冲区.缺少这些知识,我构建了一个网格类,并且能够获得一个具有正确渲染的多个网格的场景.

下面列出了该代码的一部分.请注意,我不在draw函数中调用glBindBuffer.

// MESH RENDERING

/* ...            */
/* SETUP FUNCTION */
/* ...            */

// Setup vertex array object
glGenVertexArrays(1, &_vertex_array_object_id);
glBindVertexArray(_vertex_array_object_id);

// Setup vertex buffers  
glGenBuffers(1, &_vertex_buffer_object_id);
glBindBuffer(GL_ARRAY_BUFFER, _vertex_buffer_object_id);
glBufferData(GL_ARRAY_BUFFER, _vertices.size() * sizeof(vertex), &_vertices[0], GL_STATIC_DRAW);

// Setup vertex attributes
glEnableVertexAttribArray(e_aid_position);
glEnableVertexAttribArray(e_aid_normal);
glEnableVertexAttribArray(e_aid_color);
glEnableVertexAttribArray(e_aid_tex);

glVertexAttribPointer(e_aid_position, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), (GLvoid*)offsetof(vertex, pos));
glVertexAttribPointer(e_aid_normal,   3, GL_FLOAT, GL_FALSE, sizeof(vertex), (GLvoid*)offsetof(vertex, norm));
glVertexAttribPointer(e_aid_color,    4, GL_FLOAT, GL_FALSE, sizeof(vertex), (GLvoid*)offsetof(vertex, col));
glVertexAttribPointer(e_aid_tex,      2, GL_FLOAT, GL_FALSE, …
Run Code Online (Sandbox Code Playgroud)

opengl vertex-buffer vertex-array-object

9
推荐指数
1
解决办法
3134
查看次数