11011110110011011001100110011001000110011001100111010001011

January 31, 2007

Camera In JSR184

Filed under: Programming

1. Camera类
                  — Lyo Wu

写完模拟器的M3G部分,早就想写点总结,不写怕要忘了。
那就从最简单的Camera类开始。

Camera类封装了3种投影变换:Generic、Parallel、Perspective。
1) Generic
public void setGeneric(Transform transform)
直接指定一个变换矩阵(Transform类其实就是一个矩阵的封装),可以根据需求任意设置投影矩阵。

2) Parallel
public void setParallel(float fovy, float aspectRatio, float near, float far)
 平行投影(正射投影,Orthographic Projection),忽略z轴作用,投影后的物体大小尺寸不变。M3G Specification中已经给出了对应的矩阵(NDC坐标系):
   | 2/w      0          0           0  |
   | 0       2/h         0           0  |
   | 0        0        -2/d   -(near+far)/d |
   | 0        0          0           1  |
其中,fovy - height of the view volume in camera coordinates。
h = height (= fovy)
w = aspectRatio * h
d = far - near

公式推导:

设(x, y, z, w)为视点坐标,(x’, y’, z’, w’)为投影坐标,(Px, Py, Pz, Pw)为NDC。
近平面距离为n,远平面距离为f,视口宽为w,高为h。
 x’ = x 
y’ = y
映射到NDC ([-1, 1]),
 Px = 2 * x’/ w = 2 * x / w
 Py = 2 * y’ / h = 2 * y / h
由于z坐标投影后不参与绘图,用于可见性判断,只要保证Pz与z呈线性关系,即Pz=a*z+b
将(-n,-1), (-f, 1) 代入得
 a = -2 / (f - n)
b = -(n + f) / (f - n)
Pz = -2/ (f - n)*z - (n + f) / (f - n)
即等价于
 | x |       | 2/ w   0          0                      0           |
 | y |       |  0    2 / h       0                       0           |
 | z |   *  |  0      0     -2/ (f – n)   -( n + f) / (f - n) |
 | 1 |      |  0       0         0                      1            |

3) Perspective
public void setPerspective(float fovy, float aspectRatio, float near, float far)
 透视投影,即离视点近的物体大,离视点远的物体小,符合人们心理习惯。
M3G Specification中已经给出了对应的矩阵(NDC坐标系):
   | 1/w      0          0           0       |
   | 0       1/h         0            0      |
   | 0        0     -(near+far)/d   -2*near*far/d |
   | 0        0          -1           0      |
其中,fovy - field of view in the vertical direction, in degrees。
h = tan ( fovy/2 )
w = aspectRatio * h
d = far - near

公式推导:

设(x, y, z, w)为视点坐标,(x’, y’, z’, w’)为投影坐标,(Px, Py, Pz, Pw)为NDC。
近平面距离为n,远平面距离为f,近平面宽为W,高为H。
由相识三角形可以得到
x’ = -n * x / z
y’ = -n * y / z
映射到NDC ([-1, 1]),可得
 Px = x’/ (W/2) = -2*n*x / z * W
 Py = y’/ (H/2) = -2*n*y / z * H
由于x’, y’与1/ z有线性关系,只要保证Pz与1/z呈线性关系,即Pz=a/z+b
将(-n,-1), (-f, 1) 代入得
 a = 2*n*f / f - n
b = f + n / f – n
Pz = 2*n*f / (f - n)*z + (f+n) / (f - n)
由于最后会除以w分量,所以可以把共同项写入w分量:
 -zPx = 2*n*x / W
 -zPy = 2*n*y / H
 -zPz = -2*n*f / (f – n) - (f+n) / (f - n) * z
  w = -z
即等价于
 | x |       | 2*n / W   0                 0                      0            |
 | y |       |  0       2*n / H             0                     0            |
 | z |   *  |  0           0        - (f+n) / (f - n)   -2*n*f / (f – n) |
 | 1 |      |  0           0                 -1                     0             |

引入视角fovy,即:
 h = tan ( fovy/2 ) = (H/2) / n = H / 2*n
 w = aspectRatio * h = W / 2*n
d = f - n

=============

不知道有没有下文。。。。

January 26, 2007

关于手机Java游戏模拟器

Filed under: Uncategorized

官方的模拟器就不说了,想研究的朋友可以去sun主页下载KVM源码。

1.开源的Microemulator,好像有些日子没更新了,有Swing/SWT/Applet三种接口,但只实现了MIDP1.0。

   这是基于J2SE模拟器的鼻祖,KEmulator也是这种类型的

   主页:http://sourceforge.net/projects/microemulator/

2.MpowerPlayer,没玩过,不知道怎么样

   主页:http://www.mpowerplayer.com/

   

3.Minisoyo手机模拟器,国内的,界面和mpower挺像的,也是基于J2SE的

   主页:http://www.minisoyo.com/mo.jsp

  

4. Sjboy手机模拟器,也是minisoyo做的,不过原理不同,基于Sun的官方实现,KVM。

  

5.MIDP2exe,台湾人写的MIDP转成exe运行的模拟器,很酷,KVM高手写的。

   主页:http://kwyshell.myweb.hinet.net/

=====

有机会应该去研究研究KVM, 接着可以转行去做手机了,呵呵

KEmulator Manual

Filed under: Uncategorized

今儿填了填模拟器的Manual,http://lyo.blogsome.com/kemulator/manual/

下周开始就怕没时间维护模拟器了。。。。重拾C++,发现忘得差不多啦,呵呵

KEmulator suggestions

Filed under: Uncategorized

Thanks for giving comments to the emulator.

refer to the page http://lyo.blogsome.com/kemulator/

January 24, 2007

MIDP High Level UI beta

Filed under: Uncategorized

为了能玩网游,开始高级UI的实现。。。现在基本完成了。

创新实现:文本框,与系统紧密结合:)


January 23, 2007

TextInput in KEmulator

Filed under: Programming

lcdui.TextField beta!!
support mouse, chinese input ….

January 22, 2007

SetPixelFormat

Filed under: Programming

WGL.SetPixelFormat can be called only once per thread/window.

otherwise, may be failed in some graphics cards.

January 6, 2007

Do not use Thread.yield()

Filed under: Uncategorized

I refactor the EventQueue in KEmulator, then test on some games.

when running MI3 and Gangstar, the CPU reached 100% utilization.

and after testing, i got my answer, cause of Thread.yield() in run() with a while(true) circle.

 

So i made a test, preReplace all the Thread.yield() with Thread.sleep(1) in game loading. this time, everything goes good. the MI3 got a lower 10% CPU utilization in average.

  • sleep() will let your thread do nothing for a certain amount of time. Basically, your thread can’t do anything until it is done sleeping.
  • yield() will cause your thread to voluntarily let other threads in your program run. If no other threads are ready to run, then your thread will continue.

Thread.yield() will help your thread give time to other threads, but when other threads are free or yield()ing will still take up 100% of the CPU. Otherwise, Thread.sleep() is the only way to force the CPU getting a rest.

 

=======================

May be there is a same case in Mobile development.

In some handset, when the game reaches the memory limit, the key events will cause an obviously delay. In Realfootball team last year, i found out that calling more Thread.yield()(two or three) in the run() circle can solve the problem.

Maybe one Thread.sleep(1) did the job here.

╭╮  ╭╮╭╮╭══╮
║║  ║╰╯║║╭╮║
║║  ╰╮╭╯║║║║
║║   ║║ ║║║║
║╰═╮ ║║ ║╰╯║
╰══╯ ╰╯ ╰══╯