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

    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 по старинке. Само использование данной библиотеки приблизит вас к современным стандартам шейдерного программирования, и кстати сделает ваш код более эффективным. Так как вы получите полный контроль над математическими вычислениями.