Работа с расширениями OpenGL с использованием NVIDIA OpenGL SDK 5.1. (Часть 5) (2 стр)
Автор: Сергей Гайдуков
Создание шаблона простейшей GLH-программы
Для начала мы создадим простой аналог программы Ex06 из статьи "GLUT - расширение OpenGL". Для этого достаточно добавить в пример Ex01 следующий код:
void Display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
mouse.apply_transform();
glRotatef(rr, 0, 1, 0);
glCallList(mylist);
glPopMatrix();
if (bIdle)
{
FramesCount++;
char Title[80];
if (GetTickCount()!=StartTick)
{
sprintf(Title, "FPS=%f", float(FramesCount)*1000/(GetTickCount()-StartTick));
glutSetWindowTitle(Title);
}
}
glutSwapBuffers();
}void KeyboardSpecial(int key, int x, int y) { switch ( key) { case GLUT_KEY_F2: bIdle=!bIdle; if ( bIdle) { OldTick=GetTickCount( ); StartTick=OldTick; FramesCount=0; mouse.disable( ); glut_idle( true); } else { mouse.enable( ); glut_idle( false); } break; }; } void Idle( ) { rr+=( GetTickCount( )-OldTick)*0.1; OldTick=GetTickCount( ); if ( rr>360) rr-=360; glutPostRedisplay( ); }
Обратите внимание, что для включения и выключения обработки сообщений от мыши используются методы enable() и disable() объекта mouse.
Код стал намного меньше и понятнее. В принципе, мы могли бы использовать его в качестве шаблона для будущих примеров. Но при анализе этих примеров пользователь будет все время натыкаться на фрагменты кода, отвечающего за вычисление FPS и прочие вспомогательные операции, которые, с одной стороны, не относятся к делу, а с другой - облегчают работу с этим примером. Лучшим решением этой проблемы будет инкапсуляция кода в пользовательском интеракторе (Ex04).
Сначала надо создать класс glut_simple_user_interface, производный от glut_interactor, после чего перегрузить виртуальные функции display(), idle(), keyboard() и special() и поместить в них обработчики одноименных событий. При этом в обработчике display() надо заменить код вывода сцены на экран следующим кодом:
glLoadIdentity();
mouse.apply_transform();
glRotatef(rr, 0, 1, 0);
Остается поместить в состав класса переменные, которые используют его обработчики событий, и мы получим готовый интерактор (для экономии места приводится только объявление класса интерактора):
class glut_simple_user_interface:public glut_interactor { public: glut_simple_mouse_interactor mouse; glut_perspective_reshaper reshaper; GLuint FramesCount; GLuint OldTick; GLuint StartTick; bool bIdle; GLuint rr; glut_simple_user_interface(); virtual void display( ); virtual void idle( ); virtual void keyboard( unsigned char k, int x, int y); virtual void special( int key, int x, int y); };
Чтобы не загромождать код главного модуля программы (файл main.cpp), описание интерактора лучше поместить в отдельный заголовочный файл (glh_glut_ext.h).
Теперь остается немного модифицировать главную часть программы. Для этого из программы убирается код, который был помещен в интерактор glut_simple_user_interface. Кроме того, уничтожение дисплейного списка теперь происходит в обработчике ExitProc:
...
#include "glh_glut_ext.h" GLuint WinWidth=640; GLuint WinHeight=480; GLuint mylist=0; glut_simple_user_interface user; glut_callbacks cb; void Init() { glEnable( GL_DEPTH_TEST); glEnable( GL_LIGHTING); glEnable( GL_LIGHT0); glEnable( GL_COLOR_MATERIAL); glColor3f( 0.1,0.7,0.2); glClearColor( 0.5, 0.5, 0.75, 1); mylist=glGenLists( 1); glNewList( mylist, GL_COMPILE); glutSolidTeapot( 2); glEndList( ); } void Display( ) { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glCallList( mylist); glutSwapBuffers( ); } void ExitProc( void) { glDeleteLists( mylist, 1); } int main( int argc, char* argv[]) { glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize( WinWidth,WinHeight); glutInitWindowPosition( ( glutGet( GLUT_SCREEN_WIDTH)-WinWidth)/2, ( glutGet( GLUT_SCREEN_HEIGHT)-WinHeight)/2); glutCreateWindow( "GLH Teapot"); Init( ); atexit( ExitProc); glut_helpers_initialize( ); cb.display_function=Display; glut_add_interactor( &user); glut_add_interactor( &cb); glutMainLoop( ); return 0; }
Теперь программа стала еще проще - объем файла main.cpp уменьшился в 4.5 раза по сравнению с примером Ex06.
#расширения OpenGL, #NVIDIA, #OpenGL
28 марта 2003 (Обновление: 13 ноя 2009)