Примеры кода для работы с матрицами в OpenGL

Пройдите тест, узнайте какой профессии подходите

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

Введение в матрицы в OpenGL

Работа с матрицами в OpenGL является ключевым аспектом при создании 3D-графики. Матрицы используются для преобразования координат объектов, их перемещения, вращения и масштабирования в пространстве. В OpenGL основными типами матриц являются модельная матрица (Model Matrix), матрица вида (View Matrix) и матрица проекции (Projection Matrix). В этой статье мы рассмотрим каждую из этих матриц и приведем примеры кода для их использования.

Кинга Идем в IT: пошаговый план для смены профессии

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

В OpenGL существует три основных типа матриц, которые используются для различных преобразований:

  1. Модельная матрица (Model Matrix): Преобразует координаты объекта из его локальной системы координат в мировую систему координат.
  2. Матрица вида (View Matrix): Преобразует мировые координаты в координаты камеры.
  3. Матрица проекции (Projection Matrix): Преобразует координаты из камеры в координаты экрана.

Каждая из этих матриц играет важную роль в процессе рендеринга и позволяет создавать сложные сцены с различными эффектами.

Модельная матрица (Model Matrix)

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

Пример кода для модельной матрицы

cpp
Скопировать код
glm::mat4 model = glm::mat4(1.0f); // Инициализация единичной матрицей
model = glm::translate(model, glm::vec3(1.0f, 0.0f, 0.0f)); // Перемещение на 1 единицу по оси X
model = glm::rotate(model, glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f)); // Вращение на 90 градусов вокруг оси Z
model = glm::scale(model, glm::vec3(0.5f, 0.5f, 0.5f)); // Масштабирование в 0.5 раз

В этом примере используется библиотека GLM для работы с матрицами. Мы инициализируем модельную матрицу как единичную, затем последовательно применяем к ней операции перемещения, вращения и масштабирования.

Подробное объяснение

Инициализация модельной матрицы как единичной матрицы (glm::mat4(1.0f)) означает, что изначально она не изменяет координаты объекта. Затем мы применяем несколько преобразований:

  • Перемещение: glm::translate(model, glm::vec3(1.0f, 0.0f, 0.0f)) перемещает объект на 1 единицу по оси X.
  • Вращение: glm::rotate(model, glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f)) вращает объект на 90 градусов вокруг оси Z.
  • Масштабирование: glm::scale(model, glm::vec3(0.5f, 0.5f, 0.5f)) уменьшает размер объекта в 0.5 раз по всем осям.

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

Матрица вида (View Matrix)

Матрица вида используется для преобразования мировых координат в координаты камеры. Она определяет положение и ориентацию камеры в сцене.

Пример кода для матрицы вида

cpp
Скопировать код
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f); // Позиция камеры
glm::vec3 cameraTarget = glm::vec3(0.0f, 0.0f, 0.0f); // Точка, на которую смотрит камера
glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f); // Вектор "вверх"

glm::mat4 view = glm::lookAt(cameraPos, cameraTarget, up);

В этом примере мы используем функцию glm::lookAt, чтобы создать матрицу вида. Она принимает три параметра: позицию камеры, точку, на которую смотрит камера, и вектор, указывающий направление "вверх".

Подробное объяснение

Функция glm::lookAt создает матрицу вида, которая определяет, как сцена будет отображаться с точки зрения камеры. Параметры функции:

  • Позиция камеры: glm::vec3(0.0f, 0.0f, 3.0f) указывает, что камера находится на расстоянии 3 единиц по оси Z от центра сцены.
  • Точка, на которую смотрит камера: glm::vec3(0.0f, 0.0f, 0.0f) указывает, что камера направлена на центр сцены.
  • Вектор "вверх": glm::vec3(0.0f, 1.0f, 0.0f) указывает, что верх камеры направлен вдоль оси Y.

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

Матрица проекции (Projection Matrix)

Матрица проекции используется для преобразования координат из камеры в координаты экрана. Существует два основных типа проекций: ортографическая и перспективная.

Пример кода для матрицы проекции

Перспективная проекция

cpp
Скопировать код
float fov = glm::radians(45.0f); // Угол обзора
float aspectRatio = 800.0f / 600.0f; // Соотношение сторон экрана
float nearPlane = 0.1f; // Ближняя плоскость отсечения
float farPlane = 100.0f; // Дальняя плоскость отсечения

glm::mat4 projection = glm::perspective(fov, aspectRatio, nearPlane, farPlane);

Ортографическая проекция

cpp
Скопировать код
float left = -1.0f;
float right = 1.0f;
float bottom = -1.0f;
float top = 1.0f;
float nearPlane = 0.1f;
float farPlane = 100.0f;

glm::mat4 projection = glm::ortho(left, right, bottom, top, nearPlane, farPlane);

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

Подробное объяснение

Перспективная проекция

Перспективная проекция используется для создания эффекта глубины, где объекты, находящиеся дальше от камеры, кажутся меньше. Параметры функции glm::perspective:

  • Угол обзора: glm::radians(45.0f) указывает угол обзора в радианах.
  • Соотношение сторон экрана: 800.0f / 600.0f указывает соотношение ширины к высоте экрана.
  • Ближняя плоскость отсечения: 0.1f указывает минимальное расстояние, на котором объекты будут видны.
  • Дальняя плоскость отсечения: 100.0f указывает максимальное расстояние, на котором объекты будут видны.

Ортографическая проекция

Ортографическая проекция используется для создания эффекта, где объекты сохраняют свои размеры независимо от их расстояния от камеры. Параметры функции glm::ortho:

  • Левая граница: -1.0f указывает левую границу проекции.
  • Правая граница: 1.0f указывает правую границу проекции.
  • Нижняя граница: -1.0f указывает нижнюю границу проекции.
  • Верхняя граница: 1.0f указывает верхнюю границу проекции.
  • Ближняя плоскость отсечения: 0.1f указывает минимальное расстояние, на котором объекты будут видны.
  • Дальняя плоскость отсечения: 100.0f указывает максимальное расстояние, на котором объекты будут видны.

Примеры кода и их объяснение

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

Полный пример

cpp
Скопировать код
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <GL/glew.h>
#include <GLFW/glfw3.h>

// Инициализация матриц
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(1.0f, 0.0f, 0.0f));
model = glm::rotate(model, glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f));
model = glm::scale(model, glm::vec3(0.5f, 0.5f, 0.5f));

glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
glm::vec3 cameraTarget = glm::vec3(0.0f, 0.0f, 0.0f);
glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);
glm::mat4 view = glm::lookAt(cameraPos, cameraTarget, up);

float fov = glm::radians(45.0f);
float aspectRatio = 800.0f / 600.0f;
float nearPlane = 0.1f;
float farPlane = 100.0f;
glm::mat4 projection = glm::perspective(fov, aspectRatio, nearPlane, farPlane);

// Передача матриц в шейдеры
GLuint modelLoc = glGetUniformLocation(shaderProgram, "model");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));

GLuint viewLoc = glGetUniformLocation(shaderProgram, "view");
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));

GLuint projectionLoc = glGetUniformLocation(shaderProgram, "projection");
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));

В этом примере мы инициализируем модельную, видовую и проекционную матрицы, а затем передаем их в шейдеры. Использование библиотеки GLM значительно упрощает работу с матрицами в OpenGL.

Подробное объяснение

В этом примере мы объединяем все три типа матриц, чтобы создать полноценную сцену. Сначала мы инициализируем модельную матрицу и применяем к ней преобразования перемещения, вращения и масштабирования. Затем мы создаем матрицу вида, определяя положение и ориентацию камеры. Наконец, мы создаем матрицу проекции, используя перспективную проекцию.

После инициализации матриц мы передаем их в шейдеры с помощью функций glGetUniformLocation и glUniformMatrix4fv. Эти функции позволяют нам передать матрицы в виде uniform-переменных, которые могут быть использованы в шейдерах для преобразования координат вершин.

Теперь у вас есть базовое понимание работы с матрицами в OpenGL и примеры кода, которые помогут вам начать. Удачи в ваших проектах! 😉

Читайте также