根据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;
}
谢谢,
答案 0 :(得分:6)
“推荐”机制是使用atexit
或onexit
函数来安排在程序退出时调用的函数:
void exitProgram() {
// cleanup code
}
// then put this in main():
atexit( exitProgram );
请注意,一旦程序退出,操作系统就会清除程序正在使用的所有资源,包括内存,因此技术上不会泄漏内存。
答案 1 :(得分:2)
每个正常的操作系统都会在退出后回收进程占用的内存。因此,您不需要做任何事情。当你拨打exit
时,内存将被释放。
您的程序运行缓慢的另一个原因是您正在使用glDrawPixels
。一种正确的方法是将图像加载到纹理中(在进入主循环之前执行),并在显示回调中渲染纹理。这样,您很可能会看到您的计划有了很大改进。