2
\$\begingroup\$

I have a vertex buffer. There are situations when I don't want to render the whole mesh, but let's say each nth triangle of the mesh. I am using VAOs and VBOs.

My data in the buffer is like this:

first triangle indx        seciond triangle indx
0 1 2   3 4 5   6 7 8    | 9 10 11   12 13 14   15 16 17 ...

What I want to do is - render first triangle, then skip second, then render 3d and so on. Can it be done with adjusting glVertexAttribPointer() or are there some other gl methods that can manipulate the data like that, or I have to create a new buffer with skipped triangles ?

\$\endgroup\$
  • \$\begingroup\$ I guess creating a new buffer is the only solution here. I am not sure though. \$\endgroup\$ – noob May 14 '14 at 6:54
  • \$\begingroup\$ How about solving this at the glDrawArrays level? \$\endgroup\$ – Panda Pajama May 14 '14 at 6:56
  • \$\begingroup\$ As far as I know glDrawArrays takes the number of vertices to be drawn. I can't tell it to draw each nth vertex/triangle can I ? \$\endgroup\$ – Geto May 14 '14 at 7:02
  • \$\begingroup\$ .. I guess you could just have shader discard all fragments of the non-wanted triangles .. \$\endgroup\$ – Jari Komppa May 14 '14 at 10:01
2
\$\begingroup\$

I have no idea why would you want to draw each n-th triangle, and I cannot imagine a situation in which you would want to do that.

...but supposing you do have a legitimate reason to do that...

I would say you can't, because glVertexAttribPointer is used to set the layout for the data at the vertex level, not the triangle level. In fact, OpenGL has no idea of how are you going to use the vertices inside the vertex buffer until you make a draw call.

I suppose you were thinking about playing with the stride parameter, but once again, glVertexAttribPointer works at the vertex level, so the most you can do is make triangles out of each n-th vertex, which is not what you want.

Short of creating a new vertex buffer, you can handle this when making the draw call. glDrawArrays takes the amount of triangles you want to draw and the offset from which you want to draw them, so you would have to do something like

for (int k = 0; k < totalTriangleCount; k += n)
    glDrawArrays(GL_TRIANGLES, k * 3, 3);

You might be tempted to think that this is a performance killer, but it's most likely not. You will most likely not be issuing an OpenGL flush on each glDrawArrays call, so I wouldn't say performance would drop noticeably. At least compared with creating and uploading a new vertex buffer each frame.

Now, the real question is "why would you want to do such a thing?", but we may never know...

\$\endgroup\$
  • \$\begingroup\$ Thanks for the suggestion! Now to answer your question - When I have extremely large mesh, If I want to update it (rotate, translate...) I gain a significant improvement in the framerates when I redraw it with less triangles than the original. And when I stop updating it - I render it with all the triangles. \$\endgroup\$ – Geto May 14 '14 at 7:45
  • \$\begingroup\$ @Geto then you could just reorder the triangles sot he first third is the third you want to draw \$\endgroup\$ – ratchet freak May 14 '14 at 10:34
3
\$\begingroup\$

you can step away from glDrawArrays and instead use glDrawElements and use a GL_ELEMENT_ARRAY_BUFFER​ buffer that hold the indexes of the vertexes you want to draw

the element buffer would then contain {0,1,2,9,10,11,...} and so on.

In you comments I see that you want this to draw a "light" object for quick updates, you can add all other triangles after the first third and draw all triangles that way

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.