How do I pass vertex color through the shader pipeline?

这一生的挚爱 提交于 2019-12-01 09:54:46

问题


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?


回答1:


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;
}


来源:https://stackoverflow.com/questions/14468724/how-do-i-pass-vertex-color-through-the-shader-pipeline

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!