When I resize my window, I need to resize my textures that are attached to my framebuffer. I tried calling glTexStorage2D again, with different size parameters. However that does not work.
How can I resize the textures attached to my framebuffer? (Including the depth attachment)
EDIT
Code I tried:
glBindTexture(m_target, m_name);
glTexStorage2D(m_target, 1, m_format, m_width, m_height);
glBindTexture(m_target, 0);
Run Code Online (Sandbox Code Playgroud)
where m_name, m_target and m_format are saved from the original texture and m_width and m_height are the new dimensions.
EDIT2
Please tell me why this has been downvoted so I can fix the question.
EDIT3
Here, someone else had the same problem.
I found that the texture was being rendered correctly to the FBO, but that it was being displayed at the wrong size. It was as if the first time the texture was sent to the default framebuffer the texture size was set permanently, and then when a resized texture was sent it was being treated as if it was the original size. For example, if the first texture was 100x100 and the second texture was 50x50 then the entire texture would be displayed in the bottom left quarter of the screen. Conversely, if the original texture was 50x50 and the new texture 100x100 then the result would be the bottom left quarter of the texture being displayed over the whole screen.
However, he uses a shader to fix this. That's not how I want to do this. There has to be another solution, right?
And*_*man 22
如果您使用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);
Run Code Online (Sandbox Code Playgroud)
m_width
或m_height
稍后更改,您可以以相同的方式重新分配存储:glTexImage2D (m_target, 0, m_format, m_width, m_height, 0, GL_RED, GL_FLOAT, NULL);
Run Code Online (Sandbox Code Playgroud)
这种情况与您使用时的情况完全不同glTexStorage2D (...)
.这将阻止您重新分配存储,并且只会创建GL_INVALID_OPERATION
错误.
glTexStorage2D (...)
,其中说明以下内容:描述
glTexStorage2D同时指定二维纹理或一维纹理阵列的所有级别的存储要求.使用此命令指定纹理后,除非它是代理纹理,否则所有级别的格式和维度都将变为不可变.仍然可以修改图像的内容,但是,其存储要求可能不会改变.这种纹理被称为不可变格式纹理.
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));
}
Run Code Online (Sandbox Code Playgroud)
当目标是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));
}
Run Code Online (Sandbox Code Playgroud)
当target为GL_TEXTURE_1D
or时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));
}
Run Code Online (Sandbox Code Playgroud)
由于实际上没有提供纹理数据,因此伪代码中使用的值
format
和type
不相关,并且可以被认为是对于所选择的internalformat
枚举是合法的任何值.[...]成功后,价值GL_TEXTURE_IMMUTABLE_FORMAT
就变成了GL_TRUE
.GL_TEXTURE_IMMUTABLE_FORMAT
可以通过调用glGetTexParameter并将其pname
设置为来发现值GL_TEXTURE_IMMUTABLE_FORMAT
.不能进一步改变纹理对象的尺寸或格式.使用可能改变纹理对象的维度或格式的任何命令(例如glTexImage2D或对glTexStorage2D的另一个调用)将导致生成GL_INVALID_OPERATION
错误,即使它实际上不会改变对象的维度或格式.