Яндекс.Метрика

cpp

OpenGL Mathematics (GLM) Обзор библиотеки

Данный текст является обзором библиотеки математических вычислений для OpenGL – GLM. Создан обзор дабы по мнению автора залатать брешь в информационном вакууме и направить умы несознательные по пути верному.

Математический функции в OpenGL никогда не были на высоте, а с приходом новых стандартов OpenGL 3(4,ES), математики не стало вообще. И что самое обидное, нам ничего не дали в замен. Как же теперь крутить кубы и торосы, в условиях безграничной свободы шейдерного программирования?
Напомню, что почти все манипуляции с трансформацией в 3D пространстве происходят благодаря использованию матриц и векторов. И все glRotate, glScale, glTranslate и т.п. ни что иное как формирование матрицы. Затем одну или произведение разных матриц перемножаем с вектором и попадаем в нужное место.

В связи с этим, первое решение которое приходит на ум, это написать свою библиотеку для работы с матрицами и векторами. Изобретение велосипедов дело хорошее но не всегда благодарное, баги, неверные подходы и т.п. Второе, это использовать готовую библиотеку. Вот тут возникает вопрос — а какую? Обычная библиотека для матричных преобразований работает с общими случаями и поэтому работает медленно. Нам же нужна библиотека оптимизированная под работу с матрицами 3х3 и 4х4. Кандидатом в такие библиотеки является GLM.

Брать либу тут: glm.g-truc.net/

Как мне показалось, главное достоинство библиотеки описано на в заголовке на первой странице сайта в фразе «GLSL + Optional features = OpenGL Mathematics (GLM)». Тоесть, библиотека по синтаксису и функционалу схожа с GLSL(язык шейдеров для OpenGL), но также имеет некие «Optional features» расширяющие список возможностей библиотеки.

Также отмечу, что библиотека совместима со всеми современными компиляторами с++, и даже с такой штукой как CUDA и что приятно, при подключении не требует указания библиотек или dll.

Внутри библиотека разделена на 2 части, первая часть glm.hpp — содержит описание основных типов, вторая часть это библиотека расширений ext.hpp — подключающая множество вкусных функций, таких как rotate, translate, scale, lookAt и многих других. Хотя в документации предлагается подключать расширения отдельно, указывая ту или иную библиотеку.

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

Расширения библиотеки делятся на несколько групп.
GTC – стандартные версии расширений или как сказано в заголовке ext.hpp (Stable)
GTX – экспериментальные расширения результат работы которых гарантирован и вы используете их на свой страх и риск.
VIRTREV — судя по всему что-то связанной с выводом матриц через потоки ввода\вывода

Ну а так как библиотека на плюсах то она естественно имеет собственный namespace который зовется glm.

О работе библиотеки прекрасно говорит официальный мануал glm.g-truc.net/glm.pdf.

Вот пара примеров показывающих использование библиотеки.

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

void foo(){
	glm::vec4 Position = glm::vec4(glm:: vec3(0.0f), 1.0f);
	glm::mat4 Model = glm::translate(glm::mat4(1.0f), glm::vec3(1.0f));
	Model = glm::rotate(Model,45,0,1,0);
	glm::vec4 Transformed = Model * Position;
}

Еще один пример использования GLM вместе с OpenGL

#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>

using namespace glm;

void foo(){
	vec4 v(0.0f);
	mat4 m(1.0f);
	...
	glVertex3fv(value_ptr(v))
	glLoadMatrixfv(value_ptr(m));
}

Обозреть весь функционал библиотеки в одной статье невозможно. А может она многое, есть и работа с цветом и даже обычные математические функции sin, cos. А каким там вкусные рандомы.

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

Вот пример умножения матрицы на матрицу переноса, перенос задан вектором:


template <typename T> 
GLM_FUNC_QUALIFIER detail::tmat4x4<T> translate
(
	detail::tmat4x4<T> const & m,
	detail::tvec3<T> const & v
)
{
	detail::tmat4x4<T> Result(m);
	Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3];
	return Result;
}


Подводя итог написанного выше, GLM является достойной библиотекой как для тех кто пишет код под CORE_PROFILE так и для тех кто работает с OpenGL по старинке. Само использование данной библиотеки приблизит вас к современным стандартам шейдерного программирования, и кстати сделает ваш код более эффективным. Так как вы получите полный контроль над математическими вычислениями.