2011-06-08 53 views
3

根據OpenGL的文檔,
3.1 glutMainLoop如何在glutMainLoop激活後回收內存?

glutMainLoop進入GLUT事件處理循環。

用法

void glutMainLoop(void); 

說明 glutMainLoop進入GLUT事件處理循環。這個例程在GLUT程序中最多隻能調用一次。一旦被調用,這個例程永遠不會返回。它會根據需要調用任何已經註冊的回調。

因此,只要調用glutMainLoop(),它就永遠不會返回。因此,分配後我無法釋放我的記憶。 我的問題是: 我需要從文件中加載圖像,本書(Superbible 4th edition)解決方案是將此加載文件例程放入繪圖函數中。但是,由於多個打開和關閉文件,我意識到這種方法太昂貴了。我在研究B樹時從我的數據結構類中回憶,訪問外部資源的成本相當可觀,所以我儘量避免。 所以我的替代解決方案是將此加載圖像例程放入設置的場景函數中,該函數僅調用一次。但是現在我面臨另一個問題,因爲glutMainLoop,我沒有辦法刪除內存。 在這種情況下我能做些什麼?我是新來的OpenGL,所以我真的不知道如何處理這個特定的問題。任何想法將不勝感激。

#include <cstdio> 
#include <cstdlib> 
#include <iostream> 

#include "Utility.h" 
#include "TgaHeader.h" 
#include "TgaImage.h" 

#include <GL/glut.h> 

using namespace std; 

TgaImage* image = NULL; 

void setupScene() { 
    // set color background 
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
    // load image from file 
    image = loadTgAFile("Fire.tga"); 
} 

void renderScene() { 
    // clear color 
    glClear(GL_COLOR_BUFFER_BIT); 
    // TGA format is 1 byte aligned 
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
    glRasterPos2i(0, 0); 
    if(image != NULL) { 
     glDrawPixels( 
      image->header.width, 
      image->header.height, 
      image->format, 
      GL_UNSIGNED_BYTE, 
      image->pixels 
     ); 
    } 
    glutSwapBuffers(); 
} 

void resizeWindow(int w, int h) { 
    if(h == 0) { 
     h = 1; 
    } 
    glViewport(0, 0, w, h); 
    // reset coordinate before modifying 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    // set the clipping volume 
    gluOrtho2D(0.0f, w, 0.0f, h); 
    // reset to modelview matrix 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
} 

int main(int argc, char** argv) { 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); 
    glutInitWindowSize(512, 512); 
    glutCreateWindow("Image"); 
    // register callback 
    glutReshapeFunc(resizeWindow); 
    glutDisplayFunc(renderScene); 
    // initialize scene 
    setupScene(); 
    glutMainLoop(); 
    // it will never reach this 
    delete image; 
} 

感謝,

回答

6

「推薦」的機制是使用atexitonexit功能調度功能的程序退出時被調用:

void exitProgram() { 
    // cleanup code 
} 

// then put this in main(): 
atexit(exitProgram); 

注意,一旦當程序退出時,操作系統會清除程序正在使用的所有資源,包括內存,所以它在技術上不會泄漏內存。

+1

非常感謝。直到今天,從未聽說過「atexit」;)。 – Chan 2011-06-08 01:31:35

2

每個正常的操作系統在退出後都會回收進程佔用的內存。因此,你不需要做任何事情。當您撥打exit時,內存將被釋放。


爲什麼你的程序很慢的另一個原因是因爲你正在使用glDrawPixels。正確的方法是將圖像加載到紋理中(在進入主循環之前執行),並在顯示回調中渲染紋理。這樣,你很可能會看到你的程序有很大的改進。

+0

儘管這在技術上是準確的,但我對於這樣一個事實感到不舒服:答案對於任何類型的析構函數都是非泛型的,並且只適用於內存。 – Puppy 2011-06-08 17:43:19

+0

@DeadMG當'exit'被調用時,不會調用析構函數。但我會延長答案,因爲我將如何執行上述問題 – 2011-06-08 19:06:08

+0

謝謝。使用紋理的想法很棒;)。 – Chan 2011-06-08 19:29:38