[Interest] Qt3D: Wireframe

Ch'Gans chgans at gna.org
Thu Apr 13 14:25:17 CEST 2017

On 13 April 2017 at 18:52, Sean Harmer <sean.harmer at kdab.com> wrote:
> Hi,
> On 13/04/2017 06:15, Ch'Gans wrote:
>> On 13 April 2017 at 14:38, Ch'Gans <chgans at gna.org> wrote:
>>> Hi,
>>> I would like to be able to select at run-time how my entities are
>>> rendered (ideally on a per entity basis).
>>> I would like to have 3 choices:
>>> - 1. wireframe
>>> - 2. shaded
>>> - 3. shaded + wireframe
>>> I had a look at the wire frame QML example, and translated it to C++.
>>> The code is working. I have simplified the fragment shader, as i don't
>>> need fancy light effect, other than a shaded color per face.
>>> These shaders allow me to achieve 2 & 3. But my feeling is that i need
>>> something completely different to render a 'transparent' wireframe
>>> only.
> You can do it a number of ways:
> 1) One approach is indeed to use polygon mode but as you've noticed this
> renderstate is missing from Qt 3D but should be easy to add.
> 2) You could adjust the shader from 3 such that when in the fragment shader
> you decide if a fragment is part of the line or part of the shaded mesh,
> instead of shading it, you simply call discard() to throw that fragment
> away.

Bummer! The only thing I was missing is the discard() call... See, I'm
a real noob! ;)
This, with the NoCulling simply works for 1, 2 &3!

> 3) Use custom geometry to render your wireframe however you see fit. This
> may be as simple as using a different index attribute/buffer with your
> existing vertex data buffer(s), or you may want to create entirely new
> geometry if you want something other than lines joining the original
> vertices. For, example if you want an extruded lattice type effect for your
> wire frame. You may even be able to get away with simply using lines as the
> primitive type instead of triangles. Depends upon your geometry.
> 4) Render the same geometry but with an alpha blended material.

I tried that one, with no luck as i certainly missed something. I've
read somewhere that you had to manage the z ordering in case you have
several transparent objects, so i gave up.

> 5) Probably a bunch of other ways I can't think of without another cup of
> tea...
>>> Reading through OpenGL materials, it looks like i need things like
>>> glPolygonMode, reading through Qt3D leads me to
>>> QGeometryRenderer::PrimitiveType.
>>> But i am having problems connecting the dots.
>>> PrimitiveType is a property of QGeometryRenderer, which means that it
>>> is closely related with my buffer data and how the data are arranged
>>> within the buffer.
>>> So If i want to switch from 'shaded' to wireframe I need to change my
>>> data (and my shader code too), surely there is to be a way to use the
>>> same data buffer to achieve the 3 rendering modes. Should I use a 2
>>> passes rendering? The first one renders (or not) the face shades and
>>> the second one renders (or not) the wireframes? Actually this should
>>> even be a 3 passes: back of wireframe (or not), shaded faces (or not)
>>> and front of wireframe (or not)...
> No need to render something twice to see its back and front sides. Use a
> QCullFace render state with the mode set to NoCulling. By default, it's set
> to cull the back faces because most often meshes are closed so there's no
> point in rasterizing the back faces as they will never be seen.

Yes, i get the picture now. I was thinking this way because i forgot
about the 'discard' feature.

>>> Is this the right approach? Or should I instead define 3 materials and
>>> simply switch the material as i want a different drawing style?
>>> Last thing is that my input data are triangulated polygon with holes,
>>> but i have as well access to the original polygon with holes alone.
>>> And i actually don't want to render the internal (triangulation) edges
>>> of my polygonal faces (up and down) or rectangular faces (side ones).
>>> So basically in shaded mode, i only need to calculate the color per
>>> geometric face (as oppose to triangular face) ...
> To exclude some of the triangle edges you need an additional per vertex
> attribute to use as a flag. Have a read through
> http://strattonbrazil.blogspot.co.uk/2011/09/single-pass-wireframe-rendering_11.html

Thanks for sharing, this article also explain the what, why and how of
the shader code from the wireframe example.

If i wanted to make a generic material (one you can use on any mesh,
eg QCylinderGeometry or QMesh), then i wouldn't use this. But if i use
exclusively my custom geometry this is the way to go.

> for the details.
>>> PS: I've spent serious time yesterday reading through
>>> https://learnopengl.com, although I think i now understand (way
>>> better) how OpenGL works and how to use it, Qt3D seems to be way more
>>> than a convenience wrapper around the OpenGL API.
>>> I couldn't find a place in Qt3D where you would manipulate OpenGL
>>> directly (eg calling glFooBar()). I am not even sure if it was design
>>> too do this sort of things.
>> Answering myself partially:
>> QRenderState provides lot of these. Eg.: glCullFace() => QCullFace,
>> glFrontFace() => QFrontFace, ...
>> Bu as far as i can understand OpenGL and Qt3D, i would say that Qt3D
>> simply doesn't support the OpenGL polygon mode. Maybe because it's
>> either sort-of deprecated, or there are other (better?) ways to do
>> this sort of things...
> Nope, it just slipped under the radar and you're the first person to ask for
> it. Should be simple to add. Take a look at the other render states if you
> want to contribute it.

I had a look at the source code, I might give it a try over the week-end.

Looks like that I "just" need to:
- add a new state derived from GenericState (with 2 glEnum params)
- implement the apply()
- add an enum value to Render::StateMask,
- add code to RenderStateSet::resetMasked()
- add stuff to StateVariant
- implement the public QPolygonMode and all the glue that go with it
(private, data, ...).
- 2 enums to map with glEnum face and mode in the public API

Am I missing any important steps?

> Cheers,
> Sean
> --
> Dr Sean Harmer | sean.harmer at kdab.com | Managing Director UK
> KDAB (UK) Ltd, a KDAB Group company
> Tel. +44 (0)1625 809908; Sweden (HQ) +46-563-540090
> Mobile: +44 (0)7545 140604
> KDAB - Qt Experts
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest

More information about the Interest mailing list