OpenGL学习笔记(一) 纹理基础知识

一篇纹理的详细介绍文章http://www.gesoftfactory.com/developer/Textures.htm

OpenGL函数库文档 http://www.opengl.org/sdk/docs/man , http://www.opengl.org/sdk/docs/man/xhtml

 

纹理知识总结

1,加载更新纹理

加载纹理:glTexImage, glCopyTexImage

更新纹理:glTexSubImage, glCopyTexSubImage

注:纹理的宽度,高度,深度,必须为2n

 

2,纹理坐标

指定纹理坐标 glTexCoord

纹理矩阵          glMatrixMode(GL_TEXTURE);//可以对纹理坐标执行变换,当然最终结果会执行相应的纹理环绕模式

 

3,纹理环境(底层几何图形与纹理的融合方式)

void glTexEnv[i|f]{v}(GLenum target, GLenum pname, [GLint|GLfloat]{*} param);

target:    GL_TEXTURE_ENV

pname:  GL_TEXTURE_MODE

param:   GL_MODULATE(光照后的几何与纹理相乘)

               GL_REPLACE(直接用纹理颜色替换)

               GL_DECAL(如果纹理有alpha元素,则执行混合。)

 

4,纹理参数:

void glTexParameteri(GLenum target,GLenum  pname,GLint param)

target:GL_TEXTURE_[1|2|3]D

A.纹理过滤

        过滤器(pname): GL_TEXTURE_MAG_FILTER(纹理放大时), GL_TEXTURE_MIN_FILTER(纹理缩小时)

        过滤参数(param):GL_NEARST(最邻近的像素),GL_LINEAR(线性插值)

B.纹理环绕

       环绕方向(pname):GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T, GL_TEXTURE_WRAP_R  //分别为x,y,z方向。

       参数(param):(以下,n为纹理方向上的纹理的长度)

       GL_REPEAT,                       //相当于忽略掉纹理坐标的整数部分。滤镜为线性时,处于[1/2n,1]与第一个纹理像素融合。处于[0,1/2n]与最后一个像素融合

       GL_MIRRORED_REPEAT,   //相当于将纹理坐标1.1变成0.9,达到镜像反射的效果

       GL_CLAMP,                        //截取纹理坐标到 [0,1] 。将导致纹理坐标处于[1-1/2n, 1]的像素,在纹理滤镜为线性滤镜时,与border融合,最终纹理坐标为1的像素,将为border和边界像素的中值。

       GL_CLAMP_TO_EDGE,       //截取纹理坐标到[1/2n,1-1/2n]。将导致永远不会与border融合

       GL_CLAMP_TO_BORDER   //截取纹理坐标到[-1/2n,1+1/2n]。将导致纹理坐标处于[1-1/2n,1+1/2n]范围内的像素,在纹理滤镜为线性滤镜时,与border融合,最终纹理坐标为1+1/2n的像素将于border同色。

 

下图显示不同参数的效果:

将1张2*2的纹理(分别为红,绿,蓝,黑),贴到一个方块左下角。

方块四个点的纹理坐标依次指定为(0,0), (2,0), (2,2), (0,2)。

根据上述的规则,坐标将进行截取,截取到相应的范围。

我们绘制暗白色线将纹理坐标为1的地方在图中标注出来:

注:border颜色默认为黑色

 滤镜:GL_NEAREST 缠绕模式:GL_CLAMP 或 GL_CLAMP_TO_EDGE

 

滤镜:GL_NEAREST  缠绕模式:GL_CLAMP_TO_BORDER。

滤镜:GL_LINEAR  缠绕模式:GL_CLAMP。

 

滤镜:GL_NEAREST  缠绕模式:GL_CLAMP_TO_EDGE。

滤镜:GL_NEAREST  缠绕模式:GL_CLAMP_TO_BORDER。

 

       注:关于GL_CLAMP_TO_BORDER用处,请参考  Texture Borders and Tiling

C.Mip贴图 

       glTexImage中的level可以指定加载的mip层的序号。0为最高细节。

       以下函数可以指定加载层范围

                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL,0);

                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL,4);

                可以通过GL_TEXTURE_MIN_LOD,GL_TEXTURE_MAX_LOD,参数来控制使用层的范围

        mip贴图过滤模式

                必须指定才能启动mipmap(形式为GL_FILTER_MIPMAP_SELECTOR)

        产生mip层

                 int gluBuild[1|2|3]DMipMaps 可以直接生成所有mip层次的纹理。

                 int gluBuild[1|2|3]DMipMapLevels 可以更加精细控制加载层的层次,并生成所有层次

       mip贴图硬件生成

                 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);

       LOD偏好 (负数代表倾向于选择更低序号的层次(更高细节))

                 glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -1.5);

 

5,纹理对象

分配纹理对象 void glGenTextures(GLsizei n, GLuint *textures);

绑定纹理对象 void glBindTexture(GLenum target, GLuint texture);

删除纹理对象 void glDeleteTextures(GLsizei n, GLuint *textures);

查询  GLboolean glIsTexture(GLuint texture);

对象的好处在于使不同的纹理、纹理状态以及装载相互独立。并可以在渲染的时候快速切换。

 

省略内容:常驻纹理、纹理优先级

你可能感兴趣的:(OpenGL学习)