glVertexAttribBinding的顺序绘制命令未按预期工作

Sequential draw commands with glVertexAttribBinding not working as expected

本文关键字:工作 命令 顺序 绘制 glVertexAttribBinding      更新时间:2023-10-16

我有一个结构Vertex{glm::vec4 t,n,v;}。我已经编写了一个obj加载程序,它接受两个参数,obj文件路径作为字符串,并引用一个向量"Vertex"。这个函数填充我的向量并返回索引的数量(无论如何,在我的情况下,索引只是序列号)。

由于我有6个对象要渲染,在使用该功能6次后,我得到了以下

vector<Vertex> objects[6];
GLint SIZES[6],OFFSETS[6],SIZES_I[6],OFFSETS_I[6];

已填充。SIZES是"顶点"(object[i].size())的数量,SIZES_i是索引的数量。偏移量计算如下

for(int i=0;i<6;i++)
{
  if(i==0)
  {
    OFFSETS[0]=0;OFFSETS_I[0]=0;
  }
  else
  {
    OFFSETS[i]=OFFSETS[i-1]+SIZES[i-1];
    OFFSETS_I[i]=OFFSETS_I[i-1]+SIZES_S[i-1];
  }
}

我将Vertex的矢量全部背对背地转移到单个VBO中。类似地,对于索引,转移到绑定到元素数组缓冲区的缓冲区中。该部分如下所示。

glBufferData(GL_ARRAY_BUFFER,(OFFSETS[5]+SIZES[5])*sizeof(Vertex),data,GL_STATIC_DRAW);
for(int i=0;i<6;i++)
{
  glBindVertexBuffer(i,buffer[0],OFFSETS[i]*sizeof(Vertex),sizeof(Vertex));
}
glBufferData(GL_ELEMENT_ARRAY_BUFFER,(OFFSETS_I[5]+SIZES_I[5])*sizeof(GLuint),indices,GL_STATIC_DRAW);
glVertexAttribFormat(0,4,GL_FLOAT,GL_FALSE,offsetof(Vertex,v));

现在我的问题来了。在下面显示的两个渲染代码中,第一个不起作用,但第二个效果很好。

for(int i=0;i<6;i++)
{
  glVertexAttribBinding(0,i);
  glDrawElements(GL_TRIANGLES,SIZES_I[i],GL_UNSIGNED_INT,reinterpret_cast<void*>(OFFSETS_I[i]*sizeof(GLuint));
}
//second
glVertexAttribBinding(0,0);
for(int i=0;i<6;i++)
  glDrawElementsBaseVertex(GL_TRIANGLES,SIZES_I[i],GL_UNSIGNED_INT,reinterpret_cast<void*>(OFFSETS_I[i]*sizeof(GLuint)),OFFSETS[i]);

概括地说,为了让你们理解这里发生了什么,在第一种情况下,我在具有6个偏移的同一缓冲区上创建了6个缓冲区绑定。在第二种情况下,只有一个绑定,但我使用基点偏移了6次。顺便说一句,两者都在编译,所以当我在选项卡中键入所有这些时,忽略任何拼写错误。

我的第一次调试尝试:由于基顶点方法正在运行,obj加载程序很好。无论如何,为了确保它,我只是加载了一个模型。它运行良好。

我第二次尝试调试:我的怀疑自然落在绑定调用和偏移上。为了解决这个问题,我删除了第一个方法中的for循环,并用0初始化了I(由于第二个方法,即基顶点方法有效,我们不必麻烦它)。我的第一个模特出现在屏幕上。接下来,我用1初始化了变量"I"。我的第二个模型显示在屏幕上。我重复了一遍,直到I=5。我的6个模型都显示正确。所以我的模型是单独展示的。但当我按顺序组合调用时,我会得到一些完整模型,一些部分模型,还有一些根本没有。

我的第三次调试尝试:似乎只显示了最后两个型号左右。剩余部分未绘制或部分绘制。所以我反转了for循环,从I=5开始,然后递减。现在显示前两个模型等等(这里的"前两个"answers"后两个"指的是模型在obj阅读器中加载的顺序。我没有改变这一点)。就好像后续的图形命令正在以某种方式使早期图形命令的工作消失。有点。

就是这样。我走到了死胡同。有什么想法吗?可能出了什么问题,或者我如何继续进行进一步的调试?

原来是由于我的驱动程序中的一个错误。同样的代码也在我同事的电脑里运行。