[Interest] Qt3D: Wireframe

Ch'Gans chgans at gna.org
Thu Apr 13 14:55:05 CEST 2017


On 14 April 2017 at 00:25, Ch'Gans <chgans at gna.org> wrote:
> 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?

Oh yes! The QOpenGLFunctions class doesn't provide glPoygonMode() ...
Too bad! :(

Chris

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