主题:[原创]OpenGL入门学习——第十一课
eastcowboy [专家分:25370] 发布于 2007-07-30 07:49:00
大家久等了。
因为毕业参加工作的关系,很长时间没有更新。
现在放出第十课的内容。
首先还是以前课程的连接:
[url=http://www.programfan.com/club/showbbs.asp?id=184355]第一课,编写第一个OpenGL程序[/url]
[url=http://www.programfan.com/club/showbbs.asp?id=184525]第二课,绘制几何图形[/url]
[url=http://www.programfan.com/club/showbbs.asp?id=184769]第三课,绘制几何图形的一些细节问题[/url]
[url=http://www.programfan.com/club/showbbs.asp?id=185032]第四课,颜色的选择[/url]
[url=http://www.programfan.com/club/showbbs.asp?id=196017]第五课,三维的空间变换[/url]
[url=http://www.programfan.com/club/showbbs.asp?id=196231]第六课,动画的制作[/url]
[url=http://www.programfan.com/club/showbbs.asp?id=218828]第七课,使用光照来表现立体感[/url]
[url=http://www.programfan.com/club/showbbs.asp?id=219518]第八课,使用显示列表[/url]
[url=http://www.programfan.com/club/showbbs.asp?id=224877]第九课,使用混合来实现半透明效果[/url]
[url=http://www.programfan.com/club/post-227694.html]第十课,BMP文件与像素操作[/url]
第十一课,纹理的使用入门 ——→ [color=0000FF]本次课程的内容[/color]
我们在前一课中,学习了简单的像素操作,这意味着我们可以使用各种各样的BMP文件来丰富程序的显示效果,于是我们的OpenGL图形程序也不再像以前总是只显示几个多边形那样单调了。——但是这还不够。虽然我们可以将像素数据按照矩形进行缩小和放大,但是还不足以满足我们的要求。例如要将一幅世界地图绘制到一个球体表面,只使用glPixelZoom这样的函数来进行缩放显然是不够的。OpenGL纹理映射功能支持将一些像素数据经过变换(即使是比较不规则的变换)将其附着到各种形状的多边形表面。纹理映射功能十分强大,利用它可以实现目前计算机动画中的大多数效果,但是它也很复杂,我们不可能一次性的完全讲解。这里的课程只是关于二维纹理的简单使用。但即使是这样,也会使我们的程序在显示效果上迈出一大步。
下面几张图片说明了纹理的效果。前两张是我们需要的纹理,后一张是我们使用纹理后,利用OpenGL所产生出的效果。
[img]http://blog.programfan.com/upfile/200707/20070730074740.jpg[/img]
[img]http://blog.programfan.com/upfile/200707/20070730074746.jpg[/img]
[img]http://blog.programfan.com/upfile/200707/20070730074751.jpg[/img]
纹理的使用是非常复杂的。因此即使是入门教程,在编写时我也多次进行删改,很多东西都被精简掉了,但本课的内容仍然较多,大家要有一点心理准备~
=====================未完,请勿跟帖=====================
回复列表 (共20个回复)
11 楼
stdlll [专家分:360] 发布于 2007-08-21 16:11:00
[size=3][color=FF0000]很详细,厉害了[/color][/size]
12 楼
mmjuns [专家分:0] 发布于 2007-10-15 08:55:00
好棒!!你的每课我都看了。你真的太棒了!!从这里我学习了太多东西。对于一个初学者,这个教程真的很好!!
你的每个程序我都运行了~!这一课里面有一个小问题哦:
在函数GLuint load_texture(const char* file_name)中,
定义了这么两个变量。
GLuint last_texture_ID, texture_ID = 0;
后面进行ID賦值的时候,会报错的。
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture_ID);
这里应该是:
GLint last_texture_ID;
GLuint texture_ID=0;
13 楼
eastcowboy [专家分:25370] 发布于 2007-10-17 16:08:00
to mmjuns:
你所说的问题确实存在。
在我的代码中,定义last_texture_ID为GLuint类型,因此&last_texture_ID的类型是(GLuint*),与glGetIngeterv函数所要求的(GLint*)有所不同。
不过,并不需要因此把last_texture_ID的类型修改为GLint。OpenGL是用GLuint类型来表示纹理编号,而不是用GLint来表示。因此仍然应该定义last_texture_ID为GLuint类型,只是在调用glGetIntegerv的时候,显式的执行类型转换即可。
代码如下:
glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)last_texture_ID);
关于报错的问题,C语言和C++语言有所不同。C语言一般只对上面的问题给出警告,而C++语言则会认为这是一个错误。由此也可以看出C++在类型的限定上比C语言更加严格。
14 楼
sunrisefe [专家分:0] 发布于 2007-10-17 21:30:00
直接使用你给出的源码时,因为fopen()是已经不用的函数,所以报错,我改为:
FILE *stream;
errno_t err;
// 打开文件,如果失败,返回
/*fopen_s(&stream,file_name, "rb");*/
if( (err = fopen_s( &stream, file_name, "r" )) !=0 )
{
printf( "The file 'file_name' was not opened\n" );
return 0;
}
else
printf( "The file 'crt_fopen_s.c' was opened\n" );
相应后面的出现pFile的地方都改为stream了,运行时后台也显示出了:The file 'crt_fopen_s.c' was opened\n。 但是最后结果只显示出一白色的图形,没有纹理效果,这是怎么回事呢。
15 楼
sunrisefe [专家分:0] 发布于 2007-10-17 21:37:00
原因出在这里,怎么回事
// 读取像素数据
if( fread(pixels, total_bytes, 1, stream) <= 0 )
{
free(pixels);
fclose(stream);
printf( " 读取像素数据 失败\n" );
return 0;
}
16 楼
sunrisefe [专家分:0] 发布于 2007-10-18 08:43:00
调出来了,楼主发的代码有问题:读取像素时,应该修改成如下,即是将fread的第二三个参数调换位置
// 读取像素数据
if( fread(pixels, 1, total_bytes, stream) <= 0 )
{
free(pixels);
fclose(stream);
printf( " 读取像素数据 失败\n" );
return 0;
}
17 楼
eastcowboy [专家分:25370] 发布于 2007-10-18 09:24:00
回复sunrisefe:
我觉得下面两个语句区别并不大。
fread(pixels, 1, total_bytes, stream)
fread(pixels, total_bytes, 1, stream)
两者都会尝试读取total_bytes个字节的数据,并返回成功读取到的数据数目。前者认为每个数据只有一个字节,总共有total_bytes个数据;后者认为每个数据有total_bytes个字节,总共有一个数据。因此,当数据不足时,前者会认为已经读取到一部分的数据(因为每个数据只有一个字节,即使数据不足,前面部分还是可以用的),因而指针所指的数据有一部分被赋值,函数返回一个大于零且小于total_bytes的值;后者则会认为所有的字节不能构成一个完整的数据,因此一个数据也没有读取到,所以指针所指内容不会被修改,而且函数返回零。
如果你使用我的那个代码遇到问题,而修改为你的形式后工作良好,有可能是因为你的图片文件本身不完整,例如少了一个字节,这样你的代码会认为读取了多数的字节,可以继续工作;而我的代码则认为数据信息不完整,不能继续工作。
18 楼
`凯猪` [专家分:190] 发布于 2008-01-31 22:01:00
向eastcowboy学习!!
19 楼
`凯猪` [专家分:190] 发布于 2008-02-15 13:31:00
=====================TO BE CONTINUED=====================
怎不出了?
期待ing...
20 楼
`凯猪` [专家分:190] 发布于 2008-02-15 14:33:00
调出来了,不过是去掉了个u......
我来回复