c++ - OpenGL -- 如何在 OpenGL 4.5 中处理多个 image1D

标签 c++ opengl

我需要将几个可变长度数组传输到着色器。所以我在glsl中建立了一个相当复杂的数据结构,其中包含多个image1D。但我现在无法成功将数据传输到着色器。

片段着色器:

struct HoleArea {
    bool clipping;
    int mesh_object_id;
    layout (rgba32f) image1D anchor_points;
    layout (rgba32f) image1D clip_planes;
};
layout (binding = 2) uniform HoleArea hole_area[10];

以及 C++ 代码:

// set the anchor_points in hole_area[0]
glBindBuffer(GL_TEXTURE_BUFFER, m_anchorPointBuffer);
glBufferData(GL_TEXTURE_BUFFER, m_anchorPointPos.size() * sizeof(FLOAT4), &m_anchorPointPos[0], GL_STATIC_DRAW);
glBindBuffer(GL_TEXTURE_BUFFER, 0);

glBindTexture(GL_TEXTURE_BUFFER, m_anchorPointTexture);
glTextureBuffer(m_anchorPointTexture, GL_RGBA32F, m_anchorPointBuffer);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glBindImageTexture(2, m_anchorPointTexture, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA32F);

这是我的问题:

  1. image1D 和 imageBuffer 有什么区别?当我需要将一维glm::vec4数组传输到着色器中时,似乎image1D和imageBuffer都可以满足要求。

  2. 图像格式有r32f、rg32f、rgba32f。为什么没有 rgb32f 格式来保存 glm::vec3 数据?

  3. 对于上面的代码,我应该如何为每个hole_area(hole_area[0],hole_area)设置anchor_pointsclip_planes [1]...)。换句话说,我应该如何为每个 image1D 设置 glBindImageTexture 中的第一个变量(图像单元的索引)。

如果有人能回答我的问题,我将非常感激,谢谢!

最佳答案

除非您使用 bindless texturing (如果是,那么您可能已经知道答案),您不能输入 opaque types like images UBO/SSBO 结构内部。

不透明类型只能是松散的统一变量;它们可以排列,但不能成为结构的一部分。

你可以这样做:

layout (binding = 0) uniform image1D hole_anchor_points[10];
layout (binding = 10) uniform image1D hole_clip_planes[10];

数组中的每个制服都有自己单独的位置,从layout限定符中指定的绑定(bind)开始。

但是,在单个着色器阶段中可以访问的图像数量是有限的。您想要尝试在一个阶段使用 20 个图像,这可能是exceeds your GPU's limits即使您正确创建了这样的数组。

如果您只想从缓冲区对象读取一些数据,则应该使用 SSBO。 SSBO 中的最后一个元素可以调整大小,从而允许您在其他地方确定其大小。您还可以指定每个数组的开始位置,从而允许您将多个数组放入 SSBO 定义的单个数组中:

layout(binding = 0, std430) readonly buffer anchor_points
{
  int arrayIxs[10]; //Index offset to the start of each array.
  vec4 array[]; //Unsized. Determined by the size of the bound buffer range.
} hole_anchor_points;

vec4 anchor_point_ix(int arrayIx, int ix)
{
  return hole_anchor_points.array[ix + hole_anchor_points.arrayIxs[arrayIx]];
}


What's the difference between image1D and imageBuffer?

一个是一维纹理;另一个是缓冲纹理。一种允许过滤,但有更严格的限制;而另一个总是准确地获取缓冲区中的内容,并且具有更大的限制。

如果您的数据已经在缓冲区中,并且您只想从中读取而不进行过滤,则应该使用缓冲区纹理。

Why there isn't a rgb32f format to save the glm::vec3 data?

因为硬件不喜欢未对齐的数据读取。

关于c++ - OpenGL -- 如何在 OpenGL 4.5 中处理多个 image1D,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67228464/

相关文章:

c++ - 在 Ubuntu 14.04 中使用 SOIL

opengl - 使用射线转换进行对象拾取

opengl - 延迟渲染 - 渲染缓冲区与纹理

c++ - 有什么方法可以通过 using 声明来提高可见度吗?

c++ - 当我在 glTexImage2D 中选择与在着色器中采样不同的内部格式时,情况会怎样?

c# - Windows Mobile native 异常 C#/C++

c++ - 允许变量相互覆盖的for循环

c++ - 指向具有移动语义的成员函数的指针

c++ - QXcbIntegration : Cannot create platform OpenGL context, GLX 和 EGL 均未启用

c++ - 在 openGL 中打印一个红色三角形