2011-08-24 60 views
0

如何刪除我製作的所有紋理?假設我加載了幾個紋理:如何刪除一次製作的所有紋理?

GLuint tx_wall,tx_floor,tx_tiles; 
tx_wall=LoadTexture("tex_wall.raw",512,512), 
tx_floor=LoadTexture("tex_floor.raw",512,512), 
tx_tiles=LoadTexture("tex_tiles.raw",512,512); 

然後用它們:

glBindTexture(GL_TEXTURE_2D,tx_wall); 
    glBegin(GL_QUADS); 
    glTexCoord2f(0, 0); glVertex3f(0, 0, 0); 
    glTexCoord2f(1, 0); glVertex3f(0, 50, 0); 
    glTexCoord2f(1, 1); glVertex3f(0, 0, 14); 
    glTexCoord2f(0, 1); glVertex3f(0, 50, 14); 
    glEnd(); 
glBindTexture(GL_TEXTURE_2D,tx_floor); 
    glBegin(GL_QUADS); 
    glTexCoord2f(0, 0); glVertex3f(0, 0, 0); 
    glTexCoord2f(1, 0); glVertex3f(50, 50, 0); 
    glTexCoord2f(1, 1); glVertex3f(50, 50, 0); 
    glTexCoord2f(0, 1); glVertex3f(0, 0, 0); 
    glEnd(); 
(and so on) 

,當遊戲結束時,將其刪除:

glDeleteTextures(1,&tx_wall); 
glDeleteTextures(1,&tx_floor); 
glDeleteTextures(1,&tx_tiles); 

所有工作正常,但如果我有10或20紋理比我將如何終止他們都沒有采取他們的名字?

+2

已經給出了答案(將所有待刪除的紋理名稱放入數組中,將該數組及其長度傳遞給glDeleteTextures)。但是,當你的應用程序結束時,你不需要刪除你的東西。無論如何,OpenGL都使用抽象的對象模型,所以如果你不清除任何內容就終止了這個過程,這並不是某種內存泄漏。刪除紋理名稱只是將紋理名稱從它可能攜帶的任何數據中分離出來(並且驅動程序的垃圾收集器將會清理它,有時候,也許立即) – datenwolf

回答

5

如果將所有紋理標識符放入數組中,可以使用glDeleteTextures在一次調用中全部刪除它們(就像使用glGenTextures可以在一次調用中生成所有紋理標識符一樣)。

GLuint textures[3]; 
glGenTextures(3, textures); 

/* ... */ 

glDeleteTextures(3, textures); 
+0

好的謝謝你,但無論如何刪除那些名字? – CppOgl

+1

@CppOgl:我以爲你要求能夠做到*沒有*他們的名字? –

+0

好吧,我問,如果我可以刪除他們都沒有放入一個數組。 – CppOgl

4

也許不正是你打算,但RAII將是一個明智的選擇:

class Texture 
{ 
public: 
    Texture(const std::string& name, int width, int height) : 
     m_id(LoadTexture(name.c_str(),width,height)) 
    { 
    } 

    ~Texture() 
    { 
     if(m_id) 
      glDeleteTextures(1,&m_id); 
     m_id = 0; 
    } 

    GLuint id() const 
    { 
     return m_id; 
    } 

private: 
    Texture(const Texture&); 
    Texture& operator=(const Texture&); 

    GLuint m_id; 
}; 

用法:

Texture tx_wall("tex_wall.raw",512,512); 
Texture tx_floor("tex_floor.raw",512,512); 
Texture tx_tiles("tex_tiles.raw",512,512); 

和:

glBindTexture(GL_TEXTURE_2D,tx_wall.id()); 
    glBegin(GL_QUADS); 
    glTexCoord2f(0, 0); glVertex3f(0, 0, 0); 
    glTexCoord2f(1, 0); glVertex3f(0, 50, 0); 
    glTexCoord2f(1, 1); glVertex3f(0, 0, 14); 
    glTexCoord2f(0, 1); glVertex3f(0, 50, 14); 
    glEnd(); 
glBindTexture(GL_TEXTURE_2D,tx_floor.id()); 
    glBegin(GL_QUADS); 
    glTexCoord2f(0, 0); glVertex3f(0, 0, 0); 
    glTexCoord2f(1, 0); glVertex3f(50, 50, 0); 
    glTexCoord2f(1, 1); glVertex3f(50, 50, 0); 
    glTexCoord2f(0, 1); glVertex3f(0, 0, 0); 
    glEnd(); 

的好處是你可以只保留紋理只要你需要它們,代碼是異常安全的,紋理髮布是自動的。缺點是你不能複製Texture對象而沒有某種引用計數(爲此我推薦使用boost :: shared_ptr而不是自己滾動,因爲在多線程環境中引用計數很棘手)。後者是私有拷貝構造函數和賦值操作符的原因。

+0

很好的答案。這個問題畢竟是標記爲C++,而不是C - 所以範圍是要走的路! – ltjax

+4

被警告!如果您使用RAII對象來控制OpenGL對象的生命週期,請記住OpenGL函數在OpenGL上下文初始化並變爲最新之前,或在其被銷燬或變爲非當前之前調用_cannot_。所以這個對象不能是全局的,文件靜態的,或者其他類型的東西。 –

+0

@Nicol Bolas好點。 –