我正在使用 ubuntu 13 上的 GL 和带有 nvidia ION2 的 eeepc 编写一个基本的视图管理器(使用 bumblebee 项目的 optimus )。我有一个 XML 文件,系统启动时会从该文件中创建着色器(如插件)并将其添加到字典中。一旦这些被编译和链接并准备好使用,包装函数用于根据传递的程序名称选择适当的着色器程序。
void ShadingProgramManager::useProgram(const std::string& program){
GLuint id = getProgramId(program);
glUseProgram(id);
if(GL_INVALID_VALUE == glGetError() || GL_INVALID_OPERATION == glGetError()){
printf("Problem Loading Shader Program");
return;
}
printf("%s is in use", program.c_str());
}
其中 getProgramId 只是查看预先创建的字典并返回着色器程序的 id。
当我渲染对象时,我通过调用来使用程序:
ShadingProgramManager::getInstance()->useProgram('vc');
'vc' 由以下着色器组成
顶点着色器 - vc.vert
#version 330
layout(location = 0) in vec3 position;
layout(location = 1) in vec4 color;
out vec4 vertcolor;
void main(){
vertcolor = color;
gl_Position = vec4(position, 1.0); //I've tried setting this as position * 10 also for any apparent changes on screen, but nothing changes
}
片段着色器 - vc.frag:
#version 330
in vec4 vertcolor;
out vec4 outputcolor;
void main(){
outputcolor = vertcolor;
}
我的顶点缓冲区交错为:
VertexColor vertices[] =
{
{-1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 1.0}, /*first 3 floats for pos, 4 for color */
{ 1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0},
{ 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0},
{-1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0},
};
索引缓冲区如下:
GLuint indices[] =
{
0, 1, 2,
0, 2, 3,
};
VertexColor 定义为:
class VertexColor{
GLfloat x;
GLfloat y;
GLfloat z;
GLfloat r;
GLfloat g;
GLfloat b;
GLfloat a;
/** some constants as below **/
};
const int VertexColor::OFFSET_POSITION =0;
const int VertexColor::OFFSET_COLOR =12;
const int VertexColor::SIZE_POSITION =3;
const int VertexColor::SIZE_COLOR =4;
const int VertexColor::STRIDE =28;
然后我使用下面的代码来渲染四边形:
ShadingProgramManager::getInstance()->useProgram('vc');
glBindBuffer(GL_ARRAY_BUFFER, &vb);
glBufferData(GL_ARRAY_BUFFER, size_of_vertices_array, vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, &ib);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size_of_indices_array, indices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribArrayPointer(0, VertexColor::SIZE_POSITION, GL_FLOAT, GL_FALSE, VertexColor::STRIDE, (GLvoid*)VertexColor::OFFSET_POSITION);
glVertexAttribArrayPointer(1, VertexColor::SIZE_COLOR, GL_FLOAT, GL_FALSE, VertexColor::STRIDE, (GLvoid*)VertexColor::OFFSET_COLOR);
glDrawElements(GL_TRIANGLES, size_of_indices, GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
但是,我只看到一个白色的四边形。我怀疑这是生效的固定功能管道。
即使我删除了对 glUseProgram(id) 的调用或使用 glUseProgram(0),我仍然得到相同的结果。我还尝试将顶点着色器中的位置乘以 10.0,但对屏幕没有影响。我确信着色器也在被编译和链接。当我更改为使用 glUseProgram(40) 或任何无效数字之类的东西时,我会收到必要的错误消息,但否则,我只会看到一个白色的单位正方形!
抱歉,这篇文章太长了,但我被这个帖子难住了……无论我对 vert 或 frag 着色器进行什么更改,我都会得到一个白色的单位方块。我怀疑 GL 默认使用 FFP,并且由于某种原因我的着色器程序没有生效。我希望这是一个愚蠢的错误,但任何指针将不胜感激。
PS:没有编译错误,所以请原谅代码中的任何语法错误。我已经在上面输入了完整的代码。
更新:按照 Andon、Dinesh 和 Spektre 的建议,我在调用 glVertexAttribArrayPointer 时添加了最后一个参数,我之前错过了,但结果仍然相同。