VBO 不会绘制,大型数据集
Posted
技术标签:
【中文标题】VBO 不会绘制,大型数据集【英文标题】:VBO wont draw, large dataset 【发布时间】:2014-08-22 01:29:08 【问题描述】:我正在尝试在 OpenGL 中渲染约 100 000 个值的大型数据集,现在仅作为点,稍后使用精灵。
我的向量"positions"
是这样排列的:
+-------------------------------------------------
| x | y | z | w | x | y | z | w | x | y | z | ...
+-------------------------------------------------
其中第四个分量 (w) 是在顶点/片段着色器中使用的缩放因子..
VBO创建[编辑]
...
v_size = positions.size();
GLint positionAttrib = _programObject->attributeLocation("in_position");
glGenVertexArrays(1, &_vaoID);
glGenBuffers(1, &_vboID);
glBindVertexArray(_vaoID);
glBindBuffer(GL_ARRAY_BUFFER, _vboID);
glBufferData(GL_ARRAY_BUFFER, v_size*sizeof(GLfloat), &positions[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(positionAttrib);
glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), 0 );
glBindVertexArray(0);
渲染阶段:[编辑]
现在可行,但我不确定是否 100% 正确,欢迎批评:
GLint vertsToDraw = v_size / 4;
GLint positionAttrib = _programObject->attributeLocation("in_position");
// edit 1. added vao bind
glBindVertexArray(_vaoID);
glEnableVertexAttribArray(positionAttrib);
glBindBuffer(GL_ARRAY_BUFFER, _vboID);
//glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (void*)0);
// edit 2. no stride
glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)0);
glDrawArrays(GL_POINTS, 0, vertsToDraw);
glDisableVertexAttribArray(positionAttrib);
glBindVertexArray(0);
如果需要更多代码,请告诉我。
【问题讨论】:
GLdouble* dataptr = new GLdouble[v_size]; dataptr = &positions[0];
根本上是错误的。如果需要,您可以用数据填充数组,或者根本不分配额外的数组。什么是positions
类型和数据布局?你的着色器是什么?
首先,属性不要使用GLdouble
。它们按照您设置的方式进行,当它们到达着色器时,它们将被转换为浮动。并且尝试在着色器中将它们读取为dvec4
将失败。我注意到的第二件事是你的缓冲区太小了。您尝试使用 4 个双精度点绘制 v_size
点,但缓冲区中只有 v_size
双精度点。
我同意不需要额外的指针,只是想确保我传递的内容是正确的,因为我有点不确定数据如何存储在 std::vector 中。 @derhass:我可能不清楚,向量positions
不是顶点结构的向量,我的缓冲区怎么会太小?如果我错了,请纠正我,v_size 正好是 4*(我要绘制的元素数)......你是说我应该将结构存储在向量中,即 struct vertex float x, y, z, w; // or glm::vec4 _position; ;
因为那时我想 id 必须乘以大小与 4.
DrawArrays
调用中使用的计数是顶点的数量。您将顶点数组设置为由 每个顶点 的 4 个双精度数组成。因此,您需要4 * v_size * sizeof(GLdoube)
字节的缓冲区空间。所以要么v_size
是那个缓冲区的总数,那么上面的缓冲区初始化是正确的并且绘制调用是错误的,或者v_size
是顶点的数量,那么缓冲区初始化是错误的,并且绘制调用正确。
@derhass:是的! v_size 是值的总数,大小为 402524。我要绘制的顶点数是 1/4 即 100631。drawcall 应该如何?
【参考方案1】:
按照 derhass 和 keltar 的建议修复了所有问题,请参阅 cmets 的帖子。现在一切正常。
【讨论】:
以上是关于VBO 不会绘制,大型数据集的主要内容,如果未能解决你的问题,请参考以下文章
Javascript / D3.js - 绘制大型数据集 - 提高 d3.js 绘制的 svg 图表中的缩放和平移速度