我真的很想了解这个问题,但是文档并没有让我明白。假设我想把32位的整数写入一个framebuffer,我没有任何像素数据要加载到纹理上,我只是在创建一个framebuffer。
void glTexImage2D( GLenum target,
GLint level,
GLint internalformat,
GLsizei width,
GLsizei height,
GLint border,
GLenum format,
GLenum type,
const void * data);
文档中暗示,最后两个枚举,format和type是用来知道被读入的像素数据是什么类型的数据,而internalFormat是用来知道用什么格式存储你创建的纹理。 我以为在你不提供任何纹理数据的情况下,最后一个参数,或者至少其中一个参数是不用的,然而我试着把它们改成其他的枚举值,却得到一个错误,可能是因为它们对于那个特定的参数来说是完全错误的枚举。
在什么情况下,最后两个枚举值没有被使用?比如说,三个枚举值中哪一个是决定在着色器中如何对纹理进行采样的?
假设我创建了两个示例帧缓冲器。
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32I, width, height, 0, GL_RED_INTEGER, GL_INT, NULL);
我的想法是,我想把整数值写入这个framebuffer,所以在framment shader中我这样做。
out int outIntValue
int main()
{
outIntValue = 7;
// not
// outIntValue.r = 7;
right?
}
在片段着色器中,我这样做:
layout (binding = 0) uniform isampler2D texture1;
int main()
{
int val = texture(texture1, vec2(0.5, 0.5).r; // .r right?
}
在32位浮动帧缓冲区的情况下,我这样创建它:
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, width, height, 0, GL_RED, GL_FLOAT, NULL);
我把它写成这样:
out int outFloatValue;
int main()
{
outFloatValue = 0.7;
// not
// outFloatValue.r = 0.7;
}
然后像这样采样
layout (binding = 0) uniform sampler2D texture1;
int main()
{
float val = texture(texture1, vec2(0.5, 0.5).r; // .r right?
}
另外,在这两种情况下,最后两个枚举值在哪种情况下没有作用?谢谢。
有一个重要的规则你必须考虑与积分格式有关。
从... OpenGL 4.6 API Core Profile Specification - 8.5 纹理图像规范 (第215页)。
如果内部格式是整数,而格式不是表8.3所列的整数格式之一,或如果内部格式不是整数,而格式是整数格式,则产生INVALID_OPERATION错误。
例如,整数格式有 RED_INTEGER
, RG_INTEGER
, RGB_INTEGER
...
.注意,在某些情况下 内部格式 和 格式化 产生一个错误。如果没有产生错误,那么就可以了。格式化 和 类型 不影响 内部格式 目标缓冲区的值,完全独立于最后一个参数(资料). 唯一的问题是你到底有没有收到错误,这可以在规范中读到。
在纹理被填满的那一刻,内部函数接收到的数据是 原始 字节。
因为每种数字类型(短、int、float等)都有不同的内存表示格式,所以读取函数必须知道要使用的格式。它还必须知道它要读的是什么(通道red,或者同时读几个通道等)。
在什么情况下不使用最后两个枚举?
从不使用。它们总是被使用。
在什么情况下不使用最后两个枚举?
来自OpenGL 4.6(核心配置文件)--2019年10月22日,第203页。
format, type, and data specify the format of
the image data, the type of those data, and a reference to the image data in the
currently bound pixel unpack buffer or client memory, as described in section
看起来它们不是 "二手" 如果 data
是 NULL
但它们总是被对照检查。internalFormat
如果你指定了一个非法的组合,你会得到一个错误。我想这是你在C API中所能做的最好的事情了。
比如说,三个枚举值中哪一个是决定在着色器中如何对纹理进行采样的?
只有 internalFormat
以及从着色器的角度来看,采样配置数。