Войти
ПрограммированиеСтатьиГрафика

Работа с расширениями OpenGL с использованием NVIDIA OpenGL SDK 5.1. (Часть 4)

Автор:

Начиная с этой статьи в качестве среды разработки будет использоваться Visual C++ .NET. Переход на эту платформу происходит довольно гладко, если не считать того, что в файл "\include\glh\NVEBGlutAPI.c" придётся внести небольшие изменения, поэтому мы не будем останавливаться на этом обстоятельстве.

Библиотека nv_math
Работа с векторами
Работа с матрицами
Аффинные преобразования
Другие полезные функции
  Линейная интерполяция
  Геометрические расчеты
  Математические функции

Библиотека nv_math

Во время разработки 3D приложений программисту часто приходится выполнять одни и те же математические операции - операции с матрицами и векторами, аффинные преобразования и т.д. Поэтому, для облегчения работы можно разработать свою математическую библиотеку, фактически занимаясь изобретением велосипеда, либо воспользоваться готовыми библиотеками, написанными профессионалами. Если вы сторонник второго пути, то этот раздел для вас.

В составе NVIDIA OpenGL SDK имеется математическая библиотека nv_math, содержащая множество классов и функций, которые могут серьёзно облегчить жизнь программисту. Но здесь есть одна проблема - эта библиотека поставляется в виде "как есть", т.е. в исходных кодах и без документации. Т.е. с одной стороны, после установки NVIDIA OpenGL SDK программист бесплатно получает довольно неплохую математическую библиотеку, а с другой - он ей не может пользоваться из-за отсутствия документации. В этой статье я постараюсь рассмотреть основные классы и функции этой довольно неплохой библиотеки, которые серьёзно облегчают нелёгкую жизнь 3D программиста.

Перед использованием библиотеки необходимо подключить к проекту файлы "nv_math/nv_algebra.h" и "nv_math.lib". Помните, что в составе SDK имеется 2 варианта файла nv_math.lib: RELEASE и DEBUG, причём быстродействие последнего значительно ниже.

Работа с векторами

В библиотеке nv_math за работу с 2-х, 3-х и 4-х мерными векторами отвечают классы vec2, vec3 и vec4 соответственно. В этой статье мы рассмотрим работу с классом vec4. Классы vec2 и vec3 являются просто модификацией этого класса с уменьшенным числом координат, поэтому всё сказанное ниже будет верно и для них с небольшими оговорками.

И так, класс vec4 обладает 3-мя конструкторами:

    vec4();
    vec4( const nv_scalar x, const nv_scalar y, const nv_scalar z, const nv_scalar w);
    vec4( const nv_scalar * xyzw );

Первый конструктор создаёт вектор с неопределенным значением, второй создаёт вектор и инициализирует его начальными значениями. Третий конструктор предназначен для создания копии уже существующего вектора. В классе vec4 определены перегруженные операторы, указанные в таблице 1.

Оператор Действие
Присвоение одного вектора другому
==  Сравнение двух векторов
*=  Умножение вектора на число
+=  Прибавление одного вектора к другому
–=  Вычитание вектора из другого вектора
[]  Доступ к элементу вектора

Таблица 1.

Кроме того, в nv_math определены константы нулевого и единичного векторов vec4_null и vec4_one.

Ниже приведён пример вычисления выражения (Ex01): 
A=(1,1,1,1), B=(1,2,3,4), X=3*A+2*B:

Void output(vec4& x)  //вывод вектора на экран
{
  for (unsigned int i=0; i<4; i++)
  {
    cout<<"x["<<i<<"]="<<x[i]<<endl;
  }
}

void main()
{
  vec4 a(vec4_one);  //вектор a
  vec4 b(1,2,3,4);  //вектор b

  a*=3;  //a=a*3
  b*=2;  //b=b*2
  a+=b;  //a=a+b
  
  output(a);

  getchar();
};

Рассмотрим более подробно определение класса vec4:

typedef float nv_scalar;

struct vec4
{
   ...  //определение методов пропущено
union {
        struct {
            nv_scalar x,y,z,w;          // геометрические координаты
        };
        struct {
            nv_scalar s,t,r,q;          // координаты текстуры
        };
        nv_scalar vec_array[4];     // доступ к массиву координат
    };
};

Как видно из этого определения, координаты вектора могут быть интерпретированы 3-мя способами: как геометрические координаты, текстурные координаты или массив координат. Это очень полезно при использовании команд OpenGL, допускающие векторную форму записи. Например, вывод вершины на  экран при помощи команды glVertex может быть записан следующим образом:

vec3 vertex;

glVertex3f(vertex.x, vertex.y, vertex.z);

Если же рассматривать вектор vertex как массив, то мы можем воспользоваться векторным вариантом команды glVertex3:

glVertex3fv(&vertex.vec_array[0]);

Ясно что, второй вариант предпочтительнее. Но и его можно ещё немного упростить, если учесть что поля x и vec_array[0] ссылаются на одну и туже область памяти (но на быстродействии это уже не повлияет):

glVertex3fv(&vertex.x);

Над классами vec2, vec3 и vec4 можно выполнять множество операций. Наиболее часто используемые операции приведены в таблице 2, где u, v, w - произвольные вектора, s - число.

Таблица 2. Основные операции с векторами

Название функции  Назначение
Normalize  Нормализация вектора
nv_sq_norm  Вычисление квадрата модуля вектора
nv_norm  Вычисление модуля вектора
Reflect  Вычисление отражённого вектора
Madd  Вычисление выражения u=v*s+u
Mult  Вычисление произведения соответствующих
координат векторов  (u=v*w) или
умножение вектора на число (u=v*s)
Add  Сложение векторов
Sub  Вычитание векторов
Scale  Масштабирование вектора
Dot  Вычисление скалярного произведения векторов
Cross  Вычисление векторного  произведения векторов

При использовании этих функций надо учитывать одну особенность - НЕЛЬЗЯ указывать в качестве аргумента и результата одну и ту же переменную. Т.е. если f(c, a, b) функция принимает аргументы a и b, а возвращает c, то вызов f(x, x, y) будет, скорее всего, работать неправильно.

За более подробной информацией обратитесь к файлам "\src\libs\nv_math\nv_algebra.cpp" и "\include\nv_math\nv_algebra.h".

Страницы: 1 2 3 4 Следующая »

#расширения OpenGL, #NVIDIA, #nv_math, #OpenGL, #PBuffer, #SDK, #векторы, #математика

25 февраля 2002 (Обновление: 17 сен. 2009)