Nominate our 2022 Qt Champions!

QOpenGL terrain cursor

  • Hi,

    I have another question. How is possible to create brush like on the picture


    Is possible to create it in shader language? Can you give me some tutorial?
    Why in shader? Because I downloaded example where author use shader lang to calculate render axis Y for heightmap.


  • One method that springs to mind is to:

    Provide cursor/brush centre position in (x,z) coords and radius as uniform variables to fragment shader for the terrain.

    In fragment shader calculate the base color as normal (the red with black grid lines)

    Also calculate distance of fragment from brush centre and compare with brush radius. If the fragment is within some tolerance of the brush radius from the brush centre, then mix in the white color for the brush outline.

    Hope this helps.

  • Thanks for info, I will try

  • Ok I tried my best, but I'm beginner in OpenGL. I'm using QOpenGL headers with QGLWidget. Btw if you know better how to locate mouse X,Z on heightmap teach me :)

    QGLWidget.cpp paintGL():
    @GLint viewport[4];
    GLdouble modelview[16], projection[16], posX, posY, posZ;
    GLfloat winX, winY, winZ;

        m_funcs->glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
        m_funcs->glGetDoublev(GL_PROJECTION_MATRIX, projection);
        m_funcs->glGetIntegerv(GL_VIEWPORT, viewport);
        winX = mouse_position.x();
        winY = static_cast<float>(viewport[3]) - mouse_position.y();
        m_funcs->glReadPixels(winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
        gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
        shader->setUniformValue("cursorPos", QVector2D(posX, posZ));
        shader->setUniformValue("brushRadius", 10.0f);@

    Fragment shader:
    @in terrainVertex
    vec2 position;
    } In;
    layout (location = 0) out vec4 fragColor;

    vec4 brushColor = vec4(1, 0, 0, 1);

    uniform vec2 cursorPos;
    uniform float brushRadius;

    void main()
    // Compute fragment color depending upon selected shading mode
    vec4 c = shaderModel();

    // Blend with fog color
    float dist      = abs(position.z);
    float fogFactor = (fog.maxDistance - dist) / (fog.maxDistance - fog.minDistance);
    fogFactor = clamp(fogFactor, 0.0, 1.0);
    vec4 outColor = mix(fog.color, c, fogFactor);
    // Terrain brush
    float distRing = distance(In.position, cursorPos);
    if(distRing < brushRadius)
        float str = max(0.0, mix(-1.5, 0.5, distRing / brushRadius));
        outColor += brushColor * str;
    fragColor = outColor;


    @layout (location = 0) in vec2 vertexPosition;

    out terrainVertex {
    vec2 position;
    } Out;

    void main()
    Out.position = vertexPosition;

Log in to reply