加载纹理与使用glGenTextures时应注意的一点

加载纹理与使用glGenTextures时应注意的一点_风之忧伤_新浪博客,风之忧伤,

注:该文所描述的问题应该是内存泄漏引起的,分配了纹理而没有释放掉,小时候胡乱写的,见笑了

void glGenTextures(GLsizei n, GLuint *texture);

该函数用来产生纹理名称。这里纹理名称GLuint *texture是整型的,因此也可以理解为这个函数为这n个纹理指定了n个不同的ID。

在用GL渲染的时候,纹理是很常见的东西。使用纹理之前,必须执行这句命令为你的texture分配一个ID,然后绑定这个纹理,加载纹理图像,这之后,这个纹理才可以使用。加载纹理的代码如下:

BOOL LoadTextures(IplImage *pImage, GLuint *pTexture)
{
   int Status=FALSE;
   if(pImage != NULL)
   {
       Status=TRUE;

       glGenTextures(1, &pTexture[0]); //注意这里
       glBindTexture(GL_TEXTURE_2D, pTexture[0]);
       glTexImage2D(GL_TEXTURE_2D, 0, 3,
                    pImage->width, pImage->height,
                    0, GL_BGR, GL_UNSIGNED_BYTE, (unsigned char *)pImage->imageData);
       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
   }
   return Status;
}

   使用上面这个函数时需要小心,这个函数只能放在循环外面使用!如果你想在循环中重复利用这个texture[0],给它加载不同的纹理(比如,你想在窗口 中显示序列图像),而把这个函数放在循环内部调用的话,那么当程序循环足够多次之后,你的电脑将变得巨慢无比,甚至导致死机。原因就是反复地调用 glGenTextures(1, &pTexture[0])。这个问题产生的机制我并不清楚,但是我今天实实在在的遇到了。

   所以,上面这个函数一般都是放在循环外面,窗口初始化的时候,用于给背景加载纹理。那么,如果我必须要在循环中渲染序列帧的话,该怎么做呢?我们可以对上面的函数加一点小小的改变,如下:

BOOL LoadTextures(IplImage *pImage, GLuint texture)
{
   int Status=FALSE;
   if(pImage != NULL)
   {
       Status=TRUE;
       glBindTexture(GL_TEXTURE_2D, texture);
       glTexImage2D(GL_TEXTURE_2D, 0, 3,
                    pImage->width, pImage->height,
                    0, GL_BGR, GL_UNSIGNED_BYTE, (unsigned char *)pImage->imageData);
       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
   }
   return Status;
}

在窗口初始化的时候先执行一遍:

glGenTextures(1, &texture[0]);

然后在你的循环内部调用:

IplImage *videoFrame = cvQueryFrame(capture);

LoadTextures(videoFrame, texture[0]);

这样就可以显示图像帧了,也不会再出现电脑运行速度变慢的问题了。总之,千万不要给一个texture重复分配ID。

   我自己写的这个LoadTextures函数提供了图像buffer的接口,可以从外面读取视频帧并传给这个函数,绑定纹理, 使用起来比较灵活。

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏