Опубликован: 13.07.2010 | Уровень: специалист | Доступ: платный
Самостоятельная работа 21:

Непрограммируемый конвейер в OpenGL

Аннотация: В лекции рассматривается непрогроммируемый геометрический конвейер OpenGL. Системы координат. Команды управления текущими матрицами преобразования. Модельные и проекционные преобразования. Стеки матриц. Построение модели атома в ортогональной проекции (Atom). Модель полого бруска в ортогональной проекции (Ortho). Модель полого бруска в перспективной проекции (Perspect). Построение модели атома в перспективной проекции (Atom Perspect). Моделирование системы с относительными вращениями (Solar). Прямая загрузка матриц преобразований (Transform). Прямая загрузка матриц преобразований (SphereWorld).

Файлы к лабораторной работе Вы можете скачать здесь.

Большинство этапов обработки графической информации сводится к последовательным преобразованиям геометрических характеристик координат объектов сцены, первоначально заданных вершинами ( vertex ) в базовой (мировой) системе координат, в систему координат камеры (наблюдателя). Обобщенная структура геометрического конвейера показана на рисунке

Конвейерный принцип обработки графической информации позволяет распределить однотипные операции на специализированных аппаратных средствах помимо центрального процессора, тем самым - существенно повысить скорость обработки. Преобразования в конвейере осуществляются с помощью матриц размерности 4x4 по возможности на аппаратном уровне, если он поддерживается на данном компьютере.

Создание заготовки приложения OpenGL

В данной лабораторной работе мы познакомимся с процессом преобразования графической информации, который реализован в библиотеке OpenGL как непрограммируемый конвейер.

  • Выполните команду меню оболочки File/New/Project.
  • В появившемся окне мастера создания заготовки проекта задайте имя проекта ProjectionMatrix и выберите каталог размещения проекта, как показано на снимке

  • В следующем окне оставьте установки мастера по умолчанию и щелкните на кнопке Finish

  • Переименуйте функцию _tmain() файла ProjectionMatrix.cpp в main(), измените в заголовке определения функции main() тип возвращаемого значения и удалите аргументы, чтобы код выглядел так
#include "stdafx.h"
  
void main()
{
}
Листинг 21.1. Начальная заготовка файла ProjectionMatrix.cpp
  • Через панель Solution Explorer оболочки откройте файл stdafx.h, который создал мастер проекта, и добавьте в самое его начало после инструкции #pragma once код подключения стандартных заголовочных файлов для операционной системы и OpenGL
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
  
#pragma once
  
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>  
    
#define WIN32_LEAN_AND_MEAN    // Exclude rarely-used stuff from Windows headers
#include <iostream>
#include <tchar.h>
    
// TODO: reference additional headers your program requires here
Листинг 21.2. Добавление стандартных заголовков в файл stdafx.h
Здесь предполагается, что ваша платформа настроена на разработку приложений OpenGL в соответствии с рекомендациями, которые нужно было выполнить в работе №19.

В этой лабораторной работе мы опять выполним несколько упражнений, которые упакуем в одно приложение. Соответственно, для вызова каждого отдельного упражнения предусмотрим свой пункт контекстного меню. Для взаимодействия с пользователем и рисования простых геометрических объектов применим инструментальные средства библиотеки GLUT. Код приложения будем постепенно наращивать по мере выполнения упражнений рассматриваемой темы.

При моделировании компьютерной графики можно представить, что через экран монитора мы смотрим в окно на некоторый трехмерный мир, который существует внутри компьютера в виде некоторой сцены, движущимися актерами которой и взглядом на нее стороннего наблюдателя мы хотим управлять в нашем приложении. Сцена разворачивается в мировых ( базовых ) координатах, которые представляют собой правую систему координат и изначально направлены по отношению к наблюдателю так


При моделировании взгляда наблюдателя обычно его отождествляют с фотокамерой и наделяют теми же характеристиками: направление оптической оси на сцену, угол поворота относительно оптической оси и ракурс видимости сцены. В исходном состоянии OpenGL камера находится в начале мировых координат, смотрит в отрицательную сторону оси z, направляющий вектор камеры (нормаль) совпадает с осью y (камера стоит на плоскости x0z ).

Управление объектами на сцене и камерой осуществляется с помощью последовательных преобразований, реализуемых матрицами 4x4. Конвейер преобразований в OpenGL состоит из трех частей, которые настраиваются по отдельности. Выбор требуемого режима осуществляется командой glMatrixMode(GLenum mode), которая с помощью значения перечисления mode определяет, какую из матриц преобразования размером 4x4 сделать текущей и вносить в нее изменения последующими командами:

  1. mode = GL_MODELVIEW: Модельные преобразования (модельно-видовая матрица) - применяются к размещению объектов на сцене.
  2. mode = GL_PROJECTION: Видовые преобразования (проекционная матрица) - применяются к размещению и ориентации точки обзора (настройка фотокамеры).
  3. mode = GL_TEXTURE: Текстурные преобразования (текстурная матрица) - применяются для управления текстурами заполнения объектов. В данной лабораторной работе мы не будем применять текстуры, поэтому и останавливаться здесь на них не будем.

В начальном состоянии по умолчанию любая из этих матриц преобразования размером 4x4 является единичной.

Команды управления текущими матрицами преобразования

  1. В любой момент текущей матрице преобразования можно придать значение единичной матрицы с помощью команды glLoadIdentity().
  2. В текущую матрицу преобразования можно загрузить желаемое значение, определяемое массивом m из 16 элементов, с помощью команды glLoadMatrix{fd}(const TYPE *m).
  3. Команда glLoadTransposeMatrix{fd}(const TYPE *m) также загружает в текущую матрицу преобразования желаемое значение, определяемое массивом m из 16 элементов, только предварительно транспонирует этот массив. Окончания f или d - для команд с аргументами типа float или double.
  4. Текущую матрицу преобразования можно умножить справа на произвольную матрицу, определяемую массивом из 16 элементов, с помощью команды glMultMatrix{fd}(const TYPE *m). Результат умножения помещается в текущую матрицу преобразования. Окончания f или d - для команд с аргументами типа float или double.
  5. Команда glMultTratsposeMatrix{fd}(const TYPE *m) также умножает текущую матрицу преобразования справа на произвольную матрицу, определяемую массивом из 16 элементов, только предварительно транспонирует этот массив. Результат умножения помещается в текущую матрицу преобразования. Окончания f или d - для команд с аргументами типа float или double.

Любой текущей матрицы преобразования можно передать значение с помощью указанных функций. Но весь вопрос в том, как правильно определить эти значения. При решении геометрических задач человеку всегда удобнее мыслить категориями элементарных последовательных преобразований (элементарных переходов), таких как плоскопараллельные смещения, повороты и изменения масштаба.

Иван Циферблат
Иван Циферблат
Россия, Таганрог, 36, 2000