【发布时间】:2020-06-13 04:46:38
【问题描述】:
我在使用 glBufferSubData() 将所有数据复制/上传到缓冲区时遇到问题。我想逐块复制到缓冲区。所以我使用了这种方法。当我尝试渲染时,我看到一个空白屏幕。请在下面找到我的代码。您在计算缓冲区偏移量时看到任何问题吗?或者这不是将数据复制到缓冲区的方法吗?
下面是数据结构
struct DisplayIndexID {
int idx;
DrawStateT drawState;
//Every display Index ID has its own draw models.
std::vector<std::unique_ptr<vertexModel>> readytoDrawModels;
};
void initVboData(std::vector<DisplayIndexID> & v)
{
glBindBuffer(GL_ARRAY_BUFFER, geomVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(QVector3D) * 4096, NULL, GL_DYNAMIC_DRAW);
std::vector<QVector3D> vecToDraw;
GLintptr offset = 0;
for (int i = 0; i < v.size(); i++)
for (auto& vModel : v[i].readytoDrawModels)
{
if (vModel) {
vecToDraw = vModel->getVertices();
glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(QVector3D) * vecToDraw.size(), &vecToDraw[0]);
offset += sizeof(QVector3D) * vecToDraw.size(); // is this offset calculation fine?
}
}
}
//Below is my draw function
void drawDisplayLists(std::vector<DisplayIndexID> & v)
{
initVboData(v);
for (int i = 0; i < v.size(); i++)
{
//Make context current
makeCurrent();
bool isTextureUsed = false;
//Apply Projection Matrix.
GLint mvp_mat = 0;
GLint mvp_matText = 0;
///***********PRINT AREA***********************/
for (auto& vModel : v[i].readytoDrawModels)
{
// Code related to Shaders
......
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(QVector3D), nullptr); how to get the offset and add offset here.
switch (vModel->getDrawMode())
{
case 0: //GL_POINTS
glDrawArrays(GL_POINTS, 0, vModel->getVertices().size());
break;
case 1: //GL_LINES
glDrawArrays(GL_LINES, 0, vModel->getVertices().size());
break;
case 2: //GL_LINE_LOOP
glDrawArrays(GL_LINE_LOOP, 0, vModel->getVertices().size());
break;
}
}
}
}
【问题讨论】:
-
您的
drawDisplayLists()与initVboData()不匹配 - 您突然在方法中使用了vModel变量 undefined。如果drawDisplayLists()以与初始化相同的方式迭代v,则应在循环中使用偏移量调用glVertexAttribPointer()。请在报价中添加缺失的代码。 -
非常感谢。我已经在编辑部分更新了我的代码。是的,甚至 drawDisplayLists() 以与初始化相同的方式迭代 v。请让我知道如何为 glVertexAttribPointer() 调用添加偏移量。谢谢,非常感谢。
-
@gkv311 “那么 glVertexAttribPointer() 应该在循环中使用偏移量调用” - 抱歉,这是错误的。只有顶点坐标,所以不需要偏移。如果要绘制网格的特定区域,则必须在
glDrawArrays处指定偏移量和不同的大小 -
谢谢大家。如果我将 glBufferSubData() 移动到 for 循环下的 drawDisplayList() 内,它就可以工作。但我不想每帧都复制块。这可能会影响性能。所以我想到了之前复制它并在框架开始之前准备好它。有什么办法可以做到这一点吗?因为我的顶点不会改变。一切都存储在向量中。我还尝试使用 glBufferData() 复制整个缓冲区。这没有用。如何解决这个问题?非常感谢。
-
@Rabbid76
glVertexAttribPointer()和glDrawArrays()都可用于指定偏移量 - 执行此操作的位置取决于条件。如果可能,将偏移量传递给glDrawArrays()可能会减少一点开销。