0%

Notes on Data Formats of Graphics APIs(2)

Pixel Data Internal Format

看一下glTexImage2D的函数签名,有三个参数比较费解,分别是internalformatformattype。这三个参数相互配合,共同决定了OpenGL Texture数据的在GPU上的格式以及内存数据从CPU-〉GPU上传过程中如何被‘解析’。

1
2
3
4
5
6
7
8
9
void glTexImage2D(GLenum target,
GLint level,
GLint internalformat,
GLsizei width,
GLsizei height,
GLint border,
GLenum format,
GLenum type,
const void * data);

Difference between format and internalformat中说的很直截了当,internalFormat决定GPU,format/type决定CPU数据。

The format (7th argument), together with the type argument, describes the data you pass in as the last argument. So the format/type combination defines the memory layout of the data you pass in.
internalFormat (2nd argument) defines the format that OpenGL should use to store the data internally.

这个描述是否让你觉得,如果data参数为null,format/type就不需要设置,或者随意设置了,答案是否定的。 对于glTexImage2D来说,不管data参数是否为null,internalFormatformat/type一定要是兼容的组合。

Note Even if data is NULL, the format and type fields must be legal fields, or the entire call will fail with a GL_INVALID_ENUM error.Texture_Storage

glTexImage2D做了两件事情,分配显存,并上传数据,所以需要格式的兼容,这个显存分配过程也被称作Mutable Storage。 还有一组Immutable Storage的分配方式,把glTexImage2D的分配显存和上传数据的两个过程分开,如此,在某些情况下(比如Texture as RT),可以不关心format/type的设置了。

1
2
void glTexStorage2D( GLenum target​, GLint levels​, GLint internalformat​, GLsizei width​, GLsizei height​ );
void glTexSubImage2D(GLenum target​, GLint level​, GLint xoffset​, GLint yoffset​, GLsizei width​, GLsizei height​, GLenum format​, GLenum type​, const GLvoid * data​);

Pixel Data格式的兼容

internalFormatformat/type,首先确定internalFormat,然后根据实际情况确定与其兼容的format/type,类型的兼容只是最低要求,如果没有正确设置这三个参数,数据在上传的时候,会有类型转换,那你精心组织的数据,可能就要以其他面目呈现给GL了。

举个例子:参考下面的格式语法,如果你想要4通道每个通道都是浮点型的格式,设置internalFormatGL_RGBAformat/typeGL_RGBA/GL_FLOATGL_RGBA表示unsigned normalized integer format,且每格通道8位,也就是8位无符号归一化整型,如此,GL_FLOAT则会类型转换到8 bit unsigned normalized integer

再举个例子:internalFormatGL_R32UItype就是GL_UNSIGNED_INT了,那么format就决定了数据初始化了,如果是GL_RED,会把输入作为定点数归一化到[0, 1], 正确的格式应该是GL_RED_INTEGER

GL_RED
Each element is a single red component. For fixed point normalized components, the GL converts it to floating point, clamps to the range [0,1], and assembles it into an RGBA element by attaching 0.0 for green and blue, and 1.0 for alpha.es3.0 glTexImage2D

另外,整型类型的Texture,不能设置为linear filteringGL_LINEAR,只能设置为GL_NEAREST或者GL_NEAREST_MIPMAP_NEAREST

Notes-on-Data-Formats-of-Graphics-APIs/color_format_syntax

Pixel Formats Cheatsheets

es3.0 glTexImage2D Table 2. Sized Internal Formats
gl_texture_format_util.hpp
OpenGL image formats

参考