根据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
的参数?如果const GLvoid * data
是NULL
,是否需要使用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);
在这种情况下,为什么他使用GL_UNSIGNED_BYTE
作为GLenum type
参数?
答案 0 :(得分:3)
最后一个参数是否为NULL(假设未使用PBO),相对于{,format
和type
参数必须始终是合法值 {1}}参数。
话虽这么说,pixel transfer internalformat
和format
参数不必严格匹配type
。但是它们必须与pixel transfer compatibility上的规则兼容。在您引用的特定情况下,internalformat
和format
的值都与所使用的type
之一兼容。因此您可以在理论上做到这一点:
internalforamt
话虽如此,您不应该,原因有两个:
您不应编写不想真正执行的代码。手动将未签名的标准化字节转换为16位浮点数会降低性能。即使由于指针为NULL而实际上并不会进行该转换,您仍然永远不会希望它实际发生。因此,编写有意义的代码。
您必须记住所有像素传输兼容性规则。因为如果您发现它们错误,那么如果您请求非法转换,则会得到OpenGL错误,从而导致代码损坏。如果您不习惯总是考虑glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
和format
参数是什么,切换到整数纹理并立即得到错误确实很容易,因为您没有使用{{ 1}}格式。而如果您一直在考虑代表实际使用的type
的像素传输参数,则永远不会遇到该错误。