OpenGL学习错误列表Error List
这是一份学习OpenGL时遇到的错误记录,随着实践进行,此列表将不断更新。
1.undefined reference to `glBegin'
解决办法:编译时需要连接libGL.so , libGLU.so, libglut.so三个库,或者通过添加库路径到连接路径,或者通过-l参数添加链接。
使用命令行方式:
wangdq@wangdq:~/OpenGL$ gcc example.c -o example.out -lGL -lGLU -lglut
wangdq@wangdq:~/OpenGL$ ./example.out
或者使用eclipe c/c++ for linux在工程的属性下设置如下也可以编译成功:
2.顶点着色器和片元着色器中传递颜色失败,导致无法渲染
如果着色器中变量输入输出错误,那么将会导致无法渲染。例如这里从《Learning Modern 3D Graphics Programming》例子中,从顶点着色器传递颜色给片元着色器,自己书写两个着色器代码为:
vertex shader
#version 330
layout (location = 0) in vec4 pos;
layout (location = 1) in vec4 color;
smooth out vec4 outputColor;
void main()
{
gl_Position = pos;
outputColor = incolor;
}
Fragment shader
#version 330
smooth in vec4 incolor;
out vec4 outputColor;
void main()
{
outputColor = incolor;
}
初看好像没有什么错误,运行时则无法渲染。
错误原因:OpenGL要求,前一阶段的输出变量和下一阶段的输入变量必须名称和类型相同,这里使用了smooth限定符,那么两者也必须相同。这里顶点着色器输出为outputColor,而片元着色器输入却是incolor,因此造成错误。解决办法即改成一致类型和名称。
3. 创建的windows窗口标题栏异常
使用了代码:
glutInitDisplayMode( GLUT_RGBA|GLUT_DOUBLE|GL_DEPTH);
或者:
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GL_DOUBLE);造成窗口标题栏显示异常。
错误原因: 编译器并不会报错,但是glut使用的常量是GLUT_xxx,而不是GL_XX,因此造成窗口标题栏错误。
4.编译《Learning Modern 3D Graphics Programming》一书源代码时glloadD.lib版本不同造成的错误
在编译该书World Scene示例时,从网上下载的Unofficial OpenGL Software Development Kit与作者源代码中的glsdk版本不一致,导致编译后的lib文件版本不同,因此总是提示:
unresolved symbol glload::LoadFunctions错误。
错误原因: c++ static lib版本不一致造成的错误。
解决方法:windows下使用dumpbin工具查看lib导出函数,对比发现:
两者包含的LoadFunctions函数根本不一样,因此使用新版本的lib,而是用旧版的头文件造成了不一致问题。
关于dumpbin /LINKERMEMBER 选项含义请参考:microsoft.
这里提醒我们,注意编译时lib与头文件版本问题。更应该在库中包含关于版本的信息,参考stackoverflow,更好的做法应该是:
方法一: 在头文件中声明lib版本如下:
#define MYLIB_MAJOR_VERSION 1
#define MYLIB_MINOR_VERSION 2
#define MYLIB_REVISION 3
#define MYLIB_VERSION "1.2.3"
#define MYLIB_VERSION_CHECK(maj, min) ((maj==MYLIB_MAJOR_VERSION) && (min<=MYLIB_MINOR_VERSION))
在使用的程序中进行检查:
if (! MYLIB_VERSION_CHECK(1, 2)) {
fprintf(stderr, "ERROR: incompatible library version\n");
exit(-1);
}
方法二: 可以在lib中包含版本信息如下:
struct {
const char* string;
const unsigned major;
const unsigned minor;
const unsigned revision;
} mylib_version = {
MYLIB_VERSION, MYLIB_MAJOR_VERSION, MYLIB_MINOR_VERSION, MYLIB_REVISION
};
在lib中存储这个mylib_version结构体,在lib中提供验证函数,以便在应用程序中调用来进行版本验证。
这种方式更值得提倡。
5.glDrawElements 无法渲染
函数原型为:
void glDrawElements( GLenum mode,
GLsizei count,
GLenum type,
GLsizeiptr indices);
使用glDrawElements要注意:
1)同glVertexAttribPointer一样,当有缓存对象绑定到
这段内容参考自:stackoverflowGL_ARRAY_BUFFER
时,glVertexAttribPointer的最后一个参数解释为缓存中的偏移量;当有缓存对象绑定到
GL_ELEMENT_ARRAY_BUFFER时glDrawElements的最后一个参数解释为缓存中的偏移量。因此,如果使用VBO/VAO方式来执行glDrawElements时,要注意最后一个参数是偏移量(byte-offset into the element array at which the index data begins),而不再是指向索引存贮位置的指针(Specifies a pointer to the location where the indices are stored.)。
No display from glDrawElements 。
2)注意count参数的意义,它表示将使用多少个索引进行渲染,这与渲染多少个几何图形例如三角形数目不同。
例如索引为:
const GLshort indices[] = {
0,1,3,
1,2,3,
0,2,1,
0,3,2
};
这个时候传入的count不能是4,而应该是4*3 = 12。如果传入4将只能绘制部分,例如一个三角形。
更好的方式是使用宏定义:
#define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
然后这样书写:
glDrawElements(GL_TRIANGLES,ARRAY_COUNT(indices),GL_UNSIGNED_SHORT,0);
No.6 ubuntu error: GLSL 3.30 is not supported. Supported versions are: 1.00 ES, 1.10, 1.20, and 1.30
这是一个关于显卡驱动支持的错误.
解决办法:
ubuntu 可能使用的附加驱动如下图所示,默认一般使用X.org X Server驱动,它一般只能支持GLSL 1.50左右,
我的电脑上选择NVIDIA驱动331安装后重启,可以根据需要选择你的驱动程序.
安装完驱动后重启,可以利用glxinfo(sudo apt-get install mesa-utils安装该工具)查看系统OpenGL信息如下:
glxinfo | grep OpenGL
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: GeForce G 105M/PCIe/SSE2
OpenGL core profile version string: 3.3.0 NVIDIA 331.104
OpenGL core profile shading language version string: 3.30 NVIDIA via Cg compiler
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 3.3.0 NVIDIA 331.104
OpenGL shading language version string: 3.30 NVIDIA via Cg compiler
OpenGL context flags: (none)
OpenGL profile mask: (none)
OpenGL extensions:
可以看到现在支持GLSL 3.30的着色器语言啦.
No.7 Inconsistency detected by ld.so: dl-version.c: 224: _dl_check_map_versions: Assertion `needed != ((void *)0)' failed!
ubuntu下,安装完nvidia-331驱动后,新建的OpenGL工程,编译出现错误.
解决办法,为工程添加GL链接,例如:-L/usr/lib/nvidia-331/
我的codeblocks环境,添加如下:
同时添加上相关其他库(glut/glew等)后即可,编译log显示的命令为:
g++ -Wall -std=c++11 -g -c /home/xxx/OpenGLEx/KnochSnow/main.cpp -o obj/Debug/main.o
g++ -Wall -std=c++11 -g -c /home/xxx/OpenGLEx/KnochSnow/shader.cpp -o obj/Debug/shader.o
g++ -o bin/Debug/KnochSnow obj/Debug/main.o obj/Debug/shader.o
-L/usr/lib/nvidia-331/
-lGL -lX11 /usr/lib/i386-linux-gnu/libglut.so /usr/lib/i386-linux-gnu/libGLEW.so
这样编译通过,运行正常了.