Android OpenGL ES 2.0入门实践

本文既然是入门实践,就先从简单的2D图形开始,首先,参考两篇官方文档搭建个框架,便于写OpenGL ES相关的代码:构建 OpenGL ES 环境、OpenGL ES 2.0 及更高版本中的投影和相机视图。

先上代码,代码效果如下图,屏幕上半部份是Java绘制的,下半部份是C++绘制的

一、投影和相机视图

1. 关于坐标轴方向

投影和相机视图主要是设置视点和坐标轴方向,请看下面的代码

override fun onSurfaceCreated(gl: GL10, config: EGLConfig) {...// Create a camera view matrixMatrix.setLookAtM(vMatrix, 0, 0f, 0f, -3f, 0f, 0f, 0f, 0f, 1.0f, 0.0f)
}

Matrix.setLookAtM 方法的第5个参数 eyeZ 为正值,视点在屏幕前方,负值则在屏幕后方,其符号会影响X轴方向,其绝对值影响绘制元素的大小,绝对值越大,视点离屏幕越远,物体越小,倒数第2个参数 upY 的符号是影响Y轴方向,如果发现绘制的元素上下或者左右翻转了,可以调整这俩参数再看看效果。上面代码摘自官方文档,eyeZ 是负值,看网上教程的时候都说Y轴朝上,X朝右,刚开始写代码的时候发现X坐标总是反的,就是左右颠倒了,才回过头来修改这里的代码。

2. 关于图像拉伸

override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) {GLES20.glViewport(0, 0, width, height)val ratio: Float = width.toFloat() / height.toFloat()// create a projection matrix from device screen geometryMatrix.frustumM(projMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f)
}

上面代码摘自官方文档,Open GL默认是在一个正方形区域绘制,手机屏幕都是长方形(严格讲是GLSurfaceView的宽高比例),使用默认坐标画出来的图形,看起来被拉长了,使用 Matrix.frustumM 方法结合GLSurfaceView的宽高比,可以调整,使画出来的图形达到预期的效果。

二、绘制2D图形

绘制图形主要参考了一位大佬的系列文章OpenGL ES之六——绘制矩形和圆形,使得鄙人快速入门。

1. 绘制几何图形

OpenGL ES的基本图元是点、线、三角形,参考上面提到的那位大佬的文章,可轻松画出矩形和圆形,最近项目中需要画圆角矩形,鄙人就在此基础上拓展了一下,基本思路就是划分成9块(如下图),绘制矩形使用的索引法,各点的索引已经在图中标出,4个角使用画圆的方式绘制,不过只画四分之一的圆

按照上图,代码中绘制矩形使用的顶点索引如下

private val indices = shortArrayOf(0, 1, 2, 0, 2, 3, //中间矩形4, 5, 1, 4, 1, 0,//左侧矩形1, 6, 7, 1, 7, 2,//底部矩形3, 2, 8, 3, 8, 9,//右侧矩形11, 0, 3, 11, 3, 10,//顶部矩形)

 2. 绘制图片

OpenGL ES之十——纹理贴图(展示一张图片)

3. 绘制文本

思路就是将文字转成Bitmap,再使用纹理贴图的方式绘制,将纹理贴图的Bitmap的来源改为如下代码即可

val bitmap = Bitmap.createBitmap(256, 128, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
canvas.drawColor(Color.TRANSPARENT)val textPaint = Paint()
textPaint.textSize = 32f
textPaint.isAntiAlias = true
textPaint.color = color
canvas.drawText(text, 16f, 64f, textPaint)

三、使用NDK实现

1. 添加依赖

OpenGL ES属于是Android原生API了,只需要在CMakeLists.txt链接一下相关库即可,GLESv2即OpenGL ES 2.0的库,EGL用于分配和管理 OpenGL ES 上下文和 Surface,但不是必须的,jnigraphics是用来访问Java层的Bitmap的,纹理贴图会用到

target_link_libraries(native-liblogGLESv2EGLjnigraphics
)

使用的头文件

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <EGL/egl.h>
#include <android/bitmap.h>

2. 将绘制挪到C++

NativeLib.kt

class NativeLib {companion object {init {System.loadLibrary("native-lib");}}external fun onSurfaceCreated()external fun onSurfaceChanged(width:Int, height:Int)external fun onDrawFrame()
}

native-lib.cpp

#include <jni.h>
#include <android/log.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <EGL/egl.h>
#include <EGL/eglext.h> //EGL用于分配和管理 OpenGL ES 上下文和 Surface
#include "my_gl_renderer.h"
#include "log_util.h"extern "C"
JNIEXPORT void JNICALL
Java_site_feiyuliuxing_opengltest_nativelib_NativeLib_onSurfaceCreated(JNIEnv *env, jobject thiz) {//onSurfaceCreated__android_log_print(ANDROID_LOG_INFO, "NDK GLES", "%s", glGetString(GL_VERSION));LOG_I("##### %s", glGetString(GL_VERSION));on_surface_created();
}
extern "C"
JNIEXPORT void JNICALL
Java_site_feiyuliuxing_opengltest_nativelib_NativeLib_onSurfaceChanged(JNIEnv *env, jobject thiz, jint width, jint height) {// onSurfaceChangedon_surface_changed(width, height);
}
extern "C"
JNIEXPORT void JNICALL
Java_site_feiyuliuxing_opengltest_nativelib_NativeLib_onDrawFrame(JNIEnv *env, jobject thiz) {// onDrawFrameon_draw_frame();
}

NativeGLRenderer.kt

class NativeGLRenderer : GLSurfaceView.Renderer {private val nativeLib = NativeLib()override fun onSurfaceCreated(p0: GL10?, p1: EGLConfig?) {nativeLib.onSurfaceCreated()}override fun onSurfaceChanged(p0: GL10?, width: Int, height: Int) {nativeLib.onSurfaceChanged(width, height)}override fun onDrawFrame(p0: GL10?) {nativeLib.onDrawFrame()}
}

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

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

相关文章

WPF自定义控件库之Window窗口

在WPF开发中&#xff0c;默认控件的样式常常无法满足实际的应用需求&#xff0c;我们通常都会采用引入第三方控件库的方式来美化UI&#xff0c;使得应用软件的设计风格更加统一。常用的WPF的UI控件库主要有以下几种&#xff0c;如&#xff1a;Modern UI for WPF&#xff0c;Mat…

Elasticsearch:使用 Elasticsearch 进行词汇和语义搜索

作者&#xff1a;PRISCILLA PARODI 在这篇博文中&#xff0c;你将探索使用 Elasticsearch 检索信息的各种方法&#xff0c;特别关注文本&#xff1a;词汇 (lexical) 和语义搜索 (semantic search)。 使用 Elasticsearch 进行词汇和语义搜索 搜索是根据你的搜索查询或组合查询…

0基础学习PyFlink——使用DataStream进行字数统计

大纲 sourceMapSplittingMapping ReduceKeyingReducing 完整代码结构参考资料 在《0基础学习PyFlink——模拟Hadoop流程》一文中&#xff0c;我们看到Hadoop在处理大数据时的MapReduce过程。 本节介绍的DataStream API&#xff0c;则使用了类似的结构。 source 为了方便&…

C# Onnx 用于边缘检测的轻量级密集卷积神经网络LDC

效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;namespace Onnx…

【HTML】HTML基础知识扫盲

1、什么是HTML&#xff1f; HTML是超文本标记语言&#xff08;Hyper Text Markup Language&#xff09;是用来描述网页的一种语言 注意&#xff1a; HTML不是编程语言&#xff0c;而是标记语言 HTML文件也可以直接称为网页&#xff0c;浏览器的作用就是读取HTML文件&#xff…

【网络协议】聊聊http协议

当我们输入www.baidu.com的时候&#xff0c;其实是先将baidu.com的域名进行DNS解析&#xff0c;转换成对应的ip地址&#xff0c;然后开始进行基于TCP构建三次握手的连接&#xff0c;目前使用的是1.1 默认是开启了keep-Alive。可以在多次请求中进行连接复用。 HTTP 请求的构建…

Bayes决策:身高与体重特征进行性别分类

代码与文件请从这里下载&#xff1a;Auorui/Pattern-recognition-programming: 模式识别编程 (github.com) 简述 分别依照身高、体重数据作为特征&#xff0c;在正态分布假设下利用最大似然法估计分布密度参数&#xff0c;建立最小错误率Bayes分类器&#xff0c;写出得到的决…

控梦术(一)之什么是清明梦

控梦术 首先&#xff0c;问大家一个问题。在梦中&#xff0c;你知道自己是在做梦吗&#xff1f;科学数据表明&#xff0c;大约23%的人在过去一个月中&#xff0c;至少有一次在梦中意识到自己正在做梦。科学家把这叫做清醒梦或者叫做清明梦。科学家说&#xff0c;每个人都能学会…

springboot的缓存和redis缓存,入门级别教程

一、springboot&#xff08;如果没有配置&#xff09;默认使用的是jvm缓存 1、Spring框架支持向应用程序透明地添加缓存。抽象的核心是将缓存应用于方法&#xff0c;从而根据缓存中可用的信息减少执行次数。缓存逻辑是透明地应用的&#xff0c;对调用者没有任何干扰。只要使用…

云计算与ai人工智能对高防cdn的发展

高防CDN&#xff08;Content Delivery Network&#xff09;作为网络安全领域的一项关键技术&#xff0c;致力于保护在线内容免受各种网络攻击&#xff0c;包括分布式拒绝服务攻击&#xff08;DDoS&#xff09;等。然而&#xff0c;随着人工智能&#xff08;AI&#xff09;和大数…

C#__委托delegate

委托存储的是函数的引用&#xff08;把某个函数赋值给一个委托类型的变量&#xff0c;这样的话这个变量就可以当成这个函数来进行使用了&#xff09; 委托类型跟整型类型、浮点型类型一样&#xff0c;也是一种类型&#xff0c;是一种存储函数引用的类型 using System.Reflec…

Linux网络基础2 -- 应用层相关

一、协议 引例&#xff1a;编写一个网络版的计算器 1.1 约定方案&#xff1a;“序列化” 和 “反序列化” 方案一&#xff1a;客户端发送形如“11”的字符串&#xff0c;再去解析其中的数字和计算字符&#xff0c;并且设限&#xff08;如数字和运算符之间没有空格; 运算符只…

RIS辅助MIMO广播信道容量

RIS辅助MIMO广播信道容量 摘要RIS辅助的BC容量矩阵形式的泰勒展开学习舒尔补 RIS-Aided Multiple-Input Multiple-Output Broadcast Channel Capacity论文阅读记录 基于泰勒展开求解了上行容量和最差用户的可达速率&#xff0c;学习其中的展开方法。 摘要 Scalable algorithm…

什么是神经网络,它的原理是啥?(1)

参考&#xff1a;https://www.youtube.com/watch?vmlk0rddP3L4&listPLuhqtP7jdD8CftMk831qdE8BlIteSaNzD 视频1&#xff1a; 简单介绍神经网络的基本概念&#xff0c;以及一个训练好的神经网络是怎么使用的 分类算法中&#xff0c;神经网络在训练过程中会学习输入的 pat…

Pmdarima实现单变量时序预测与交叉验证

目录 1. pmdarima实现单变量时间序列预测 2. 时间序列交叉验证 2.1 滚动交叉验证(RollingForecastCV) 2.2 滑窗交叉验证(SildingWindowForecastCV) 1. pmdarima实现单变量时间序列预测 Pmdarima是以statsmodel和autoarima为基础、封装研发出的Python时序分析库、也是现在市…

故障诊断模型 | Maltab实现GRU门控循环单元故障诊断

文章目录 效果一览文章概述模型描述源码设计参考资料效果一览 文章概述 故障诊断模型 | Maltab实现GRU门控循环单元故障诊断 模型描述 利用各种检查和测试方法,发现系统和设备是否存在故障的过程是故障检测;而进一步确定故障所在大致部位的过程是故障定位。故障检测和故障定位…

3ds Max2022安装教程(最新最详细)

目录 一.简介 二.安装步骤 网盘资源见文末 一.简介 3DS Max是由Autodesk公司开发的一款专业三维建模、动画和渲染软件&#xff0c;广泛应用于影视、游戏、建筑和工业设计等领域。 3DS Max的主要特点和功能包括&#xff1a; 三维建模&#xff1a;3DS Max提供了各种强大的建…

如何用思维导图开会

在办公室和会议室使用思维导图会有无数好处。今天我们就聊聊思维导图在开会中的作用&#xff1f; 为什么要在会议中使用思维导图&#xff1f; 思维导图可以帮助我们整理思路。会议通常涉及到复杂的议题和讨论&#xff0c;使用思维导图可以帮助整合和梳理参与者的思路和观点。通…

Vue项目搭建及使用vue-cli创建项目、创建登录页面、与后台进行交互,以及安装和使用axios、qs和vue-axios

目录 1. 搭建项目 1.1 使用vue-cli创建项目 1.2 通过npm安装element-ui 1.3 导入组件 2 创建登录页面 2.1 创建登录组件 2.2 引入css&#xff08;css.txt&#xff09; 2.3 配置路由 2.5 运行效果 3. 后台交互 3.1 引入axios 3.2 axios/qs/vue-axios安装与使用 3.2…

priority_queue 的模拟实现

priority_queue 的底层结构 我们已经学习过栈和队列了&#xff0c;他们都是用一种容器适配出来的。今天我们要学习的 prority_queue 也是一个容器适配器。在 priority_queue 的使用部分我们已经知道想要适配出 priority_queue&#xff0c;这个底层的容器必须有以下接口&#x…