【openGL2021版】纹理贴图

      大家好,我是Lampard猿奋~

今天学习的是纹理贴图

 

Python裁剪astc纹理头文件_图形学

 (一)回顾

      上周我们学习了openGL的固定管线光照,制作了一个“躺着的”三角形(顶点的Z轴坐标不同),并给三个点设置了不同的法线方向以至呈现不同的颜色

      代码:

Python裁剪astc纹理头文件_opengl_02

      效果图: 

Python裁剪astc纹理头文件_opengl_03

       今天就是要为这个三角形贴上纹理图片,给它换一个皮肤

(二)封装纹理类

(1)创建工具Utils

      要给三角形创建一个皮肤,那么首先就要把我们的纹理图片,从磁盘读取到内存中,然后再从内存读取到显存中去。因此我们需要一个工具类Utils帮助我们去读取信息

      代码:

Python裁剪astc纹理头文件_opengl_04

      然后我们创建一个txt去测试是否读取数据成功

Python裁剪astc纹理头文件_宽高_05

引入Util库然后读取这个txt即可

Python裁剪astc纹理头文件_初始化_06

(2)创建纹理类Texture

     ,只需要有一个Init初始化的方法,以及一个成员变量记录创建出来的GPU的ID即可

Python裁剪astc纹理头文件_宽高_07

      紧接着就是实现这个初始化函数。纹理的格式有png,jpg,bmp等等格式。测试用例中会使用格式简单bmp图片,并对其进行解码。之后使用png或者jpg图片的时候会利用第三方库

Python裁剪astc纹理头文件_图形学_08

(3)解码bmp纹理

     第一是读出纹理的宽高,第二部是根据宽高拿到每个像素的rgb数据

Python裁剪astc纹理头文件_Python裁剪astc纹理头文件_09

       此时我们可以在main中我们可以实例化一个纹理对象,然后设置断点看看此时的宽高的数据是不是正确的(此时的width喝height都有数据,证明成功读取)

Python裁剪astc纹理头文件_宽高_10

(4)让gpu生成纹理

     生成一个纹l理ID,然后绑定该Id对其进行初始化。初始化的方法为glTexParameteri一会单独来讲,在初始化完之后,就可以glTexImage2D来生成一张纹理图片了

Python裁剪astc纹理头文件_图形学_11

      创建完之后,记得delete掉之前申请的内存,避免内存泄漏此时的准备工作已经完成,紧接着就是把生成的纹理图片绑定到三角形中去了

(三)把纹理挂载到图形上

(1)生成一个Texture对象

      首先我们需要生成一个纹理对象,让它读取我们的bmp纹理,然后进行初始化

Python裁剪astc纹理头文件_opengl_12

(2)开启GL_TEXTURE_2D

      通过glEnable(GL_TEXTURE_2D)和glBindTexture(GL_TEXTURE_2D, texture.mTextureId);来把生成的纹理对象设置为当前使用的2d纹理对象

      最后再通过glTexCoord2f来设置每个点对应的纹理坐标就可以了,示例代码如下:

Python裁剪astc纹理头文件_宽高_13

(3)不要在openGL初始化之前生成纹理对象

      当按照上面的流程走完之后,得到的结果却没有变化。根据调试之后看到,我们通过glGenTextures生成的纹理Id返回值是0,那就是生成不成功,在查阅资料后得知,原因是我们在Main函数的第一行就生成了纹理,正确做法应该是在openGL初始化工作做完之后再去生成

Python裁剪astc纹理头文件_opengl_14

       然后我们就得到了一块带上皮肤的三角形,如果两个三角形拼在一起,我们就得到了一个矩形

Python裁剪astc纹理头文件_Python裁剪astc纹理头文件_15

(四)纹理过滤模式glTexParameteri

我们已经实现了给openGL的面增加纹理的功能,还剩下最后一个知识点就是在纹理对象进行Init的时候使用到的纹理过滤模式glTexParameteri

      图象从纹理图象空间映射到帧缓冲图象空间(映射需要重新构造纹理图像,这样就会造成应用到多边形上的图像失真),这时就可用glTexParmeteri()函数来确定如何把纹理象素映射成像素.

Python裁剪astc纹理头文件_图形学_16

 (1)target目标纹理

      活动纹理单元的目标纹理,GLES20.GL_TEXTURE_2D表示2D纹理,还有其他纹理,比如GLES11Ext.GL_TEXTURE_EXTERNAL_OES,这是Android特有的OES纹理,预览相机或者视频使用此纹理

 (2)pname纹理参数

      纹理参数主要有四种:

Python裁剪astc纹理头文件_初始化_17

      GL_TEXTURE_MAG_FILTER:是指纹理小于渲染屏幕,没有足够的像素映射到屏幕上的处理方法

      GL_TEXTURE_MIN_FILTER:是指纹理大于渲染屏幕,需要进行裁剪的处理方法

      GL_TEXTURE_WRAP_S和GL_TEXTURE_WRAP_T:指输入的纹理坐标参数大于1或者小于0时候对应的解决办法

 (3)param对应的参数

     GL_LINEAR来进行线性过滤,或者使用GL_NEAREST取最接近的颜色作为需要绘制的像素颜色

效果如下(网图左为GL_LINEAR比较模糊):

Python裁剪astc纹理头文件_Python裁剪astc纹理头文件_18

      在输入的纹理坐标参数大于1或者小于0的时候有

      GL_CLAMP_TO_EDGE:剩余部分显示纹理临近的边缘颜色值

      GL_REPEAT:重复纹理

      GL_MIRRORED_REPEAT:镜像重复纹理

       比如说,当我把纹理坐标1都该为2的时候,此时是只有左下角是有图的,因为此时我们的参数是设置为GL_CLAMP,右下右上左上,都是取边缘的颜色也就是黑色

Python裁剪astc纹理头文件_初始化_19

       当我们把参数改为GL_REPEAT的时候,那么就会出现重复的纹理,出现四个圆

Python裁剪astc纹理头文件_初始化_20

 

好啦今天就到这里

点赞,关注!!!

Python裁剪astc纹理头文件_opengl_21