سؤال

I'm completing a wavefront object parser and I want to use it to construct generic mesh objects. My engine uses OpenGL 4 and shaders to draw everything in my engine.

My question is about how to ensure best rendering efficiency for rendering a mesh.

A wavefront .obj file normally has many object sub-groups specified.

A sub-group might be assigned a specific material (e.g. a shiny red colour).

So a mesh might be a fairly complex collection of sub-groups, each with their own material assigned.

My questions are -

Q. Do I need to draw each sub-group separately e.g. with a call to glDrawElements for each sub-group ? (So if I had 4 separate sub-groups, I'd have to make four glDrawElements calls, thereby invoking the shader 4 times with 4 uniform changes (for the materials/textures) )

glDrawElements( GL_TRIANGLES, nNumIndicesInGroup, GL_UNSIGNED_INT, ((char*)NULL)+ first-vertex-offset );

If this is correct, then I'll have to calculate:

The indices in each sub-group (implying a separate index array and VAO for each sub-group) The vertex offset of the start of the sub-group

This seems terribly inefficient, am I barking up the wrong tree?

Also, from the Wavefront obj wiki page:

Smooth shading across polygons is enabled by smoothing groups.
 s 1
 ...
  # Smooth shading can be disabled as well.
  s off
  ...

Can anyone suggest what smooth shading values indicate? E.g. s1, s2, s4 etc.

هل كانت مفيدة؟

المحلول

Yes, you should draw each sub-group separately from the others. This is required till the state is different between sub-groups.

But you are making a too long step.

To avoid multiple draw calls, you can introduce a vertex attribute indicating an index used for accessing uniform array values (array of materials, array of textures). In this way, you need only one draw call, but you will have the cost of one additional attribute and its relative management.

I would avoid the above approach. What if a sub-group is textured and another one not? How do you discriminate whether to texture or not? Introducing other attributes? Seems confusing.

The first point is that the buffer object management is very flexible. Indeed you could have a single element buffer object and a single vertex buffer object: using offsets and interleaving you can satisfy every level of complexity. And then, on modern harware, using vertex array objects you can minimize the cost of the different buffer bindings.

Second point is that your software can group different sub-group having the same uniform state, joining multiple draw calls into a single one. Remember that you can use Multi draw entry points variants, and there's also the primitive restart that can aid you (in the case stripped primitives).

Other considerations are not usefull, because you have to draw anyway, regardless if it's complex or not. Successively, when you have a correct rendering, you could profile the application and the rendering, cutting-off the hot-spots.


Smoothing groups are a collection of vertices that are sharing the same option attribute (normals, texture coordinates). This is the case of element-indexed vertices.

To go deeper on subject, read one of the specification found by googling.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top