ПрограммированиеСтатьиГрафика

Работа с расширениями 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.

Страницы: 1 2 3 Следующая »

#расширения OpenGL, #NVIDIA, #OpenGL

28 марта 2003 (Обновление: 13 ноя 2009)