【openGL2021版】纹理贴图

 【openGL2021版】纹理贴图

      大家好,我是Lampard猿奋~

      欢迎来到船新的openGL基础系列的博客,今天学习的是纹理贴图

 

 (一)回顾

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

      代码:

      效果图: 

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

(二)封装纹理类

(1)创建工具Utils

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

      代码:

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

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

(2)创建纹理类Texture

      实现从磁盘读取文件之后,我们就可以创建一个纹理类然后利用这个接口去读取磁盘中的纹理。纹理类比较简单,只需要有一个Init初始化的方法,以及一个成员变量记录创建出来的GPU的ID即可

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

(3)解码bmp纹理

      既然使用bmp文件,那么我们就需要对读取到的bmp文件内容进行解码。主要分为两步:第一是读出纹理的宽高,第二部是根据宽高拿到每个像素的rgb数据

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

 (4)让gpu生成纹理

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

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

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

(1)生成一个Texture对象

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

(2)开启GL_TEXTURE_2D

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

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

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

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

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

(四)纹理过滤模式glTexParameteri

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

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

 (1)target目标纹理

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

 (2)pname纹理参数

      纹理参数主要有四种:

      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比较模糊):

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

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

      GL_REPEAT:重复纹理

      GL_MIRRORED_REPEAT:镜像重复纹理

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

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

 

好啦今天就到这里

点赞,关注!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lampard杰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值