Thursday, September 30, 2010

How-To Embed RSS Feeds

If you ever feel the need to embed an RSS feed in a webpage (like my BitBucket feed on the right), maybe this Javascript snippet will be helpful (just remember to replace the bits marked in red). It uses the Google AJAX Feed API, which is pretty nifty!

<script src="http://www.google.com/jsapi/?key=GOOGLE AJAX API KEY" type="text/javascript"></script>

<div id="feedControl"></div>

<script type="text/javascript">
  function loadFeedControl() {
    var feed = new google.feeds.Feed("FEED URL");
    feed.setNumEntries(16);
    feed.includeHistoricalEntries();
    feed.load(function(result) {
      if (result.error) {
          return;
      }

      var container = document.getElementById("feedControl");
      if (!container) {
          return;
      }

      for (var i = 0; i < result.feed.entries.length; i++) {
        var p = document.createElement("p");
        p.innerHTML = result.feed.entries[i].content;
        container.appendChild(p);
      }
    });
  }

  google.load("feeds", "1");
  google.setOnLoadCallback(loadFeedControl);
</script>

Friday, September 24, 2010

Reconstructing View Space Position from Depth in OpenGL ES 2.0

There is a lot of information scattered around the Internet on this (some of which seems wrong). Here is some rough code for my solution to the problem. I only just got this working, so I hope it is correct... you have been warned!

First, I will describe the inputs:

  • winPos - Pixel position (from gl_FragCoord.xy).
  • winSize - Size of window in pixels.
  • depthSample - Raw depth value from the depth texture (should be in the range of [0, 1]).
  • nearFar - Distances of the near and far planes.
  • u_top, u_right - Top and right limits of the near plane.

For u_top and u_right, I derive it from my vertical field of view angle and aspect ratio (width / height) like so (C++):
    m_top = m_near * Math::tan(0.5f * m_verticalFov);
    m_right = m_top * m_display->aspectRatio();
Given all that, here is the GLSL function that will return the view space position for the given pixel position:
vec3 viewSpacePos(vec2 winPos, vec2 winSize, vec4 depthSample, vec2 nearFar)
{
    vec3 position;

    float depth = depthSample.x;
    position.z = -nearFar.x / (nearFar.y - (depth * (nearFar.y - nearFar.x))) * nearFar.y;

    position.x = (((winPos.x / winSize.x) * 2.0) - 1.0) * u_right;
    position.y = (((winPos.y / winSize.y) * 2.0) - 1.0) * u_top;

    float scale = -position.z / nearFar.x;
    position.x *= scale;
    position.y *= scale;

    return position;
}
Hope this helps someone out there! It might be best you try derive it yourself too, so you can debug it (if you ever need to)... :)

UPDATE: Made small correction to how scale was calculated. Oops!

Sunday, August 29, 2010

Deferred Rendering Done!



Just a quick update - finally finished the deferred rendering system for Battle Balloons! Guerilla Games has a good presentation for Killzone 2 on the theory behind it - but mine is not as advanced. Not much to show as it's pretty much all under-the-hood at the moment. But this excites me because I no longer need to worry about how to limit the number of lights in the game - they can now be practically unlimited. I went with a fairly simple approach:
  1. the scene normals are rendered in RGB as-is (if it's good enough precision for Insomniac Games' Resistance 2, then it's good enough for me!),
  2. pixel world position is derived from the 2D screen co-ordinates and depth buffer value, and
  3. lighting happens in two stages: a spherical mesh is first rendered for each light onto the stencil buffer and the light shading is then calculated for each pixel not masked out by the stencil.
In the process of doing so I also removed all legacy, fixed-functionality OpenGL code. Everything is now pretty-much OpenGL ES v2.0 compliant. Now with this out of the way, it is on to adding networking support; the last, major, technical hurdle for this project! :)