Today’s Chrome web browser update means you can develop, sell, download and play 3D games written in C++ right from the Chrome Web Store, without plug-in.

This is a quick walk-through on how to develop a basic 3D Native Client app. You can try out my test app from the Chrome Web Store here.

Alternatively you can visit http://bulletphysics.org/nacl but in that case you need to enable Native Client by typing about://flags in the Chrome address bar. Chrome Web Store Native Client apps don’t require flags.

Either way, make sure your Chrome About Box shows version 15 or later.

Some features of the simple test app:

  • OpenGL ES2 3D rendering with textures
  • Mouse interaction
  • Load binary files using a file chooser
  • Use of middleware: Bullet Physics, libjpeg

Download the SDK

You can download the Native Client SDK and all tutorial and build system files in a single self-contained zip file here (64 MB). It should work out-of-the-box under Windows. This tutorial also builds under Linux or Mac OSX but that is left as an exercise for the reader (or leave a comment for help).

Setup your build system

Just unzip the zip file (64 MB) in a folder without spaces in the name and you are all set to go under Windows.

The Native Client SDK comes with a gcc-based compiler toolchain. You need to tell your build system the location of the C compiler (CC), C++ compiler (CXX) and linker (AR). Above zip file includes make.exe and Makefiles that work under Windows out-of-the-box. There is no need to install Cygwin or MinGW. I used premake to generate the Makefiles.

Add some salt and pepper

An API called Pepper is used to provide hooks between Native Client and web browser services such as HTML5 and 3D. This test application was a port from a simple Win32 application. I used the Tumbler NaCl example as a starting point. The original version is located in build\nacl\nacl_sdk\pepper_15\examples\tumbler. In order to ‘port’ it to Native Client in a web page, the following changes were made. Most of the source code is shared and portable, to make debugging easier.

  • Program entry point: The Windows application used WinMain as a program entry point. For Native Client the entry point is the constructor of your module.
  • All of the OpenGL ES initialization of matrices, shaders, textures, vertex and index buffers are the same, except for creating the context.
  • Keyboard and mouse input. Instead of a Windows event you register for keyboard and/or mouse events and implement the event callback.
  • Loading files from the local file system is not possible for obvious security reasons, so there is no ‘fopen’ command. You can let the user pick a file using the browsers build-in File Chooser, load the file in memory and use Javascript to pass the file to the Native Client module. Binary files can be base64 encoded by the browser, and decoded by your Native Client code. This works well in practice. In the future you can call the File Chooser directly from NaCl C++ code.

Build the executable

Click on build/nacl.bat and wait. Here is the content of the batch file:

set NACL_TARGET_PLATFORM=pepper_15
 
  set NACL_SDK_ROOT=%CD%/nacl/nacl_sdk
 
   
 
  premake4 --with-nacl gmake
 
  cd nacl
 
   
 
  set AR=%NACL_SDK_ROOT%\%NACL_TARGET_PLATFORM%\toolchain\win_x86_newlib\bin\x86_64-nacl-ar.exe
 
  set CC=%NACL_SDK_ROOT%\%NACL_TARGET_PLATFORM%\toolchain\win_x86_newlib\bin\x86_64-nacl-gcc.exe
 
  set CXX=%NACL_SDK_ROOT%\%NACL_TARGET_PLATFORM%\toolchain\win_x86_newlib\bin\x86_64-nacl-g++.exe
 
   
 
  set config=release32
 
  make
 
   
 
  set config=release64
 
  make

This builds two Native Client executables, 32bit x86 and 64bit x64, they are located in build\nacl\nginx-1.1.2\html\NativeClientTumbler.exe and build\nacl\nginx-1.1.2\html\NativeClientTumbler_64.exe
The web page know how to load this module using a manifest file called tumbler.nmf :

{
 
    "program": {
 
      "x86-64": {"url": "NativeClientTumbler_x64.exe"},
 
      "x86-32": {"url": "NativeClientTumbler.exe"}
 
    }
 
  }

The index.html web page can load the Native Client code using this tumbler.nmf file. Check out tumbler.js for details.

Test the application

Click on build/nacl_runtest.bat and confirm that the nginx web browser is allowed to wait for connections.

Native Client applications hosted in the Chrome Web Store should run without special flags or settings. In order to run NaCl modules in web pages outside of the Store you need to enable Native Client manually. Just type about://flags in the Chrome address bar and enable the Native Client setting.

Now open Chrome and type http://localhost/index.html and if all goes well you can play your app.

Debug the application

You can use ‘printf’ debugging using the Javascript console, but in most cases it is easier to maintain a Windows version and perform debugging under Visual Studio. You can compile the tutorial under Visual Studio by clicking on the build/vs2008.bat file and open the GLES2_BulletBlendReader_Angle project. This project emulates OpenGL ES2 under Windows using a DirectX wrapper called Angle.

Deploy to the Chrome Web Store

You can make your C++ Native Client module available for free or for sale in the Chrome Web Store. A one-time registration fee of just 5$ is used, probably to stop spam. You have to create a manifold.json that provides the information about your application. This includes the name, description and where the web page and assets are located. Here is the manifest used for this tutorial:

{
 
      "name": "Bullet Physics NaCl Test",
 
      "version": "0.8",
 
      "description": "This Native Client module runs a C++ Bullet Physics simulation.",
 
      "app": {
 
  	    "launch": {
 
  	       "local_path": "index.html"
 
  	    }
 
  	  },
 
  	  "icons": {
 
  	  "16": "bullet_icon16.png",
 
        "128": "bullet_icon128.png"
 
      }
 
  }

Notes

Most of the Google NaCl SDK relies on having Python installed, and I wanted this tutorial to work without external dependencies such as Python, Cygwin or MinGW etc. I used the following replacements:

  • Python was used for the scons build system. I replaced scons by Makefiles, because I think Makefiles are more standard and simpler to adapt to other build systems. I used premake4 to generate the Makefiles to keep it self-contained.
  • Python was also used to download and update the Native Client SDK. To avoid this, the zip file already contains the Native Client SDK and the build system knows its location. If you have Python installed you can still run this updater, it is located under build\nacl\nacl_sdk\update_naclsdk.bat in the zip file.
  • Finally, Python was used for the web server. I replaced this with the tiny but powerful nginx web server.

I recommend checking out the links below if you are interested to learn more.

Enjoy!

Useful Links

http://gonacl.com (it has some links to other middleware that support Native Client such as FMOD, Ogre and Unity)

http://code.google.com/chrome/nativeclient

https://groups.google.com/group/native-client-discuss

http://code.google.com/chrome/webstore/articles/apps_vs_extensions.html