Mesh color

  • Hi everyone,

    very new to Qt here. I am willing to develop a GUI for a scientific software, which will use a mesh visualization tool. I found the Wireframe example which makes me want to start using Qt. However, it uses a general material model that seems to be uniform for the whole mesh (everything is red or blue or...). What I want to achieve is selecting the color for each mesh vertex (just like that).

    Does someone know about a way to do that ?

    Thanks in advance.


  • Hi @Florent-Mathieu

    , it uses a general material model that seems to be uniform for the whole mesh (everything is red or blue or...)
    ->> Not exactly, It is something from from the openGL. vec4 color = vec4(r,g,b,a) or some (calculations like position, normalize, color from vertex like this ) in the fragment shader.

    What I want to achieve is selecting the color for each mesh vertex (just like that).
    -> Are you trying to make Color configurable. Like select the area/ mesh/box and give desired color?

    If not that , could you please be more specific what you want to achieve ?


  • Hi Florent, and welcome to the Qt Forum!
    I guess you're talking about this example, right? If so: Have a look at the shaders. You need to give the vertex shader your velocity data and make it compute a per vertex color from that. Let the vertex shader emit this (varying, thus automatically interpolated) color to the fragment shader. Use this color in the fragment shader instead of the global colors and phong shading that are used in the example.

  • Hi, and thanks for you answer.

    From what I understand, my problem is to manage the .vec4 color for each vertex, and thus to display a color that evolves within each facet. The values would be taken from a vector I have already. In other words, I want to make the color configurable for the programmer and not for the user. I am still a newbie, so from your example I do not really understand how it relates to face colors.

  • Qt Champions 2016

    Are we talking Qt3D here, if so I think @Wieland's comment is exactly on track. The example picture you've provided however doesn't at all seem like a mesh (at least not a tree dimensional one). The wing profile, which doesn't look to have vertices at all, seems to be overlaid onto a scalar field. If you're doing 2D graphics maybe Qt3D is not the right choice? Please do elaborate what you're trying to achieve.

    Kind regards.

  • @Wieland I am indeed talking about this one. Thanks for the advice ! Would you have any recommendation for a reference that explains how the shaders work and how to transfer data to them ? Thanks in advance.

    @kshegunov I will have to deal with 2D and 3D data, so this seems adapted to what I need. Thanks for you comment anyway.

  • I'm working on a problem similar to yours. Qt3D (the Qt module we're talking about) is still pretty hard to use since it's brand new (it's actually still a tech preview) and has virtually no documentation. My code can now generate triangulated meshes from PSLG (2D) on the fly and load them into a Qt3D scene (see below). Right now I'm adding additional per vertex attributes which is just what you want, too. I can share parts of the code with you if you like.


  • @Wieland Then I guess I am lucky. I am really interested indeed, if that's not too sensitive data for you.

  • Got it to work but need to clean it up now. The faces are colored in typical FEM/CFD style in 10 steps. Could also use a continous color scale, doesn't make much difference in the code. Looks nice ^_^


  • @Wieland Looks nice indeed ! It's a classical FE look, pretty much what I'm looking for (except I like better the new matlab colormaps but this choice belongs to the user ;) ).

  • @Florent-Mathieu Hi! I've created a demo application. I've sent you a chat message with the download link. If you have any questions feel free to ask them here.

  • @Wieland

    Hey, thanks for this, it seems amazing. However it seems maybe a version issue prevents me to compile. Indeed I have a few problems :

    • I don't have a "Qtrender" folder in the repositories, just "Qtrenderer". This can be modified easily, then come the real things
    • I don't have a Qt3DRender::QGeometry or Qt3DCore::QNode. All of these classes I can find in Qt3D (and not Qt3DRender or Qt3DCore).
    • This leads to probably a linking problem :
      /Users/LMT/Downloads/meshviewer/femmeshgeometry.cpp:15: erreur : initializer 'QGeometry' does not name a non-static data member or base class; did you mean the base class 'QGeometry'?
      : Qt3DRender::QGeometry(parent)

    ... and further issues when I tried to replace all QtRender's by Qt3D which has the class. Do you have a hint on how to solve this ? Currently using 5.5, maybe I just need to update ?

    Thanks again !

  • You need to update to Qt 5.6 (beta).

  • @Wieland Hey, thanks for the info. Two questions then :

    • I obtain a gray 'A', no colors set from the beginning. How can I set them ?
    • I tried a few things which didn't work and prevented from compiling. Now won't open :
    QFile::open: File (:assets/ already open

    ... even if I restart Qt, change/replace the file. do you have any idea why ? I already checked it wasn't open in another program.

    Thanks again, and sorry for being slow :)

  • @Florent-Mathieu said:

    I obtain a gray 'A', no colors set from the beginning. How can I set them ?

    That's a problem with your graphics card driver. I developed the program on a Linux machine with a Nvidia graphics card and with original Nvidia driver installed. There the program works fine. I also tested the program on another machine that has only integrated Intel graphics and uses the Mesa driver and the program shows only a dark "A" on that machine. The example program from KDAB (the red trefoil knot with black mesh lines) doesn't work on that machine either. Generally speaking, the various free graphics cards drivers for Linux all have very incomplete OpenGl support so if your software really has to run on such computer you'll have to find out what OpenGl features are supported on that machine and then work around the missing parts.

  • @Wieland Okay, I'll try on another computer. I currently use a macbook pro, on which the first example was running. Thanks for the heads up

  • @Wieland Indeed it works now, but only after I updated the nvidia drivers to the latest version, good to know. Two last questions then before I close the topic :

    • I cannot seem to understand where the color data is introduced in the material. Is the temperature what you plot ?
    • I keep having this error when trying to move the scene:
    Qt3D.Renderer.Backend: void Qt3DRender::Render::RenderView::setShaderAndUniforms(Qt3DRender::Render::RenderCommand*, Qt3DRender::Render::RenderPass*, Qt3DRender::Render::ParameterInfoList&, const QMatrix4x4&, const QVector<Qt3DRender::Render::RenderView::LightSource>&) Trying to bind a Parameter that hasn't been defined "vertexTemperature"

    Do you have this too ?

  • @Florent-Mathieu Glad to hear it works now :) This error.. I know it, it nearly drove me crazy but eventually I figured out where it comes from. In FemEffect.qml there is

    , ParameterMapping { parameterName: "vertexPosition"; shaderVariableName: "vertexPosition"; bindingType: ParameterMapping.Attribute }
    , ParameterMapping { parameterName: "vertexForce"; shaderVariableName: "vertexForce"; bindingType: ParameterMapping.Attribute }
    , ParameterMapping { parameterName: "vertexTemperature"; shaderVariableName: "vertexTemperature"; bindingType: ParameterMapping.Attribute 

    These ParameterMapping s tell the render pipeline that we have attributes with the names "vertexPosition", "vertexForce" and "vertexTemperature". These are the attributes in femmeshgeometry.h :

        Qt3DRender::QAttribute *m_positionAttribute;
        Qt3DRender::QAttribute *m_forceAttribute;
        Qt3DRender::QAttribute *m_temperatureAttribute;

    They get their actual names in femmeshgeometry.cpp:

    // Qt3DRender::QAttribute::defaultPositionAttributeName() return "vertexPosition"

    In FemEffect.qml the parameter mappings tell the render pipeline that these attributes are used in our vertex shader (fem.vert). "Attribute" is the OpenGl terminology for "input value for a vertex shader". So the mappings say: We have three input values for our vertex shader and the values in C++ have the names "vertexPosition", "vertexForce" and "vertexTemperature" and we use the same names in fem.vert.

    When and why does the error arise? The error comes from the ParameterMapping when Qt3D tries to map our C++ attribute to an attribute in the vertex shader but the vertex shader does not contain an attribute with that name.

    Now you ask: "But vertexTemperature is in the vertex shader! I can see it in the file right on top!" Here comes the magic: The shader is compiled by the graphics driver at runtime. It also does optimization. If the vertexTemperature attribute is not actually used then the shader compiler optimizes it away and the parameter mapping fails. This is what my comment in fem.vert is about:

    / Beware to actually use the input in the code !
    // Otherwise the shader compiler will optimize them away
    // and then the Qt3D parameter bindings will scream error!

  • @Florent-Mathieu said:

    I cannot seem to understand where the color data is introduced in the material. Is the temperature what you plot ?

    The color is computed in the fragment shader (fem.frag):

    vec4 shadeLine( const in vec4 color )
    vec4 ccc = vec4( computeRed(color.r), computeGreen(color.r), computeBlue(color.r), 1.0 );
    void main()
        vec4 color = vec4(fs_in.force, 1.0);   
        fragColor = shadeLine( color  );

    In the demo I use the force value to compute a color from it. More specifically I only use the x component (color.r).

    The values for vertexForce and vertexTemperature are not contained in the file. I assign random force and temperature data at runtime when the file is loaded. You can find the code in meshdataloaderoff.cpp:

    static bool readVertexData(QTextStream &in, QVector3D &position, QVector3D &force, float &temperature)
        const QStringList lst = readSkip(in).split(' ');
        if (lst.size()<3) return false; // TODO: 7
        int idx = 0;
        bool ok = false;
        position.setX( ); if (!ok) return false;
        position.setY( ); if (!ok) return false;
        position.setZ( ); if (!ok) return false;
        // TODO: remove comments
        //    force.setX( ); if (!ok) return false;
        //    force.setY( ); if (!ok) return false;
        //    force.setZ( ); if (!ok) return false;
        //    temperature =; if (!ok) return false;
        // TODO: remove this
        force.setX( randomFloat() );
        force.setY( randomFloat() );
        force.setZ( randomFloat() );
        temperature = randomFloat();
        return true;

    I did this because I had this file at hand and it contained only geometric data. You can add additional float values to the vertices in the off file and change the code above to use these values.

  • @Wieland Can't see how I missed that. Thanks a lot, that's great, I'm going to close the topic.

  • The reason I introduced force and temperature data in the demo is because I wanted to show how to push vector and scalar data into the vertex shader. Clearly this was hard enough to figure out as Qt3D has no documentation yet and I had to learn everything from the sources ;-)

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.