0

I am trying to figure out how to switch outputs in the geometry shader, specifically these two outputs:

layout(points, max_vertices = 1) out;          // OUTPUT 1
layout(triangle_strip, max_vertices = 4) out;  // OUTPUT 2

I am doing a rendering of starclusters and have a dataset of 100 000+ stars using sprites generated in the geometry shader. But, the sprite "halos" are to only appear if we move closer to the target star.

Geometry Shader

#version 440
const vec2 corners[4] = { 
    vec2(0.0, 1.0), 
    vec2(0.0, 0.0), 
    vec2(1.0, 1.0), 
    vec2(1.0, 0.0) 
};

layout(points) in;
layout(points, max_vertices = 1) out;
//layout(triangle_strip, max_vertices = 4) out;

uniform vec4 campos;

float spriteSize = 0.000005; // set here for now.
out vec2 texCoord;

void main(){
    float distToPoint = 1; //(1.f/((length(gl_in[0].gl_Position - campos)) ));

    if(distToPoint == 1){ // dumb condition just to illustrate my point
    // EMIT QUAD
        for(int i=0; i<4; ++i){
            vec4 pos    = gl_in[0].gl_Position;                 
            pos.xy     += spriteSize *(corners[i] - vec2(0.5)); 
            gl_Position = pos;                                  
            texCoord    = corners[i];                           
            EmitVertex();
        }
        EndPrimitive();
    }else{ 
    // EMIT POINT
        gl_Position = gl_in[0].gl_Position;
        EmitVertex();
        EndPrimitive();
    }
}

Fragment Shader

void main(void){
    ... // First I do a bunch of depth computation, irrelevant to this question
    gl_FragDepth = depth;

   // Here I want to switch between these two outputs! 

    //diffuse = texture2D(texture1, texCoord); // OUTPUT 1
   diffuse = vec4(Color, 1.0);                 // OUTPUT 2

}

I have recently encountered streams for geometry shader but cant find a decent example of how this can be done in my instance.

Please let me know if more code needs to be posted.

mike
  • 194
  • 1
  • 2
  • 18
  • 2
    You can't switch what primitive type is emitted in a geometry shader. `ARB_transform_feedback3` allows you to set up multiple output streams when transform feedback, but the output goes to a VBO and the only output mode is points. – Colonel Thirty Two Aug 28 '14 at 17:25
  • @ColonelThirtyTwo - So my only option is using a separate shader then? There must be a more elegant solution than that though, right? – mike Aug 28 '14 at 19:20
  • ^ Also, is it possible to just have two different geometry shaders and switch those at runtime? How? (Vertex & Fragment shaders same always) – mike Aug 28 '14 at 19:40
  • 2
    Yes, you'll have to use two geometry shaders, and either specify what geometry goes to which shaders via draw calls or just don't emit geometry in the shaders. I think [`ARB_separate_shader_objects`](http://www.opengl.org/registry/specs/ARB/separate_shader_objects.txt) will let you reuse shader objects in different programs, but I haven't used it. Also remember that you can specify multiple "files" to `glShaderSource`, so you don't have to duplicate code between shaders. – Colonel Thirty Two Aug 28 '14 at 19:50

0 Answers0