OpenGLES:3D立方体纹理贴图

效果展示

一.概述

前几篇博文讲解了OpenGLES绘制多种3D图形,并赋予丰富的色彩,但是在这些3D图形绘制过程中,有一点还没有涉及,就是纹理贴图。

今天这篇博文我会用如下六张图片对立方体进行纹理贴图,实现六个面都是贴图的3D旋转立方体

二.GLRender:变量定义

2.1 常规变量定义

//顶点坐标属性
private int vPosition;
//纹理坐标属性
private int aTextureCoord;
//转换矩阵属性
private int mvpMatrix;
//采样器
private int sampler;      //surface宽高比
private float ratio;

2.2 顶点、纹理相关变量定义

之前绘制混色旋转立方体的博文:《OpenGLES:绘制一个混色旋转的3D立方体》,定义了三个数组,在onDrawFrame()绘制时直接绘制索引实现立方体

  • 顶点坐标数组
  • 顶点颜色数组
  • 顶点索引数组

今天这篇博文对立方体的实现与之前并不相同,不再使用索引绘制,只定义并实现了两个数组:

  • 顶点坐标数组
  • 纹理坐标数组

这两个数组是必须的

//顶点坐标数组
public static float[] vertexData = new float[] {...
}
//纹理坐标数组
public static float[] textureData = new float[] {...
}//顶点坐标缓冲
private FloatBuffer vertexBuffer;
//纹理坐标缓冲
private FloatBuffer textureBuffer;

纹理和贴图也定了两个数组:

  • 纹理Id数组
  • 图片资源Id数组

图片资源Id数组并不是必须的,主要是优化纹理操作时的流程代码

//纹理id数组
private int[] textureIds;//图片资源id数组
public static int[] textureResIds = new int[]{R.drawable.cube_texture_1,R.drawable.cube_texture_2,R.drawable.cube_texture_3,R.drawable.cube_texture_4,R.drawable.cube_texture_5,R.drawable.cube_texture_6
};

2.3 定义MVP矩阵

//MVP矩阵
private float[] mMVPMatrix = new float[16];

三.GLRender:着色器、内存分配等

3.1 着色器创建、链接、使用

3.2 着色器属性获取、赋值

3.3 缓冲内存分配

这几个部分的代码实现2D图形绘制基本一致

可参考以前2D绘制的相关博文,里面都有详细的代码实现

不再重复展示代码

三.GLRender:多纹理加载

多纹理加载在之前这篇博客中有讲解过:《OpenGLES:多纹理贴图,文字水印》,其中实现了一个LoadTexture()函数,通过多次调用该函数,传入纹理Id图片资源Id实现纹理生成和贴图绑定。

本篇博文对这个函数进行优化,只需要传入图片资源Id数组,在函数内部根据图片数量完成纹理生成和绑定,并返回生成的纹理数组

代码如下:

//纹理Id根据贴图数量在Api内部创建,加载纹理贴图后返回纹理Id数组
public static int[] LoadTexture(Context context, int[] resIds) {BitmapFactory.Options options = new BitmapFactory.Options();options.inScaled = false;Bitmap[] bitmaps = new Bitmap[resIds.length];// 生成纹理idfinal int[] textureIds = new int[resIds.length];glGenTextures(resIds.length, textureIds, 0);for (int i = 0; i < resIds.length; i++) {bitmaps[i] = BitmapFactory.decodeResource(context.getResources(), resIds[i], options);// 绑定纹理到OpenGLglBindTexture(GL_TEXTURE_2D, textureIds[i]);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// 加载bitmap到纹理中GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmaps[i], 0);// 生成MIP贴图glGenerateMipmap(GL_TEXTURE_2D);// 取消绑定纹理glBindTexture(GL_TEXTURE_2D, 0);bitmaps[i].recycle();}return textureIds;
}

五.GLRender:绘制

onDrawFrame()中的关键点有两处

5.1 MVP矩阵

//MVP矩阵赋值
mMVPMatrix = TransformUtils.getCubeTextureMVPMatrix(ratio);
//设置MVP变换矩阵到着色器程序/渲染器
glUniformMatrix4fv(mvpMatrix, 1, false, mMVPMatrix, 0);

getCubeTextureMVPMatrix() 函数代码:

//计算MVP变换矩阵
public static float[] getCubeTextureMVPMatrix(float ratio) {//初始化modelMatrix, viewMatrix, projectionMatrixfloat[] modelMatrix = getIdentityMatrix(16, 0); //模型变换矩阵float[] viewMatrix = getIdentityMatrix(16, 0); //观测变换矩阵/相机矩阵float[] projectionMatrix = getIdentityMatrix(16, 0); //投影变换矩阵//获取modelMatrix, viewMatrix, projectionMatrixmCubeTextureRotateAgree = (mCubeTextureRotateAgree + 0.5f) % 360;Matrix.rotateM(modelMatrix, 0, mCubeTextureRotateAgree, -1, -1, 1); //获取模型旋转变换矩阵Matrix.setLookAtM(viewMatrix, 0, 0, 5, 10, 0, 0, 0, 0, 1, 0); //获取观测变换矩阵,设置相机位置Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1, 1, 3, 20); //获取透视投影变换矩阵,正交投影:Matrix.orthoM(...)//计算MVP变换矩阵: mvpMatrix = projectionMatrix * viewMatrix * modelMatrixfloat[] tempMatrix = new float[16];float[] mvpMatrix = new float[16];Matrix.multiplyMM(tempMatrix, 0, viewMatrix, 0, modelMatrix, 0);Matrix.multiplyMM(mvpMatrix, 0, projectionMatrix, 0, tempMatrix, 0);return mvpMatrix;
}

5.2 激活、绑定和绘制纹理

/********* 纹理操作:激活、绑定 **********/
glActiveTexture(GL_TEXTURE);
int count = 4;
for (int i =0; i < textureIds.length; i++) {int first = i * count;//绑定纹理glBindTexture(GL_TEXTURE_2D, textureIds[i]);//绘制正方体的表面(6个面,每个面2个三角形)glDrawArrays(GL_TRIANGLE_FAN, first, count);
}

六.着色器代码

就是最基础的着色器实现,并无特别之处

(1).cube_texture_vertex_shader.glsl

#version 300 eslayout (location = 0) in vec4 vPosition;
layout (location = 1) in vec2 aTextureCoord;uniform mat4 mvpMatrix;out vec2 vTexCoord;void main() {gl_Position = mvpMatrix * vPosition;vTexCoord = aTextureCoord;
}

(2).cube_texture_fragtment_shader.glsl

#version 300 es
#extension GL_OES_EGL_image_external_essl3 : require
precision mediump float;uniform sampler2D sampler;in vec2 vTexCoord;out vec4 outColor;void main(){outColor = texture(sampler,vTexCoord);
}

八.结束语

3D立方体纹理贴图的讲解到此就结束了

最终实现效果如本博文开头所示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/94964.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Springboot中的@Import注解~

Import注解是Spring框架中的注解之一&#xff0c;用于导入其他配置类或者组件 Import注解的作用有以下几点&#xff1a; 导入其他配置类&#xff1a;可以使用Import注解导入其他的配置类&#xff0c;将其加入到当前配置类中&#xff0c;从而可以共享配置信息 导入其他组件&am…

开箱即用轻量级雪花算法id生成器Java工具类

开箱即用轻量级雪花算法id生成器Java工具类 1.1 背景1.2 雪花算法id生成器Java工具类 1.1 背景 在 Java后端研发过程中&#xff0c;对于分布式微服务来说&#xff0c;一般需要分布式 id生成. 这里分享一个非常好用且大多数情况下都可用的开箱即用轻量级雪花算法id生成器Java工…

英语——分享篇——每日100词——601-700

disastrous——adj.灾难性的&#xff0c;完全失败的——disast(e)r灾难(熟词)ous藕丝(拼音)——灾难性的地震后大家只能吃藕丝 disorder——n.骚乱&#xff0c;混乱&#xff1b;vt.使失调——dis的士(谐音)order命令(熟词)——的士司机命令我稳住那场骚乱 distract——vt.转移…

C++ - 布隆过滤器

前言 之前介绍了 位图&#xff0c;位图在判断某一个 数是否存在&#xff0c;或者在计算某个数是否出现 一次 或者 两次这些问题之上有着非常高效的实现复杂度&#xff0c;它的时间复杂度 可以达到 O&#xff08;1&#xff09;&#xff0c;因为都是逻辑判断和 &#xff0c;常数…

Web前端-Vue2+Vue3基础入门到实战项目-Day2(指令补充, computed计算属性, watch侦听器, 水果购物车)

Web前端-Vue2Vue3基础入门到实战项目-Day2 指令补充指令修饰符v-bind 对样式控制的增强控制class案例 - 京东秒杀tab导航高亮控制style案例 - 控制进度条 v-model 应用于其他表单元素 computed计算属性基本使用computed计算属性 vs methods方法计算属性完整写法案例 - 成绩 wat…

论文学习:RT-DETR

RT-DETR 摘要 DETR取得显著性能&#xff0c;但高成本计算使其无法发挥无NMS的优势&#xff0c;无法实际应用。本文分析了NMS对准确性和速度的负面影响&#xff0c;并建立端到端的速度基准。第一个实时端到端检测器&#xff0c;高效处理多尺度特征&#xff0c;并提出IoU-aware…

【云备份】

文章目录 [toc] 1 :peach:云备份的认识:peach:1.1 :apple:功能了解:apple:1.2 :apple:实现目标:apple:1.3 :apple:服务端程序负责功能:apple:1.4 :apple:服务端功能模块划分:apple:1.5 :apple:客户端程序负责功能:apple:1.6 :apple:客户端功能模块划分:apple: 2 :peach:环境搭建…

mac电脑任务管理器 Things3 for Mac中文

Things 3是一款效率软件&#xff0c;可以帮助用户规划一天行程、管理项目&#xff0c;并使使用者按部就班地朝目标迈进。以下是Things 3的主要特点和功能&#xff1a; 待办事项&#xff1a;以“待办事项”为基本组成部分&#xff0c;每一则待办事项都是迈向大成就的一小步。用…

scala入门

视频 scala学习配套视频 资料目录 网盘地址&#xff1a;https://pan.baidu.com/s/1vJzjHhaC1NCcAGry6SLIpg&pwd1706 文档资料下载 第一章Scala的相关概述 第二章变量 第三章运算符 第四章循环 第五章方法 第七章继承、抽象类、匿名类 第八章特质 第九章包、样例…

Redis-双写一致性

双写一致性 双写一致性解决方案延迟双删&#xff08;有脏数据的风险&#xff09;分布式锁&#xff08;强一致性&#xff0c;性能比较低&#xff09;异步通知&#xff08;保证数据的最终一致性&#xff0c;高并发情况下会出现短暂的不一致情况&#xff09; 双写一致性 当修改了数…

Docker镜像管理

Docker 基本管理 Docker 概述 Docker是一个开源的应用容器引擎&#xff0c;基于go语言开发并遵循了apache2.0协议开源。 Docker是在Linux容器里运行应用的开源工具&#xff0c;是一种轻量级的“虚拟机”。 Docker 的容器技术可以在一台主机上轻松为任何应用创建一个轻量级的、…

Go 语言内置类型全解析:从布尔到字符串的全维度探究

目录 一、布尔类型定义基础用法声明与初始化逻辑运算 进阶用法条件语句循环结构函数返回值 常见错误与陷阱 二、整数类型定义基础用法声明与初始化运算符位运算 进阶用法数据溢出类型转换类型推断 特殊整数类型runebyte 常见问题和陷阱 三、浮点数类型定义基础用法声明与初始化…

云原生边缘计算KubeEdge安装配置

1. K8S集群部署&#xff0c;可以参考如下博客 请安装k8s集群&#xff0c;centos安装k8s集群 请安装k8s集群&#xff0c;ubuntu安装k8s集群 2.安装kubEedge 2.1 编辑kube-proxy使用ipvs代理 kubectl edit configmaps kube-proxy -n kube-system #修改kube-proxy#大约在40多行…

通过BeanFactotyPostProcessor动态修改@FeignClient的path

最近项目有个需求&#xff0c;要在启动后&#xff0c;动态修改FeignClient的请求路径&#xff0c;网上找到的基本都是在FeignClient里使用${…}&#xff0c;通过配置文件来定义Feign的接口路径&#xff0c;这并不能满足我们的需求 由于某些特殊原因&#xff0c;我们的每个接口…

Spring bean定义Spring Bean 的作用域

Spring bean定义 目录 Spring bean定义 Spring配置元数据 Spring Bean 的作用域 singleton作用域&#xff1a; 原型作用域&#xff1a; 示例&#xff1a; 形成应用程序的骨干是由Spring IoC容器所管理的对象称为bean。bean被实例化&#xff0c;组装&#xff0c;并通过Sprin…

运行pytorch时出现version `CXXABI_1.3.9‘ not found

发现问题&#xff1a;运行bert预测代码时出现如下错误 /envs/py38/lib/python3.8/site-packages/transformers/utils/import_utils.py", line 1184, in _get_module RuntimeError: Failed to import transformers.onnx.config because of the following error (look up …

华为OD机试真题【不含 101 的数】

1、题目描述 【不含 101 的数】 【题目描述】 小明在学习二进制时&#xff0c;发现了一类不含 101的数&#xff0c;也就是&#xff1a; 将数字用二进制表示&#xff0c;不能出现 101 。 现在给定一个整数区间 [l,r] &#xff0c;请问这个区间包含了多少个不含 101 的数&#…

互联网金融理财知识点简单总结

互联网金融理财知识点总结 互联网金融理财是指通过互联网平台进行资产管理和投资的一种金融方式。它结合了金融、科技和互联网&#xff0c;为投资者提供了更多选择和便捷性。本文将介绍互联网金融理财的关键知识点&#xff0c;包括理财基础、投资产品、风险管理和未来趋势等方…

Spring 体系架构模块和三大核心组件介绍

Spring架构图 模块介绍 1. Spring Core&#xff08;核心容器&#xff09;&#xff1a;提供了IOC,DI,Bean配置装载创建的核心实现。 spring-core &#xff1a;IOC和DI的基本实现 spring-beans&#xff1a;BeanFactory和Bean的装配管理(BeanFactory) spring-context&#xff1…

Python数据攻略-高级文件操作与Json序列化

当我们谈论数据分析时,第一个想到的可能是CSV或Excel文件,这些都是我们平时最常接触的数据格式。然而,在实际工作中,数据来源可能更加多样,比如网页上的表格、SQL数据库,甚至各种API返回的Json数据。因此,本篇文章的目标是让你掌握如何使用Pandas进行更高级的文件操作。…