2021SC@SDUSC山东大学软件学院软件工程应用与实践--Ebiten代码分析 源码分析(十三)
2021/12/24 20:07:53
本文主要是介绍2021SC@SDUSC山东大学软件学院软件工程应用与实践--Ebiten代码分析 源码分析(十三),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
2021SC@SDUSC
目录
- 一.概述
- 二.回顾
- 1.Ebiten综述
- 2.游戏窗口大小调整即游戏运行
- 3.RunGame包含的三个主要方法
- 4.DrawImage核心方法分析
- 5.DrawTrangiles方法分析
- 6.Graphics图像操作方法分析
- 7.文本系统的渲染分析
- 8.图像绘制的合成模式分析
- 9.时钟系统即过滤器Filter的分析
- 10.packing包装方法分析
- 11.ebiten中的颜色变换分析
- 12.矢量图形渲染功能分析
- 三.总结
一.概述
本文主要是对本次课程发布的所有博客进行一个总结。结合最开始的小组分工,我负责分析的核心代码主要是将ebiten游戏逻辑在屏幕上绘制成图像的相关功能分析。
二.回顾
1.Ebiten综述
Ebiten 是一个Go 编程语言的开源游戏库。Ebiten 的简单 API 可让我们快速轻松地开发可跨多个平台部署的 2D 游戏。
在 Ebiten 中,一切都是图像:屏幕、图像文件中的数据,甚至屏幕外的项目都表示为图像对象。大多数渲染操作包括在另一张图像上绘制一张图像。
2.游戏窗口大小调整即游戏运行
我们以ebiten源码中自带的游戏2048为例子依次介绍了实现这些功能的具体代码,了解到ebiten的修改窗口大小的方法步骤大致如下:输入目的窗口宽高,获取当前窗口对象,利用glfw的方法多次传参,通过系统调用最终修改游戏窗口的大小。以及总结,RunGame()方法是通过开启一个主循环线程反复调用game对象的Update方法,Draw方法和Layout方法,来保证游戏的正常运行的。
3.RunGame包含的三个主要方法
介绍了ebiten在RunGame函数中逐帧执行的Update()方法,Draw()方法和Layout()方法以及它们的实现细节。
Update()——更新游戏逻辑,几乎每一帧都要调用,Ebiten默认每秒调用Update方法60次,且第一次调用Draw方法之前确保必须先调用一次Update方法初始化。
Draw()——绘制游戏画面,每帧都会调用游戏的Draw函数来绘制屏幕,参数表示一个屏幕图像。采用更新后的内容作为游戏屏幕。
Layout()——接受以设备无关像素为单位的原生外部大小,并返回游戏的逻辑屏幕大小,在台式机上,外部是窗口或显示器(全屏模式)。在浏览器上,外部是一个实体元素;在手机上,外部是视野的大小。即使外部大小和屏幕大小不同,渲染比例也会自动调整为与外部相配。确保在第一次调用Update之前先调用Layout。
铺垫了Draw方法的核心部分也就是ebiten的核心部分,图像绘制。
4.DrawImage核心方法分析
继续讨论根目录下image.go文件中的DrawImage方法,逐层寻找调用,反推出最核心的方法DrawTrangiles方法
5.DrawTrangiles方法分析
继续讨论了DrawImage()方法中嵌套调用的DrawTriangles()方法。
首先是mipmap类调用的,定义在internal/buffered/image.go的DrawTriangles方法。
该方法又调用了定义在internal/atlas/image.go中的DrawTriangles()方法。
然后atlas中的DrawTriangles()方法又调用了同文件下的drawTriangles()方法。
drawTriangles()方法又调用了位于internal/restorable/image.go中的DrawTriangles()方法。
接下来是internal/grasphiccommand/image.go方法中的DrawTriangles()方法且该方法最终调用了同文件夹下的command.go中的EnqueueDrawTrianglesCommand()方法调用请求绘制三角形命令,使用命令队列的方法来执行方法。
命令类的方法由小组内其他成员负责分析。
6.Graphics图像操作方法分析
介绍Ebiten操作图像的相关方法,例如初始化,放大缩小,新建一张图像等方法。
7.文本系统的渲染分析
讨论了对ebiten的文本渲染系统,即如何将文本内容渲染在游戏屏幕上。发现与图像渲染类似,同样是一个文本和一个文本绘制选项相互协调完成绘制。
8.图像绘制的合成模式分析
图像在屏幕上绘制需要有一个图像绘制选项对象来提供图像绘制的具体信息,例如需要对其进行的颜色变换,几何变换,选择哪种类型的合成模式以及过滤器。CompositeMode表示Porter-Duff合成模式。此命名约定遵循css合成。
主要有如下几种合成模式可供选择,且它们都有不同的作用。
CompositeModeUnknown:表示未知的合成模式,作用是当传入的合成模式错误时,转到该项用于通知系统传入错误。
CompositeModeSourceOver:表示默认合成模式,即源图像的Alpha用于在目标顶部混合像素。
CompositeModeClear:清除模式,[0, 0],即图像中所有像素点的alpha和颜色值均为0。
CompositeModeCopy:复制模式,将源图像的颜色和透明度复制到目的图像。
CompositeModeDestination:输出是目标像素。这意味着混合无效。
CompositeModeDestinationOver:目标的Alpha用于将其混合在源像素的顶部。此模式与CompositionMode_SourceOver相反。
CompositeModeSourceIn:输出是源,其中的alpha值将减去目标的alpha值。
CompositeModeDestinationIn:输出是目标,其中的alpha值被源的alpha值减小。此模式与CompositionMode_SourceIn相反。
CompositeModeSourceOut:输出是源,其中alpha减小了目标的倒数。
CompositeModeDestinationOut:输出是目标,其中的alpha值由源的倒数减少。此模式与CompositionMode_SourceOut相反。
CompositeModeSourceAtop:源像素在目标顶部混合,源像素的alpha减少了目标像素的alpha。
CompositeModeDestinationAtop:目标像素混合在源的顶部,目标像素的alpha减小目标像素的alpha。此模式与CompositionMode_SourceAtop相反。
CompositeModeXor:源(其alpha值与目标alpha值的倒数成反比)与目标合并,该目标的alpha值与源alpha的倒数成反比。 CompositionModeXor与按位Xor不同。
CompositeModeLighter:设置了源色和目标之和
CompositeModeMultiply:输出是源颜色乘以目标颜色。将颜色与白色相乘会使颜色保持不变,而颜色与黑色相乘则会产生黑色。
9.时钟系统即过滤器Filter的分析
介绍了ebiten的时钟系统以及图像绘制选项中的Filter纹理过滤器。首先了解到时钟系统是用来在游戏的进行过程中对时间线进行一个记录,有获取当前时间,初始化参数,获取当前FPS(每秒传输帧数),TPS(每秒处理事务数),获取TPS的计算计数,更新当前FPS和TPS,更新系统时间等方法,然后Filter是图像绘制选项中的参数,设置绘制图像中的纹理滤镜。
注意到纹理过滤器的其中一个很重要的目的就是图像的缩放,以图像缩放为例,采用最近的过滤器时,用最靠近像素中心的那个纹理单元进行放大和缩小,效率更高,但效果不好,锯齿严重。
采用线性过滤器时,是对靠近像素中心的纹理单元,取加权平均值,用于放大和缩小。效果更好,效率稍低。
但是线性方式存在问题,那就是边缘处理,通常情况下有两种方法,一种是取边缘外元素作为普通点进行加权计算,一种是不取。
前者表示“使用纹理中坐标最接近的一个像素的颜色作为需要绘制的像素颜色”,只经过简单比较,需要运算较少,可能速度较快
后者表示“使用纹理中坐标最接近的若干个颜色,通过加权平均算法得到需要绘制的像素颜色”,需要经过加权平均计算,其中涉及除法运算,可能速度较慢。
10.packing包装方法分析
分析ebiten中的packing包中的相关方法,了解了packing包提供了一种二维空间的包装算法。
11.ebiten中的颜色变换分析
颜色变换是图像绘制选项的其中一个重要属性,同样是图像绘制选项中的一个属性,也有初始化,平移,选转,缩放等方法。
12.矢量图形渲染功能分析
描述ebiten的矢量图形渲染功能,该方法在vector/path.go文件中定义,且该部分目前处于测试阶段,可能会因为破坏后向兼容性而改变接口。提供类似于在界面上直接绘制线条的功能。
三.总结
通过本学期的软件工程应用与实践的课程,以小组合作的形式共同分析了ebiten的源文件中的核心代码,熟悉了类似方法的实现流程,同时也学习到了很多新的知识。
这篇关于2021SC@SDUSC山东大学软件学院软件工程应用与实践--Ebiten代码分析 源码分析(十三)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享