根据opengl的参考页面,glTexImage2D的结构如下所示:
void glTexImage2D( GLenum target,
GLint level,
GLint internalformat,
GLsizei width,
GLsizei height,
GLint border,
GLenum format,
GLenum type,
const GLvoid * data);
据我所知,最后 3 个参数是函数应该如何解释const GLvoid * data
给出的图像数据
同时,我正在研究帧缓冲的主题。在此链接 https://learnopengl.com/Advanced-Lighting/HDR 的"浮点帧缓冲区"部分中,编写器创建了帧缓冲区的颜色附件,如下所示
glBindTexture(GL_TEXTURE_2D, colorBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL);
我的问题是,他为什么要给GL_FLOAT作为GLenum type
的参数?如果无论如何NULL
const GLvoid * data
,是否需要使用GL_FLOAT?我最初以为它与GL_RGBA16F
有关,但是 16 位是 2 个字节,浮点数是 4 个字节,所以我想它根本不相关。
此外,在本教程之前,作者曾经制作过这样的颜色附件:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
在这种情况下,他为什么对GLenum type
参数使用GL_UNSIGNED_BYTE
?
无论最后一个参数是否为 NULL(假设未使用 PBO(,format
和type
参数必须始终是相对于internalformat
参数的合法值。
话虽如此,像素传输format
和type
参数并非绝对必要 与internalformat
完全匹配 .但它们确实必须与它兼容,符合像素传输兼容性的规则。在您引用的特定情况下,format
和type
值都与所使用的internalforamt
中的任何一个兼容。所以理论上你可以这样做:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
话虽如此,您不应该这样做,原因有两个:
你不应该编写你不想真正执行的代码。让实现手动将无符号规范化字节转换为 16 位浮点数会降低性能。即使它实际上不会执行该转换,因为指针为 NULL,您仍然不希望它实际发生。因此,编写有意义的代码。
您必须记住像素传输兼容性的所有规则。因为如果你弄错了,如果你要求非法转换,你就会得到一个OpenGL错误,从而破坏代码。如果您不习惯总是考虑
format
和type
参数是什么,那么切换到整数纹理并立即出现错误非常容易,因为您没有使用_INTEGER
格式之一。然而,如果您始终考虑代表您实际使用internalformat
的像素传输参数,则永远不会遇到该错误。