这是一份学习OpenGL时遇到的错误记录,随着实践进行,此列表将不断更新。
解决办法:编译时需要连接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在工程的属性下设置如下也可以编译成功:
如果着色器中变量输入输出错误,那么将会导致无法渲染。例如这里从《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; }
#version 330 smooth in vec4 incolor; out vec4 outputColor; void main() { outputColor = incolor; }
错误原因:OpenGL要求,前一阶段的输出变量和下一阶段的输入变量必须名称和类型相同,这里使用了smooth限定符,那么两者也必须相同。这里顶点着色器输出为outputColor,而片元着色器输入却是incolor,因此造成错误。解决办法即改成一致类型和名称。
使用了代码:
glutInitDisplayMode( GLUT_RGBA|GLUT_DOUBLE|GL_DEPTH);
或者:
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GL_DOUBLE);造成窗口标题栏显示异常。
错误原因: 编译器并不会报错,但是glut使用的常量是GLUT_xxx,而不是GL_XX,因此造成窗口标题栏错误。
在编译该书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); }
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 };
这种方式更值得提倡。
函数原型为:
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 };
更好的方式是使用宏定义:
#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);
这是一个关于显卡驱动支持的错误.
解决办法:
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的着色器语言啦.
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