OpenGLES:绘制一个彩色、旋转的3D圆柱
一.概述
上一篇博文讲解了怎么绘制一个彩色旋转的立方体
这一篇讲解怎么绘制一个彩色旋转的圆柱
圆柱的顶点创建主要基于2D圆进行扩展,与立方体没有相似之处
圆柱绘制的关键点就是将圆柱拆解成:两个Z坐标不为0的圆 + 一个长方形的圆柱面
绘制2D圆的过程这里不再复述,不理解的可以参看前面这篇博文:《OpenGLES:绘制一个颜色渐变的圆》
废话不多说,正文开始了。
二.Render:变量定义
2.1 常规变量定义
//着色器程序/渲染器
private int shaderProgram;//着色器mvp矩阵属性
private int mvpMatrix;
//位置属性
private int aPositionLocation;//surface宽高比率
private float ratio;
2.2 定义顶点坐标数组和缓冲
概述中提到过,绘制圆柱的关键思路是将圆柱拆解成:两个Z坐标不为0的圆 + 一个长方形的圆柱面
所以定义三个顶点坐标数组和对应缓冲
//圆柱柱面顶点数组
private float[] vertexData;
//圆柱顶部圆的顶点数组
private float[] vertexData1;
//圆柱底部圆的顶点数组
private float[] vertexData2;//圆柱柱面顶点缓冲
private FloatBuffer vertexBuffer;
//圆柱顶部圆的顶点缓冲
private FloatBuffer vertexBuffer1;
//圆柱顶部圆的顶点缓冲
private FloatBuffer vertexBuffer2;
需要注意的是,这次我并没有把顶点颜色单独定义成一个数组,而且在Render类中也不会像上一篇绘制立方体时动态加载和填充顶点颜色值
这次我会换一种方式,直接把颜色填充和变换在着色器代码中实现
最终的色彩渐变效果是一样的,殊途同归,丰富对OpenGLES不同实现方式的学习。
2.3 定义MVP矩阵
//MVP矩阵
private float[] mMVPMatrix = new float[16];
三.Render:着色器、内存分配等
3.1 着色器创建、链接、使用
3.2 着色器属性获取、赋值
3.3 缓冲内存分配
这几个部分的代码实现2D图形绘制基本一致
可参考以前2D绘制的相关博文,里面都有详细的代码实现
不再重复展示代码
四.Render:动态创建顶点
float radio = 0.6f;
int spanIdx = 60;vertexData = createSidePos(radio, spanIdx);
vertexData1 = createBottomCirclePos(radio, spanIdx, 0.7f);
vertexData2 = createBottomCirclePos(radio, spanIdx, -0.7f);
重点就在于创建圆柱顶点的两个函数:
- createSidePos()
- createBottomCirclePos()
4.1 createSidePos()
private float[] createSidePos(float radius, int n) {ArrayList<Float> data = new ArrayList<>();//设置顶部/底部圆的顶点坐标float angDegSpan = 360f / n;for (float i = 0; i < 360 + angDegSpan; i += angDegSpan) {data.add((float) (radius * Math.sin(i * Math.PI / 180f)));data.add((float) (radius * Math.cos(i * Math.PI / 180f)));//顶部/底部圆的顶点Z坐标设置为-0.7fdata.add(-0.7f);data.add((float) (radius * Math.sin(i * Math.PI / 180f)));data.add((float) (radius * Math.cos(i * Math.PI / 180f)));//顶部/底部圆的顶点Z坐标设置为-0.7fdata.add(0.7f);}//所有顶点坐标float[] f = new float[data.size()];for (int i = 0; i < data.size(); i++) {f[i] = data.get(i);}return f;
}
4.2 createBottomCirclePos()
private float[] createBottomCirclePos(float radius, int n, float circleCenterZ) {ArrayList<Float> data = new ArrayList<>();//顶部/底部圆心坐标data.add(0.0f);data.add(0.0f);data.add(circleCenterZ);//设置顶部/底部圆的顶点坐标float angDegSpan = 360f / n;for (float i = 0; i < 360 + angDegSpan; i += angDegSpan) {data.add((float) (radius * Math.sin(i * Math.PI / 180f)));data.add((float) (radius * Math.cos(i * Math.PI / 180f)));//顶部/底部圆的顶点Z坐标设置为-0.7fdata.add(circleCenterZ);}//所有顶点坐标float[] f = new float[data.size()];for (int i = 0; i < data.size(); i++) {f[i] = data.get(i);}return f;
}
五.Render:绘制
5.1 MVP矩阵
//填充MVP矩阵
mMVPMatrix = TransformUtils.getCylinderMVPMatrix(ratio);
//将变换矩阵传入顶点渲染器
glUniformMatrix4fv(mvpMatrix, 1, false, mMVPMatrix, 0);
5.2 绘制圆柱柱面、顶部圆、底部圆
(1).drawSide()
//准备顶点坐标和颜色数据
glVertexAttribPointer(aPositionLocation, 3, GL_FLOAT, false, 0, vertexBuffer);
//绘制
glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexData.length / 3);
(2).drawBottomCircle1()
//准备顶点坐标和颜色数据
glVertexAttribPointer(aPositionLocation, 3, GL_FLOAT, false, 0, vertexBuffer1);
//绘制
glDrawArrays(GL_TRIANGLE_FAN, 0, vertexData1.length / 3);
(3).drawBottomCircle2()
//准备顶点坐标和颜色数据
glVertexAttribPointer(aPositionLocation, 3, GL_FLOAT, false, 0, vertexBuffer2);
//绘制
glDrawArrays(GL_TRIANGLE_FAN, 0, vertexData2.length / 3);
六.着色器代码
6.1 cylinder_vertex_shader.glsl
先实现一个顶部绿色,底部红色,柱面绿红渐变的旋转圆柱
#version 300 eslayout (location = 0) in vec4 vPosition;
layout (location = 1) in vec4 aColor;uniform mat4 mvpMatrix;out vec4 vColor;void main() {gl_Position = mvpMatrix * vPosition;if (vPosition.z == 0.7) {vColor = vec4(0.0, 1.0, 0.0, 0.0); //绿} else if (vPosition.z == -0.7) {vColor = vec4(1.0, 0.0, 0.0, 0.0); //红}
}
6.2 cylinder_fragtment_shader.glsl
#version 300 es
#extension GL_OES_EGL_image_external_essl3 : require
precision mediump float;in vec4 vColor;out vec4 outColor;void main(){outColor = vColor;
}
七.最终效果
上一节中讲了,先来一个顶部绿,底部红,柱面绿红渐变的旋转3D圆柱
效果如下:

如何实现混色渐变的旋转圆柱呢?
很简单,只要修改顶点着色器代码:
void main() {gl_Position = mvpMatrix * vPosition;//颜色混合渐变vColor = vec4(vPosition.x,vPosition.y, vPosition.z,0.0);
}
效果如下:

八.结束
彩色旋转的3D圆柱绘制到此结束
下一篇讲解彩色旋转的圆锥
相关文章:
OpenGLES:绘制一个彩色、旋转的3D圆柱
一.概述 上一篇博文讲解了怎么绘制一个彩色旋转的立方体 这一篇讲解怎么绘制一个彩色旋转的圆柱 圆柱的顶点创建主要基于2D圆进行扩展,与立方体没有相似之处 圆柱绘制的关键点就是将圆柱拆解成:两个Z坐标不为0的圆 一个长方形的圆柱面 绘制2D圆的…...
【QT开发(6)】0926-QT 中加入 fastDDS 通信库的程序使用说明
在智能驾驶中,DDS有可能被广泛使用,因此推出这篇说明教程。 1、基于【QT开发(5)】教程的项目文档进行开发 2、安装DDS 查看《【eProsima Fast DDS(1)】安装eProsima Fast DDS》 至少安装: foonathan_m…...
js 判断字符串中是否包含某个字符串
方法一(推荐使用): indexOf() indexOf() 方法:返回某个指定的字符串值在字符串中首次出现的位置。如果要检索的字符串值没有出现,则该方法返回 -1。 var str "LiHeErNAN"; console.log(str.indexOf("A") ! -1 ); // true方法二:m…...
部署在阿里云ECS服务器上的微服务项目中获取到的时间和windows的时间不一样的问题
继上一篇文章《阿里云ECS服务器无法发送邮件问题解决方案》之后,又发现登录的时候发送邮件中的时间和自己windows上的时间不一样,大概找了一下原因,是LocaDateTime使用的时区不一样导致的远程服务器和本机时间不一致。 只需要在LocaDateTime…...
怎么通过portainer部署一个vue项目
这篇文章分享一下今天通过docker打包vue项目,并使用打包的镜像在portainer上部署运行,参考了vue-cli和docker的官方文档。 首先,阅读vue-cli关于docker部署的说明 vue-cli关于docker部署的说明https://cli.vuejs.org/guide/deployment.html#…...
Springboot实现websocket(连接前jwt验证token)
背景 用户连接服务器weksocket前,需经过jwt的token验证(token中包含账号信息),验证合法后,才可以于服务器正常交互。 实现 一、配置依赖(pom.xml) <!-- websocket --><dependency&g…...
2023/10/3
平荒尽处是春山 二零二三年的十月 似乎已经过去了很久很久 没有了曾经的意气风发 也没有了歌伴夜声 之前一直不知道自己为什么喜欢打篮球 虽然打得不好 但是今天突然明白了 我喜欢的不是过人后的喜悦 而是篮球应声入网的清脆的声音 当然 出来进球 还有的是擦筐而出和三不沾 但是…...
zemax场曲/畸变图与网格畸变图
网格畸变是XY两个方向上的几何畸变,是不同视场实际像高与近轴像高的偏差。 垂轴放大率在整个视场范围内不能保持常数 当一个有畸变的光学系统对一个方形的网状物体成像时,若δy>0,则主光线的交点高度y比理想像高y低,视场越大,低得越多&a…...
【小尘送书-第六期】《巧用ChatGPT轻松玩转新媒体运营》AI赋能运营全流程,帮你弯道超车、轻松攀登运营之巅
大家好,我是小尘,欢迎你的关注!大家可以一起交流学习!欢迎大家在CSDN后台私信我!一起讨论学习,讨论如何找到满意的工作! 👨💻博主主页:小尘要自信 …...
GD32F10 串口通信
1. 什么是通信 通信,指人与人或人与自然之间通过某种行为或媒介进行的信息交流与传递,从广义上指需要信息的双方或多方在不违背各自意愿的情况下采用任意方法,任意媒质,将信息从某方准确安全地传送到另方。通信双方如果想正确传输…...
QT常用控件介绍
QT信号与槽机制 connect (A,SIGNLA(aaa()),B, SLOT(bbb())); GUI继承简介 布局管理器 垂直布局水平布局网格布局表单布局 输出控件 Label: 标签Text Browser: 文本浏览器Graphics View : 图形视图框架Calendar Widget: 日历控件LCD Number: 液晶字体数…...
[FineReport]安装与使用(连接Hive3.1.2)
一、安装(对应hive3.1.2) 注:服务器的和本地的要同时安装。本地是测试环境,服务器的是生产环境 1、服务器安装 1、下载 免费下载FineReport - FineReport报表官网 向下滑找到 2、解压 [rootck1 /home/data_warehouse/software]# tar -zxvf tomcat…...
黑马mysql教程笔记(mysql8教程)基础篇——数据库相关概念、mysql安装及卸载、数据模型、SQL通用语法及分类(DDL、DML、DQL、DCL)
参考文章1:https://www.bilibili.com/video/BV1Kr4y1i7ru/ 参考文章2:https://dhc.pythonanywhere.com/article/public/1/ 文章目录 基础篇数据库相关概念(数据库DataBase(DB)、数据库管理系统DataBase Management Sy…...
最新AI智能创作系统源码V2.6.2/AI绘画系统/支持GPT联网提问/支持Prompt应用
一、AI创作系统 SparkAi创作系统是基于国外很火的ChatGPT进行开发的AI智能问答系统和AI绘画系统。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT?小编这里写一个详细图…...
神器 CodeWhisperer
这两天看到了好多关于 Amazon CodeWhisperer 针对个人用户终身免费使用的消息,便抽空简单来重点介绍下如何在 VS Code 这款 IDE 上安装和使用 CodeWhisperer。 亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视…...
GraphQL全面深度讲解
目录 一、GraphQL 是什么 二、GraphQL 规范 数据模型 字段 参数 三、运行示例 四、优势和劣势 优势 劣势 一、GraphQL 是什么 GraphQL 是一种用于 API 的查询语言,也是一个基于服务端的运行引擎。 GraphQL 提供了一套完整的规范和描述用于查询 API…...
9.1 链表
链表:数据结构,一堆数据的集合,链表的每一项都是结构体,都使用指针指向下一个结构体。 数组的缺点:由于数组的地址是连续的,对数组的数据进行增、删、改后数据不连续,需要较大的运算量才能实现…...
分布式文件系统FastDFS实战
1. 分布式文件系统应用场景 互联网海量非结构化数据的存储需求: 电商网站:海量商品图片视频网站:海量视频文件网盘:海量文件社交网站:海量图片 2.FastDFS介绍 https://github.com/happyfish100/fastdfs 2.1简介 …...
手机自动直播系统源码交付与代理加盟注意事项解析!
随着直播行业的不断发展,手机自动直播已经成为了人们生活中不可或缺的一部分。手机无人直播软件成了香饽饽,各类手机实景直播APP大批量涌现。因为创业和技术门槛低,市场需求高,所以成了最火热创业赛道。那么如果是不懂技术的人群&…...
NodeJS 如何连接 MongoDB
初始化: yarn init使用命令: yarn add mongodb新建 index.js 文件: const MongoClient require(mongodb).MongoClient; const db_name "fly_articleDb"; const url mongodb://127.0.0.1:27017;(async function () {const cli…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
