Как восстановить память после активации glutMainLoop? - PullRequest
3 голосов
/ 08 июня 2011

Согласно документации OpenGL,
3.1 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;
}

Спасибо,

Ответы [ 2 ]

6 голосов
/ 08 июня 2011

«Рекомендуемый» механизм заключается в использовании функции atexit или onexit для планирования функции, вызываемой при выходе из программы:

void exitProgram() {
    // cleanup code
}

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

Обратите внимание, что как только программа выходит из программыоперационная система очищает все ресурсы, включая память, которые использовала программа, так что это не технически утечка памяти.

2 голосов
/ 08 июня 2011

Каждая нормальная операционная система будет освобождать память, занятую процессом, после его выхода.Поэтому вам не нужно ничего делать.Когда вы звоните exit, память освобождается.


Другая причина, по которой ваша программа работает медленно, заключается в том, что вы используете glDrawPixels.Правильным способом было бы загрузить изображение в текстуру (вы делаете это перед входом в основной цикл), а в обратном вызове дисплея визуализировать текстуру.Таким образом, вы, скорее всего, увидите значительное улучшение вашей программы.

...