載入紋理與使用glGenTextures時應注意的一點(解決吃記憶體)

來源:互聯網
上載者:User
載入紋理與使用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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.