Thursday, November 30, 2006

mIrrlicht has its own homepage.

Since google now offers up to five personal webpages for Google Page Creator, I applied a new one for the mobile porting of irrlicht project. In the developer section, you might find some useful information for building the project.

Friday, November 24, 2006

Puyo puyo mobile edition 0.1 released!

This mobile edition is developed with NetBeans 5.5. It runs on J2ME platform and has been tested on my Siemens CX65. Download the zipped executables and source code on the project page. The latest source code shares the same subversion depot with the J2SE version.

Monday, November 20, 2006

New screenshot of irrlicht symbian port

Time to release a new screenshot and a video clip. Now the scene becomes more interesting. It's a Quake3 map with two animated faeries. This roughly corresponds the Collision example included in the irrlicht engine. In addition, the user can navigate in the small castle scene.

The video clip you can download here.

(Note: currently in the mirrlicht subversion depot on google code, I use a different animated figure, a monkey. The reason is: under the default setting of the emulator, the RAM is 32M. After loading the quake3 map, the faerie model can't be loaded due to memory constraint. If you want to load the faerie model, you have to adjust the emulator's setting. I've tested 48M. It works fine.)

Tuesday, November 14, 2006

Porting irrlicht to Symbian platform.

Recently, I'm trying to port a popular open-source graphics engine irrlicht onto mobile platforms. The first target is nokia's S60. Some preliminary results have been achieved. Have a look! (Screen shot, Video clip).

Latest source code can be download here with a subversion client tool. The trunk contains the ported code and synced with revision 301(13.11.2006) of the sourceforge svn depot of irrlicht. A sync branch under "branches" serves as a bridge for merging with the irrlicht depot. In the directory "source/irrlicht", there are two symbian projects generated by CarbideVS. The first one is mirrlicht(the directory name is Symbian), which contains irrlicht compiled as a dll and a helloworld example exe. It currently doesn't work (simply crashes the emulator) since I haven't figured out how to use dlls on Symbian platform. The second one is symbirrlicht. It's compiled as a monolithic exe consisting of the ported irrlicht source code and the hello world sample code. The screenshot and videos are generated by this project.

Since no STL is used in irrlicht and the software structure also lends itself to easy extending, the porting goes rather smoothly. I've spent only several days before getting the first results (including fighting with Symbian dev platform coz I'm a newbie of it) .

The following outlines some important points for the porting.


This is key component for the porting to work. Because OpenGL ES 1.1 doesn't support glBegin/glEnd, glVertex commands, I have to replace some 2D rendering code with glDrawElements. Some other unsupported features like glPushAttrib/glPopAttrib, Texcoord generation needs workarounds or completely disable.


Reversed color formt like A1R5B5G5 is not supported by OpenGL ES, so we have to convert the image data to normal order.

3.In image and 3D model loading code, the compiler directives for byte alignment needs to be adapted for Symbian. (All of them actually are the same, maybe later this could be refactored to a common place to facilitate porting to other systems.)

4.Add a new irrDevice -- irrDeviceSymbian.
The cursorcontrol and event handling has been completely disabled.

Saturday, November 04, 2006

Puyo puyo - A puzzle game written in java

Just published a puzzle game called "Puyo Puyo". The project is hosted using google's project hosting service and written in java. The license is LGPL.Currently it has a simple project homepage at

If you have NetBeans 5.5 installed, you can check out all the files under /trunk/puyo and directly open it using the IDE. Of course if you are familiar with Java SDK, it should be easy to only check out the essential source code and compile and run it using the command line tools provided by the SDK.

The look and feel is rather primitive at the moment. But it could be improved over time. If you have interest, you can also drop me a line and we can do it together.

The first release (version 0.1) can be downloaded here. If you already have java run time environment installed on your machine, simply double click the jar file starts the game.

Have fun with it!

Wednesday, November 01, 2006

Raytraced balls with refraction using FX Composer

I've tweaked a little bit the raytrace.fxproj shipped with FX Composer 1.8 from NVidia. Originally the raytracer support only reflection. I tried to show refraction (Figure 1) instead of reflection (Figure 2).

Figure 1. Raytraced balls with refraction

Figure 2. Raytraced balls with reflection

The following gives some details about the tweak.

First of all, we need to specify a transmittance coefficient to describe how much light can be refracted. We give a name Kt.

struct Sphere {
float3 centre;
float rad2; // radius^2
float4 color;
float Kd, Ks, Kr, Kt;
~~~ //this variable is added

Then we need a function to compute the direction of refracted ray given the incoming ray and a refraction index. You can find the function and explanation in the Cg Tutorial book sample chaper. The formula behind it can be also found on the Snell's law on wikipedia.

float3 refract(float3 i, float3 n, float eta)
float cosi = dot(-i, n);
float cost2 = 1.0 - eta * eta * (1.0 - cosi*cosi);
float3 t = eta*i + ((eta*cosi - sqrt(abs(cost2))) * n);
return t * float3(cost2 > 0.0, cost2>0.0, cost2 > 0.0);

Finally, in the RayTracePS function, we comment out the reflection part and add a similar part for refraction:

// shoot reflection ray
float3 r = reflect(eyeray.d, n);
Ray reflray;
reflray.o = i;
reflray.d = r;
float3 ri = NearestHit(reflray, hitobj2, hit);
if (hit) {
n = SphereNormal(object[hitobj2], ri);
c += Shade(ri, n, reflray.d, hitobj2) * object[hitobj].Kr;
} else {
c += backgroundColor;

// shoot refraction ray
float3 t = refract(eyeray.d, n, 0.9);
Ray refrray;
refrray.o = i;
refrray.d = t;
float3 ti = NearestHitExcludeObj(refrray, hitobj, hitobj2, hit);
if (hit) {
n = SphereNormal(object[hitobj2], ti);
c += Shade(ti, n, refrray.d, hitobj2) * object[hitobj].Kt;
} else {
c += backgroundColor;

Note that everything is similar except the routine for computing the nearest hit point for the refracted ray:
NearestHitExcludeObj(refrray, hitobj, hitobj2, hit).

This function computes a hit obj (hitobj2) but excluding the current hit obj (hitobj). This is because the refracted ray starts from the current hit obj. If we don't exclude it, the function will return "no hit" result since the ray intersects the current obj at the very origin point of the ray and the parameter t of the ray is then 0 and below the error threshold.

// find nearest hit returns intersection point. The excludeobj will be excluded.

float3 NearestHitExcludeObj(Ray ray, int excludeobj,
out int hitobj, out bool anyhit)
float mint = 1e10;
hitobj = -1;
anyhit = false;
for(int i=0; i < NOBJECTS; i++) {
bool hit;
float t = SphereIntersect(object[i], ray, hit);
if (hit && i!=excludeobj) {
if (t < mint) {
hitobj = i;
mint = t;
anyhit = true;
return ray.o + ray.d*mint;