在opengl中实现三维物体的纹理贴图的第一步就是要读入图片,然后指定该图片为纹理图片。我最早接手的项目中是通过一个专门的读取bmp图片的函数来实现纹理图片的读取的。这个函数有三个缺点:
1、只能读取bmp的图片,无法读取jpg,ppm等其他类型的图片,要想使用其他类型的图片,必须事先将他们转化成bmp的图片;
2、只能读取2的幂次方宽和2的幂次方长的大小的图片,否则函数无法正确读取图片内容;
3、只能读取24位的bmp图片。
上述三个缺点使我们的程序有了很大的局限性。为此,在学习了opencv之后,我利用opencv中的cvloadimage()函数解决了上述问题。
我们的解决方法如下:
首先利用下面这行代码将图片读取到内存中:
IplImage * Iface = cvLoadImage(szFileName);
然后利用下面代码在内存中开辟一个跟读入图片大小相同的内存空间:
m_new_face_BMPbytes = (unsigned char *)malloc(sizeof(unsigned char)*Iface->imageSize);
如果我们读取的是24位的rgb彩色图片,那么Iface->imageSize几位图片的像素大小乘以3,比如我们的图片是512*512大小的那么Iface->imageSize就是512*512*3.
接着我们利用下面的代码将Iface中的图片的实际数据部分拷贝到我们制定的内存空间中:
memcpy(m_new_face_BMPbytes,Iface->imageData,sizeof(unsigned char)*Iface->imageSize);
Iface->imageData为存储图片像素数据的空间的首地址
然后我们保存图片的大小:
m_new_face_width = Iface->width;
m_new_face_Height = Iface->height;
最后我们设置将m_new_face_BMPbytes指向的图片数据制定为opengl中的纹理图片:
glGenTextures(1, &m_texName); //1表示生成纹理的数量,m_texName用来存储生成纹理的索引,在绑定纹理的时候用到
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, m_new_face_width, m_new_face_Height, 0,
GL_BGR_EXT, GL_UNSIGNED_BYTE, m_new_face_BMPbytes);
这样我们就完成了将我们读入的图片设置成为opengl的纹理图片的设置了。