glutMainLoop激活后如何回收内存?
根据 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
“推荐”机制是使用
atexit
或onexit
函数来安排程序退出时调用的函数:请注意,一旦程序退出,操作系统会清理程序正在使用的所有资源,包括内存,因此从技术上讲它不会泄漏内存。
The "recommended" mechanism is to use the
atexit
oronexit
function to schedule a function to be called when the program is exiting: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.
每个正常的操作系统都会在进程退出后回收其占用的内存。因此,您不需要执行任何操作。当你调用
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.