glutMainLoop激活后如何回收内存?

发布于 2024-11-14 19:07:21 字数 2244 浏览 5 评论 0原文

根据 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;
}

谢谢,

According to OpenGL documentation,
3.1 glutMainLoop

glutMainLoop enters the GLUT event processing loop.

Usage

void glutMainLoop(void);

Description
glutMainLoop enters the GLUT event processing loop. This routine should be called at most once in a GLUT program. Once called, this routine will never return. It will call as necessary any callbacks that have been registered.

So whenever glutMainLoop() is called, it will never return. As consequence, I could not release my memory after allocating.
My problem is:
I need to load an image from file, the book (Superbible 4th edition) solution is to put this loading file routine inside the drawing function. However, I realized this method was too expensive due to multiple opening and closing files. I recalled from my Data structure class when studying B-tree, the cost of accessing external resources is considerable, so I try to avoid as much as I can.
So my alternative solution is to put this loading image routine inside the set up scene function which is called only once. But then I now face another issue, there is no way I delete memory because of the glutMainLoop.
What can I do in this situation? I'm new to openGL so I really don't know to how to handle this particular problem. Any idea would be greatly appreciated.

#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;
}

Thanks,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

塔塔猫 2024-11-21 19:07:21

“推荐”机制是使用 atexitonexit 函数来安排程序退出时调用的函数:

void exitProgram() {
    // cleanup code
}

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

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

The "recommended" mechanism is to use the atexit or onexit function to schedule a function to be called when the program is exiting:

void exitProgram() {
    // cleanup code
}

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

Note that as soon as a program exits, the operating system cleans up all resources, including memory, that the program was using, so it's not technically leaking memory.

素年丶 2024-11-21 19:07:21

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


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

Every normal operating system is going to reclaim a memory occupied by a process after it exit. Therefore, you do not need to do anything. When you call exit, the memory will be released.


Another reason why your program is slow is because you are using glDrawPixels. A proper way would be to load the image in a texture (you do it before entering the main loop), and in the display callback render the texture. This way, you would most likely see great improvement of your program.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文