openglglslgeometry-shader

How do I pass vertex color through the shader pipeline?


I am trying to pass vertex color through the vertex, geometry and fragment shader:

glBegin(GL_POINTS);
    glVertex3f(-2.0f, 0.0f, 0.0); glColor3f(0.0,1.0,0.0);
    glVertex3f(+2.0f, 0.0f, 0.0); glColor3f(0.0,0.0,1.0);
glEnd();

vertex shader:

# version 130 
varying vec4 colorv;
void main() {
    // pass trough:
    gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex; 
    colorv = gl_Color; 
}

geometry shader:

#version 150

layout(points) in; // origo of cell
layout(points, max_vertices = 1) out;

varying vec4 colorv; 
varying vec4 color;
void main (void) 
{   
    for(int i = 0; i < gl_in.length(); ++i)
    {
        color = colorv;
        gl_Position = gl_in[i].gl_Position;
        EmitVertex();
        EndPrimitive();    
    }
}

fragment shader:

# version 130 
varying vec4 color;
void main (void) 
{   
    // pass-trough:    
    gl_FragColor = color;
}

However it is not working :-(. Both points get a grey color. How do I do this?


Solution

  • Try changing the input/ouput declaration in your geometry shader from this:

    varying vec4 colorv; 
    varying vec4 color;
    

    to this:

    in vec4 colorv[];
    out vec4 color;
    

    Like so:

    #include <GL/glew.h>
    #include <GL/glut.h>
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    #define GLSL( version, shader )  "#version " #version "\n" #shader
    
    const GLchar* vert = GLSL
    ( 
        130,
        varying vec4 colorv;
        void main() {
            // pass trough:
            gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex; 
            colorv = gl_Color; 
        }
    );
    
    const GLchar* geom = GLSL
    ( 
        150,
        layout(points) in; // origo of cell
        layout(points, max_vertices = 1) out;
    
        in vec4 colorv[];
        out vec4 color;
        void main (void) 
        {   
            for( int i = 0; i < gl_in.length(); ++i )
            {
                color = colorv[i];
                gl_Position = gl_in[i].gl_Position;
                EmitVertex();
            }
            EndPrimitive();    
        }
    );
    
    const GLchar* frag = GLSL
    (
        130,
        varying vec4 color;
        void main (void) 
        {   
            // pass-trough:    
            gl_FragColor = color;
        }
    );
    
    GLuint LoadShader( GLenum type, const string& aShaderSrc )
    {
        GLuint shader = glCreateShader( type );
        const char* srcPtr = aShaderSrc.c_str();
        glShaderSource( shader, 1, &srcPtr, NULL );
        glCompileShader( shader );
        return shader;
    }
    
    GLuint LoadProgram( const string& aVertSrc, const string& aGeomSrc, const string& aFragSrc )
    {
        GLuint vert = LoadShader( GL_VERTEX_SHADER, aVertSrc );
        GLuint geom = LoadShader( GL_GEOMETRY_SHADER, aGeomSrc );
        GLuint frag = LoadShader( GL_FRAGMENT_SHADER, aFragSrc );
        GLuint program = glCreateProgram();
        glAttachShader( program, vert );
        glAttachShader( program, geom );
        glAttachShader( program, frag );
        glLinkProgram( program );
        return program;
    }
    
    GLuint prog = 0;
    void display()
    {
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    
        glMatrixMode( GL_PROJECTION );
        glLoadIdentity();
        double w = glutGet( GLUT_WINDOW_WIDTH );
        double h = glutGet( GLUT_WINDOW_HEIGHT );
        double ar = w / h;
        glOrtho( -2 * ar, 2 * ar, -2, 2, -1, 1);
    
        glMatrixMode( GL_MODELVIEW );
        glLoadIdentity();
    
        glUseProgram( prog );
    
        glBegin(GL_POINTS);
        glColor3ub( 0, 255, 0 );
        glVertex3f(-1.0f, 0.0f, 0.0);
        glColor3ub( 0, 0, 255 );
        glVertex3f(+1.0f, 0.0f, 0.0);
        glEnd();
    
        glutSwapBuffers();
    }
    
    int main( int argc, char **argv )
    {
        glutInit( &argc, argv );
        glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
        glutInitWindowSize( 640, 480 );
        glutCreateWindow( "Geometry Shaders" );
        glewInit();
    
        prog = LoadProgram( vert, geom, frag );
    
        glutDisplayFunc( display );
        glutMainLoop();
        return 0;
    }