简体   繁体   中英

Sequential draw commands with glVertexAttribBinding not working as expected

I have a struct Vertex{glm::vec4 t,n,v;}. I have written a obj loader that takes two parameters, obj file path as string and reference to a vector of 'Vertex'es. This function populates my vector and returns the number of indices(In my case indices are just sequential numbers, anyway).

As I have 6 objects to render, after using that function 6 times I have the following

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

filled. SIZES are number of 'Vertex'es(object[i].size()) and SIZES_I are number of indices. The offsets are calculated as below

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];
  }
}

I transferred vectors of Vertex into a single VBO all back to back. Similarly for indices, transferred into buffer bound to element array buffer. That part is shown below.

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));

Now comes my problem. Of the two rendering codes shown below the first one doesn't work but the second works perfectly.

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]);

To summarily say what I have done so u guys can understand whats going on here, in the first case i created 6 buffer bindings on the same buffer with 6 offsets. In the second case there is only one binding, but I used base vertex to offset 6 times. Btw both are compiling, so ignore any typos as I typed all this in my tab.

My first attempt at debugging: Since base vertex approach is working, obj loader is fine. Anyway to make sure of it, I just loaded a single model. Its working fine.

My second attempt at debugging: My suspicion naturally fell on binding calls and offsets. To resolve this, I removed the for loop in the first method and initialized i with 0(Since second method ie base vertex method works, we dont bother with it). My first model appeared on screen. Next I initialized 'i' variable with 1. My second model was displayed on screen. This I repeated till i=5. Each of my 6 models were displayed correctly. So my models were displayed individually. But when I combine my calls sequentially, I get some full models, some partial models and some not at all.

My third attempt at debugging: It seems that only last 2 models and so are displayed. Remaining are not drawn or partially drawn. So I reversed my for loop starting with i=5 and decrementing. Now first 2 models and so are displayed(Here 'first two' and 'last two' refers to the order in which models are loaded in obj reader. I did not change that). It is as if the subsequent drawing commands are somehow making the work of earlier drawing commands vanish. Sort of.

Thats it. Here I hit a dead end. Any ideas what might be wrong or how I might proceed with further debugging?

Turned out that it is due to a bug in my driver. The same code worked in my colleague's computer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM