Monday, August 10, 2009

Project Mod SVN 14

SVN commit log:

  • Moved lighting to eye space to reduce roundoff error.

  • Added PeriodicBroadcastGame and ListenerGame to start testing very simple client/server game state transfer.

  • Fixed some horrible errors in newmath/Matrix{2,3,4}, which weren't really being used before.

  • Added ability to get the inverse() or inverseTranspose() of a Matrix{2,3,4}.

  • Added a ReadByteStream to go with the WriteByteStream.

  • Implemented better bzip2 support in {Read,Write}ByteStream.

  • Added SDL_net to build-system3.

  • Core classes State, Body, Solid, Constraint, and Light are serializeable through toBytes() and fromBytes().

  • TODO: implement toBytes() and fromBytes() in Controller.



The window on the left is sending a game state packet over UDP to the window on the right, which is displaying it from a fixed viewpoint. :3

Wednesday, August 5, 2009

Deferred shadow maps

After a bit of time off I made the deferred shader not be a hack and added colored, shadow mapped lighting. Code will be in SVN 11, maybe tomorrow evening.

In this screenshot, the car thingy has three colored spot lights attached to its front:


Edit: SVN 11 committed.

Saturday, July 25, 2009

Project Mod SVN 10

Tonight I added an HDR deferred shading system:

  • A simple shader writes surface color, normal, and world position to a trio of RGBA16F screen-sized textures.

  • The blend target (a fourth RGBA16F screen-sized texture) is cleared.

  • For each light in the scene one of the light shaders uses the three deferred textures to compute the light's contribution to each pixel, which is added to the blend target.

  • The tone mapping shader exposes and gamma corrects each blended pixel and writes them to the back buffer


I'm cheating right now by hard coding a point light and a spot light into the renderer code, but it should be easy enough to generalize. The code is a bit ugly, but it's all confined to the renderer class.







Up next: shadow mapping.

Friday, July 24, 2009

Project Mod SVN 9

Here's the evening's update. I implemented controllers, which basically have a step function and can manipulate things. Player is a subclass of controller with two additional functions: getViewPos and getViewQuat. The game client uses these to control the camera. To test the framework I wrote a CarPlayer class that manages a few rigid bodies and constraints to make a simple front wheel drive car with steering.



Next up:

  • Lighting - I implemented a hacky shadow mapping system after SVN 7 which looked really nice, but I set it aside because the code was so ugly. I'll need to think of a way to keep the GL state management code out of the SinglePlayerGame class, and maybe split some of the texture/model management from the GUI class into some kind of video state manager.

  • Screenshot / video capture - For the spamming of YouTube, and because this build looks much cooler in motion.

  • More test textures and models - This will not be one of those cool but ugly open source projects.

Thursday, July 23, 2009

Project Mod SVN 8

This car thingy consists of five rigid bodies, five collision objects, and four hinge constraints. Keyboard input applies locally-aligned torque to each wheel. Up next: controller objects. These will be non-physical, but will be allowed to interact with bodies, solids, and constraints. The player object will be a special controller subclass with access to input devices and ability to control the viewpoint.

Tuesday, July 21, 2009

Project Mod work

I've been working on Project Mod, my grand vision for an open-source-powered multiplayer physics sandbox game. As usual, I've thrown out a good chunk of the old code and have started (mostly) anew. This time my first focus has been a usable GUI layer for configuration and game selection. I just committed SVN revision 5, and this is what it looks like:


Main menu with some buttons


Video settings menu with buttons, a drop list, and a checkbox

At the moment the "game" is just a white rotating quad, but the core code incorporates ODE and should give me tumbling boxes soon enough.

For anyone interested (all zero of you subscribers from the internets):
Google Code project page
SVN repository

Building on Linux is easy: go to the /mod3client folder and make run, or make all && build/linux/mod3client if you really like typing. Building on Windows works, but isn't as automated. I've made it work with Visual C++ 2008 Express, after setting up all the requisite libraries, by dumping the source into a Win32 Console Application and changing a few project settings.

Up next: importing my old model loader, and upgrading the game to involve something exciting like box sliding.

Thursday, April 16, 2009

GPU Global Illumination

By this point it must be clear that my hobby programming has a very short attention span.


A purplish glow is cast on the wall. The ceiling is softly illuminated by reflections from the floor.


Some color bleeding is visible on the wall and floor. The spheres display the captured incident light at each probe point.


Wide view with indirect lighting disabled.


Wide view with indirect lighting enabled.

This demo divides the space in a small room into a voxel grid. Light probes (16x16 cube maps) are captured at the center points of each voxel, arranged as tiles on a huge 96x4096 RGB16F texture. This texture is then modulated by the first nine real spherical harmonic basis functions and rendered to a set of nine more 96x4096 RGB16F textures, three per pass. These nine huge float textures are reduced and rearranged in a number of passes to a set of nine 8x8x4 RGB16F volume textures representing the (rather low-resolution) incident light at every point in the room as a set of real spherical harmonic coefficients. The final pass is rendered using these volume textures to provide one bounce of interpolated indirect light in addition to the direct light cast by the static and camera-mounted spot lights.

Whew.

To summarize, this demo renders a scene with one bounce of indirect light, based on real spherical harmonic coefficients interpolated from a regular grid of 256 light probes.

The sample scene runs at about 15 FPS on my aging desktop with an NVIDIA GeForce 7800 GT.

Now to optimize the slow out of it.

Saturday, March 14, 2009

C++ pointer-to-member-function events

I made an Event class that can be hooked with a member function from any class. I ended up using a combination of virtual functions, templates, and nested classes, and I was just pleased enough with the result to blag about it for a while.

Static example

class Foo {
private:
  Event _wasFrobbed;
  
public:
  Foo() { }
  Event::PublicEvent& wasFrobbed() { return _wasFrobbed.pub(); }
  void Frob() { _wasFrobbed.Fire(); }
};

void CharlesWasFrobbed() {
  cout << "Charles was frobbed\n";
}

void Test1() {
  Foo charles;
  
  //Hooking his event
  charles.wasFrobbed().Hook(&CharlesWasFrobbed);
  
  //Frobbing him
  charles.Frob();
  
  //Unhooking his event
  charles.wasFrobbed().Unhook(&CharlesWasFrobbed);
}

That's easy enough to use, but not so impressive on its own. The fun part is that it works with pointers to member functions as well!

Pointer-to-member-function example

class Bar {
private:
  Foo* _pfoo;
  
public:
  void NoticeFrob() {
    cout << "a Bar was witness to a frobbing\n";
  }
  
  Bar(Foo* pfoo) : _pfoo(pfoo) {
    //Hook the target Foo's event
    _pfoo->wasFrobbed().Hook(this, &Bar::NoticeFrob);
  }
  
  ~Bar() {
    //Unhook the target Foo's event
    _pfoo->wasFrobbed().Unhook(this, &Bar::NoticeFrob);
  }
};

void Test2() {
  Foo winston;
  Bar nigel(&winston);
  
  //Frobbing Winston ... Nigel will notice
  winston.Frob();
}

Next step: add a template parameter to the Event class itself so the event can fire with an argument.

Sunday, February 1, 2009

Networking model

I've been reading up on how Valve's Source engine handles network play, and I've come up with an outline for how I want this to work in Project Mod.

The key feature is a deliberate addition of input latency, sacrificing some snappiness for a smoother appearance on the client. Clients sample the local player's controls and send them to the server at the world's step rate (200 Hz at the moment, one step per 5 ms), but tagged for a future step. Source defaults to 100 ms. The server operates in the future, collecting controls packets, simulating the world, and sending periodic bunched updates to all clients.

When network latency is less than (input latency - update interval) and no packets are dropped, every client will already have the current world state stored in a buffer when it's time to refresh the screen. This means no prediction, no extrapolation, and zero jittering for ping up to 80 ms, at the cost of a consistent input latency of 100 ms. This delay could of course be adjusted for connections with higher or lower average latency, or even disabled for a local single player game.

I'll post more as I attempt to implement it.

Saturday, January 17, 2009

Saturday, January 10, 2009

Network testing

I got my UDP networking code functional on a "brute force and who cares if we clog the intertubes" level. It sends 200 full game state updates per second, and the clients spit out controls packets (containing, of all bandwidth wasting things, ASCII strings) as quickly as they can generate them. So I went to #wiidev and got a helper on board to fire up the Wii client from an external network:


Each of those crates is under the control of one client. One is a Linux client running on the same machine as the game server. One is a Wii client on the same LAN as the game server, and one is a Wii client about 90 ms away over the internet. The screenshot was captured by the Linux client.

Friday, January 9, 2009

Filesystem layer and menus

I implemented most of a filesystem layer. It gives me uniform access to a media tree on Linux/Windows local filesystem, Wii front SD card slot, Wii USB flash drive, Wii/GameCube memory card files, and the media server I'll keep running. To configure this thing I wrote a simple menu module that pops up on startup to let you pick an FS module and, on some modules, browse for a root directory.



I'm thinking a list of default locations (~/.mod2, sd:/apps/mod2, %whatever-is-the-shortcut-for-application-data%\mvanbem\mod2, etc.) combined with a simple .txt config file would make this screen usually skippable.

I'm hard at work getting some netcode and a useful Player object going. At the moment I can connect to the game server and show unpredicted snapshots on the client's screen. No interactivity yet.

Monday, January 5, 2009

YouTube poop: The Birth of Weegee

Yesterday I was inspired with a vision, so I fired up my XP VM and spent all day fighting with Windows Movie Maker. I also used a healthy dose of the GIMP, but that went much more smoothly. This is what happened:



Here's its page on YouTube. Rate me!

Thursday, January 1, 2009

More configure tricks

I previously set up all of the libs needed to compile Project Mod on my Windows XP VirtualBox instance, but it takes forever to compile, so I'm trying once again to set up cross compiling from Linux. It turns out that lots of libs will compile just fine if you pass in a few flags when you configure them:

./configure --host=i586-mingw32msvc --prefix=/usr/i586-mingw32msvc

Of course, more will go wrong, so you have to be willing to dive into the configure script and search for override flags. Some are easier, like how SDL_net requires --disable-sdltest. Without that flag the configure script will try to run a test program, which will fail since it's not producing Linux executables. Others are a bit trickier:

ac_cv_lib_png_png_create_read_struct=yes ./configure --host=i586-mingw32msvc --prefix=/usr/i586-mingw32msvc --disable-sdltest

SDL_image needs libpng for PNG image support, but it compiles a test program to check if libpng works. I know that libpng is fine (I just compiled it), so I made it skip the check by defining_that_long_environment_variable. This command makes the configure script spit out:

checking png.h usability... yes
checking png.h presence... yes
checking for png.h... yes
checking for png_create_read_struct in -lpng... (cached) yes

Without the environment variable that last line fails and PNG support is left out.