我正在尝试使用两个不同的着色器程序来渲染两个不同的对象。
我有两个具有相同输入参数的顶点着色器和两个片段着色器,其中一个设置为将片段着色为红色。
尝试在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;
}