1
$\begingroup$

So I seem to have some trouble getting a geometry shader working with "glDrawArrays(GL_LINE_STRIP, 0, 4);". When I omit the geometry shader and make some minor variable changes, the vertex and fragment shader outputs the line strips properly, but adding the geometry shader somehow doesn't output anything (there doesn't seem to be any compile issues).

I have also tried modifying the geometry shader to be a passthrough shader, and even that fails to output anything.

Code attached below. Intention of the pipeline is to interpolate 4 colors across corners of a quad given as 4 vertices, so geometry shader is for coalescing data. Note that "pos" in "GS_OUT" in the fragment shader is unused right now because code has been heavily modified after testing.

Vertex Shader:

#version 460 core
in vec2 in_Position;
in vec3 in_Color;

out VS_OUT
{
    vec2 position;
    vec3 color;
} vs_out;

void main(void)
{
    vs_out.position = in_Position;
    vs_out.color = in_Color;
    gl_Position = vec4(in_Position, 0.0, 1.0);
}

Geometry Shader:

#version 460 core
layout (lines_adjacency) in;
layout (triangle_strip, max_vertices = 4) out;

in VS_OUT
{
    vec2 position;
    vec3 color;
} gs_in[4];

// tl, tr, bl, br
out GS_OUT
{
    flat vec2 pos[4];
    flat vec3 rgb[4];
} gs_out;

void main() {
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            gs_out.pos[j] = gs_in[j].position;
            gs_out.rgb[j] = gs_in[j].color;
        }
        gl_Position = gl_in[i].gl_Position;
        EmitVertex();
    }
    EndPrimitive();
}

Fragment Shader:

#version 460 core

precision highp float;

// tl, tr, bl, br
in GS_OUT
{
    flat vec2 pos[4];
    flat vec3 rgb[4];
} fs_in;

out vec4 fragColor;

void main(void)
{    
    fragColor = vec4(fs_in.rgb[0], 1.0);
}
$\endgroup$
6
  • $\begingroup$ I don't think gs_in should have the size of the input. Try changing it to gs_in[] instead of gs_in[4]. $\endgroup$
    – Reynolds
    Nov 27, 2023 at 10:20
  • $\begingroup$ @Reynolds While there might always be drivers doing weird things, it should certainly be allowed to have the size of the input, even if it doesn't need to. That should also be a compile error if it doesn't (or the size is wrong). $\endgroup$ Nov 27, 2023 at 17:35
  • $\begingroup$ Have you checked if face culling is turned off? Maybe the triangle back face points towards the camera $\endgroup$
    – Thomas
    Nov 28, 2023 at 7:38
  • $\begingroup$ In your draw call, try to exchange GL_LINE_STRIP by GL_LINE_STRIP_ADJACENCY. Because then the geometry shader loads 4 vertices. Otherwise the vertex shader output doesn't fit the geometry shader input $\endgroup$
    – Thomas
    Nov 28, 2023 at 7:44
  • 1
    $\begingroup$ @Thomas bit late to respond, but yeah, seems like the issue is that I should be passing "GL_LINE_STRIP_ADJACENCY" to the GlDrawArrays() call; thank you everyone for your inputs $\endgroup$
    – TFamIdoing
    Nov 28, 2023 at 19:00

2 Answers 2

2
$\begingroup$

So as @Thomas mentioned, the issue seems to be the fact that I was passing "GL_LINE_STRIP" instead of "GL_LINE_STRIP_ADJACENCY" to the glDrawArrays() call. Apparently, "GL_LINE_STRIP_ADJACENCY is needed when there is a geometry shader involved ("https://www.khronos.org/opengl/wiki/Primitive#Adjacency_primitives").

Edit: Originally I meant to use "GL_LINES_ADJACENCY" and somehow got mixed up with "GL_LINE_STRIP". Don't code at 5am.

$\endgroup$
1
  • $\begingroup$ "Apparently, "GL_LINE_STRIP_ADJACENCY is needed when there is a geometry shader involved" that's not 100% correct... You need the ADJACENCY because your GS wants to operate on 4 input vertices. When only working on 2 input vertices within the GS you can simply use GL_LINE_STRIP $\endgroup$
    – Thomas
    Nov 29, 2023 at 19:19
-1
$\begingroup$

The geometry shader should look something like this: the fragment shader should be changed to match.

#version 460 core
layout (lines_adjacency) in; // converting lines to triangles?
layout (triangle_strip, max_vertices = 4) out;

in VS_OUT
{
    vec2 position;
    vec3 color;
} gs_in[];

// tl, tr, bl, br
out GS_OUT
{
    // vec2 pos; the fragment shader isn't using it so why output it?
    vec3 rgb;  
} gs_out;

void main() {
    for (int i = 0; i < 4; i++)
    {
        //gs_out.pos = gs_in.position; -- don't output it if it isn't being used

        gs_out.rgb = gs_in[i].color;
        gl_Position = gl_in[i].gl_Position;
        EmitVertex();
    }
    EndPrimitive();
}
$\endgroup$
1
  • 1
    $\begingroup$ Can you add some more explanation why this would solve the OP's problem and what issues with his shader it actually fixes? Because right now I can't really see how this is related to his issues (and "use this code instead" doesn't exactly help with that). The output might have been superflous in his example, but that's not an error (and any reasonable shader compiler would do what you did internally anyway). Also changing the output from an array to a single variable changes his entire algorithm. How does that help? $\endgroup$ Dec 12, 2023 at 12:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.