OpenGL学习错误列表Error List

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一样,当有缓存对象绑定到GL_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.)。这段内容参考自:stackoverflowNo 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

这样编译通过,运行正常了.

OpenGL网格简化是一种通过减少网格中的顶点数量来降低模型复杂度的技术。这可以提高渲染性能并减少内存消耗。在OpenGL中,可以使用不同的算法和技术来实现网格简化。其中一种常用的方法是使用LOD(Level of Detail)技术,根据观察距离和模型的重要性,动态地选择合适的细节级别来渲染模型。 在网格简化过程中,可以使用不同的算法来决定哪些顶点可以被移除或合并。一种常见的算法是基于误差度量的方法,例如Quadric Error Metric(QEM)算法。该算法通过计算顶点之间的误差来决定哪些顶点可以被合并,以达到减少顶点数量的目的。 另外,OpenGL还支持创建多级显示列表来实现复杂物体的层次建模。通过将低层图段的显示列表按照一定的位置、方向和尺寸调用构成高层图段,可以实现更高级别的模型简化和优化。\[3\] 总结起来,OpenGL网格简化是通过减少网格中的顶点数量来降低模型复杂度的技术。可以使用不同的算法和技术来实现网格简化,其中一种常用的方法是使用LOD技术。另外,OpenGL还支持创建多级显示列表来实现复杂物体的层次建模。 #### 引用[.reference_title] - *1* [OpenGL 学习笔记III: 图形管线、三角形、shader 流水线](https://blog.csdn.net/u010180372/article/details/122246810)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [图形学2](https://blog.csdn.net/weixin_30645617/article/details/95799443)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值