OpenGL использует несколько матриц для преобразования геометрии и связанных данных.Эти матрицы:
- ModelView - помещает геометрию объекта в глобальное пространство, не проецируется пространство
- Проекция -проецирует глобальные координаты в пространство клипа;Вы можете думать об этом как о типе линзы
- Текстура - прежде чем настраивать координаты текстуры;в основном используется для реализации текстурного проецирования (т.е. проецирования текстуры, как если бы она была слайдом в проекторе)
- Цвет - регулирует цвета вершин.Крайне редко трогает
Все эти матрицы используются постоянно.Поскольку они следуют одним и тем же правилам, OpenGL имеет только один набор функций для работы с матрицами: glPushMatrix
, glPopMatrix
, glLoadIdentity
, glLoadMatrix
, glMultMatrix
, glTranslate
, glRotate
, glScale
, glOrtho
, glFrustum
.
glMatrixMode
выбирает, на какую матрицу будут действовать эти операции.Скажем, вы хотели написать какую-нибудь оболочку для пространства имен C ++, это могло бы выглядеть так:
namespace OpenGL {
// A single template class for easy OpenGL matrix mode association
template<GLenum mat> class Matrix
{
public:
void LoadIdentity() const
{ glMatrixMode(mat); glLoadIdentity(); }
void Translate(GLfloat x, GLfloat y, GLfloat z) const
{ glMatrixMode(mat); glTranslatef(x,y,z); }
void Translate(GLdouble x, GLdouble y, GLdouble z) const
{ glMatrixMode(mat); glTranslated(x,y,z); }
void Rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) const
{ glMatrixMode(mat); glRotatef(angle, x, y, z); }
void Rotate(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) const
{ glMatrixMode(mat); glRotated(angle, x, y, z); }
// And all the other matrix manipulation functions
// using overloading to select proper OpenGL variant depending on
// function parameters, and all the other C++ whiz.
// ...
};
//
const Matrix<GL_MODELVIEW> Modelview;
const Matrix<GL_PROJECTION> Projection;
const Matrix<GL_TEXTURE> Texture;
const Matrix<GL_COLOR> Color;
}
Позже в программе на C ++ вы могли бы написать
void draw_something()
{
OpenGL::Projection::LoadIdentity();
OpenGL::Projection::Frustum(...);
OpenGL::Modelview::LoadIdentity();
OpenGL::Modelview::Translate(...);
// drawing commands
}
К сожалению, C ++ не может шаблонироватьпространства имен, или применить using
(или with
) к экземплярам (другие языки имеют это), в противном случае я написал бы что-то вроде (недействительный C ++)
void draw_something_else()
{
using namespace OpenGL;
with(Projection) { // glMatrixMode(GL_PROJECTION);
LoadIdentity(); // glLoadIdentity();
Frustum(...); // glFrustum(...);
}
with(Modelview) { // glMatrixMode(GL_MODELVIEW);
LoadIdentity(); // glLoadIdentity();
Translate(...); // glTranslatef(...);
}
}
Я думаю, что это последний фрагмент (псевдо-) код проясняет: glMatrixMode
является своего рода with
оператором OpenGL.