根据OpenGL文档,
3.1 glutMainLoop
glutMainLoop进入GLUT事件处理循环。
用法
void glutMainLoop(void);
说明
glutMainLoop进入GLUT事件处理循环。此例程在GLUT程序中最多应调用一次。一旦被调用,该例程将永远不会返回。它将在必要时调用已注册的任何回调。
因此,每当调用glutMainLoop()时,它将永远不会返回。结果,分配后我无法释放内存。
我的问题是:
我需要从文件中加载图像,这本书(Superbible 4th Edition)的解决方案是将此加载文件例程放入绘图函数中。但是,由于多个打开和关闭文件,我意识到这种方法太昂贵了。我在学习B树时从数据结构类(class)中记忆起,访问外部资源的成本相当可观,因此我会尽量避免。
因此,我的替代解决方案是将此加载图像例程放入设置场景函数中,该函数仅调用一次。但是后来我又遇到了另一个问题,由于
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;
}
谢谢,
最佳答案
“推荐”机制是使用atexit
或onexit
函数来安排程序退出时要调用的函数:
void exitProgram() {
// cleanup code
}
// then put this in main():
atexit( exitProgram );
请注意,一旦程序退出,操作系统就会清理程序正在使用的所有资源,包括内存,因此从技术上讲,它不会泄漏内存。