我想创建一个 3D 纹理,将最低(级别 0)的 mipmap 级别设置为在着色器中生成的一些数据,然后自动填充其余的 mipmap 级别。
我按如下方式创建纹理:
//Initialize texture dimensions
width = w;
height = h;
depth = d;
//set the texture rendering target, always GL_TEXTURE3D for 3D images
target = GL_TEXTURE_3D;
//Create the texture
glGenTextures(1, &textureID);
glBindTexture(target, textureID);
glObjectLabel(GL_TEXTURE, textureID, -1, "\"3D Texture\"");
//Set the texture sampling parameters
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//Allocate VRAM storage for the texture
vector<GLbyte> empty = vector<GLbyte>(width*height*depth*(32));
glTexImage3D(target, 0, GL_RGBA8, width, height, depth, 0,
GL_RGBA, GL_FLOAT, empty.data());
然后我使用 imageStore 在着色器中写入它(按 LOD 0 的预期工作)。
然后我尝试像这样生成 mipmap 级别:
glDrawArrays(GL_TRIANGLE_STRIP,0,4);
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
glGenerateTextureMipmap(textureID);
但是,这会导致在 glGenerateTextureMipmap()
处生成段错误。
我是不是在内存屏障中遗漏了一点,还是在创建纹理时没有分配足够的内存?我做错了什么?
最佳答案
您以错误的方式使用了 glMemoryBarrier
。你应该给这个函数的位域是你想要使用结果的方式。对于 mipmap 生成,不需要使用内存屏障。
您正在使用 glGenerateTextureMipmap
,但您没有使用 glCreateTextures
。为什么您有时只想使用 DSA。在任何地方使用 DSA 或不使用它(对于 glTextureParameteri、glTextureStorage3D... 也会发生同样的情况)。
您正在使用 glTexImage3D
,请改用 glTextureStorage3D
。它将节省您“无用” vector 的构建
您正在使用非 mipmap 过滤,因此请使用像 GL_NEAREST_MIPMAP_NEAREST
这样的 mipmap 过滤。我不知道这是否是崩溃的原因,但这是第一个想法。
告诉我们当您更正代码时发生了什么 ;)。 也许您可以向我们提供 ARB_DEBUG_OUTPUT 的输出,如果它告诉您任何信息的话。
关于崩溃,似乎使用 glTexStorage3D
解决了问题。我没有证据,我可能是错的,但我怀疑这种工作方式:
glTexImage3D
不分配内存,而是使用纹理进行分配。 (这就是为什么我更喜欢 Vulkan,因为它是明确的)。
因此,当您在不使用 glGenerateMipmap3D
的情况下执行 glTexImage3D
时,会发生以下情况:
使用 glTexImage3D
:假设我们需要这个尺寸的图像。使用纹理:驱动程序看到不需要 mipmapping,因此它只分配一个驱动程序,尽管有 GL_TEXTURE_MAX_LEVEL。调用 generateMipmap :崩溃,因为驱动程序试图到达尚未分配的其他层
第二种方式,在使用前使用generateMipmap :
glTexImage3D
+ generateMipmap
:我需要一张带有 mipmap 的图像。当您使用它时,驱动程序会发现您确实需要所有层,因此它会分配所需的层。
当您使用 glTextureStorage3D
时,您会明确要求图层,因此当驱动程序进行分配时,它将分配所有内容,而不仅仅是一个
关于c++ - 在 imageStore() 之后为 3D 纹理生成 MipMap 级别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51547394/