- 博客(362)
- 资源 (60)
- 问答 (4)
- 收藏
- 关注

原创 【OpenGL ES】在Windows上手撕一个mini版的渲染框架
摘要 本文介绍了一个名为"glcore"的mini版OpenGLES渲染框架的设计与实现。该框架旨在封装约70个常用OpenGLES指令,简化图形渲染开发流程,提高性能并方便跨平台使用。 框架的主要特点包括: 封装友好:提供EGL环境搭建、着色器程序生成、网格构建等基础能力 代码规整:设计了规范的bind/unbind接口体系 易于扩展:通过TextureAction接口统一管理纹理活动 性能高效:使用VBO、IBO、VAO缓存数据,减少CPU-GPU交互 跨平台:基于C++实现,核心库
2025-07-18 00:42:56
964

原创 【OpenGL ES】在Android上手撕一个mini版的渲染框架
OpenGLES渲染框架glcore设计与实现 本文介绍了一个基于C++的OpenGLES渲染框架glcore的设计与实现。该框架旨在简化OpenGLES开发流程,提高渲染效率,并具有良好的跨平台特性。 框架特点 封装友好:对70个常用OpenGLES指令进行封装,提供EGL环境搭建、着色器程序生成、网格构建等基础功能 性能优化:通过VBO、IBO、VAO缓存数据到显存,减少CPU-GPU数据传输,并缓存attribute和uniform的location 跨平台:基于C++实现,核心依赖库独立封装,方便迁
2025-07-13 17:46:00
1255

原创 【libGDX】2D粒子系统
下载后,在命令行窗口输入以下命令打开粒子编辑器。打开粒子编辑器后,界面如下,有经典模式(Classic)和向导模式(Wizard),一般选择经典模式(本文只介绍经典模式)。经典模式界面如下,可以通过拖动这些面板之间的边框来调整它们的大小。预览窗口用于预览粒子效果,界面如下,左键单击并拖拽可以平移摄像机,右键单击可以重设粒子发射位置,右键单击并拖拽可以让粒子发射位置跟随鼠标位置变化,滑动滚轮或单击缩放按钮可以放大和缩小。预览窗口的标签含义如下。FPS:帧率,即帧 / 秒。
2025-01-25 17:35:29
1007

原创 【Rive】眼睛互动动画
本文基于 Rive 社区开放的眼睛动画,进一步加工处理,实现更有趣的眼睛互动动画。原始资源见 →,效果如下。原始资源只有一只眼睛,并且没有事件交互,动画比较单一。本文在该资源的基础上进行了以下修改。绘制两只眼睛;无事件时,眼睛在微眯和张开之间循环动画;移动鼠标(或手指)时,眼睛看向鼠标(或手指)位置;鼠标(或手指)移至眼睛附近时,眼睛聚焦,眼睛和瞳孔逐渐变小;鼠标(或手指)远离眼睛时,眼睛和瞳孔逐渐恢复原来大小;单击背景时,眨下眼(逐渐闭眼,然后逐渐张开,再逐渐微眯,再张开);单击背景或鼠标(或
2024-12-12 21:57:23
1009

原创 【Filament】材质系统
本文主要介绍 Filament 的材质系统,官方介绍详见 →。。需要注意的是,Unity 世界空间是左手坐标系,OpenGL 和 Filament 的世界空间是右手坐标系,Filament 的世界空间坐标轴如下。读者如果对 Filament 不太熟悉,请回顾以下内容。
2024-01-16 01:05:24
1870

原创 【Unity3D】屏幕深度和法线纹理简介
深度纹理本质是一张图片,图片中每个像素反应了屏幕中该像素位置对应的顶点z值相反数(观察坐标系),之所以用 “反应了”而不是 “等于”(或 “对应” ),因为深度纹理中颜色的值域是 [0, 1],而顶点z值相反数不一定在该区间,另外顶点 z值相反数与深度纹理不是线性关系(透视投影引起的)。法线纹理本质也是一张图片,图片中每个像素的 R、G值对应该点法线向量的x、y 值(观察空间),z值通过公式 z =sqrt(x * x + y * y)计算得到。深度纹理和法线纹理可以用于边缘检测特
2023-06-13 00:35:47
2585

原创 【Unity3D】魔方
1)魔方渲染模块用户选择魔方阶数,渲染指定阶数的魔方;2)魔方整体控制模块用户 Scroll 或 Ctrl + Scroll,控制魔方放大和缩小;用户 Drag 空白处(或右键 Drag),控制魔方整体连续旋转;用户点击翻面按钮(或方向键,或 Ctrl + Drag,或 Alt + Drag),控制魔方翻面;用户点击朝上的面按钮,控制魔方指定面朝上;可以实时识别用户视觉下魔方的正面、上面、右面;3)魔方局部控制模块用户点击刷新按钮,打乱魔方;用户 Drag 魔方相邻的两个方块,控制该层旋
2023-04-19 21:15:59
6020
5

原创 【Unity3D】空间和变换
Unity 局部空间、世界空间、裁剪空间、屏幕空间都采用左手坐标系,只有观察空间采用右手坐标系。左右手坐标系除了坐标系朝向(旋向性)不同,还存在以下差异:左手坐标系下旋转正方向的定义遵循左手法则,右手坐标系下旋转正方向的定义遵循右手法则;左手坐标系下向量叉乘遵循左手法则。Unity局部空间世界空间裁剪空间屏幕空间都采用左手坐标系,只有观察空间采用右手坐标系。左右手坐标系除了坐标系朝向(旋向性)不同,还存在以下差异:旋转正方向的定义旋转正方向的定义向量叉乘向量叉乘。
2023-02-23 01:01:57
7377
13

原创 【Unity3D】Unity3D技术栈
本文梳理了笔者在学习 Unity3D 的过程中,对 Unity3D 的理解和学习路线,以帮助读者循序渐进地学习 Unity3D,后续笔者仍会持续更新 Unity3D 相关技术栈,并同步到本文中。
2023-01-19 00:47:49
48058
51

原创 【OpenGL ES】渲染管线
渲染管线是指:将模型的顶点序列、颜色系列、纹理序列、法线序列等数据输入到 OpenGL ES 中,到输出屏幕,这个阶段数据所经历的流程。裁剪:进行透视分割,并剔除视锥体外面的顶点,根据 x, y, z 的值是否在 [-1, 1] 之间判断是否淘汰顶点;屏幕映射:根据视口(Viewport)大小,将近平面上的点映射到屏幕上图元装配:根绝输入顶点序列和和图元类型(mode)组装图元;光栅化:对图元内部进行插值,使其与屏幕中的像素一一对应;裁剪测试:指定一个矩形的剪裁区域,当启用剪裁测试后,只有在这个区域
2022-09-09 01:42:42
6548
4

原创 三阶数字华容道最优解
1 前言三阶数字华容道问题又称八数码问题,目前解决数字华容道问题的方法主要有DFS、贪婪算法、A*算法等。DFS时间复杂度较高,贪婪算法和A*算法都能得到一个有效解,但都不是最优解。笔者通过大量实验,使用BFS进行数据预处理后,能够得到最优解。(1)定义:状态(S):每个棋盘的布局称为一个状态,其中状态 [[1,2,3],[4,5,6],[7,8,9]] 称为零状态代价(C):从当...
2019-12-15 22:21:58
14237
10
原创 【OpenGL ES】光栅化插值原理和射线拾取原理
本文探讨了光栅化插值和射线拾取算法中的共同数学原理。两者都采用四面体模型,以三条边作为基向量构建非直角坐标系,并需要求解射线向量在基向量上的坐标。在光栅化插值中,通过求解三角形内任意点Q的坐标系数(x,y,z)来实现属性插值;在射线拾取中,通过求解射线与三角形交点Q的坐标参数d来判断相交情况。文章推导了关键矩阵方程,分析了参数的几何意义:在光栅化中参数和等于1表示点在三角形内,在射线拾取中参数为负表示交点在三角形外。这两种图形学算法展现了相似的数学处理思路。
2025-08-30 19:41:43
430
原创 【OpenGL ES】Windows上OpenGL环境搭建
本文介绍了Windows平台下OpenGL开发的四种主流方案:GLFW+Glad、GLFW+GLEW、freeglut+Glad和freeglut+GLEW。文章首先对比了GLFW与freeglut的特性差异(现代轻量级vs.兼容性方案),以及Glad与GLEW的区别(灵活定制vs.通用加载),推荐GLFW+Glad作为最佳组合。详细说明了各个库的环境搭建方法,包括下载预编译库或源码编译,并提供了基于CMake的项目目录结构规范。最后通过四个完整示例分别演示了四种搭配的具体实现,包含CMake配置、事件回调
2025-07-16 00:50:37
947
原创 【OpenGL ES】不用GLSurfaceView,如何渲染图像
本文介绍了在Android中不使用GLSurfaceView实现OpenGL ES渲染的两种方案:1)继承SurfaceView,通过EGL创建窗口表面;2)继承TextureView,利用SurfaceTexture创建EGL渲染表面。两种方案都详细展示了EGL环境的搭建过程,包括创建Display、Config、Context和Surface,并绑定到当前线程。第一种方案通过SurfaceHolder获取Surface,第二种通过TextureView的SurfaceTexture创建Surface。
2025-06-19 00:10:36
826
原创 【JNI】JNI基础语法
本文详细介绍了JNI(Java Native Interface)的核心语法与Java交互方法。首先对比了C和C++在JNI中的差异:C++需用extern "C"避免名称修饰,且JNIEnv的调用方式不同(C用(*env)->,C++用env->)。其次,讲解了JNI数据类型,包括基本类型(如jint、jboolean)和引用类型(如jobject、jstring),并区分了局部引用、全局引用和弱全局引用的使用场景。此外,文章详细说明了字符串和数组的操作方法,如NewStringUTF创建字符串、Ge
2025-06-12 00:39:17
701
原创 【JNI】JNI环境搭建
JNI开发环境搭建与实践摘要 本文介绍了JNI(Java Native Interface)技术及其开发流程。主要内容包括:1)JNI基本概念与官方文档说明;2)命令行环境搭建(JDK和MinGW安装配置);3)通过HelloWorld案例演示JNI开发步骤(Java代码编写、头文件生成、C代码实现、动态库编译);4)Android Studio中配置JNI项目(CMake构建、ABI架构指定、Native代码集成)。文章提供了完整的代码示例和环境配置方法,涵盖Windows/Linux平台的动态库生成(.
2025-06-01 01:05:46
879
原创 【Android】基于SurfaceControlViewHost实现跨进程渲染
本文介绍了使用SurfaceControlViewHost实现跨进程渲染普通View和GLSurfaceView的方法。通过AIDL实现跨进程通信,服务端创建SurfaceControlViewHost并绑定目标View(ImageView或GLSurfaceView),客户端获取SurfacePackage并将其设置到宿主SurfaceView中。核心代码包括服务端的getSurfacePackage方法创建渲染视图,客户端的绑定服务及设置SurfacePackage流程。文章提供了完整的项目结构、AID
2025-05-25 20:21:13
918
原创 【Rive】rive-android源码分析
本文基于 rive-android 10.1.0 进行源码分析,主要介绍 Rive 的渲染类型、RendererType 透传流程、Surface 透传流程、渲染流程、启动渲染流程、暂停渲染流程等内容。 rive-android 类图框架如下。图中,蓝色的类表示 rive-android 中 Kotlin 代码,绿色的类表示 rive-android 中 C++ 代码,橙色的类表示 rive-runtime 中代码(下同)。本文只解读 rive-android 的源码,不解读 rive
2025-04-28 00:47:27
803
原创 【Android】RuntimeShader 应用
RuntimeShader 是 Android 13(T)中新增的特性,用于逐像素渲染界面,它使用 AGSL(Android Graphics Shading Language)编写着色器代码,底层基于 Skia 图形渲染引擎。官方介绍详见 →。相较于 OpenGL ES,RuntimeShader 具有以下特点。
2025-03-15 21:29:24
1172
原创 【Groovy】类和对象
使用 abstract 修饰的类称为抽象类,抽象类中可以有抽象函数,这些函数被添加了 abstract 修饰符,父类不能实现,子类必须重写实现(子类如果也是抽象类除外)。抽象类不能被实例化,只能实例化其具化子类,抽象类中允许有具化的函数。@Override//def peo = new People() // 编译报错, 抽象类不能被实例化stu.say() // 打印: xiao min: Hello。
2025-03-02 17:55:50
999
原创 【Groovy】函数、闭包、泛型
如下,Integer 是 Number 的子类,Number 引用可以指向 Integer 对象,并且 Data<Number> 引用可以指向 Data<Integer> 对象,Data<Integer> 引用也可以指向 Data<Number> 对象,还可以访问、修改对象的泛型变量,这在 Java 和 Kotlin 中是不允许的。泛型的类型检查只存在于编译阶段,在源代码编译之后,不会保留任何关于泛型类型的内容,即类型擦除。当闭包入参个数只有一个时,可以省去,引用时使用 it 替代,如下。
2025-03-01 20:27:17
1033
原创 【Groovy】变量和基本数据类型
Groovy 允许实例化 java.lang.String 类定义一个字符串对象,也可以实例化 groovy.lang.GString 类定义一个字符串对象,两者可以混合编程second'''def str4 = """第一行第二行"""456/// 字符串插值def str5 = "买了${count}个苹果" // 买了15个苹果单引号(')、双引号(")、三引号(''')、三双引号(""")、斜线(/)的区别如下。单引号和三引号不支持插值、转义字符(\' 和 \\ 除外)、混合编程;
2025-02-27 23:28:03
832
2
原创 【Groovy】Groovy环境搭建
Groovy 是一种基于 JVM 平台的敏捷且动态的编程语言,能与 Java 无缝集成。该语言由 James Stracham 和 Bob McWhirter 于 2003 年启动开发,在 2007 年 1 月发布第一个版本。Groovy 具有以下优势。Groovy 的语法比 Java 更加简洁,省略了繁琐的代码结构,例如分号、类型声明等,让开发者更专注于业务逻辑的实现。Groovy 是动态类型语言,无需显式声明变量类型,编译器会在运行时自动推断类型,提高了代码的灵活性和开发效率。
2025-02-24 00:44:04
892
原创 【OpenGL ES】GLSL基础语法
本文将介绍 GLSL 中数据类型、数组、结构体、宏、运算符、向量运算、矩阵运算、函数、流程控制、精度限定符、变量限定符(in、out、inout)、函数参数限定符等内容,另外提供了一个 include 工具,方便多文件管理 glsl 代码,实现代码的精简、复用。 Unity 中 Shader 介绍详见 →【Unity3D】Shader常量、变量、结构体、函数,渲染管线介绍详见 →【OpenGL ES】渲染管线。
2024-12-29 00:54:32
1726
原创 【Rive】骨骼动画
骨骼不能渲染显示,只能控制其他图形变换,具有以下特性。绑定图形:可以将图形绑定到骨骼上,使图形随骨骼移动、旋转或缩放。权重 (Weights):通过调整顶点权重,可以控制图形在骨骼运动时的变形程度,从而实现平滑的形变效果。IK(反向动力学)约束:通过操控骨骼末端来控制整个骨骼链条的姿态(如:角色开枪后,枪的震动带动手和胳膊的抖动)。
2024-12-11 00:23:45
663
原创 【Rive】波动文字
本文将使用文本修改器(Text Modifiers)做文字动画,实现文字波动效果。按以下步骤可以创建一个 Modifier Group 和 Range。部分参数的释义如下。RangeFalloff本节完整资源详见 →。
2024-12-10 00:10:07
685
原创 【Rive】事件
Rive 中事件监听器(Listener)、状态动画(Timeline)、过度动画、关键帧都可以抛出自定义事件,并且状态动画和过度动画可以在动画开始和结束的时机抛出事件。Rive 中可以创建一个监听器,监听抛出的自定义事件。需要注意:绑定的元素只能是画板,才能监听自定义事件。Android 中可以通过 RiveAnimationView 的 addEventListener 方法添加动画监听器,用于监听状态动画和过渡动画的开始和结束时机,实现动画开始和结束时的事件回调;也可以监听 Rive 事件触发的时机
2024-12-09 21:33:10
1217
原创 【Rive】Android与Rive交互
①时间线说明:Color_Red、Color_Green、Color_Blue 都只对颜色参数做动画,并且都只有一帧,对应的颜色分别是红、绿、蓝;Scale_Idle、Scale 都只对缩放参数做动画,Scale_Idle 只有一帧,值为 0,Scale 里有 3 帧,值分别为 100%、120%、100%。③Scale状态机说明:当 Trigger_Scale 被激活时,会触发一次缩放动画,Scale→Scale_Idle 过渡条件的 Exit Time 设置为 100%。文本操作的官方介绍详见 →。
2024-12-09 19:11:08
1293
1
原创 【Rive】混合动画
中介绍了 Rive 中动画的基础概念和一般动画的制作流程,本文将介绍混合动画的基础概念和一般制作流程。Unity 中混合动画介绍详见→。混合动画是指同一时刻多个动画按照一定比例同时执行,这些动画控制的动画参数往往是相同的参数。与动画图层不同,动画图层是指多个动画同时执行,互不干扰,这些动画控制的动画参数往往是不同的参数。在动画状态机窗口右键,在弹出的菜单栏中选择【Add State】创建一个新的动画节点,选中创建的动画节点,在右侧窗口选择动画混合选项卡,如下。
2024-12-07 21:50:21
634
原创 【Rive】Rive在Android上的简单应用
Rive 是一款强大的矢量图编辑器,可以设计图形、也可以制作动画。Rive 提供了矩形、圆形、三角形、多边形、星形、钢笔、文字等工具来绘制各式各样的矢量图形;提供了平移、旋转、缩放等工具对矢量图形进行各种变换;提供了骨骼、约束、时间线、状态机、过渡条件、事件监听器等工具来制作各种交互复杂、动作炫酷的动画。
2024-12-03 21:04:59
1892
1
原创 【Kotlin】select简介
协程的 select 是一种用于异步操作的选择器,它允许同时等待多个挂起函数的结果,并在其中一个完成时执行相应的操作。能够被 select 的事件都是 SelectClause,在 select.kt 中有定义,如下。
2024-04-28 01:27:49
1155
2
原创 【Kotlin】Channel简介
Channel 是一个并发安全的阻塞队列,可以通过 send 函数往队列中塞入数据,通过 receive 函数从队列中取出数据。当队列被塞满时,send 函数将被挂起,直到队列有空闲缓存;当队列空闲时,receive 函数将被挂起,直到队列中有新数据存入。Channel 中队列缓存空间的大小需要在创建时指定,如果不指定,缓存空间默认是 0。
2024-04-27 18:19:21
2172
5
原创 【Kotlin】Flow简介
Flow 是 Kotlin 标准库中的一个新的异步流处理框架,旨在简化异步数据流的操作和处理,它提供了一种声明式的方式来处理数据流。Flow 中一些接口调用有些类似 Sequence(详见 →),协程的使用详见 →。Flow 有以下特性和概念。:Flow 允许以一种非阻塞的方式处理一系列的值或事件,这使得在处理大量数据或涉及 IO 操作时能够更加高效。:只有在收集器(collector)订阅(或启动)了之后才会开始发射(emit)数据。
2024-04-24 00:08:34
4111
2
原创 【Kotlin】协程
相较于 C# 中的协程(详见 →),Kotlin 中协程更灵活,难度更大。协程是一种并发设计模式,用于简化异步编程,它允许以顺序化的方式表达异步操作,避免回调地狱等问题。使用协程,可以将异步操作的代码像同步代码一样写,而无需显式地管理线程。在 Kotlin 中,协程由 kotlinx.coroutines 库提供支持。它使用 suspend 修饰符来标记挂起函数(即可暂停执行并稍后恢复执行的函数),这使得编写异步代码更加直观和简单。协程和线程具有以下异同点。
2024-04-17 00:50:06
1861
4
原创 【Kotlin】委托模式
Kotlin 中可以通过 by 关键字实现委托,包括类委托和属性委托,属性委托包含:by T、by lazy、by Delegates.observable、by ::T、by map
2024-04-02 00:16:31
830
原创 【Kotlin】Sequence简介
序列(Sequence)是 Kotlin 中为方便操作集合及其元素而定制的接口,是一个延迟获取数据的集合,只有需要元素时才会生产元素。在处理大量数据时,序列可以显著地提升性能。Sequence 类似 Java 中的 Stream,详见 →。Sequence 有中间操作和终端操作,如下。中间操作终端操作。
2024-03-30 12:15:47
1554
Filament立方体贴图(6张图)
2023-12-25
Filament纹理贴图
2023-12-23
Filament绘制立方体
2023-12-22
Filament绘制圆形
2023-12-21
Filament绘制圆形(更新版)
2023-12-22
Filament绘制矩形
2023-12-19
Filament绘制三角形
2023-12-18
libGDX加载G3DJ模型
2023-11-28
libGDX立方体手动旋转
2023-11-26
libGDX Mesh立方体贴图(6张图)
2023-11-25
libGDX Mesh纹理贴图
2023-11-25
libGDX使用Mesh绘制立方体
2023-11-25
libGDX使用Mesh绘制圆形
2023-11-25
libGDX使用Mesh绘制矩形
2023-11-25
使用Mesh绘制三角形
2023-11-25
基于libGDX实现接水游戏
2023-11-25
基于AssetBundle实现资源热更新(更新版)
2023-11-17
Libgdx全套工具包,包含gdx-setup、Particle Editor、fbx-conv、Texture Packer等
2023-11-13
基于 Unity3D 的 2 ~ 10 阶魔方实现(Windows+Android)
2023-11-05
libGDX 项目 Setup Tool (gdx-setup)
2023-09-23
一键抓 perfetto trace 脚本
2025-07-31
【OpenGL ES】一个mini版的Windows渲染框架
2025-07-18
Windows上 GLFW + Glad、GLFW + GLEW、freeglut + Glad、freeglut + GLEW 环境搭建
2025-07-16
【OpenGL ES】一个mini版的Android native渲染框架
2025-07-13
不用GLSurfaceView,如何渲染图像
2025-06-19
基于SurfaceControlViewHost实现跨进程渲染
2025-05-25
RuntimeShader应用
2025-03-16
libgdx实现2D粒子效果
2025-01-25
Android中基于Rive实现眼睛互动动画
2024-12-12
基于Rive骨骼动画实现绳摆动画
2024-12-11
Android中监听Rive事件回调案例
2024-12-10
Android中使用Rive实现文字波动特效
2024-12-10
Android与Rive交互应用案例
2024-12-09
Rive基于Android和Rive实现秒表
2024-12-07
Rive在Android上的简单应用
2024-12-03
使用AIDL实现进程间通讯简单案例(更新版)
2024-05-19
基于Filament实现壁纸
2024-01-08
Filament基于物理的光照(PBR)
2024-01-06
Filament自定义Blinn Phong光照模型
2024-01-06
Filament加载obj和fbx模型
2024-01-05
python绘图,如何让坐标轴不自动显示加上一个数
2020-04-07
Visual C++中Gellery文件夹文件夹为空
2020-04-03
卡尔曼滤波能否做多步轨迹预测?
2020-02-06
二级和三级标题缩进不对,怎么使三级标题缩进在二级标题里面
2020-01-16
TA创建的收藏夹 TA关注的收藏夹
TA关注的人