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 不会绘制,大型数据集的主要内容,如果未能解决你的问题,请参考以下文章

在 Scipy 错误中为大型数据集绘制树状图

Javascript / D3.js - 绘制大型数据集 - 提高 d3.js 绘制的 svg 图表中的缩放和平移速度

Weka 中的 KNN 算法永远不会在大型数据集上完成

Python Windrose 挂起大型数据集,不会崩溃或产生结果

通过 AJAX 处理大型数据集不会带来速度优势

如何改进热图的大型数据集的 KQL 查询