ПРИХОДИТЕ УЧИТЬСЯ НОВОЙ ПРОФЕССИИ ЛЕТОМ СО СКИДКОЙ ДО 70%Забронировать скидку

Работа с GLM библиотекой: glm::mat4

Пройдите тест, узнайте какой профессии подходите и получите бесплатную карьерную консультацию
В конце подарим скидку до 55% на обучение
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Введение в GLM и glm::mat4

GLM (OpenGL Mathematics) — это библиотека, предоставляющая математические функции и структуры данных, которые часто используются в графическом программировании, особенно в OpenGL. Она была разработана для обеспечения удобного и эффективного интерфейса для работы с векторами, матрицами и другими математическими объектами, которые необходимы для создания 3D-графики. Одной из ключевых структур в GLM является glm::mat4, представляющая собой 4x4 матрицу, которая широко используется для трансформаций в 3D графике. Эти матрицы позволяют выполнять операции, такие как перемещение, вращение и масштабирование объектов в трехмерном пространстве.

Пройдите тест и узнайте подходит ли вам сфера IT
Пройти тест

Создание и инициализация матриц glm::mat4

Создание матрицы

Для создания матрицы glm::mat4 можно использовать несколько способов. В зависимости от ваших потребностей, вы можете создать матрицу, инициализированную как единичная, нулевая или с конкретными значениями:

cpp
Скопировать код
#include <glm/glm.hpp>

glm::mat4 matrix1; // Инициализируется как единичная матрица
glm::mat4 matrix2(1.0f); // Явное задание единичной матрицы
glm::mat4 matrix3(0.0f); // Инициализация нулевой матрицей

Единичная матрица — это матрица, в которой все элементы главной диагонали равны 1, а остальные элементы равны 0. Она часто используется в качестве начальной точки для различных трансформаций.

Инициализация матрицы

Можно инициализировать матрицу конкретными значениями. Это может быть полезно, когда вам нужно задать матрицу с определенными параметрами:

cpp
Скопировать код
glm::mat4 matrix = glm::mat4(
    1.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 1.0f, 0.0f,
    0.0f, 0.0f, 0.0f, 1.0f
);

Эта матрица также является единичной, но она инициализируется явно. Вы можете изменить значения элементов матрицы в зависимости от ваших нужд.

Основные операции с матрицами glm::mat4

Умножение матриц

Умножение матриц — одна из самых распространенных операций в 3D-графике. Оно позволяет комбинировать различные трансформации, такие как перемещение, вращение и масштабирование. Например, чтобы создать матрицу Model-View-Projection (MVP), необходимо умножить матрицы модели, вида и проекции:

cpp
Скопировать код
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = glm::mat4(1.0f);
glm::mat4 projection = glm::mat4(1.0f);

glm::mat4 mvp = projection * view * model; // Матрица Model-View-Projection

Трансформации

Трансформации включают в себя масштабирование, вращение и перемещение. Эти операции позволяют изменять положение, ориентацию и размер объектов в трехмерном пространстве.

Перемещение

Перемещение объекта в пространстве можно выполнить с помощью функции glm::translate. Эта функция принимает матрицу и вектор, определяющий направление и величину перемещения:

cpp
Скопировать код
glm::mat4 translate = glm::translate(glm::mat4(1.0f), glm::vec3(1.0f, 2.0f, 3.0f));

Вращение

Вращение объекта вокруг оси можно выполнить с помощью функции glm::rotate. Эта функция принимает матрицу, угол вращения (в радианах) и вектор, определяющий ось вращения:

cpp
Скопировать код
glm::mat4 rotate = glm::rotate(glm::mat4(1.0f), glm::radians(45.0f), glm::vec3(0.0f, 0.0f, 1.0f));

Масштабирование

Масштабирование объекта можно выполнить с помощью функции glm::scale. Эта функция принимает матрицу и вектор, определяющий коэффициенты масштабирования по каждой из осей:

cpp
Скопировать код
glm::mat4 scale = glm::scale(glm::mat4(1.0f), glm::vec3(2.0f, 2.0f, 2.0f));

Использование glm::mat4 в OpenGL

Передача матрицы в шейдер

Чтобы передать матрицу в шейдер, нужно сначала получить её местоположение в шейдере, а затем установить значение. Это делается с помощью функций OpenGL glGetUniformLocation и glUniformMatrix4fv:

cpp
Скопировать код
GLuint shaderProgram = ...; // Ваш шейдерный программный объект
GLuint matrixLocation = glGetUniformLocation(shaderProgram, "u_MVP");

glm::mat4 mvp = ...; // Ваша матрица Model-View-Projection
glUniformMatrix4fv(matrixLocation, 1, GL_FALSE, &mvp[0][0]);

Пример шейдера

Шейдер — это программа, выполняемая на графическом процессоре (GPU). В данном примере шейдер использует матрицу MVP для преобразования вершин объекта:

glsl
Скопировать код
#version 330 core

layout(location = 0) in vec3 aPos;
uniform mat4 u_MVP;

void main()
{
    gl_Position = u_MVP * vec4(aPos, 1.0);
}

Этот шейдер принимает позиции вершин и умножает их на матрицу MVP, чтобы получить конечные позиции вершин в экранных координатах.

Примеры и практические задачи

Пример 1: Простая трансформация объекта

Создадим простую программу, которая перемещает объект. В этом примере объект перемещается на единицу по оси X:

cpp
Скопировать код
glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(1.0f, 0.0f, 0.0f));
glm::mat4 view = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 projection = glm::perspective(glm::radians(45.0f), 4.0f / 3.0f, 0.1f, 100.0f);

glm::mat4 mvp = projection * view * model;

Пример 2: Вращение объекта

Добавим вращение к объекту. В этом примере объект вращается на 45 градусов вокруг оси Y:

cpp
Скопировать код
glm::mat4 model = glm::rotate(glm::mat4(1.0f), glm::radians(45.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 view = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 projection = glm::perspective(glm::radians(45.0f), 4.0f / 3.0f, 0.1f, 100.0f);

glm::mat4 mvp = projection * view * model;

Практическая задача

Попробуйте создать программу, которая будет масштабировать объект в зависимости от времени. Используйте функцию glm::scale и glfwGetTime для получения текущего времени. В этом примере объект будет пульсировать, изменяя свой размер в зависимости от синуса текущего времени:

cpp
Скопировать код
float time = glfwGetTime();
glm::mat4 model = glm::scale(glm::mat4(1.0f), glm::vec3(sin(time), sin(time), sin(time)));
glm::mat4 view = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 projection = glm::perspective(glm::radians(45.0f), 4.0f / 3.0f, 0.1f, 100.0f);

glm::mat4 mvp = projection * view * model;

Эти примеры помогут вам лучше понять, как использовать glm::mat4 в ваших проектах. Удачи в изучении OpenGL и GLM! 😉