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.rhkb.cn/news/173475.html

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

相关文章

SSH安全登录远程主机

SSH服务器简介 SSH即Security SHell的意思&#xff0c;它可以将连线的封包进行加密技术&#xff0c;之后进行传输&#xff0c;因此相当的安全。 SSH是一种协议标准&#xff0c;其目的是实现安全远程登录以及其它安全网络服务。 SSH协定&#xff0c;在预设的状态下&#xff0c;…

Android问题笔记四十一:JNI NewStringUTF错误的几种解决方案

点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册点击跳转>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&…

ITSource 分享 第5期【校园信息墙系统】

项目介绍 本期给大家介绍一个 校园信息墙 系统&#xff0c;可以发布信息&#xff0c;表白墙&#xff0c;分享墙&#xff0c;校园二手买卖&#xff0c;咨询分享等墙信息。整个项目还是比较系统的&#xff0c;分为服务端&#xff0c;管理后台&#xff0c;用户Web端&#xff0c;小…

刀具磨损状态识别(Python代码,MSCNN_LSTM_Attention模型,初期磨损、正常磨损和急剧磨损分类,解压缩直接运行)

1.运行效果&#xff1a;刀具磨损状态识别&#xff08;Python代码&#xff0c;MSCNN_LSTM_Attention模型&#xff0c;初期磨损、正常磨损和急剧磨损&#xff09;_哔哩哔哩_bilibili 环境库&#xff1a; NumPy 版本: 1.19.4 Pandas 版本: 0.23.4 Matplotlib 版本: 2.2.3 Keras …

SpringBoot小项目——简单的小区物业后台管理系统 认证鉴权 用户-角色模型 AOP切面日志 全局异常【源码】

目录 引出一、应用到的技术栈Spring、Spring MVC、Spring Boot基础SpringBoot进阶、SpringMVC原理、AOP切面MyBatis 数据库相关JavaWeb基础&#xff1a;Session等前端Vue、JavaScript、Bootstrap 二、后台管理系统的功能登录功能1.用户名密码登录2.验证码的登录 报修业务的处理…

电路器件认识与KV STUDIO的实践(二)

当当当当&#xff0c;下班了&#xff0c;下面来记录一下小编学习到的电气知识与plc的应用吧&#xff01;&#xff01;&#xff01; 目录 电路元器件的认识 断路器&#xff08;作用是过载保护、短路保护、地线故障保护和手动控制&#xff09; 漏电断路器&#xff08;当漏电电…

AC修炼计划(AtCoder Regular Contest 164)

传送门&#xff1a;AtCoder Regular Contest 164 - AtCoder A.签到题&#xff0c;在此不做赘述 B - Switching Travel 这题本来该是秒的&#xff0c;但是因为没有考虑清楚环的问题而被卡半天&#xff0c;其实我们不难发现&#xff0c;要想使题目存在节点&#xff0c;就得让该节…

【数据结构练习题】删除有序数组中的重复项

✨博客主页&#xff1a;小钱编程成长记 &#x1f388;博客专栏&#xff1a;数据结构练习题 &#x1f388;相关博文&#xff1a;消失的数字 — 三种解法超详解 删除有序数组中的重复项 1.&#x1f388;题目2. &#x1f388;解题思路3. &#x1f388;具体代码&#x1f387;总结 1…

【鸿蒙软件开发】ArkTS基础组件之TextClock(时间显示文本)、TextPicker(滑动选择文本)

文章目录 前言一、TextClock1.1 子组件1.2 接口参数TextClockController 1.3 属性1.4 事件1.5 示例代码 二、TextPicker2.1 子组件2.2 接口参数 2.3 属性2.4 事件2.5 示例代码 总结 前言 TextClock组件:通过文本将当前系统时间显示在设备上。支持不同时区的时间显示&#xff0…

ELASTICO-A Secure Sharding Protocol For Open Blockchains

INTRO 在中本聪共识中&#xff0c;通过POW机制来公平的选举leader&#xff0c;不仅非常消耗power&#xff0c;并且拓展性也不好。现在比特币中是7 TPS&#xff0c;和其他的支付系统相比效率相差甚远。 当前的许多拜占庭共识协议&#xff0c;并不支持在一个开放的环境中使用&a…

论文速递 TMC 2023 | RoSeFi: 一种利用商用WiFi设备进行稳健的久坐行为监测系统

注1:本文系“最新论文速览”系列之一,致力于简洁清晰地介绍、解读最新的顶会/顶刊论文 TMC 2023 | RoSeFi: 一种利用商用WiFi设备进行稳健的久坐行为监测系统 原文链接:https://ieeexplore.ieee.org/abstract/document/10269067 本文提出了一种稳健的久坐行为监测系统RoSeFi。…

Spring AOP源码解读

今天我们来分析Spring中AOP的源码&#xff0c;主要是关于SpringAOP是如何发挥作用的。 前期准备 首先我们需要有一个Spring AOP项目&#xff0c;添加好了SpringAOP的依赖。 <dependency><groupId>org.springframework</groupId><artifactId>spring-co…

MAYA教程之模型的UV拆分与材质介绍

什么是UV 模型制作完成后&#xff0c;需要给模型进行贴图&#xff0c;就需要用到UV功能 UV编译器介绍 打开UI编译器 主菜单有一个 UV->UV编译器&#xff0c;可以点击打开 创建一个模型&#xff0c;可以看到模型默认的UV UV编译器功能使用 UV模式的选择 在UV编译器中…

单调队列和单调栈

单调队列 这种涉及到维护子数组的最大/小值的操作&#xff0c;一般都会是 1 剑指 Offer 59 - II. 队列的最大值 2 239. 滑动窗口最大值 3 1438. 绝对差不超过限制的最长连续子数组 单调栈

Unity之ShaderGraph如何实现冰冻效果

前言 今天我们来实现一个冰冻的效果,非常的炫酷哦。 如下图所示: 主要节点 Voronoi:根据输入UV生成 Voronoi 或Worley噪声。Voronoi 噪声是通过计算像素和点阵之间的距离生成的。通过由输入角度偏移控制的伪随机数偏移这些点,可以生成细胞簇。这些单元的规模以及产生的…

什么?Postman也能测WebSocket接口了?

01、WebSocket 简介 WebSocket是一种在单个TCP连接上进行全双工通信的协议。 WebSocket使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务端主动向客户端推送数据。在WebSocket API中&#xff0c;浏览器和服务器只需要完成一次握手&#xff0c;两者之间就直…

pycharm 2023.2.3设置conda虚拟环境

分两步&#xff1a; &#xff08;1&#xff09;设置Virtualenv Environment &#xff08;2&#xff09;设值Conda Executable 加载conda环境&#xff0c;然后选择conda环境

hadoop使用简介

git clone hadoop源码地址&#xff1a;https://gitee.com/CHNnoodle/hadoop.git git clone错误&#xff1a; Filename too long错误&#xff0c;使用git config --global core.longpaths true git clone https://gitee.com/CHNnoodle/hadoop.git -b rel/release-3.2.2 拉取指定…