0

根据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

4

1 回答 1

3

无论最后一个参数是否为 NULL(假设不使用 PBO),formattype参数必须始终是相对于参数的合法值internalformat

话虽这么说,像素传输 formattype参数完全匹配并不是绝对必要的internalformat。但它们必须与它兼容,符合像素传输兼容性的规则。在您引用的特定情况下,formatandtype值都与使用的任何一个internalforamts 兼容。所以理论上你可以这样做:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

话虽如此,您不应该这样做,原因有两个:

  1. 你不应该编写你不想真正执行的代码。让实现手动将无符号规范化字节转换为 16 位浮点数会降低性能。即使由于指针为 NULL 而实际上不会进行该转换,您仍然不会希望它实际发生。因此,编写有意义的代码。

  2. 您必须记住像素传输兼容性的所有规则。因为如果你弄错了,如果你要求进行非法转换,你会得到一个 OpenGL 错误,从而导致代码损坏。如果您不习惯总是考虑您的formattype参数是什么,那么切换到整数纹理并立即收到错误非常容易,因为您没有使用其中一种_INTEGER格式。然而,如果您一直在考虑代表internalformat您实际使用的像素传输参数,您将永远不会遇到该错误。

于 2018-09-09T15:25:24.907 回答