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立方体纹理贴图的讲解到此就结束了
最终实现效果如本博文开头所示
相关文章:
OpenGLES:3D立方体纹理贴图
效果展示 一.概述 前几篇博文讲解了OpenGLES绘制多种3D图形,并赋予丰富的色彩,但是在这些3D图形绘制过程中,有一点还没有涉及,就是纹理贴图。 今天这篇博文我会用如下六张图片对立方体进行纹理贴图,实现六个面都是贴…...
线程的概述
#include <pthread.h> int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); 功能:创建一个子线程 参数: -thread:传出参数,线程创建成功后,子线程的ID被写到…...
竞赛选题 机器视觉目标检测 - opencv 深度学习
文章目录 0 前言2 目标检测概念3 目标分类、定位、检测示例4 传统目标检测5 两类目标检测算法5.1 相关研究5.1.1 选择性搜索5.1.2 OverFeat 5.2 基于区域提名的方法5.2.1 R-CNN5.2.2 SPP-net5.2.3 Fast R-CNN 5.3 端到端的方法YOLOSSD 6 人体检测结果7 最后 0 前言 ǵ…...
python绘图系统27:matplotlib中平面坐标、极坐标和三维坐标的所有绘图函数
文章目录 绘图函数列表为DrawType添加这些绘图函数绘图类别跳转坐标系坐标源代码 绘图函数列表 下面整理了几乎所有matplotlib中的绘图函数,及其在不同坐标轴下的表现。 函数类别2Dpolar3D备注imshow图像X❌❌pcolormesh伪彩图[X,Y,]ZX,Y,Z❌plot曲线图x[,y]x[,y]…...
国庆中秋宅家自省: Python在Excel中绘图尝鲜
【一】国庆中秋: 悟 【国庆中秋】双节来临,相信各位有自己度过的方式,而我却以独特的方式度过了一个说出来不怕各位见笑的双节; 双节到来,没有太多惊喜,也没有太多的负面情绪, 只是喜欢独处,静静反省这些年走过的酸甜苦辣;生活中的许多不欢而散,不期而遇…...
计算机中的进制转换
在计算机软件中,经常需要进行进制转换,这包括二进制、八进制、十进制和十六进制之间的转换。以下是一些常见的转换方法: 二进制转十进制:这是最直接的转换,基本上不需要什么特别的算法。你只需要按照二进制的权值进行…...
Oracle统计信息问题排查常用SQL
Oracle统计信息问题排查常用SQL 对表的基本情况分析统计信息收集作业分析最近一次的统计信息收集修改触发统计信息收集的阈值 对表的基本情况分析 是否为临时表: select owner,table_name,temporary from dba_tables where table_namexxx;是否为分区表:…...
css圣杯布局和双飞翼布局
圣杯布局 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, in…...
机器学习笔记 - 深入研究spaCy库及其使用技巧
一、简述 spaCy 是一个用于 Python 中高级自然语言处理的开源库。它专为生产用途而设计,这意味着它不仅功能强大,而且快速高效。spaCy 在学术界和工业界广泛用于各种 NLP 任务,例如标记化、词性标注、命名实体识别等。 安装,这里使用阿里的源。 pip install spacy…...
网站强制跳转至国家反诈中心该怎么办?怎么处理?如何解封?
在互联网环境中,网站安全是非常重要的。然而,在实际操作过程中,不少网站可能因内容问题、技术安全漏洞等原因被迫下线甚至跳转至国家反诈骗中心网址。面对这一严峻问题,我们如何有效解决,让网站恢复运行并解除强制跳转…...
2023年10月4日
服务器 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//实例化一个服务器server new QTcpServer(this);//此时,服务器已经成功进入监听状态&…...
MacBook 录制电脑内部声音
MacBook 录制电脑内部声音 老妈喜欢跳广场舞,现在广场舞音频下载都收费了!没办法,只能自己录歌了,外录有杂音大家也都知道,所以就只能采用内录的方式然后再用 Audition 调整一下音量大小。 一、(前置条件&a…...
mysql主从复制和读写分离
在企业应用中,成熟的业务通常数据量都比较大 单台MySQL在安全性、高可用性和高并发方面都无法满足实际的需求 配置多台主从数据库服务器以实现读写分离 所以要做主从服务器,保证安全性 做一写一读服务器,将提升性能 1、什么是读写分离 …...
【计算机网络】网络层-数据平面(学习笔记)
一、网络层提供的服务 1、虚电路服务 通讯前建立虚电路,发送前认为选择路径,所以分组沿着同一条虚电路。 特点:带宽固定 2、数据报服务 数据可能沿着不同路径传输 3、网络层的两个层面 数据层面:源主机到目标主机 控制层面&…...
el-collapse 嵌套中 el-checkbox作为标题,选中复选框与el-tree联动
<el-drawertitle"应用授权":visible.sync"menuDrawer"><el-collapse accordion style"padding: 15px"><el-collapse-item v-for"item in platList"><template slot"title"><el-checkbox v-model…...
Ubuntu中还换源 sudo apt-get update更新失败
sudo apt-get update更新失败 1 前提2 编辑3 换源 1 前提 浏览器可以访问百度 如下文章: VMware 中虚拟机没网 2 编辑 输入如下命令,进入换源文件: sudo gedit /etc/apt/sources.list 3 换源 中科大 deb http://mirrors.ustc.edu.cn/ub…...
flutter播放rtmp视频
安装 dependencies:fijkplayer: ^0.11.0使用方法 import package:fijkplayer/fijkplayer.dart; import package:flutter/material.dart;class RtmpPlayerPage extends StatefulWidget {const RtmpPlayerPage({super.key});overrideState<RtmpPlayerPage> createState()…...
stm32 - 中断
stm32 - 中断 概念中断向量表NVIC 嵌套中断向量控制器优先级 中断EXTI概念基本结构例子- 对射式红外传感器计次例子 - 旋转编码器 概念 stm32 支持的中断资源(都属于外设) EXTITIMADCUSARtSPII2C stm32支持的中断 内核中断 外设中断 中断通道与优先级 一…...
【洛谷 P1216】[USACO1.5] [IOI1994]数字三角形 Number Triangles 题解(动态规划)
[USACO1.5] [IOI1994]数字三角形 Number Triangles 题目描述 观察下面的数字金字塔。 写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。 在上面的样例中,从 7 → 3 → 8 →…...
十四天学会C++之第四天(面向对象编程基础)
类和对象是什么? 在C中,类是一种用户定义的数据类型,它可以包含数据成员(也就是属性)和成员函数(也就是方法)。类是一种模板或蓝图,用于创建具体的对象。 对象是类的实例ÿ…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...
Vue3 PC端 UI组件库我更推荐Naive UI
一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用,前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率,还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库(Naive UI、Element …...
代理服务器-LVS的3种模式与调度算法
作者介绍:简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 我们上一章介绍了Web服务器,其中以Nginx为主,本章我们来讲解几个代理软件:…...
