当我调整窗口大小时,我需要调整附加到帧缓冲区的纹理。我尝试使用不同的大小参数再次调用glTexStorage2D。然而,这不起作用。
如何调整附加到帧缓冲区的纹理? (包括深度附件)
修改
我试过的代码:
glBindTexture(m_target, m_name);
glTexStorage2D(m_target, 1, m_format, m_width, m_height);
glBindTexture(m_target, 0);
其中m_name,m_target和m_format是从原始纹理中保存的,m_width和m_height是新维度。
EDIT2
请告诉我为什么这个被投票,所以我可以解决这个问题。
EDIT3
Here,其他人也有同样的问题。
我发现纹理正确地呈现给FBO,但它显示的大小错误。就好像第一次将纹理发送到默认帧缓冲区时,纹理大小是永久设置的,然后当发送一个调整大小的纹理时,它被视为原始大小。例如,如果第一个纹理为100x100,第二个纹理为50x50,则整个纹理将显示在屏幕的左下角。相反,如果原始纹理为50x50,新纹理为100x100,则结果将是整个屏幕上显示的纹理的左下角四分之一。
但是,他使用着色器修复此问题。那不是我想要做的。必须有另一种解决方案,对吧?
答案 0 :(得分:20)
如果您使用glTexImage2D (...)
为纹理分配存储空间,则可以随时为纹理中的任何图像重新分配存储空间,而无需先删除纹理。
但是,您使用glTexImage2D (...)
不 ,您正在使用glTexStorage2D (...)
。这会创建一个 不可变的 纹理对象,其存储要求设置一次,永远不会再次更改。在您最初分配存储空间后,对glTexImage2D (...)
或glTexStorage2D (...)
的任何来电都会生成GL_INVALID_OPERATION
,而不会执行任何操作。
如果要创建可随时更改大小的纹理,请不要使用glTexStorage2D (...)
。相反,将数据类型和格式的一些虚拟(但兼容的)值传递给glTexImage2D (...)
。
m_width
x m_height
:glTexImage2D (m_target, 0, m_format, m_width, m_height, 0, GL_RED, GL_FLOAT, NULL);
m_width
或m_height
,您可以采用相同的方式重新分配存储空间:glTexImage2D (m_target, 0, m_format, m_width, m_height, 0, GL_RED, GL_FLOAT, NULL);
这种情况与使用glTexStorage2D (...)
的情况完全不同。这将阻止您重新分配存储空间,并且只会创建GL_INVALID_OPERATION
错误。
glTexStorage2D (...)
的手册页,其中说明了以下内容:<强>描述强>
glTexStorage2D同时指定二维纹理或一维纹理阵列的所有级别的存储要求。 使用此命令指定纹理后,除非是代理纹理,否则所有级别的格式和尺寸都将变为不可变。 图像的内容可能仍会被修改,< strong> 但是,其存储要求可能不会更改 。这种纹理称为 不可变格式纹理 。
glTexStorage2D 的行为取决于目标参数。
当目标为GL_TEXTURE_2D, GL_PROXY_TEXTURE_2D
,GL_TEXTURE_RECTANGLE
,GL_PROXY_TEXTURE_RECTANGLE
或GL_PROXY_TEXTURE_CUBE_MAP
时,假设没有生成错误,调用 glTexStorage2D 等同于执行以下伪代码:
for (i = 0; i < levels; i++) {
glTexImage2D(target, i, internalformat, width, height, 0, format, type, NULL);
width = max(1, (width / 2));
height = max(1, (height / 2));
}
当目标为GL_TEXTURE_CUBE_MAP
时, glTexStorage2D 相当于:
for (i = 0; i < levels; i++) {
for (face in (+X, -X, +Y, -Y, +Z, -Z)) {
glTexImage2D(face, i, internalformat, width, height, 0, format, type, NULL);
}
width = max(1, (width / 2));
height = max(1, (height / 2));
}
当目标为GL_TEXTURE_1D
或GL_TEXTURE_1D_ARRAY
时, glTexStorage2D 相当于:
for (i = 0; i < levels; i++) {
glTexImage2D(target, i, internalformat, width, height, 0, format, type, NULL);
width = max(1, (width / 2));
}
由于实际上没有提供纹理数据,因此
format
和type
的伪代码中使用的值无关紧要,可以认为是 任何合法的值所选internalformat
枚举的 。 [...]成功后,GL_TEXTURE_IMMUTABLE_FORMAT
的值变为GL_TRUE
。可以通过调用 glGetTexParameter 并将GL_TEXTURE_IMMUTABLE_FORMAT
设置为pname
来发现GL_TEXTURE_IMMUTABLE_FORMAT
的值。不能进一步改变纹理对象的尺寸或格式。使用可能改变纹理对象的尺寸或格式的任何命令(例如 glTexImage2D 或对 glTexStorage2D 的另一次调用)将导致生成GL_INVALID_OPERATION
错误,即使它实际上不会改变对象的尺寸或格式。