c++qtopenglgeometry-shader

Implementing clip planes with geometry shaders?


What am I using: Qt 5.11.1, MinGW 5.3, Windows 10, C++11, GPU: NVidia 820M (supports OpenGL 4.5)

My task: I have non-solid (just surface) object, rendering by glDrawArrays, and i need to get cross-section of this object by plane. I have found ancient openGL function glClipPlane, but its not compability with VAOs and VBOs. Also Ive found out that its possible to rewrite glClipPlane via geometry shader.

My questions/problems:

  1. Do you know other ways to realize this task?

  2. I really dont understand, how to add geometry shader in QtCreator, there is no "icon" of geometry shader, I tried to add vertex shader and rename it to .gsh or just .glsl, tried to use QOpenGLShaderProgram::addShaderFromSourceCode(QOpenGLShader::Geometry, QString &source) and write shader code in program, but every time I get "QOpenGLShader: could not create shader" on string with adding geometry shader.

look of adding shader into program

screenshot

Vertex shader:

layout (triangles) in;
layout (triangles) out;
layout (max_vertices = 3) out;

void main()
{
    int i;

    for (i = 0; i < gl_in.length(); i++)
    {
        gl_Position = gl_in[i].gl_Position;
        EmitVertex();
    }
    EndPrimitive();
}

Geometry shader:

layout (triangles) in;
layout (triangles) out;
layout (max_vertices = 3) out;

void main()
{
    int i;

    for (i = 0; i < gl_in.length(); i++)
    {
        gl_Position = gl_in[i].gl_Position;
        EmitVertex();
    }
    EndPrimitive();
}

Fragment shader:

precision mediump float;

uniform highp float u_lightPower;
uniform sampler2D u_texture;
uniform highp mat4 u_viewMatrix;
varying highp vec4 v_position;
varying highp vec2 v_texCoord;
varying highp vec3 v_normal;

void main(void)
{
    vec4 resultColor = vec4(0.25, 0.25, 0.25, 0.0);
    vec4 diffMatColor = texture2D(u_texture, v_texCoord);
    vec3 eyePosition = vec3(u_viewMatrix);
    vec3 eyeVect = normalize(v_position.xyz - eyePosition);
    float dist = length(v_position.xyz - eyePosition);
    vec3 reflectLight = normalize(reflect(eyeVect, v_normal));
    float specularFactor = 1.0;
    float ambientFactor = 0.05;

    vec4 diffColor = diffMatColor * u_lightPower * dot(v_normal, -eyeVect);//     * (1.0 + 0.25 * dist * dist);

    resultColor += diffColor;

    gl_FragColor = resultColor;

}    

Solution

  • Let's sort out a few misconceptions first:

    have found ancient openGL function glClipPlane, but its not compability with VAOs and VBOs.

    That is not correct. The user defined clip planes via glClipPlane are indeed deprecated in modern GL, and removed from core profiles. But if you use a context where they still exist, you can combine them with VAOs and VBOs without any issue.

    Also Ive found out that its possible to rewrite glClipPlane via geometry shader.

    You don't need a geometry shader for custom clip planes.

    The modern way of user-defined clip planes is calculating gl_ClipDistance for each vertex. While you can modify this value in a geometry shader, you can also directly generate it in the vertex shader. If you don't otherwise need a geometry shader, there is absolutely no reason to add it just for the clip planes.

    I really dont understand, how to add geometry shader in QtCreator, there is no "icon" of geometry shader, I tried to add vertex shader and rename it to .gsh or just .glsl, tried to use OpenGLShaderProgram::addShaderFromSourceCode(QOpenGLShader::Geometry, QString &source) and write shader code in program, but every time I get "QOpenGLShader: could not create shader" on string with adding geometry shader.

    You first need to find out which OpenGL version you're actually using. With Qt, you can easily end up with an OpenGLES 2.0 context (depending on how you create the context, and also how your Qt was compiled). Your shader code is either desktop GL 2.x (GLSL 1.10/1.20) or GLES 2.0 (GLSL 1.00ES), but not valid in modern core profiles of OpenGL.

    GLES2 does not support geometry shaders at all. It also does not support gl_ClipDistance, so if you _really) have to use GLES2, you can try to emulate the clipping in the fragment shader. But the better option would be switching to a modern core profile GL context.