如何使用两个着色器在OpenGL中渲染两个对象

时间:2014-01-10 13:00:07

标签: c++ opengl

我正在尝试使用两个不同的着色器程序来渲染两个不同的对象。

我有两个具有相同输入参数的顶点着色器和两个片段着色器,其中一个设置为将片段着色为红色。

尝试在loadPlainShader中获取颜色的属性位置时,我会得到一个GL_INVALID_INDEX作为回报。

为什么OpenGL不能第二次找到颜色属性,即使顶点着色器实际上是相似的?

我已经包含了我的代码,它也可以在这里找到: https://www.dropbox.com/sh/8o98ovh8pzubxiw/XGbO-IGQsW/stackoverflow

我正在尝试

从主要我试图首先加载两个着色器程序:

 int main(int argc, char* argv[]) {
  ... GLUT and GLEW initilization ...
    loadPlainShader();
    loadShader();
    loadGeometry();

    glutMainLoop();
 }

loadPlainShader()

 void loadPlainShader(){
    plainShader = InitShader("plain-shader.vert", "plain-shader.frag", "fragColor");
    plainProjUniform = glGetUniformLocation(plainShader, "projection");
    plainModelViewUniform = glGetUniformLocation(plainShader, "modelView");
    plainColorAttribute = glGetAttribLocation(plainShader, "color");
    plainPositionAttribute = glGetAttribLocation(plainShader, "position");
 }

loadShader()

 void loadShader(){
    shaderProgram = InitShader("color-shader.vert",  "color-shader.frag", "fragColor");
    projectionUniform = glGetUniformLocation(shaderProgram, "projection");
    modelViewUniform = glGetUniformLocation(shaderProgram, "modelView");
    colorAttribute = glGetAttribLocation(shaderProgram, "color");
    positionAttribute = glGetAttribLocation(shaderProgram, "position");
 }

initShader()

 GLuint InitShader(const char* vShaderFile, const char* fShaderFile, const char* outputAttributeName) {
    struct Shader {
       const char*  filename;
       GLenum       type;
       GLchar*      source;
    }  shaders[2] = {
       { vShaderFile, GL_VERTEX_SHADER, NULL },
       { fShaderFile, GL_FRAGMENT_SHADER, NULL }
    };

    GLuint program = glCreateProgram();

    for ( int i = 0; i < 2; ++i ) {
       Shader& s = shaders[i];
       s.source = readShaderSource( s.filename );
       if ( shaders[i].source == NULL ) {
          std::cerr << "Failed to read " << s.filename << std::endl;
          exit( EXIT_FAILURE );
       }
       GLuint shader = glCreateShader( s.type );
       glShaderSource( shader, 1, (const GLchar**) &s.source, NULL );
       glCompileShader( shader );

       GLint  compiled;
       glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
       if ( !compiled ) {
          std::cerr << s.filename << " failed to compile:" << std::endl;
          GLint  logSize;
          glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logSize );
          char* logMsg = new char[logSize];
          glGetShaderInfoLog( shader, logSize, NULL, logMsg );
          std::cerr << logMsg << std::endl;
          delete [] logMsg;

          exit( EXIT_FAILURE );
       }

       delete [] s.source;

       glAttachShader( program, shader );
    }

    /* Link output */
    glBindFragDataLocation(program, 0, outputAttributeName);

    /* link  and error check */
    glLinkProgram(program);

    GLint  linked;
    glGetProgramiv( program, GL_LINK_STATUS, &linked );
    if ( !linked ) {
       std::cerr << "Shader program failed to link" << std::endl;
       GLint  logSize;
       glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logSize);
       char* logMsg = new char[logSize];
       glGetProgramInfoLog( program, logSize, NULL, logMsg );
       std::cerr << logMsg << std::endl;
       delete [] logMsg;

       exit( EXIT_FAILURE );
    }
    /* use program object */
    glUseProgram(program);
    return program;
 }

loadGeometry()

 void loadGeometry() {
    vec3 color(1.0f, 1.0f, 0.0f);
    vec3 colorR(1.0f, 0.0f, 0.0f);
    Vertex rectangleData[rectangleSize] = {
       { vec2(-5.0, -5.0 ), color },
       { vec2(-5.0,  5.0 ), color },
       { vec2( 8.0,  5.0 ), color },
       { vec2( 8.0, -5.0 ), color }
    };

    Vertex triangleData[triangleSize] = {
       { vec2(2.0, 2.0 ), vec3(1.0f, 0.0f, 0.0f)},
       { vec2(5.0,  2.0 ), vec3(0.0f, 1.0f, 0.0f) },
       { vec2( 3.5,  5.0 ), vec3(0.0f, 0.0f, 1.0f) }
    };
    rectangleVertexArrayBuffer = loadBufferData(rectangleData, rectangleSize);
    triangleVertexArrayBuffer = loadPlainBufferData(triangleData, triangleSize);
 }

loadBufferData

GLuint loadBufferData(Vertex* vertices, int vertexCount) {
   GLuint vertexArrayObject;

   glGenVertexArrays(1, &vertexArrayObject);
   glBindVertexArray(vertexArrayObject);

   GLuint vertexBuffer;
   glGenBuffers(1, &vertexBuffer);
   glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
   glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW);

   glEnableVertexAttribArray(positionAttribute);
   glEnableVertexAttribArray(colorAttribute);
   glVertexAttribPointer(positionAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)0);
   glVertexAttribPointer(colorAttribute  , 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)sizeof(vec2));

   return vertexArrayObject;
}

loadPlainBufferData

GLuint loadPlainBufferData(Vertex* vertices, int vertexCount) {
   GLuint vertexArrayObject;

   glGenVertexArrays(1, &vertexArrayObject);
   glBindVertexArray(vertexArrayObject);

   GLuint vertexBuffer;
   glGenBuffers(1, &vertexBuffer);
   glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
   glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW);

   glEnableVertexAttribArray(plainPositionAttribute);
   glEnableVertexAttribArray(plainColorAttribute);
   glVertexAttribPointer(plainPositionAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)0);
   glVertexAttribPointer(plainColorAttribute  , 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)sizeof(vec2));

   return vertexArrayObject;
}

我的显示功能

void display() {    
   glClearColor(0.0, 0.0, 0.0, 1.0);
   glClear(GL_COLOR_BUFFER_BIT);

   glUseProgram(shaderProgram);

   mat4 projection = Ortho2D(-15.0f, 15.0f, -10.0f, 15.0f);
   glUniformMatrix4fv(projectionUniform, 1, GL_TRUE, projection);

   mat4 modelViewRec;
   mat4 modelViewTri;

   modelViewRec = RotateZ(45) * modelViewRec;

   // render rectangle
   glUniformMatrix4fv(modelViewUniform, 1, GL_TRUE, modelViewRec);
   glBindVertexArray(rectangleVertexArrayBuffer);
   glDrawArrays(GL_TRIANGLE_FAN, 0, rectangleSize);

   modelViewTri = Translate(6,7,0) * modelViewTri;

   glUseProgram(plainShader);

   // render triangle
   glUniformMatrix4fv(plainModelViewUniform, 1, GL_TRUE, modelViewTri);
   glBindVertexArray(triangleVertexArrayBuffer);
   glDrawArrays(GL_TRIANGLES, 0, triangleSize);

   glutSwapBuffers();

   Angel::CheckError();
}

颜色着色器顶点着色器和普通着色器顶点着色器(相同)

#version 150

uniform mat4 projection;
uniform mat4 modelView;

in vec2 position;
in vec3 color;

out vec4 colorV;

void main (void)
{
   colorV = vec4(color, 1.0);
   gl_Position = projection * modelView * vec4(position, 0.0, 1.0);
}

Plainshader片段着色器

#version 150

in vec4 colorV;
out vec4 fragColor;

void main(void)
{
    fragColor = vec4(1.0,0.0,0.0,1.0);
}

颜色着色器片段着色器

#version 150

in vec4 colorV;
out vec4 fragColor;

void main(void)
{
    fragColor = colorV;
}

0 个答案:

没有答案