使用 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
这是使用顶点着色器和片段着色器的best/modern方法吗?大约 5-10 年前有很多图像示例做了一些不同的事情。
如果我加载了四张图片,我可以为每张图片重复使用相同的顶点和片段着色器吗?
我目前关于在 2x2 网格中渲染图像的想法是在每个象限(-1 到 0、0 到 1 等)中创建 4 vertices[]
。这意味着我需要 4 个顶点 VAO 对象。这是最好的方法,还是可以做一些更简单的事情?
一旦我开始工作,我会share/post为未来的读者提供代码。
如果没有任何代码提供您正在尝试做的事情的进一步上下文,就很难提供“最佳方法”。
- 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.
没有看到教程,很难给出答案。但是,我假设您指的是使用固定功能管道的示例。如果是这样,那么是的,坚持使用着色器。
- 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 所需的纹理。
- 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);
}
我正在学习 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
这是使用顶点着色器和片段着色器的best/modern方法吗?大约 5-10 年前有很多图像示例做了一些不同的事情。
如果我加载了四张图片,我可以为每张图片重复使用相同的顶点和片段着色器吗?
我目前关于在 2x2 网格中渲染图像的想法是在每个象限(-1 到 0、0 到 1 等)中创建 4
vertices[]
。这意味着我需要 4 个顶点 VAO 对象。这是最好的方法,还是可以做一些更简单的事情?
一旦我开始工作,我会share/post为未来的读者提供代码。
如果没有任何代码提供您正在尝试做的事情的进一步上下文,就很难提供“最佳方法”。
- 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.
没有看到教程,很难给出答案。但是,我假设您指的是使用固定功能管道的示例。如果是这样,那么是的,坚持使用着色器。
- 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 所需的纹理。
- 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);
}