我试图让我的跨平台着色器编译一个默认着色器,它只不过是这样的基本着色器程序:
顶点程序:
void main()
{
//vec4 vertex = matModelView * a_vertex;
gl_Position = ftransform();//matProj * vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
}
片段程序:
uniform sampler2D colorMap;
void main()
{
gl_FragColor = texture2D(colorMap, gl_TexCoord[0].st);
}
我知道 gl_ 前缀是不推荐使用的函数,但这只是一个默认着色器,所以我知道一切正常。这个示例在我的着色器类的 windows 下运行良好。
现在进入我的着色器类,当我创建一个着色器对象时,我调用加载方法,该方法采用没有文件扩展名的路径。例如: ./data/shaders/default 加载器接受这个并搜索该字符串 + .vert .geom 或 .frag 以查找适当的着色器程序。然后将它们加载并传递给创建程序的 OpenGL 部分。这似乎是哪里出了问题,我可以确认着色器程序的内容是从磁盘正确加载的,所以据我所知,这不是问题所在。
加载文件后,它会继续编译顶点和片段程序(或几何,但这是可选的):
a_Type
要么GL_FRAGMENT_SHADER
要么GL_VERTEX_SHADER
。a_Source
是着色器程序文件(.vert/.frag/.geom 文件)的内容。当我加载顶点程序时,编译立即失败并被if( success != GL_TRUE )
击中并被评估为如此,我得到一个编译错误。我没有得到任何输出,“着色器编译输出” printf 没有打印任何关于编译的信息。(这OGLCHECK
是一个检查 opengl 错误堆栈的宏,它也不显示任何内容。)
GLuint Shader::Compile(const GLuint a_Type, const char* a_Source)
{
if(a_Source == NULL)
return 0;
GLuint handle = glCreateShader(a_Type); OGLCHECK
glShaderSource(handle, 1, &a_Source, NULL); OGLCHECK
glCompileShader(handle); OGLCHECK
int bufflen = 0;
GLint success = GL_FALSE;
glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &bufflen); OGLCHECK
if(bufflen > 1)
{
GLchar* logString = new GLchar[bufflen + 1];
glGetShaderInfoLog(handle, bufflen, 0, logString); OGLCHECK
printf( "Shader compile output:\n%s\n", logString );
delete logString;
logString = 0;
}
glGetShaderiv(handle, GL_COMPILE_STATUS, &success); OGLCHECK
if(success != GL_TRUE)
{
printf( "Failed to compile shader!\n" );
glDeleteShader(handle); OGLCHECK
handle = 0;
}
return handle;
}
我不确定发生了什么,这个实现在 Windows 下运行良好,因为这是我移植到 linux 的渲染引擎的一部分。有人在linux下对着色器编译有类似的问题吗?
另外,我检查了 glxinfo,这里有一些信息:
glxinfo | grep "OpenGL version"
OpenGL version string: 4.2.0 NVIDIA 295.49
我还在 fragment_program、vertex_program、geometry_program 上进行了 grep,所有这些扩展似乎都可用。我正在运行 Ubuntu 12.04。
更新:它似乎与着色器文件无关,但其他东西,当我从终端运行它时,它可以编译着色器并使用它们,但是每当我从 Code::Blocks 运行它时,它就无法编译着色器.. 他们正在加载并传递给 OpenGL。不知道发生了什么。