Ранее я уже упоминал о понятии матрицы. Нет смысла в этих коротких шагах объяснять основы линейной алгебры. И вообще разводить тут "большую" теорию. Достаточно того, что при помощи некоторых операций над матрицами мы можем перевести координаты из одной системы координат в другую, т.е. в нашем случае из системы координат связанной с моделью (3D) в систему координат связанную с плоскостью отображения (Window). Можно догадаться, что для этих операций существует 2 типа матриц: матрицы модели (modelview) и матирицы проекции (projection). Разумеется все остальные операции в OpenGL: перенос, масштаб, поворот осуществляются тоже при помощи матриц.
В данном примере мы попоробуем заменить стандартную команду glTranslate(...) на свою. Прежде всего подготовим эту "свою" матрицу. Сделаем член класса C...View, навовем его, например, GLfloat mt[4][4];
В конструкторе класса проинициализируем его:
CExampleView::CExampleView() { // TODO: add construction code here memset(mt, 0, 16*sizeof(GLfloat)); mt[0][0] = 1; mt[1][1] = 1; mt[2][2] = 1; mt[3][3] = 1; mt[3][2] = -8; }
(не забудьте обнулить все элементы массива перед его заполнением, к сожалению VС++ не обнуляет статические массивы)
Теперь изменим 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); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum (-1, 1, -1, 1, 3, 10); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMultMatrixf((const GLfloat*)mt); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glRotatef(30.0, 1.0, 0.0, 0.0); glRotatef(70.0, 0.0, 1.0, 0.0); DrawCube(); SwapBuffers(pDC->m_hDC); }
Вместо функции glTranslate поставим glMultMatrix. Как можно заметить ничего при этом не изменилось. Таким образом можно сделать вывод о том, что же делает команда glTranslate. Функция OnDraw притерпела еще одно изменение. В нее добавлено несколько строк:
glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum (-1, 1, -1, 1, 3, 10); glMatrixMode(GL_MODELVIEW); glLoadIdentity();
Такая последовательность команд является стандартной, ее логика будет понятна позже, пока не стоит забивать себе голову. По сути дела этот блок делает следующее: