Шаг 35 - Матрицы в OpenGL

Ранее я уже упоминал о понятии матрицы. Нет смысла в этих коротких шагах объяснять основы линейной алгебры. И вообще разводить тут "большую" теорию. Достаточно того, что при помощи некоторых операций над матрицами мы можем перевести координаты из одной системы координат в другую, т.е. в нашем случае из системы координат связанной с моделью (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();

Такая последовательность команд является стандартной, ее логика будет понятна позже, пока не стоит забивать себе голову. По сути дела этот блок делает следующее:


Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Kirill V. Ratkin - 30.05.2000