OpenGL для начинающих

// mode =
 // GL_MODELVIEW - выбрать видовую матрицу
 // GL_PROJECTION - выбрать матрицу проекций
 // GL_TEXTURE - выбрать матрицу текстур
 glMatrixMode(<mode>);
По умолчанию все матрицы нулевые, поэтому при инициализации их заполняем,разумеется выбрав сначала тип матрицы.Можно заполнить какой-то конкретной или просто единичной, как в MyOpenGL.glInit.(Единичная - это та, у которой на диагонали единицы, а остальные нули). // отличие glLoadMatrixf от glLoadMatrixg заключается в том, как будет // восприниматься входной массив, определяющий матрицу // так - <строка1>, <строка2>, <строка3>, <строка4> // или так - <столбец1>, <столбец2>, <столбец3>, <столбец4> glLoadMatrixf(<указатель на массив из 16 элементов типа double>); или glLoadMatrixg(<указатель на массив из 16 элементов типа double>); или glLoadIdentity(); // заполнение единичной " Часто нужно сохранить содержимое текущей матрицы для дальнейшего использования, для чего используют команды" glPushMatrix(); // сохранить матрицу (в стеке) glPopMatrix(); // извлечь матрицу (из стека) Вспоминаем, что такое стек )Для GL_MODELVIEW-матриц глубина стека не менее 32, для других типов не менее 2. Далее попробую объяснить для чего нужны различные матрицы и как их использовать.Итак, задача такова, что надо создать трехмерную фигуру, изменить ее и потом отобразить на плоскость окна. Реализация OpenGL такова, что при этом имеем четыреперехода из одних координат в другие.Координаты объекта (4D) => Видовые координаты (4D) => Усеченные координаты (4D) => Нормализованные координаты (3D) => Оконные координаты (2D)(4D - это точка имеет 4 координаты, первые 3 - ее 3D координаты, последняя дополнительная составляющая).Переход от координат объекта к видовым осуществляется при использовании GL_MODELVIEWматрицы. По видовым координатам вычисляются усеченные координаты, используя GL_PROJECTION матрицу (название усеченные координаты идет от того, что для любой точки фигуры (x1, x2, x3, x4), верно -1 <= x_i <= 1, то есть GL_PROJECTION матрица отображает фигуру в 4D-куб c длиной стороны 2 и центром в (0, 0, 0, 0)). Нормализванные координаты получаются из усеченных следующим преобразованием (x1', x2', x3') = (x1/x4, x2/x4, x3/x4).Размер окна, куда будет отображаться фигура заданная в нормализованных координатах, определяется функцией glViewPort. Теперь, думаю, код glOnResize достаточно понятен.
// 1
 glViewport(0, 0, Width, Height); // Устанавливаем область отображения
  // на все окно
 // 2
 // Настройка матрицы проекции
 glMatrixMode(GL_PROJECTION); // Выбираем матрицу проекции
 glLoadIdentity(); // Устанавливаем ее единичной
 // Устанавливаем тип проеции - Ортогональный
 glOrtho(-Width div 2, Width div 2, -Height div 2, Height div 2, -800, 800);
 // 3
 // Настройка видовой матрицы
 glMatrixMode(GL_MODELVIEW); // Выбираем матрицу проекции
 glLoadIdentity(); // Устанавливаем ее единичной
Блоки 1, 2 и 3 можно менять местами. Единственное отличие, если поменять местами 2 и 3, точто текущая матрица будет не GL_MODELVIEW, а GL_PROJECTION.Примечание: GL_PROJECTION матрицу лучше выбирать так, чтобы * GL_MODELVIEW была единичной;* исходные размеры объекта были в пределах отрезка [-1; 1]. Цитата A: Для того, чтобы пpименить pазные пpеобpазования к pазным объектам сцены, надоделать так: glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotate, glScale, glTranslate // ... --- в общем, всё что нyжно... Затем pисyешь объекты...После того, как наpисовал, yказываешь новое пpеобpазование: glLoadIdentity(); glRotate, glScale, glTranslate // ... Снова pисyешь объекты. И так повтоpяешь, сколько надо.А теперь все это так, как было бы в коде (напр. в MyOpenGL.glDraw)
// Указываем, что работать будем с видовой матрицей
 // Если она и так была текущей, то можно не выполнять
 glMatrixMode(GL_MODELVIEW);
 // Сбрасываем до единичной
 // (Считаем, что GL_PROJECTION подобрана, как указано выше)
 glLoadIdenty();
 glTranslatef(100.0, 0.0, 0.0); // Добавим к матрице перенос на 100 вдоль ОХ
 glPushMatrix; // сохраняем матрицу в стек - она нам еще понадобится
 ...
 // Рисуем какую-нить фигуру1
 ...
 glRotate (-90, 0.0 , 1.0, 0.0); // Поворот на -90 градусов вокруг оси OY
 glRotate(60, 1.0, 0.0, 0.0); // Поворот на 60 градусов вокруг оси OX.
 ...
 // Рисуем фигуру2
 ...
 glPopMatrix; // восстанавливаем матрицу из стека
 ...
 glTranslatef(0.0, 10.0, 0.0); // двигаем на 10 по оси OX
 ...
 // Рисуем фигуру3
 ...
После этого имеем - фигура1 перенесена от центра на 100 по оси ОХ. Фигура2 имеет матрицу - соответствующую следующим последовательным действиям: перенос на 100, поворот, поворот. glPopMatrix - возвращает нас к исходной матрице, содержащей только перенос на 100, потому GL_MODELVIEW-матрица у фигуры3 - это перенос на 100 + перенос на 10 по оси ОY.Вообще говоря, последовательность неких действий - это домножение исходной матрицы наматрицы, отвечающие этим действиям. Поскольку умножение матриц некоммуникативно (AB <> BA),то и при смене чередовании элементов последовательности, получим другой результат. Дополнительно - www.ru-coding.com/ogl_1_3.php04а GL_PROJECTION=================Считаем, что GL_MODELVIEW матрица единичная.Задание матрицы проекции, которое могло быть напр. в MyOpenGL.glOnResizeПерспективная проекция
glFrustum( - Width div 2, Width div 2, - Height div 2, Height div 2, 100, 300);
 glTranslatef(0, 0, -200);
Ортогональная проекция
glOrtho(- Width div 2, Width div 2, -Height div 2, Height div 2, -800, 800);
Примерный смысл для параметров команд glFrustum и glOrtho. Первые четыре, расписанные как (left, top) и (right, bottom) определяют прямоугольник.Лучше представить его как окно, через которое мы смотрим на мир (т. е. на группу объектов,которые были получены при преобразовании их исходных координат их GL_MODELVIEW-матрицами). Чем оно больше (больше значения параметров), тем больше объекты (по размерам) можем видеть (по другому - как будто отходим назад от объектов). При симметричных координатах - смотрим на центр.Если провести через все углы линии ортогональные прямоугольнику, то высекаемый ими объем будет тем, что мы видим в мире. Поскольку объекты в бесконечности никого не интересуют (напр. не видны из-за малого размера при перспективной проекции), то логично ввести плоскость, параллельную плоскости окна и если объект оказался за ней, то забыть о его существовании - это сильно упрощает OpenGL расчеты. Логично ввести такую же плоскость и для объектов сблизи (хотя бы из соображений симметрии ;-)), т. е. если объект ближе чем она, то он не выводится. Пятый и шестой параметры - как раз и задают расположение второй и первой плоскости: при перспективной проекции - как растояние от окна до требуемых плоскостей (следствие: всегда пятый параметр меньше шестого и оба больше 0), при ортогональной - расстояние от начала координат (поскольку при ортогональной проекции нет искажении из-за того как далеко от нас находится центр, то можно представить его где-либо перед нами и соответсвенно задать координаты плоскостей отсечения).Если мы рисуем объекты вокруг центра координат, напр. так создаются Quadric-объекты, то для перспективной проекции также надо добавить сдвиг, помещающий центр координат МЕЖДУплоскостями отсечения (этот же сдвиг можно сделать и в GL_MODELVIEW матрице).

Очень сильно помогло для вывода текста. Спасибо.

Отправить комментарий

Проверка
Антиспам проверка
Image CAPTCHA
...