john-chapman/im3d

Is there a way for this to work without the geometry shaders

Opened this issue · 5 comments

The library is pretty cool but is there a way for it to work without the geometry shaders for lower end devices?

Yes, you're free to implement the draw callback/shader in any way you like.

Without geometry shaders the only issue you might have is that (depending on the graphics API) you may be unable to change the line thickness/point size per vertex. You could live without this, it just won't render as nicely.

An alternative approach, slightly more involved, would be to build your own application-side vertex list from the data passed to the draw callback. This way you can reformat the vertices however you like - for example you could construct a single large triangle strip, expanding the points/lines as you go, then draw the whole thing in a single draw call after Im3d::Draw() returns.

Which graphics API are you working with? It may be worth adding an example.

Well I am using BGFX library that wraps everything in one api. Unfortunetely it does not have a support for geometry shaders yet so thats why I am asking :)

A third option would be to upload the Im3d vertex data to a constant buffer, then make an instanced draw call with 4 vertices and do the point/line expansion in the vertex shader. This will probably have similar performance to the geometry shader approach.

I'll try and get around to adding a 'no geometry shaders' example soon as a reference for these techniques. In the meantime let me know if you have any success integrating it.

Well integrating the library is a matter of an hour's work tops. Looks pretty easy. The only thing stopping me to replace my existing stuff with your library is this issue.

I've added an example which targets OpenGL 3.1 as a reference for how to integrate Im3d without geometry shaders. I went with the last approach I mentioned above - uploading the vertex data to a constant buffer and manually fetching it in the vertex shader to do point/line expansion. The performance is roughly the same as the geometry shader version.

There are 2 important things to note:

  • The example has to contend with the OpenGL uniform buffer size limit; it splits up the vertex data into 64kb blocks. In your case you probably don't need to do this if you can allocate and bind arbitrarily large constant buffers.
  • In order to be able to upload the Im3d vertex data directly to the GPU you have to ensure that it is aligned correctly (e.g. 16 byte alignment for an OpenGL uniform buffer). This can be done by setting IM3D_VERTEX_ALIGNMENT in im3d_config.h.