Я изучаю OpenGL, чтобы попытаться создать некоторые базовые инструменты визуализации. Первое, что я хочу сделать, это отрендерить сохраненные изображения с 4 камер. Хотел бы получить макет изображений 2x2
Я следую этому руководству (https://learnopengl.com/Getting-started/Textures и полный исходный код https://learnopengl.com/code_viewer_gh.php?code=src/1.getting_started/4.1. текстуры/текстуры.cpp) об использовании текстур. Я могу успешно загрузить одно из изображений и отобразить его в полноразмерном окне. Я изменил массив vertices[]
в примере на максимальный (от -1 до 1 во всех направлениях), чтобы получить полноэкранный режим. Мои вопросы: быть новичком в OpenGL
Является ли это лучшим/современным подходом с использованием вершинного шейдера и фрагментного шейдера? Есть много примеров изображений 5-10-летней давности, которые делают что-то другое.
Если у меня загружено четыре изображения, могу ли я повторно использовать одни и те же вершинные и фрагментные шейдеры для каждого изображения?
В настоящее время я думаю о подходе к рендерингу изображений в сетке 2x2, чтобы создать 4 vertices[]
с каждым квадрантом (от -1 до 0, от 0 до 1 и т. д.). Это означало бы, что мне понадобятся 4 объекта вершины VAO. Это лучший подход, или есть что-то более простое, что можно сделать?
Как только я заработаю, я поделюсь/опубликую код для будущих читателей.
Вы можете сделать то же самое и с 3D-текстурами ... Вот пример использования нескольких текстур одновременно Отображение нормалей пошло ужасно неправильно здесь пример 3D-текстуры 3D-воксельная обратная трассировка лучей массив текстур почти такой же, как и здесь Отладочные отпечатки GLSL - это пример печати текстов из фрагментного шейдера (вы можете использовать его для отладки, печати информации о кадре или чего-то еще), он также показывает, как вычислять координаты текстуры из положения ..
Трудно предоставить «лучший подход» без какого-либо кода, предоставляющего дополнительный контекст того, что вы пытаетесь сделать.
- Является ли это лучшим/современным подходом с использованием вершинного шейдера и фрагментного шейдера? Есть много примеров изображений 5-10-летней давности, которые делают что-то другое.
Не видя учебники, трудно дать ответ. Однако я предполагаю, что вы имеете в виду примеры с использованием конвейера с фиксированной функцией. Если так, то да, придерживайтесь шейдеров.
- Если у меня загружено четыре изображения, могу ли я повторно использовать одни и те же вершинные и фрагментные шейдеры для каждого изображения?
Предполагая, что ваш фрагментный шейдер в некоторой степени совпадает с тем, на который вы ссылались (4.1.texture.fs), то есть сводится к чему-то вроде этого:
#version 330 core
out vec4 fragColor;
in vec2 vTexCoord;
uniform sampler2D tex;
void main() {
fragColor = texture(tex, vTexCoord);
}
Тогда да, вы можете повторно использовать шейдер. Предполагая, что ваш текущий подход включает 4 вызова отрисовки, тогда просто привяжите необходимую текстуру до вызова отрисовки.
- В настоящее время я думаю о подходе к рендерингу изображений в сетке 2x2, чтобы создать 4 вершины [] с каждым квадрантом (от -1 до 0, от 0 до 1 и т. д.). Это означало бы, что мне понадобятся 4 объекта вершины VAO. Это лучший подход, или есть что-то более простое, что можно сделать?
Насколько я понимаю, ваши данные вершины не меняются для каждого изображения. Только положение и, ну, собственно изображение. Таким образом, вместо дублирования массивов вершин и данных вершин вы можете использовать матрицу в вершинном шейдере для преобразования вершин.
Вы познакомитесь с этим в следующем учебнике LearnOpenGL «Преобразования».
Короче говоря, вы добавите uniform mat4 mvp
к вашему вершинному шейдеру и умножите его на позицию вершины, примерно так:
#version 330 core
layout (location = 0) in vec3 pos;
uniform mat4 mvp;
void main() {
gl_Position = mvp * vec4(pos, 1.0);
}
Существуют также альтернативные способы, с помощью которых вы можете выполнить то, что пытаетесь сделать, с помощью одного вызова отрисовки.
Чтобы использовать текстуру массива, ваш шейдер должен указать sampler2DArray
вместо sampler2D
. Наряду с вашим vTexCoord
необходимо указать третью координату, представляющую слой.
#version 330 core
out vec4 fragColor;
in vec3 vTexCoord;
uniform sampler2DArray tex;
void main() {
fragColor = texture(tex, vTexCoord);
}
По сравнению с uniform
массивом текстур. Вы бы добавили атрибут layer
к своим вершинным данным и шейдерам.
Вершинный шейдер:
#version 330 core
layout (location = 0) in vec3 pos;
layout (location = 1) in vec2 texCoord;
layout (location = 2) in uint layer;
flat out uint vLayer;
uniform mat4 mvp;
void main() {
vTexCoord = texCoord;
vLayer = index;
gl_Position = mvp * vec4(position, 0.0, 1.0);
}
Фрагментный шейдер:
#version 330 core
out vec4 fragColor;
in vec2 vTexCoord;
flat in uint vLayer;
uniform sampler2D tex[4];
void main() {
fragColor = texture(tex[vLayer], vTexCoord);
}
вы можете использовать мультитекстурирование, поэтому привязывайте каждое изображение к другому текстурному блоку и используйте только один вызов VBO/VAO и рендеринг. Также вы можете передать только один Quad
-1,+1
и вычислить координаты текстуры и исходную текстуру в вершинном шейдере из него нет необходимости рендерить 4 Quad Однако загрузка 4 текстур на каждом кадре в GL может быть медленной ... Не эксперт в этом вопросе, но IIRC в новом API GL есть некоторые механизмы для более быстрой передачи с использованием PBO или FBO, я думаю. Если у вас много памяти графического процессора, вы можете использовать массив текстур и загружать видео полностью или частично в графический процессор и «лениво» загружать каждые n кадров.