0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
32, // 32-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
int pixelformat;
if ((pixelformat = ChoosePixelFormat(pDC->GetSafeHdc(), &pfd)) == 0) {
MessageBox("ChoosePixelFormat failed");
return FALSE;
}
if (SetPixelFormat(pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE) {
MessageBox("SetPixelFormat failed");
return FALSE;
}
return TRUE;
}
Как не трудно заметить, она почти полностью взята из Win32API приложения за исключением того, что hDC заменена на pDC->GetSafeHdc().
Теперь добавим в нашу программку обработчик от таймера (мы его недавно сделали в ф-ции Init())
void CBitScrollDlg::OnTimer(UINT nIDEvent) {
DrawScene();
CDialog::OnTimer(nIDEvent);
}
Все тривиально. По смыслу ясно, что каждый раз, когда срабатывает обработчик таймера (а делает он это часто) рисуется сцена. Таким образом получается анимация. Посмотрим на эту функцию:
void CBitScrollDlg::DrawScene() {
static GLfloat angle = 0;
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, –2.0f);
glRotatef(angle, 1.0f, 0.5f, 0.3f);
glBegin(GL_QUADS);
glColor3f(1.0f, 0.0f, 1.0f);
glVertex3f(-0.5f, 0.5f, 0.0f);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(0.5f, 0.5f, 0.0f);
glColor3f(0.0f, 1.0f, 1.0f);
glVertex3f(0.5f, –0.5f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-0.5f, –0.5f, 0.0f);
glEnd();
glFinish();
SwapBuffers(wglGetCurrentDC());
angle += 0.5f;
}
По моему проще уже некуда. Я надеюсь, что все ясно.
Ну вот казалось бы и все. Единственное, что остается сделать – убраться за собой. Т.е. надо при выходе удалить контекст рендеринга и убить таймер.
Эти вещи надо сделать в 2-х обработчиках OnClose и OnDestroy. Посмотрим на них:
void CBitScrollDlg::OnClose() {
// TODO: Add your message handler code here and/or call default
HGLRC hrc;
KillTimer(1);
hrc = ::wglGetCurrentContext();
::wglMakeCurrent(NULL, NULL);
if (hrc) ::wglDeleteContext(hrc);
CDialog::OnClose();
}
и
void CBitScrollDlg::OnDestroy() {
CDialog::OnDestroy();
// TODO: Add your message handler code here
HGLRC hrc;
KillTimer(1);
hrc = ::wglGetCurrentContext();
::wglMakeCurrent(NULL, NULL);
if (hrc) ::wglDeleteContext(hrc);
}
Она практически одинаковые. Работают так же как и case WM_CLOSE в Win32API. Т.е. убиваем таймер, получаем контекст рендеринга, если он есть – удаляем его.
Ну вот и все. Еще добавлю, что в проекте есть функция OnSize для обработки изменений размеров окна. В данном случае она не нужна, но если вставлять OpenGL в SDI или MDI, то она вам понадобится.