添加代码和变量
1、 #include <stdio.h> :对文件进行操作,后面的代码中使用了 fopen() 。
2、三个浮点变量xrot , yrot 和 zrot:使立方体绕X、Y、Z轴旋转。
3、 Luint texture[1] :为一个纹理分配存储空间。(注意:如果不止一个的纹理,应该将参数1改成所需要的参数。)
在 ReSizeGLScene() 之前增加两个函数
1、加载位图文件
*LoadBMP(char *Filename)
用作纹理的图像标准:宽和高必须是2的n次方;宽度和高度最小必须是64象素;并且出于兼容性的原因,图像的宽度和高度不应超过256象素。如果原始素材的宽度和高度不是64、128、256象素的话,使用图像处理软件重新改变图像的大小。
2、载入位图(调用上面的代码)并转换成纹理(创建多个纹理添加代码处)
LoadGLTextures()
变量Status:跟踪是否能够载入位图以及能否创建纹理。
TextureImage[1]; 存储位图的图像记录,包含位图的宽度、高度和数据。
清除图像记录:memset
载入位图------TextureImage[0]=LoadBMP("Data/NeHe.bmp") (图像的位置,JPG文件不可载入)
(1)创建纹理
现在使用中 TextureImage[0] 的数据创建纹理。
glGenTextures(1, &texture[0])
生成一个纹理名字(如果想载入多个纹理,加大数字)。
注意:第一个纹理就是存放在 &texture[0]中 。同样如果使用 GLuint texture[2] 的话,第二个纹理存放在 texture[1] 中。
glBindTexture(GL_TEXTURE_2D, texture[0])
将纹理名字 texture[0] 绑定到纹理目标上。2D纹理只有高度(在 Y 轴上)和宽度(在 X 轴上)。主函数将纹理名字指派给纹理数据。&texture[0] 处的内存已经可用。创建的纹理将存储在 &texture[0] 的 指向的内存区域。
(2)生成纹理
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data)
GL_TEXTURE_2D:此纹理是一个2D纹理。
参数“0”:图像的详细程度。
参数“3”:数据的成分数。因为图像是由红色数据,绿色数据,蓝色数据三种组分组成。 TextureImage[0]->sizeX :纹理的宽度。也可以自己填入,但计算机可以很容易指出此值。 TextureImage[0]->sizey :纹理的高度。
参数“0”:边框的值。
GL_RGB :图像数据由红、绿、蓝三色数据组成。
GL_UNSIGNED_BYTE :组成图像的数据是无符号字节类型的。
TextureImage[0]->data:纹理数据的来源。指向存放在 TextureImage[0] 记录中的数据。
(3)滤波
当图象放大得比原始的纹理大 ( GL_TEXTURE_MAG_FILTER )或缩小得比原始得纹理小( GL_TEXTURE_MIN_FILTER )时OpenGL采用的滤波方式。
GL_LINEAR :使得纹理从很远处到离屏幕很近时都平滑显示。需要CPU和显卡做更多的运算。
GL_NEAREST:机器很慢时使用 。过滤的纹理在放大的时候,看起来斑驳(马赛克)。
也可以结合这两种滤波方式。在近处时使用 GL_LINEAR ,远处时 GL_NEAREST。
(4)释放前面用来存放位图数据的内存
在 InitGL 中增加代码
纹理创建和启用2D纹理映射。
在 DrawGLScene 中增加代码
1、选择纹理
2、绘制纹理映射过的立方体
glTexCoord2f (X坐标,Y坐标)
第一个参数:0.0f 是纹理的左侧, 0.5f 是纹理的中点, 1.0f 是纹理的右侧。
第二个参数:0.0f 是纹理的底部。 0.5f 是纹理的中点, 1.0f 是纹理的顶部。
按逆时针顺序画
| 纹理 | 四边形 |
左下 | X:0.0f,Y:0.0f | X: -1.0f,Y:-1.0f |
右下 | X:1.0f,Y:0.0f | X: 1.0f,Y:-1.0f |
右上 | X:1.0f,Y:1.0f | X: 1.0f,Y:1.0f |
左上 | X:0.0f,Y:1.0f | X: -1.0f,Y:1.0f |
3、贴不同的纹理注意
A 如果在场景中使用多个纹理,应使用 glBindTexture(GL_TEXTURE_2D, texture[所使用纹理对应的数字]) 选择要绑定的纹理。
B当想改变纹理时,应该绑定新的纹理。不能在 glBegin() 和 glEnd() 之间绑定纹理,必须在 glBegin() 之前或 glEnd() 之后绑定。
其它
1、memest原型
void *memset(void *s, int c, size_t n)
作用:在一段内存块中填充某个给定的值,它对较大的结构体或数组进行清零操作的一种最快方法。
2、全局、静态变量初始值一般默认为0。