关闭

OpenGL API 之 glTexImage2D

151人阅读 评论(0) 收藏 举报
分类:
 http://blog.csdn.net/hsujouchen/article/details/4204969

OpenGL API 之 glTexImage2D

glTexImage2D在OpenGL中主要用来指定二维纹理和立方体纹理,函数原型如下(OpenGL 2.1):

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

参数:

target :指定纹理单元的类型是哪一种,必须指定为 GL_TEXTURE_2DGL_PROXY_TEXTURE_2D,GL_TEXTURE_CUBE_MAP_POSITIVE_XGL_TEXTURE_CUBE_MAP_NEGATIVE_XGL_TEXTURE_CUBE_MAP_POSITIVE_Y,GL_TEXTURE_CUBE_MAP_NEGATIVE_YGL_TEXTURE_CUBE_MAP_POSITIVE_ZGL_TEXTURE_CUBE_MAP_NEGATIVE_Z, orGL_PROXY_TEXTURE_CUBE_MAP中的一个。二维纹理需要指定为GL_TEXTURE_2D

level:指定纹理单元的层次,非mipmap纹理level设置为0,mipmap纹理设置为纹理的层级

internalFormat:指定OpenGL是如何管理纹理单元中数据格式的。网络上很多解释说这个参数必须和后面的format参数一样,这个说法是不正确的

width:指定纹理单元的宽度

height:指定纹理单元的高度

border:指定纹理单元的边框,如果包含边框取值为1,不包含边框取值为0

format:指定data所指向的数据的格式

type:指定data所指向的数据的类型

data:实际指向的数据是什么,这个参数有两种解释

下面对这些参数作更详细的解释,记录下来备忘。


target:由于目前只用到了二维纹理的部分,因此这个参数必须指定为GL_TEXTURE_2D

level:目前只用在非mipmap纹理方式下,因此这个参数必须设置为0

internalFormat:对于这个参数需要重点解释一下,以前的使用中一般也是参考网络上的解释将它和后面的format参数设置为一样的,但是具体是什么原因并不清楚。查阅一些资料后,对这个参数有了更好的理解。

以下是stackoverflow 中的一段解释:

The format and type parameters describe the data you are passing to OpenGL as part of a pixel transfer operation. The internalforamt describes the format of the texture. You're telling OpenGL that you're giving it takes that looks like X, and OpenGL is to store it in a texture where the data is Y. Theinternalformat is "Y".

从描述中我们知道:internalFormat用来指定OpenGL中纹理单元中的格式是什么样的,而参数中的后三个(format 、type、 data)是用来指定用来传输到OpenGL中纹理单元数据的格式是怎么样的。回忆一下我们是如何加载一张图片作为纹理的,一般过程如下:

  1. 读取一张图片到内存中的某处(假设到pBytes指向的内存中)
  2. 生成一个绑定纹理ID(假设为texID),并绑定纹理ID到一个纹理单元(glGenTexture和glBindTexture)
  3. 使用glTexImage2D将内存中的数据拷贝到OpenGL纹理单元中
  4. 设置纹理单元的过滤方式、插值方式等(一般是使用glTexParameter)
  5. 绑定纹理(texID)并使用纹理

上面的internalForamt参数指定的就是texID对应纹理单元中的数据格式(An Image Format describes the way that the images in Textures and renderbuffers store their data. They define the meaning of the image's data.),它是对OpenGL硬件驱动的一种很强的提示,告诉驱动它里面的数据是怎么组织的。

因此如果我们将internalForamt中的格式指定的和format中格式一致就可以更快地进行传输,而不需要在二者之间进行转换。


format、type、data指定的是pBytes中数据是怎么样组织的(A Pixel Transfer operation is the act of taking pixel data from an unformatted memory buffer and copying it in OpenGL-owned storag)

参数format和type指定了pBytes中的像素数据该如何解译:

其中format指定了每一个像素所包含的成分以及这些成分的顺序是怎么样的,比如:GL_RGBA指定了每个像素包含RGBA四个部分,顺序是R、G、B、A 而如果我们指定GL_BGRA则说明每个像素包含四个部分,但是顺序却不一样;

type则指定每一个成分需要几个字节来表示,比如我们指定GL_UNSIGNED_BYTE在说明每个成分需要一个unsigned byte来表示也就是一个字节,type的取值还包括:

  • GL_(UNSIGNED_)BYTE​: 1 byte
  • GL_(UNSIGNED_)SHORT​: 2 bytes
  • GL_(UNSIGNED_)INT​: 4 bytes
  • GL_HALF_FLOAT​: 2 bytes
  • GL_FLOAT​: 4 bytes

参数data在上文中说有两种解释:

1.当有缓冲区绑定到 GL_PIXEL_PACK/UNPACK_BUFFER 时,这时候使用了PBO(Pixel Buffer Object),此时的data是一个指向缓冲区对象数据的偏移量

2.当没有缓冲区绑定到GL_PIXEL_PACK/UNPACK_BUFFER 时,这是data是指向内存中的指针(上文中提到的pBytes)

这两者之间的转换过程:(将Memory中的格式转换为纹理中的格式的过程):

包括如下两个阶段:

先将Memory转换为RGBA的方式(中间过程),转换方式:

Memory                                            RGBA (中间过程)
----------------------------------------------------------------
RED                                                           R001
----------------------------------------------------------------
GREEN                                                       0G01
----------------------------------------------------------------
BLUE                                                          00B1
----------------------------------------------------------------
ALPHA                                                         000A
----------------------------------------------------------------
RGB                                                            RGB1
----------------------------------------------------------------
RGBA                                                           RGBA
----------------------------------------------------------------
LUMINANCE                                               LLL1
----------------------------------------------------------------
LUMINANCE_ALPHA                               LLLA 
----------------------------------------------------------------

之后再从中间过程的RGBA转换到internalFormat指定的格式(转换的方式按下面的公式进行)

INTENSITY = R 
LUMINANCE = R 
R = R 
G = G 
B = B 
A = A

举例说明:如果你指定format是GL_RGB,但是你指定internalFormat是GL_LUMINANCE ,那么转换过程是这样的

1.现将GL_RGB转为GL_RGBA其中A都是1

2.将GL_RGBA中的R成分给解释为LUMINANCE

另外一种情况,如果你将一个GL_RGB的format指定为GL_ALPHA的internalFormat,那么得到的值全都是0

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:3571次
    • 积分:55
    • 等级:
    • 排名:千里之外
    • 原创:0篇
    • 转载:13篇
    • 译文:0篇
    • 评论:0条