Ответ 1
OpenGL использует несколько матриц для преобразования геометрии и связанных данных. Этими матрицами являются:
- Modelview - помещает геометрию объекта в глобальное непроецируемое пространство
- Проекция - проектирует глобальные координаты в пространстве клипов; вы можете подумать об этом как о объективе
- Текстура - корректирует координаты текстуры раньше; в основном используется для реализации текстурной проекции (т.е. проецирования текстуры, как если бы это был слайд в проекторе).
- Цвет - регулирует цвета вершин. Редко касался вообще
Все эти матрицы используются все время. Поскольку они соответствуют всем тем же правилам, OpenGL имеет только один набор функций манипуляции матрицами: glPushMatrix
, glPopMatrix
, glLoadIdentity
, glLoadMatrix
, glMultMatrix
, glTranslate
, glRotate
, glScale
, glOrtho
, glFrustum
.
glMatrixMode
выбирает, на какой матрице действуют эти операции. Предположим, вы хотели написать некоторую оболочку имен на С++, это может выглядеть так:
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;
}
Позже в программе на С++ вы можете записать
void draw_something()
{
OpenGL::Projection::LoadIdentity();
OpenGL::Projection::Frustum(...);
OpenGL::Modelview::LoadIdentity();
OpenGL::Modelview::Translate(...);
// drawing commands
}
К сожалению, С++ не может создавать пространства имен шаблонов или применять using
(или with
) к экземплярам (другие языки имеют это), иначе я написал что-то вроде (недопустимый С++)
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.