OpenGL API 之 glTexImage2D

来源:互联网 发布:azw3 打开软件 编辑:程序博客网 时间:2024/06/03 04:32
  • 原文:http://blog.csdn.net/csxiaoshui/article/details/27543615

  • 简介

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

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  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
原创粉丝点击