Opengl 如何在帧缓冲区调整现有纹理附件的大小?
调整窗口大小时,需要调整附加到帧缓冲区的纹理的大小。我尝试使用不同的大小参数再次调用glTexStorage2D。然而,这是行不通的 如何调整附加到帧缓冲区的纹理的大小?(包括深度附件) 编辑 我试过的代码:Opengl 如何在帧缓冲区调整现有纹理附件的大小?,opengl,fbo,Opengl,Fbo,调整窗口大小时,需要调整附加到帧缓冲区的纹理的大小。我尝试使用不同的大小参数再次调用glTexStorage2D。然而,这是行不通的 如何调整附加到帧缓冲区的纹理的大小?(包括深度附件) 编辑 我试过的代码: glBindTexture(m_target, m_name); glTexStorage2D(m_target, 1, m_format, m_width, m_height); glBindTexture(m_target, 0); 其中,m_名称、m_目标和m_格式是从原始纹理保存
glBindTexture(m_target, m_name);
glTexStorage2D(m_target, 1, m_format, m_width, m_height);
glBindTexture(m_target, 0);
其中,m_名称、m_目标和m_格式是从原始纹理保存的,m_宽度和m_高度是新的尺寸
EDIT2
请告诉我为什么这被否决了,这样我就可以解决这个问题了
EDIT3
,其他人也有同样的问题
我发现纹理被正确地渲染到FBO,但显示的大小不正确。就好像第一次将纹理发送到默认帧缓冲区时,纹理大小被永久设置,然后当发送调整大小的纹理时,它被视为原始大小。例如,如果第一个纹理为100x100,第二个纹理为50x50,则整个纹理将显示在屏幕的左下角。相反,如果原始纹理为50x50,新纹理为100x100,则结果将是整个屏幕上显示的纹理的左下四分之一
但是,他使用着色器来修复此问题。我不想这样做。必须有另一种解决方案,对吗?如果使用
GLTEXAGE2D(…)
为纹理分配存储,则可以在任何时候为纹理中的任何图像重新分配存储,而无需先删除纹理
但是,您使用的不是glTexImage2D(…)
,而是glTexStorage2D(…)
。这将创建一个不可变的纹理对象,该对象的存储要求只设置一次,不能再更改。最初分配存储后,对glTexImage2D(…)
或glTexStorage2D(…)
的任何调用都将生成GL\u INVALID\u操作
,而不执行其他操作
如果要创建大小可以随时更改的纹理,请不要使用glTexStorage2D(…)
。相反,将数据类型和格式的一些伪(但兼容)值传递给glTexImage2D(…)
例如,如果要分配一个LOD为
m\u width
xm\u height
的纹理:
如果以后更改m_宽度
或m_高度
,则可以使用相同的方法重新分配存储:
与使用glTexStorage2D(…)
相比,这是一种非常不同的情况。这将阻止您重新分配存储,只会创建一个GL\u INVALID\u操作
错误
您应该查看手册页,了解以下内容: 说明 同时指定二维纹理或一维纹理阵列的所有级别的存储要求使用此命令指定纹理后,除非它是代理纹理,否则所有级别的格式和尺寸都将保持不变。图像的内容仍然可以修改,但是,其存储要求可能不会更改。。这种纹理称为不可变格式纹理 glTexStorage2D的行为取决于目标参数 当目标为
GL\u TEXTURE\u 2D、GL\u PROXY\u TEXTURE\u 2D
、GL\u TEXTURE\u RECTANGLE
、GL\u PROXY\u TEXTURE\u RECTANGLE或GL\u PROXY\u TEXTURE\u CUBE\u 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_纹理_1D
或GL_纹理_1D_数组
时,gltextorage2d相当于:
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));
}
for (i = 0; i < levels; i++) {
glTexImage2D(target, i, internalformat, width, height, 0, format, type, NULL);
width = max(1, (width / 2));
}
for(i=0;i
由于没有实际提供纹理数据,因此格式
和类型
的伪代码中使用的值是不相关的,并且可能被视为对于所选内部格式
枚举器合法的任何值。[…]成功后,GL\u纹理\u不可变\u格式
的值变为GL\u真
。GL\u TEXTURE\u IMMUTABLE\u FORMAT
的值可以通过调用glGetTexParameter来发现,并将pname
设置为GL\u TEXTURE\u IMMUTABLE\u FORMAT
。不得对纹理对象的尺寸或格式进行进一步更改。使用任何可能改变纹理对象的尺寸或格式的命令(例如glTexImage2D或另一个调用glTexStorage2D)将导致生成GL\u INVALID\u操作
错误,即使实际上不会改变对象的尺寸或格式
您必须重新创建纹理句柄。因此,如果要调整窗口大小,我不应该使用glTexStorage?如果您希望纹理与窗口的比例为1:1,则不应该使用glTexStorage。您总是可以提前调整纹理的大小,也可以进行高级调整。但是
glTexStorage(…)
阻止您在创建纹理后重新调整纹理大小<另一方面,code>glTexImage2D(…),将允许您随时更改它。
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));
}
for (i = 0; i < levels; i++) {
glTexImage2D(target, i, internalformat, width, height, 0, format, type, NULL);
width = max(1, (width / 2));
}