如何在glutMainLoop被激活后回收内存

How to reclaim memory after glutMainLoop is activated?

本文关键字:内存 激活 glutMainLoop      更新时间:2023-10-16

根据OpenGL文档,
3.1 glutMainLoop

glutMainLoop进入GLUT事件处理循环。

用法

void glutMainLoop(void);

描述glutMainLoop进入GLUT事件处理循环。在GLUT程序中,此例程最多应调用一次。一旦调用,此例程将永远不会返回。它将根据需要调用任何已注册的回调。

因此,无论何时调用glutMainLoop(),它都不会返回。因此,分配后我无法释放内存。我的问题是:我需要从文件中加载图像,这本书(Superbible第4版)的解决方案是将这个加载文件的例程放入绘图功能中。然而,由于打开和关闭多个文件,我意识到这种方法过于昂贵。我回忆说,在学习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;
}

谢谢,

"推荐"机制是使用atexitonexit函数来调度程序退出时要调用的函数:

void exitProgram() {
    // cleanup code
}
// then put this in main():
atexit( exitProgram );

请注意,一旦程序退出,操作系统就会清理程序正在使用的所有资源,包括内存,因此从技术上讲,它不会泄漏内存。

每个正常的操作系统都会在进程退出后回收其占用的内存。因此,您不需要做任何事情。当您调用exit时,内存将被释放。


程序速度慢的另一个原因是您使用的是glDrawPixels。一种合适的方法是在纹理中加载图像(在进入主循环之前进行),并在显示回调中渲染纹理。这样,你很可能会看到你的程序有很大的改进。