加载纹理与使用glGenTextures时应注意的一点(解决吃内存)[转]

转载 2012年03月29日 15:41:20

加载纹理与使用glGenTextures时应注意的一点(解决吃内存)[转]

glGenTextures

  glGenTextures(GLsizei n, GLuint *textures)函数说明
 
n:用来生成纹理的数量
 
textures:存储纹理索引的
 
glGenTextures函数根据纹理参数返回n个纹理索引。纹理名称集合不必是一个连续的整数集合。
 
(glGenTextures就是用来产生你要操作的纹理对象的索引的,比如你告诉OpenGL,我需要5个纹理对象,它会从没有用到的整数里返回5个给你)
 
glBindTexture实际上是改变了OpenGL的这个状态,它告诉OpenGL下面对纹理的任何操作都是对它所绑定的纹理对象的,比如glBindTexture(GL_TEXTURE_2D,1)告诉OpenGL下面代码中对2D纹理的任何设置都是针对索引为1的纹理的。
 
产生纹理函数假定目标纹理的面积是由glBindTexture函数限制的。先前调用glGenTextures产生的纹理索引集不会由后面调用的glGenTextures得到,除非他们首先被glDeleteTextures删除。你不可以在显示列表中包含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的接口,可以从外面读取视频帧并传给这个函数,绑定纹理, 使用起来比较灵活。

分类: OpenGL ES

《高效学习OpenGL》 之 纹理对象 glGenTextures(),glIsTexture(),glBindTexture(),glDeleteTextures()

命名纹理对象: void glGenTextures (GLsizei n, GLuint *textures); //在数组textures中返回n个当期未使用的值,表示纹理对象的名称...
  • huangbangqing12
  • huangbangqing12
  • 2014-02-28 11:25:08
  • 4422

OpenGL ES glGenTextures返回值为0

最近在Android的一个项目要用到OpenGL ES,自己对于图形引擎这块又不了解,顶多就是看过点DirectX,不过也是挺久以前的了,早忘完了。 想着这下完了,肯定又得掉坑。 坑确实多,不过大...
  • u011810659
  • u011810659
  • 2017-07-30 20:06:53
  • 501

OpenGL绘制纹理时,glGenTextures()函数带来的内存泄露,使程序被杀死。

项目中,我需要定时的去更换纹理图片,贴到指定的位置。我就理所当然的写了一个函数,然后定时去执行一次该函数。 函数中有代码:             glPixelStorei(GL_UNPACK_...
  • gagabook
  • gagabook
  • 2016-09-02 13:58:55
  • 2062

opengl glBindTexture为何失败

半年没有写点东西总结下了。有时候脑中想法很多,却又感觉文字功底着实有限,无法把自由散漫的思想分门别类地记下来,好在可以与人交流,掏空自己,然后吸收些新东西;有时候却什么都不想,就翻翻书,享受前人的精神...
  • C__Allen
  • C__Allen
  • 2013-12-31 10:32:50
  • 2923

glGenTextures(GLsizei n, GLuint *textures)函数说明

BOOL LoadTextures(IplImage *pImage, GLuint *pTexture) { int Status=FALSE; if(pImage != NULL)...
  • gggg_ggg
  • gggg_ggg
  • 2014-12-29 16:12:10
  • 937

glGenTextures

参考: http://blog.163.com/qiang_zx/blog/static/4321934200781693752845/glGenTextures (GLsizei n, GLuin...
  • thufreshman
  • thufreshman
  • 2010-08-19 22:46:00
  • 3067

OpenGL函数思考-glGenTextures

OpenGL函数思考-glGenTextures函数原型:      void glGenTextures(GLsizei n, GLuint *textures)参数说明:      n:用来生成纹...
  • shuaihj
  • shuaihj
  • 2012-02-09 09:37:32
  • 7987

GLSurfaceView中GL相关资源销毁问题

GLSurfaceView中GL相关资源销毁问题
  • dizuo
  • dizuo
  • 2015-02-13 16:20:32
  • 3558

OpenGL学习笔记-2015.4.1——纹理加载与控制

在纹理贴图技术问世之前,虚拟3维世界只能通过几何模型去模拟现实,可想而知,现实世界的错综复杂,计算量之大并不能满足实时显示的需求。纹理映射带来了革命性的变换,简单的使得虚拟的3维世界得以无限接近于现实...
  • coderling
  • coderling
  • 2015-04-05 18:18:37
  • 3108

OpenGL学习脚印: 帧缓冲对象(Frame Buffer Object)

写在前面 一直以来,我们在使用OpenGL渲染时,最终的目的地是默认的帧缓冲区,实际上OpenGL也允许我们创建自定义的帧缓冲区。使用自定义的帧缓冲区,可以实现镜面,离屏渲染,以及很酷的后...
  • ziyuanxiazai123
  • ziyuanxiazai123
  • 2016-09-03 14:42:29
  • 4008
收藏助手
不良信息举报
您举报文章:加载纹理与使用glGenTextures时应注意的一点(解决吃内存)[转]
举报原因:
原因补充:

(最多只允许输入30个字)