В этом шаге нарисуем кубик и посмотрим как влияют установки вида на вид кубика.
Как обычно делаем проект. Добавим в проект 2 переменных: m_iMode - определяет режим вывода граней куба, m_fFar - определяет дальнее расстояние границ пространства.
Для упрощения функции OnDraw(...) добавим функцию DrawCube(void), которая будет просто рисовать куб, отрисовывая последовательно все его 6 граней. Чтобы посмотреть разные режимы отображения полигонов сделаем пункт меню (View->Mode) и сделаем его (меню) обработчик, который будет изменять режим. Вот его код:
void CExampleView::OnViewMode() { // TODO: Add your command handler code here if(m_iMode>=2) m_iMode = 0; else m_iMode++; InvalidateRect(NULL, FALSE); }
Комментарии излишни. Теперь сделаем обработчик от клавиатуры. Напишем его так, чтобы при нажатии на стрелку вверх дальняя граница пространства отодвигалась, а при нажатии на стрелку вниз - приближалась. Допустим такой код:
void CExampleView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default if(nChar==VK_UP) m_fFar+=0.5f; if(nChar==VK_DOWN) m_fFar-=0.5f; InvalidateRect(NULL, FALSE); CView::OnKeyDown(nChar, nRepCnt, nFlags); }
Разумеется, незабудьте создать переменные m_iMode и m_fFar и проинициализировать их в конструкторе.
Теперь наша многострадальная функция OnDraw(...) примет следующий вид:
void CExampleView::OnDraw(CDC* pDC) { CRect clientRect; CExampleDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here GetClientRect(&clientRect); glViewport(0, 0, clientRect.right, clientRect.bottom); glClearColor (0.5, 0.5, 0.75, 1.0); glClear (GL_COLOR_BUFFER_BIT); glColor3f (1.0, 0.0, 0.5); glLoadIdentity(); glFrustum (-1, 1, -1, 1, 3, m_fFar); glTranslatef(0.0, 0.0, -8.0); glRotatef(30.0, 1.0, 0.0, 0.0); glRotatef(70.0, 0.0, 1.0, 0.0); switch(m_iMode) { case 0: glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break; case 1: glEnable(GL_POINT_SMOOTH); glPointSize(10); glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); break; case 2: glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break; } DrawCube(); SwapBuffers(pDC->m_hDC); }
Где функция DrawCube(void) выглядит так:
GLvoid CExampleView::DrawCube() { glBegin (GL_QUADS); glVertex3f (1.0, 1.0, 1.0); glVertex3f (-1.0, 1.0, 1.0); glVertex3f (-1.0, -1.0, 1.0); glVertex3f (1.0, -1.0, 1.0); glEnd(); glBegin (GL_QUADS); glVertex3f (1.0, 1.0, -1.0); glVertex3f (1.0, -1.0, -1.0); glVertex3f (-1.0, -1.0, -1.0); glVertex3f (-1.0, 1.0, -1.0); glEnd(); glBegin (GL_QUADS); glVertex3f (-1.0, 1.0, 1.0); glVertex3f (-1.0, 1.0, -1.0); glVertex3f (-1.0, -1.0, -1.0); glVertex3f (-1.0, -1.0, 1.0); glEnd(); glBegin (GL_QUADS); glVertex3f (1.0, 1.0, 1.0); glVertex3f (1.0, -1.0, 1.0); glVertex3f (1.0, -1.0, -1.0); glVertex3f (1.0, 1.0, -1.0); glEnd(); glBegin (GL_QUADS); glVertex3f (-1.0, 1.0, -1.0); glVertex3f (-1.0, 1.0, 1.0); glVertex3f (1.0, 1.0, 1.0); glVertex3f (1.0, 1.0, -1.0); glEnd(); glBegin(GL_QUADS); glVertex3f (-1.0, -1.0, -1.0); glVertex3f (1.0, -1.0, -1.0); glVertex3f (1.0, -1.0, 1.0); glVertex3f (-1.0, -1.0, 1.0); glEnd(); }
Единственная особенность новой OnDraw(...) - это 2 команды glRotatef(...), которые просто поворачивают систему координат для удобного простора объекта. Если вы закомментируете эти функции, станет понятно их предназначение.
Вот собственно и все. Соберите проект и понажимайте стрелки...