I've added image support to the HTTP server this Saturday. Turns out no Base64 encoding is necessary (don't know why I assumed this), it's perfectly fine to just send the raw image data over the line. I wrote a StreamTextureSaver class which can save the content of a texture into a stream in a couple of formats (JPG, BMP, PNG and DDS). It's platform-specific and just uses the D3DXSaveTextureToFileInMemory() function on Win32 and Xbox360, so the Nebula3 code is really small. To send a texture to a web browser, the following steps are necessary
- lookup the texture object in the SharedResourceServer
- create a StreamTextureSaver and attach it to the texture object and the output stream (which represents the body of the HTTP response)
- call Save() on the texture, this will save the image data to the output stream
- set the matching MediaType on the content stream (i.e. "image/png")
- that's it, the HttpResponseWriter will wrap everything into a valid HTTP response message and send it off to the web browser; everything is in-memory, no disk i/o is involved
There's a special method SaveScreenshot() in the RenderDevice, which basically does the same thing, but uses the backbuffer as the image source. This special case is necessary, because the backbuffer cannot be exposed as a texture (well it could, but this would add unnecessary overhead).
To capture a screenshot from the currently running Nebula3 application into the browser, simply navigate to
http://127.0.0.1:2100/display/screenshot
This produces a PNG screenshot. To get the screenshot as JPEG:
http://127.0.0.1:2100/display/screenshot?fmt=jpg
To retrieve the content of a shared texture resource (including render targets):
http://127.0.0.1:2100/texture?img=[resId]
For instance to get the content of the example Tiger's texture:
http://127.0.0.1:2100/texture?img=textures:examples/tiger.dds
This will only return currently loaded texture resources. If the texture is not currently loaded, a "404 Not Found" will be returned.
The HttpServer is going to become an extremely useful debugging tool. One can easily navigate through an application's runtime data on a much higher level then a source-level debugger allows, since the data can be presented in an application-specific way. It's the perfect complement to source-level debugging and other specialized debugging and profiling tools like PerfHUD or PIX. And since it's HTTP everything also works over the network by design. This is especially useful for console development, where it's often not possible or desirable to add a complex in-game user interface just for debugging and visualization purposes.
Beyond debug visualizations the whole HTTP communication stuff is really inspiring. Imagine what would be possible with XUL (Mozilla's user interface XML dialect).
Some Bioshock-in-progress notes: I'm about 8 hours into the 360-version. As expected the game is pretty damn near perfect (I have only 1 small gripe: the human character models... compared to the graphics quality of the environment and the Big Daddies and Rosies they really look quite ugly). But overall: a masterpiece! Definitive must-play for everybody who loves computer games. The immersion and mood can't be described with words. It's obvious that the developer dodged any face-to-face dialogs (and right so). Yesterday I almost expected to actually meet a sane person face-to-face... but nope, it's all tapes and monitors, I was a little bit disappointed at first... but honestly, it wouldn't have looked very good (quality-wise) if they had chosen to talk directly to other characters. And handling the story in such an "impersonal" way actually adds a lot to the loneliness and depressive mood of the game. The German localization is *excellent*. Usually I'm playing the original version, but Bioshock's voice-over localization is extremely well done. "Movie-quality-well-done".