Просмотр нескольких изображений в сетке 2x2 в одном окне с использованием OpenGL и текстур

Я изучаю 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

  1. Является ли это лучшим/современным подходом с использованием вершинного шейдера и фрагментного шейдера? Есть много примеров изображений 5-10-летней давности, которые делают что-то другое.

  2. Если у меня загружено четыре изображения, могу ли я повторно использовать одни и те же вершинные и фрагментные шейдеры для каждого изображения?

  3. В настоящее время я думаю о подходе к рендерингу изображений в сетке 2x2, чтобы создать 4 vertices[] с каждым квадрантом (от -1 до 0, от 0 до 1 и т. д.). Это означало бы, что мне понадобятся 4 объекта вершины VAO. Это лучший подход, или есть что-то более простое, что можно сделать?

Как только я заработаю, я поделюсь/опубликую код для будущих читателей.

вы можете использовать мультитекстурирование, поэтому привязывайте каждое изображение к другому текстурному блоку и используйте только один вызов VBO/VAO и рендеринг. Также вы можете передать только один Quad -1,+1 и вычислить координаты текстуры и исходную текстуру в вершинном шейдере из него нет необходимости рендерить 4 Quad Однако загрузка 4 текстур на каждом кадре в GL может быть медленной ... Не эксперт в этом вопросе, но IIRC в новом API GL есть некоторые механизмы для более быстрой передачи с использованием PBO или FBO, я думаю. Если у вас много памяти графического процессора, вы можете использовать массив текстур и загружать видео полностью или частично в графический процессор и «лениво» загружать каждые n кадров.

Spektre 22.12.2020 10:03

Вы можете сделать то же самое и с 3D-текстурами ... Вот пример использования нескольких текстур одновременно Отображение нормалей пошло ужасно неправильно здесь пример 3D-текстуры 3D-воксельная обратная трассировка лучей массив текстур почти такой же, как и здесь Отладочные отпечатки GLSL - это пример печати текстов из фрагментного шейдера (вы можете использовать его для отладки, печати информации о кадре или чего-то еще), он также показывает, как вычислять координаты текстуры из положения ..

Spektre 22.12.2020 10:11
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
207
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Трудно предоставить «лучший подход» без какого-либо кода, предоставляющего дополнительный контекст того, что вы пытаетесь сделать.

  1. Является ли это лучшим/современным подходом с использованием вершинного шейдера и фрагментного шейдера? Есть много примеров изображений 5-10-летней давности, которые делают что-то другое.

Не видя учебники, трудно дать ответ. Однако я предполагаю, что вы имеете в виду примеры с использованием конвейера с фиксированной функцией. Если так, то да, придерживайтесь шейдеров.

  1. Если у меня загружено четыре изображения, могу ли я повторно использовать одни и те же вершинные и фрагментные шейдеры для каждого изображения?

Предполагая, что ваш фрагментный шейдер в некоторой степени совпадает с тем, на который вы ссылались (4.1.texture.fs), то есть сводится к чему-то вроде этого:

#version 330 core

out vec4 fragColor;
in vec2 vTexCoord;
uniform sampler2D tex;

void main() {
    fragColor = texture(tex, vTexCoord);
}

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

  1. В настоящее время я думаю о подходе к рендерингу изображений в сетке 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);
}

Другие вопросы по теме