【问题标题】:How to reclaim memory after glutMainLoop is activated?glutMainLoop激活后如何回收内存?
【发布时间】:2011-06-09 03:08:44
【问题描述】:

根据 OpenGL 文档,
3.1 glutMainLoop

glutMainLoop 进入 GLUT 事件处理循环。

用法

void glutMainLoop(void);

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

所以每当调用 glutMainLoop() 时,它永远不会返回。结果,分配后我无法释放内存。 我的问题是: 我需要从文件中加载图像,本书(Superbible 4th edition)的解决方案是将这个加载文件例程放在绘图函数中。但是,我意识到这种方法过于昂贵,因为需要多次打开和关闭文件。我在学习 B-tree 的数据结构课上回忆,访问外部资源的成本是相当可观的,所以我尽量避免。 所以我的替代解决方案是将这个加载图像例程放在只调用一次的设置场景函数中。但是我现在面临另一个问题,因为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;
}

谢谢,

【问题讨论】:

    标签: c++ opengl glut


    【解决方案1】:

    “推荐”机制是使用atexitonexit函数来调度一个函数在程序退出时被调用:

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

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

    【讨论】:

    • 非常感谢。直到今天才听说过atexit ;)。
    【解决方案2】:

    每个正常的操作系统都会在进程退出后回收进程占用的内存。因此,您无需执行任何操作。当你调用exit时,内存会被释放。


    您的程序运行缓慢的另一个原因是您使用的是glDrawPixels。正确的方法是将图像加载到纹理中(您在进入主循环之前执行此操作),并在显示回调中渲染纹理。这样,您很可能会看到您的程序有很大的改进。

    【讨论】:

    • 虽然这在技术上是准确的,但对于任何类型的析构函数需求的答案都不是通用的并且仅适用于记忆这一事实,我会感到不舒服。
    • @DeadMG 当exit 被调用时,不会调用任何析构函数。但我会将答案扩展为如何实现上述问题
    • 谢谢。使用纹理的想法很棒;)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-03
    • 1970-01-01
    • 2017-06-14
    • 2011-11-03
    • 2019-08-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多