Tuesday, December 13, 2011

Model Viewer in WebGL

As HTML5/WebGL was picking up some momentum earlier this year, I started experimenting with it, naively thinking that it would be the new standard for browser gaming. Little by little I added some code to the small project whenever I remembered it. However it has been sitting on the back burner for a few months without any update. Now that Flash 11 has been release, it's finally time to part with this little project, which could be viewed with Firefox (not guaranteed with any other browsers). External Link Here

Usage: AWSD to move the camera and mouse drag to rotate it.

How it is done:
First I found an open source linear-algebra library called glMatrix.js, which serves as the foundation to all math done here. JSON is a no-brainer for the mesh format because Javascript supports it natively. Pretty much everything else is built from scratch, for example shaders.

A few reasons that HTML5 might not be very feasible for gaming:
1. Lacks a comprehensive IDE for development such as Flash Builder, and thus
auto-completion and spelling check(in Javascript spelling something wrong is fatal)
2. Cross-browser compatibility has a huge question mark(it's still called experimental-webgl), with IE falling behind.
3. Performance concerns. Flash is compiled while Javascript is not, and how(if any) the browsers speed up this is totally up to them.
4. Javascript as a language sucks.

Added May/7/2012

Let's see how Epic's Tim Sweeney sees Adobe Flash and HTML5:
So what about the browser? That's something that relates more to something specific that you guys are working on with Unreal Engine. Where do you see the future of the browser in games?

TS: Well, we would like to see the web browser as another platform. You should be able to take any game -- a PlayStation 3 or iOS game, for example -- and just go to that and play it from any web browser.
We're slowly heading in that direction as an industry. One thing that's happened recently is Adobe Flash. For a decade or more, Adobe Flash was a little scripting language for creating more interactive webpages using a proprietary browser plug-in, but more recently Adobe created a translator.
You give it any C++ program, like Unreal Engine 3, and it translates it to a platform-independent application that can run within Flash, within any web browser or on any platform where Flash runs.
And so now any browser that supports Flash can play any web game that's built with Unreal Engine 3, or any other engine that's cross-compatible with Flash. That's an awesome breakthrough; it shows you the possibilities.
But I think the next step in that is cross-compiling games from C++ or whatever and directly running them as native HTML5 and JavaScript applications within any standard web browser. And you can do that in theory today, but it ends up being slow and unstable just because of the early state of JavaScript implementations, and limited performance, and current web browsers.
In another few years, I think that's going to be a very realistic scenario. And so the web will generally be a platform, and you can have a real application with a full feature set that runs within a web browser; that'll be very welcome. The web is a fairly awkward experience when you use a platform that's not the majority of the install base, and I think we're going to see big improvements 

Saturday, March 12, 2011

Handwriting Recognition API

A while ago I was thinking of an iOS project that would utilize handwriting recognition elegantly, and thus better interacts with the user just like Professor Layton series. Then as I looked for robust algorithms that tackle this particular problem I came across this awesome open source library called Zinnia, which not only makes good use of SVM but also provides some ready-to-use training sets including Japanese. Using the library is as straightforward as follows:
recognizer = zinnia.Recognizer()
recognizer.open("C:\Python26\handwriting-ja.model")
character = zinnia.Character()
character.clear()
character.set_width(self.width)
character.set_height(self.height)
counter = 0
for curve in self.curves:
   for x, y in curve:
      character.add(counter, x, y)
   counter+=1
result = recognizer.classify(character, 10)
print unicode(result.value(0), "utf-8")
Where recognizer.open() opens the training module to compare the user mouse strokes against. Then we use set_width(), set_height() to set the canvas size, add() to add the mouse strokes as (x,y) positions. Finally we can pass the character along with the desired number of potential matches to classify(), and print out the most possible UTF-8 string with result.value(0).

Tuesday, February 15, 2011

Break the Language Barrier Series - Chapter Java

Recently I was asked to do some work on JNI for Java programmers to have low-level access
to the underlying systems, such as Win32 API and Cocoa Framework.
Then I ran into some interesting technologies called JNA and JInvoke, both of which claim to provide dll import for Java. However, on the official website of JInvoke they claim to be 10X faster than JNA. According to them, it compares to the performance of JNI, and even native C code's LoadLibrary from Win32 API.
Since I've been so curious about their statement, I decided to run a benchmark on all 3 approaches. To achieve this, we would create a very simple function that takes 5 input parameters and returns a sum of 5 numbers. The reason behind this is that the performance is only measurable from invoking the function and observing its overhead. So now let's take a look at all 3 implementations:

1. JNA
package com.talent;
import com.sun.jna.Library;
import com.sun.jna.Native;
public class MyJNA {
 public static int nLoops = 5000000;
 public interface CLibrary extends Library{
  int fnSpeedtest(int a, int b, int c, int d, int e);
 }
 public static void main(String[] args)
 {
  CLibrary clib = (CLibrary) Native.loadLibrary("C:/jni/Speedtest.dll", CLibrary.class);
  long startTime = System.currentTimeMillis();
  for(int i = 0 ; i < nLoops; i ++)
  {
   int sum = clib.fnSpeedtest(1, 2, 3, 4, 5);
  }
  long timeElapsed = System.currentTimeMillis() - startTime;
  System.out.println(nLoops + " Loops took JNA " + timeElapsed + " milliseconds to complete.");
 }
}
2. JInvoke
package com.talent;
import com.jinvoke.CallingConvention;
import com.jinvoke.JInvoke;
import com.jinvoke.NativeImport;
public class MyJInvoke {
 public static int nLoops = 5000000;
 @NativeImport(library="C:/jni/Speedtest.dll", convention=CallingConvention.CDECL)
 public static native int fnSpeedtest(int a, int b, int c, int d, int e);
 public static void main(String[] args)
 {
  JInvoke.initialize();
  long startTime = System.currentTimeMillis();
  for(int i = 0 ; i < nLoops; i ++)
  {
   int sum = fnSpeedtest(1,2,3,4,5);
  }
  long timeElapsed = System.currentTimeMillis() - startTime;
  System.out.println(nLoops + " Loops took JInvoke " + timeElapsed + " milliseconds to complete.");
 }
}

3. JNI
package com.talent;
import java.io.*;

class SpeedtestJNI{
 public static int nLoops = 5000000;
 static {
  try{
   System.loadLibrary("Speedtest");
                }
                catch(UnsatisfiedLinkError e){       
                 System.out.println(e.getMessage());
                 e.printStackTrace();   
                }
        }
        public static native int fnSpeedtest(int a, int b, int c, int d, int e);
        
        public static void main(String s[]){
         long startTime = System.currentTimeMillis();
         for(int i = 0 ; i < nLoops; i++)
         {
          int sum = fnSpeedtest(1,2,3,4,5);
         }
         long timeElapsed = System.currentTimeMillis() - startTime;
  System.out.println(nLoops + " Loops took JNI " + timeElapsed + " milliseconds to complete.");
        }
}

Finally the chart that compares the 3 of them:

5000000 Loops took JNA 43656 milliseconds to complete.
5000000 Loops took JInvoke 5615 milliseconds to complete.
5000000 Loops took JNI 297 milliseconds to complete.

I don't understand the nature of this performance discrepancy, but it still holds true that JInvoke is about 8 times faster than JNA. Although it's nowhere comparable to JNI, let alone pure C code. Interested readers can get the dll file here.
In the following weeks(hopefully) I will also explore the differences between C++ Interop, PInvoke, and COM Interop, when it comes to .NET calling C libraries.

Thursday, February 3, 2011

Proof of Belief

Here let me quote my own words : "Finally in hindsight, the lessons I learned from them is that the most successful teams would not make things from scratch, given how short the duration is, and should also stick with tried-and-true concepts.".
Time flew by, with Global Game Jam entering its 3rd year. I showed up again at 721 Broadway building as I always had, with same passion and same perseverance. The only difference on me is the added experience from last 2 years, the one of defeat. So I decided to try something that I never before had, which is to be more conservative and less ambitious. This may sound a little pessimistic, but come on~ we only have 48 hours to finish the whole thing.
With that new disposition, I set out to explore the Flixel engine 3 days before the event, and luckily I got all the content creation pipeline pinned down, and by the midnight of the first day I laid out a very simple backbone for my awesome teammates to spend their time with(while I showed up late). On day 2 we not only agreed on using the same technology but also worked with a single goal, that is, put out one game that's playable and tons of fun.
Things were going too well, and by the end of the 2nd day we already had something playable, so basically the final day was all about fixing bugs and adding some finishing touch to the game(music, sound, menu...etc.). During the demo session, however, our presentation was kind of rushy, with only 2 of the maps shown to the audience(plus we didn't have very impressive graphics either!). All of us felt doomed, but not until the staff announced the winners did we realize that we got 3 grand awards.
According to Randall, one of my teammates, even if you think your game is damn good you still have to hear it from the mouths of others, because a game is meant to be played! So while we are preparing for an exhibition at Babycastles and the notification that we won another award in Europe, I cannot help myself but say: "Ned, you really suck the boredom out of my life"

Thursday, January 13, 2011

I'm Not Very "Objective"

Some time ago I was asked to implement a javascript interpreter for iOS,
 so some people could write javascript instead of Objective-C if they are
afraid of learning a new language. Of course we could build from ground
up with a parser generator such as Antlr, which I found to be very fascinating.
However given the deadline of a couple of weeks this is a little too challenging,
 thus I had been googling for a quick solution like crazy. Well, there were
indeed some open source libraries like SpiderMonkey, JSCocoa and JavascriptCore,
which I tried to port to iOS but I wasn't very successful in the end. Just as I was
about to throw in the white towel I came to a site which explained how
one can just expose the hidden JavascriptCore framework from Apple and use
them! The steps one has to take is roughly:
1. Include "dlfcn.h", which defines the dynamic library loading functions.
2. Since the libraries are loaded by default, we can simply use dlsym to get
    a pointer to the function of interest, like below:
    _JSEvaluateScript = dlsym(RTLD_DEFAULT, "JSEvaluateScript");

3. Include JSBase.h, JSContextRef.h, JSObjectRef.h, JSStringRef.h, JSStringRefCF.h, JSValueRef.h in the project.
And here is the video which shows the results from user input, function 1 and function 2: