Android OpenGL ES 2.0入门实践

news2024/11/25 14:52:41

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

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

一、投影和相机视图

1. 关于坐标轴方向

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

override fun onSurfaceCreated(gl: GL10, config: EGLConfig) {
    ...
    // Create a camera view matrix
    Matrix.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 geometry
    Matrix.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-lib
        log
        GLESv2
        EGL
        jnigraphics
)

使用的头文件

#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) {
    // onSurfaceChanged
    on_surface_changed(width, height);
}
extern "C"
JNIEXPORT void JNICALL
Java_site_feiyuliuxing_opengltest_nativelib_NativeLib_onDrawFrame(JNIEnv *env, jobject thiz) {
    // onDrawFrame
    on_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.coloradmin.cn/o/1147237.html

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

相关文章

MQ——进阶

文章目录 消息可靠性生产者消息确认消息持久化消费者确认演示none模式演示auto模式 失败重试机制本地重试失败策略 死信交换机初始死信交换机TTL延迟队列安装DelayExchange插件使用DelayExchange 惰性队列消息堆积问题惰性队列 MQ集群集群分类普通集群镜像模式镜像模式的配置 仲…

私有云:【6】VCenter安装SqlServer

私有云&#xff1a;【6】VCenter安装SqlServer 1、VCenter安装SqlServer1.1、通过模板创建虚拟机1.2、安装sqlserver服务 2、搭建sqlserver群集2.1、安装群集功能2.2、在ad域服务器创建共享文件夹&#xff0c;供集群选举使用 3、创建故障转移群集【只需安装一台即可】3.1、创建…

操作系统 --- 存储器管理

一、简答题 1.存储器管理的基本任务&#xff0c;是为多道程序的并发执行提供良好的存储器环境。请问好的存储器环境”应包含哪几个方面&#xff1f; 答&#xff1a; 2.内存保护是否可以完全由软件实现&#xff1f;为什么&#xff1f; 答&#xff1a;内存保护的主要任务是确保每…

LeetCode热题100——双指针

双指针 1.移动零2.盛最多水的容器3.三数之和 1.移动零 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 // 题解&#xff1a;使用双指针&#xff0c;其中快指针指向非零元素&#xff0c;慢指针指向首个零元素下…

msvcp120.dll怎么修复,五种方法教你如何修复msvcp120.dll文件

在运行软件时&#xff0c;我们常常会遇到一些错误提示&#xff0c;其中之一就是“由于找不到msvcp120.dll无法继续执行代码”。这个错误通常发生在使用Microsoft Visual C 2013编译的程序运行时。本文将介绍5种修复这个问题的方法&#xff0c;帮助各位解决这个困扰。 方法一、使…

如何使用批量重命名的方法替换重复文件名内容

在文件管理过程中&#xff0c;我们有时会遇到文件名中包含相同部分内容的情况&#xff0c;这不仅会使文件显得混乱&#xff0c;而且还会给文件检索和使用带来不便。为了解决这个问题&#xff0c;我们可以使用云炫文件管理器批量重命名进行批量替换。下面是如何使用这种方法进行…

RT-Thread入门

1、初识RT-Thread RT-Thread&#xff0c;全称是Real Time-Thread&#xff0c;即嵌入式实时多线程操作系统。其基本属性之一是支持多任务&#xff0c;但是允许多任务同时运行&#xff0c;但是并不是意味着处理器在同一时刻真的执行了多个任务。实际上&#xff0c;一个处理器核心…

mac 安装homebrew ,golang

mac 安装homebrew ,golang 安装homebrew安装golang选择 apple arm 版本安装配置环境变量 安装homebrew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"回车执行指令后&#xff0c;根据提示操作。具体包括以下提示操作&am…

深度学习(4)---生成式对抗网络(GAN)

文章目录 一、原理讲述1.1 概念讲解1.2 生成模型和判别模型 二、训练过程2.1 训练原理2.2 损失函数 三、应用 一、原理讲述 1.1 概念讲解 1. 生成式对抗网络&#xff08;Generative Adversarial Network&#xff0c;GAN&#xff09;是一种深度学习模型&#xff0c;是近年来复杂…

vue vant van-uploader使用compressorjs解决拍照上传的图片被旋转 90 度方法,图片压缩上传

vue vant van-uploader使用compressorjs解决拍照上传的图片被旋转 90 度方法&#xff0c;图片压缩上传_van-uploader 拍照上传服务器后图片翻转-CSDN博客文章浏览阅读3.2k次&#xff0c;点赞4次&#xff0c;收藏6次。van-uploader使用compressorjs解决拍照上传的图片被旋转 90 …

游戏找不到x3daudio1_7.dll无法继续执行的解决方法,快速解决dll问题

x3daudio1_7.dll是一个音频处理库&#xff0c;主要用于实现三维音频渲染。它包含了微软的XAudio2音频API&#xff0c;该API被许多游戏和应用程序用于实现高质量的音频效果。这个库文件主要处理音频的空间定位、响度均衡以及多通道音频输出等功能。在游戏中&#xff0c;它可以为…

08 MIT线性代数-求解Ax=b:可解性与结构Complete Solution of Ax=b

1. 可解的条件 Solvability conditions on b 检验Axb是否可解的方法是对增广矩阵进行行消元。如果矩阵A的行被完全消去的话&#xff0c;则对应的b的分量也要得0 两条关于b的限制条件(等价) 1. if a comb. of rows of A gives zero row, then same comb. of enties of b must …

笔记46:ResNeXt 网络详解

本地笔记地址&#xff1a;D:\work_file\DeepLearning_Learning\03_个人笔记\2.图像处理任务\ResNeXt网络学习 a a a a a a a a a a a a a a

【论文阅读VLDB23】Online Schema Evolution is (Almost) Free for Snapshot Databases

Online Schema Evolution is (Almost) Free for Snapshot Databases 对snapshot DB来说可以几乎在线进行schema的演变。 ABSTRACT 在现有数据库系统中&#xff0c;对在线和事务模式演变的支持仍然具有挑战性。之前处理这种schema 演变基本是patches补丁的方式来做&#xff0…

实战授权码登录流程

我是经常阅读公众号优质文章&#xff0c;也经常体验到公众号的授权登录功能。今天就来实现下&#xff0c;流程图如下 效果图 后端接口 主要用来接收微信服务器推送的公众号用户触发的事件、生成和验证授权码的有效性 解析微信服务器推送的事件通知 public String login(Se…

深度强化学习用于博弈类游戏-基础测试与说明【1】

深度强化学习用于博弈类游戏-基础【1】 1. 强化学习方法2. 强化学习在LOL中的应⽤2.1 环境搭建2.2 游戏特征元素提取1)小地图人物位置&#xff1a;2)人物血量等信息3)在整个图像上寻找小兵、防御塔的位置4&#xff09;自编码器提取 3. 策略梯度算法简介参考资料 1. 强化学习方法…

工程建筑模板厂家货源,酚醛胶镜面胶合板实用型

作为工程建筑模板厂家&#xff0c;我们提供高品质的酚醛胶镜面胶合板&#xff0c;为建筑行业的模板需求提供可靠的货源。我们的产品以实用型为设计理念&#xff0c;旨在满足各类工程的施工需求并提供出色的性能。我们的酚醛胶镜面胶合板采用优质的木材作为原材料&#xff0c;经…

负载均衡的综合部署练习(hproxy+keepalived和lvs-DR+keepalived+nginx+Tomcat)

一、haproxykeepalived haproxy 2台 20.0.0.21 20.0.0.22 nginx 2台 20.0.0.23 20.0.0.24 客户机 1台 20.0.0.30 这里没有haproxy不是集群的概念&#xff0c;他只是代理服务器。 访问他直接可以直接访问后端服务器 关闭防火墙 安装haproxy和环境&#xff1a; yum in…

数据结构-初识泛型

写在前&#xff1a; 这一篇博客主要来初步的记录以下泛型的相关内容&#xff0c;内容比较琐碎&#xff0c;就不进行目录的整合&#xff0c;后续可能会对泛型这里进行系统性的梳理&#xff0c;此篇博客主要是对泛型有一个简单的认识与理解&#xff0c;需要知晓的内容。 当我调用…

能量管理系统(EMS):新能源储能行业的智能化大脑

导语&#xff1a;能源管理系统&#xff08;EMS&#xff09;是新能源储能行业中一种关键的智能化技术。它的作用类似于大脑&#xff0c;能够监控、控制和优化能源系统的运行&#xff0c;为储能设施提供高效稳定的能源管理。本文将介绍能量管理系统的基本概念、功能和应用。 一、…