gpt4 book ai didi

opengl - 如何调整帧缓冲区中现有纹理附件的大小?

转载 作者:行者123 更新时间:2023-12-03 20:20:33 26 4
gpt4 key购买 nike

调整窗口大小时,需要调整附加到帧缓冲区的纹理的大小。我尝试使用不同的大小参数再次调用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是新尺寸。

编辑2

请告诉我为什么这被否决了,所以我可以解决这个问题。

编辑3

Here,其他人也有同样的问题。


我发现纹理已正确渲染到FBO,但是显示的尺寸错误。好像第一次将纹理发送到默认帧缓冲区时,将永久设置纹理大小,然后在发送调整大小的纹理时,将其视为原始大小。例如,如果第一个纹理为100x100,第二个纹理为50x50,则整个纹理将显示在屏幕的左下角。相反,如果原始纹理为50x50,而新纹理为100x100,则结果将是在整个屏幕上显示纹理的左下角四分之一。


但是,他使用着色器来解决此问题。那不是我想要的方式。必须有另一种解决方案,对不对?

最佳答案

如果使用glTexImage2D (...)为纹理分配存储空间,则可以随时为纹理中的任何图像重新分配存储空间,而无需先删除纹理。

但是,您没有使用glTexImage2D (...),而是正在使用glTexStorage2D (...)。这将创建一个不变的纹理对象,其存储需求仅设置一次,就无法再更改。最初分配存储后,对glTexImage2D (...)glTexStorage2D (...)的任何调用都将生成GL_INVALID_OPERATION,并且不执行其他任何操作。

如果要创建可以随时更改大小的纹理,请不要使用glTexStorage2D (...)。而是将一些用于数据类型和格式的伪(但兼容)值传递给glTexImage2D (...)



例如,如果要分配具有1个LOD为m_width x m_height的纹理:

glTexImage2D (m_target, 0, m_format, m_width, m_height, 0, GL_RED, GL_FLOAT, NULL);




如果 m_widthm_height稍后更改,则可以使用以下方式重新分配存储:

glTexImage2D (m_target, 0, m_format, m_width, m_height, 0, GL_RED, GL_FLOAT, NULL);


这与使用 glTexStorage2D (...)的情况大不相同。这将阻止您重新分配存储,并且只会创建一个 GL_INVALID_OPERATION错误。



您应该查看手册页面上的 glTexStorage2D (...),其中指出以下内容:


描述


glTexStorage2D同时指定二维纹理或一维纹理数组的所有级别的存储要求。使用此命令指定纹理后,除非它是代理纹理,否则所有级别的格式和尺寸都将变得不可变。图像的内容仍可以修改,但是其存储要求可能不会改变。这样的纹理称为不变格式纹理。

glTexStorage2D的行为取决于目标参数。



当目标是 GL_TEXTURE_2D, GL_PROXY_TEXTURE_2DGL_TEXTURE_RECTANGLEGL_PROXY_TEXTURE_RECTANGLEGL_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_1DGL_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));
}




由于实际上没有提供纹理数据,因此在 formattype的伪代码中使用的值无关紧要,并且可以认为是对于所选 internalformat枚举器合法的任何值。 [...]成功后, GL_TEXTURE_IMMUTABLE_FORMAT的值将变为 GL_TRUE。可以通过在 GL_TEXTURE_IMMUTABLE_FORMAT设置为 pname的情况下调用glGetTexParameter来发现 GL_TEXTURE_IMMUTABLE_FORMAT的值。不能对纹理对象的尺寸或格式做进一步的更改。使用任何可能会更改纹理对象的尺寸或格式的命令(例如glTexImage2D或对glTexStorage2D的另一次调用)都会导致产生 GL_INVALID_OPERATION错误,即使实际上不会更改尺寸或格式对象。

关于opengl - 如何调整帧缓冲区中现有纹理附件的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23362497/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com