使用 OpenGL 和纹理在同一个 window 的 2x2 网格中查看多个图像

Viewing multiple images in a 2x2 grid in the same window using OpenGL and textures

我正在学习 OpenGL 以尝试创建一些基本的可视化工具。我要做的第一件事是渲染来自 4 个摄像机的保存图像。想要获得 2x2 图像的布局

我正在学习有关使用纹理的教程 (https://learnopengl.com/Getting-started/Textures and full source https://learnopengl.com/code_viewer_gh.php?code=src/1.getting_started/4.1.textures/textures.cpp)。我可以成功加载其中一张图像并将其显示为完整尺寸 window。我将示例中的 vertices[] 数组更改为最大值(在所有方向上为 -1 到 1)以获得全屏。我的问题是,刚接触 OpenGL

  1. 这是使用顶点着色器和片段着色器的best/modern方法吗?大约 5-10 年前有很多图像示例做了一些不同的事情。

  2. 如果我加载了四张图片,我可以为每张图片重复使用相同的顶点和片段着色器吗?

  3. 我目前关于在 2x2 网格中渲染图像的想法是在每个象限(-1 到 0、0 到 1 等)中创建 4 vertices[]。这意味着我需要 4 个顶点 VAO 对象。这是最好的方法,还是可以做一些更简单的事情?

一旦我开始工作,我会share/post为未来的读者提供代码。

如果没有任何代码提供您正在尝试做的事情的进一步上下文,就很难提供“最佳方法”。

  1. Is this the best/modern approach using a vertex shader and fragment shader? There is a lot of image examples from ~5-10 years ago that do something different.

没有看到教程,很难给出答案。但是,我假设您指的是使用固定功能管道的示例。如果是这样,那么是的,坚持使用着色器。

  1. If I have four images loaded, can I re-use the same vertex and fragment shaders for each image?

假设您的片段着色器与您链接到的片段着色器有些匹配 (4.1.texture.fs),即归结为如下内容:

#version 330 core

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

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

那么是的,您可以重复使用着色器。假设您当前的方法涉及 4 个绘制调用,那么在绘制调用之前只需 bind 所需的纹理。

  1. My current thinking on approaching rendering the images in a 2x2 grid is to create 4 vertices[] with each quadrant (-1 to 0, 0 to 1, etc). This would mean I would need 4 vertex VAO objects. Is this the best approach, or is there something simpler that can be done?

据我了解,您的顶点数据不会因每张图像而改变。只有位置,嗯,实际图像。因此,您可以在顶点着色器中使用矩阵来变换顶点,而不是复制顶点数组和顶点数据。

您将在随后的 LearnOpenGL "Transformations" 教程中了解这一点。

简而言之,您将 uniform mat4 mvp 添加到顶点着色器,并将其与顶点位置相乘,如下所示:

#version 330 core

layout (location = 0) in vec3 pos;
uniform mat4 mvp;

void main() {
    gl_Position = mvp * vec4(pos, 1.0);
}

还有其他方法,您可以通过单个绘制调用来完成您想要做的事情。

  • 您可以使用“texture atlas
  • 如果所有图片大小相同,您可以使用“array texture
  • 您还可以使用 uniform array 个纹理

要使用数组纹理,您的着色器需要指定 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);
}