技术宅的结界

 找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 705|回复: 3
收起左侧

【算法】在文曲星平台上,用gvmaker实现3D场景渲染!(附:文曲星GVMaker开发环境下载,GVMaker模拟器下载,源码下载)

[复制链接]

986

主题

2165

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
197
威望
261 点
宅币
15942 个
贡献
30920 次
宅之契约
0 份
在线时间
1517 小时
注册时间
2014-1-26
发表于 2017-3-17 12:14:42 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有帐号?立即注册→加入我们

x
注:本文所指的“文曲星”是“文曲星A2008”机型。。

wqx.png
QQ图片20170316224846.png

    文曲星不支持浮点数运算,而且运行也十分缓慢——其实不是文曲星慢,而是它上面运行的gvmaker虚拟机太慢了。所以我使用定点数来代替浮点数进行运算。

    所谓定点数,就是小数点位置被固定到指定位置的一种数据类型,比如我存储1.0,对于定点数,我把小数点固定在第10位,那么我实际存储的数值就是0x400(十进制1024)。这样的话,我的定点数的精度,最低也是1/1024。

    定点数的加减法和整数无异,直接+ - 就好。但乘除法的话,如果你用一个定点数去乘一个定点数,并且你直接用的是整数的乘法的处理方式的话,你需要把得到的积再除以定点数表示的1.0,你才能得到正确的结果。比如你的定点数1.0用整数方式存储是1024的话,为了得到2.0 * 2.0 = 4.0的效果,你实际做的整数乘法是2048 * 2048,得到的是4194304,你需要再除以1024(也就是你的定点数的1.0),你才能得到4096。同理除法也需要经过这样的处理,只不过除法是先让被除数乘上定点数1.0,再除以除数。比如1.0 / 2.0 = 0.5,用定点数做运算的话,就是1024 * 1024 / 2048 = 512。

    和浮点数做对比,定点数运算比较快,并且它的精度是可控的——因为浮点数的小数点位置是浮动的,它的精度与数值的大小有密切的关系,所以用定点数能保证精度的统一,而浮点数则不能。

    但定点数的缺点在于做乘除法的时候,会严重地损失精度,尤其是圆周率,32位浮点数能存储3.1415927,而定点数假设小数点在第10位,那么它只能用 3216 来表示圆周率(3216 = π×1024 取整)。而如果我把小数点放在第16位的位置上(1.0用65536表示)的话,我虽然能精确到1/65536,但我能存储的最大的数值也从之前的4294966272变成了65536,而且我每次做乘除法的时候,我都要用一个64位的整数来存储中间值,这会严重降低运算的效率(然而x86平台还好)。

    有关3D渲染的算法,其实就是很简单的矩阵变换和投影,其它并没有什么玄妙。顺带一提,很多人以为用了DirectX或者OpenGL才能算真3D,但其实3D渲染的“真伪”只取决于你用的算法,和你使用的媒介无关。事实上就算你用的是正交投影,某种程度上也算是“真3D”的。我之前就写过一篇帖子,讲如何用VB自带的Line进行3D画面的绘制的。

    文曲星运行用户程序,用的是一款叫“gvmaker”的开发环境,和它的启动器。这里放出下载:
gvmaker开发环境: GVmaker2.4开发环境_20071011_113832.rar (6.08 MB, 下载次数: 8)

25

主题

75

帖子

1009

积分

用户组: 版主

UID
1821
精华
6
威望
57 点
宅币
759 个
贡献
31 次
宅之契约
0 份
在线时间
186 小时
注册时间
2016-7-12
发表于 2017-3-17 18:07:24 | 显示全部楼层
本帖最后由 Ayala 于 2017-3-17 18:28 编辑
    但定点数的缺点在于做乘除法的时候,会严重地损失精度,尤其是圆周率,32位浮点数能存储3.1415927,而定点数假设小数点在第10位,那么它只能用 3216 来表示圆周率(3216 = π×1024 取整)。而如果我把小数点放在第16位的位置上(1.0用65536表示)的话,我虽然能精确到1/65536,但我能存储的最大的数值也从之前的4294966272变成了65536,而且我每次做乘除法的时候,我都要用一个64位的整数来存储中间值,这会严重降低运算的效率(然而x86平台还好)

这个问题其实可以用1024* PI*2**8 (定点数 π×1024 * 256 =0xC90FE)来解决 当然也可以用 1024*PI*2**15更高数值
另外PI*1024 取整也应该是3216.990877≈3217 而不是 3216

986

主题

2165

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
197
威望
261 点
宅币
15942 个
贡献
30920 次
宅之契约
0 份
在线时间
1517 小时
注册时间
2014-1-26
 楼主| 发表于 2017-3-17 20:06:54 | 显示全部楼层
Ayala 发表于 2017-3-17 18:07
这个问题其实可以用1024* PI*2**8 (定点数 π×1024 * 256 =0xC90FE)来解决 当然也可以用 1024*PI*2**15更 ...

其实是说错,不是取整,而是“商”,所以是没有四舍五入的

986

主题

2165

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
197
威望
261 点
宅币
15942 个
贡献
30920 次
宅之契约
0 份
在线时间
1517 小时
注册时间
2014-1-26
 楼主| 发表于 2017-9-15 17:52:06 | 显示全部楼层
另外因为文曲星的解释器特征,优化方面侧重于多调用它的函数进行绘图,少进行自己的绘图方式。比如它的画线函数,其实虽然明明可以自己写一个不使用乘除法的画线函数,但依然还是推荐使用它自己的画线函数(VLine、HLine、Line)。因为自己写的画线函数在运行的时候需要GVMaker虚拟机对其进行指令层面的判断和模拟执行的操作,而它自己的画线函数则是用文曲星本机的处理器指令执行的。

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号|网站地图

GMT+8, 2018-5-25 18:45 , Processed in 0.094796 second(s), 18 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表