My Oculus DK2 arrived!

I heard about a week ago that folks were starting to get their Oculus (Dev Kit 2) DK2’s. The big changes are the improivement of the display to be more VR friendly  – the low-persistence OLED display in the DK2 are improvements to “eliminate motion blur and judder” – and they go a long way to that end.  You now have a camera to track the HMD (and your head) in six dimensions (pitch, yaw, and roll , and XYZ positioning) along with the accelerometers in the HMD. And they finally put headphones on the HMD! Overall when I got to try them at GDC they were instantly immerse and provided a completely believable VR experience with no disorientation (I was sitting) and it was very intuitive to control and look around.

Here’s what my DK2 looks like.

OculusDK2

PROS: Ergonomics of the headset are about the same (fit and heft), but the single cable from the headset, a nicer sleeker HMD enclosure,  960×1090/eye with lower persistence and the better head tracking are definite improvements for the VR experience. Headphones on the HDM for 3D positional sound as well. The new headset has a (optionally powered) USB port for adding accessories, a plethora of various style AC power connectors (a nice touch) and a new SDK. Oh yeah – and it’s $350.

CONS:  None of the old DK1 demos will runs without a recompilation – so it’s harder to find content. The new SDK is required. Still not the consumer model, but is a significant step in the right direction. The plastic carrying case of the DK1 is now a cardboard one 🙁 .

I’m thrilled start working with the new DK2 and I’m really looking forward to posting some of the results here. I’m a firm believer in the benefits of what VR/AR can become.

Posted in Augmented Reality | Leave a comment

OpenGL 4.5 Specs Released at Siggraph

The Khronos group publicly released the OpenGL 4.5 specification at Siggraph this week. The two biggest changes are OpenGL ES 3.1 compatibility (including ES shaders) and DX11 feature emulation. The first will make it easier to write OpenGL or OpenGL-ES  apps for any platform on a desktop. The second will make it easier to port DX11.2 apps to OpenGL. The main list of new features is;

  • Direct State Access (DSA) – object accessors enable state to be queried and modified without binding objects to contexts, for increased application and middleware efficiency and flexibility;
  • Flush Control – applications can control flushing of pending commands before context switching – enabling high-performance multithreaded applications;
  • Robustness – providing a secure platform for applications such as WebGL browsers, including preventing a GPU reset affecting any other running applications;
  • OpenGL ES 3.1 API and shader compatibility – to enable the easy development and execution of the latest OpenGL ES applications on desktop systems;
  • DX11 emulation features – for easier porting of applications between OpenGL and Direct3D.

Most of the changes deal with API alignment, corralling the proliferation of OpenGL, OpenGL-ES and WebGL syntactic differences and making WebGL a bit more secure – a requirement from browsers for a while now. This will allow OpenGL devices to run GL-ES, and with WebGL it will remove some obstacles that have prevented WebGL from being adopted widely. OpenGL-ES will again be an API aligned subset of OpenGL.

The DX11 emulation will allow easier porting by reproducing some of DX11.2’s implementation details into the OpenGL API – reducing the need to an extensive rewrite by providing simulation of some of DX11’s quirks/API features.

You can read all about the news here.

Posted in Conferences, OpenGL | Leave a comment

20% of Android devices are OpenGL-ES 3.0 capable

OpenGL-ES 3.0 adoption is continuing at a high pace. We’re still on track for 1/3rd of all Android devices to be OpenGL-ES 3.0 capable by years end, and we haven’t even seen the newest hardware due out in a few months, AND Google has announced the Android Extension Pack for OpenGL-ES 3.1 support for release with the next Android version!

GLES3Proliferation8-14

Posted in Android, Hardware, OpenGL | Leave a comment

Procedurally Distributing Game Objects

I was discussing procedural content with someone last week and I was reminded of some research into space filling distributions and their use in games. One interesting procedure that I’ve run across is called the Halton Sequence, and it has some interesting properties.  It’s space filling, deterministic, and pseudo-random. As such, it’s not only great for distributing things seemingly at random over a surface, but the objects will never overlap and can be made to cluster. You can  read a nice description of how it was used in the game Spore from Maxis’ 2007 Game Developer Conference presentation.

It’s not a terribly efficient sequence generation algorithm if you’re generating them on the fly, but if you know you’ll need a block of them it’s much more efficient to generate a table at a time. This is because the distribution function requires the previously generated value to calculate the next – similar to a Fibonacci sequence. You can create multiple distributions because one of the input parameters is a prime number, thus it’s easy to generate 2D, 3D, etc. sequences just by providing different primes for each dimension you need.

It’s better if we look at it in action. Let’s look at a random distribution of 256 points via rand(). The first quarter generated are red, the second are blue, the third green, the fourth white.

RandomDistribution

You get the random scattering you’d expect, with some too near or even intersecting each other.

Now let’s use a Halton Sequence with a prime of 2 for the horizontal distribution and 3 for the vertical with the same colorization scheme.

HaltonDistribution

See how much more evenly distributed the colors are? And how “later” colors are clustered around earlier one? You can use this to distribute “types” evenly and cluster objects around them – for example trees in the first pass, then – continuing with the same Halton Sequence – tall bushes, then following that, still using the same sequence – shorter shrubs, then grasses. The Halton sequence will prevent them from overlapping but they will fill in space around already placed objects.

It’s not quite that easy in practice, but it gets you 95% of the way there, and with some filtering techniques and some care about the primes you use (some start off too well ordered – see the Wikipedia article) you can put the generation tools in the hands of your artists and generate tons of seeming naturally ordered, yet randomized procedurally grouped content. YMMV – will require some tweaking to get that last 5%.

And it’s not just geometric objects you can place, but NPCs (or clusters of NPCs), loot, terrain features —  you can even use it to procedurally generate features in texture maps (like spots on a leopard, etc. ). I love procedurally generated content, and this is one of the tools I use to get great looking environments.

OK – what does the code look like – here’s a very simple and unoptimized version – you start off with some seed index value (zero works initially) along with a prime number as the base, then you increment the index value  with that same prime to generate the next number in the sequence.

.
// A simple Halton Sequence generation routine
// indx is the starting value for the sequence (0 or 1 is always good)
// and base is a prime number. 
// Increment indx value for the next value in the sequence.
float halton(int indx, int base)
{
    float b = (float)base;
    float i = (float)indx;
    float h = 0.0f, digit = 0.0f, f = 1.0f/b;

    while (i>0)
        {
        digit = (int)i % base;
        h += digit * f;
        i  = (i-digit) / b;
        f /= b;
        } 

    return(h);
}
.

It’s not efficient to generating each number one at a time, but it works. A better way is to have it generate an array sequentially using results to continue to the next value in the sequence  – this is a much more efficient calculation. Then you can generate batches of numbers with much less overhead (or have some state residing the the sequence generator).

Posted in Code, Graphics | Leave a comment

OpenGL-ES 3.1 Support & Extensions are to be supported in next Android “L” release.

At Google IO, Google announced that OpenGL ES 3.1 and the Android Extension Pack  going to be are released in the upcoming Android L release. OpenGL ES 3.1 brings cleaner shader support and compute shaders, while the Android Extension Pack is a set of extensions to OpenGL ES which provides support for tessellation and geometry shaders, and ASTC compression formats. This is an important step because (for those GPU’s that support 3.1, which are the majority that support 3.0) will enable some rendering techniques that have long been used by desktop rendering systems, including;

  • HDR Tone Mapping
  • More Efficient/Better Smoke/Particles Effects
  • Deferred Shading
  • Global Illumination & Reflection
  • Physically Based Shading

“Quite literally, this is PC gaming graphics in your pocket” Dave Burke, Android engineering director at Google.

Posted in Android, OpenGL | Leave a comment

EGL- Understanding eglChooseConfig, then ignoring it

A few months ago I posted a talk on initializing OpenGL-ES using the EGL API. Well now I’m going to walk you through how to actually get the configuration you want. Nearly all of the OpenGL-ES code I’ve seen (including the Android SDK samples) provide boilerplate so that you just ask for the configs that meet your requirements, and just take the config that is first in the list. Usually this is the exact WRONG configuration you want. It will certainly work, but it’s usually the “most capable” configuration, where as you just want the “best for my needs” configuration.

What you are actually choosing is the format of the “Surface” (EGL terminology for the Render Target (aka destination buffer) where the output will be rendered). If you are coming from Windows this is the “pixel format descriptor”. On Mac it’s the “pixel format object”. You look at what you are rendering and make a decision – for example, I need to render to a 32bit/32bit/32bit RGB color buffer, with a 16-bit depth buffer, and a 32-bit stencil buffer.

So let’s review the code that you typically see in an OpenGL-ES app to get select a Surface.

.
    // Get Display Type
    EGLDisplay eglDisplay = eglGetDisplay( EGL_DEFAULT_DISPLAY );
    eglInitialize( eglDisplay, NULL, NULL);

    // typical high-quality attrib list
    EGLint defaultAttribList[] = {
	// 32 bit color
	EGL_RED_SIZE, 8,
	EGL_GREEN_SIZE, 8,
	EGL_BLUE_SIZE, 8,
	// at least 24 bit depth
	EGL_DEPTH_SIZE, 24,
	EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
	// want opengl-es 2.x conformant CONTEXT
	EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 
	EGL_NONE
    };

    EGLint numConfigs;
    EGLConfig config;

    // DO THIS AT YOUR OWN PERIL!
    eglChooseConfig(eglDisplay, defaultAttribList,
                   &config, 1, &numConfigs)
.

Since we ask for just one config, we get one config. You can only choose one config.  What you really need to do is two steps;

  1. Make the call to eglChooseConfig as before, but pass in a null pointer for the configs parameter. This will return to total available configs that match the description in the numConfigs parameter.
  2. Allocate an array of EGLConfig’s big enough and make the same call, this time passing in the new array pointer and the new size. You will then have an array of all possible configurations available.

This will return you all the the configs that EGL thinks MEET OR BEAT your specified criteria. Note the OR BEAT.  The eglChooseConbfig spec clearly states;

When more than one EGL frame buffer configuration matches the specified attributes, a list of matching configurations is returned. The list is sorted according to the following precedence rules, which are applied in ascending order (i.e., configurations that are considered equal by a lower numbered rule are sorted by the higher numbered rule):

Special: by EGL_CONFIG_CAVEAT, where the precedence is EGL_NONE, EGL_SLOW_CONFIG, and EGL_NON_CONFORMANT_CONFIG.

Special: by EGL_COLOR_BUFFER_TYPE, where the precedence is EGL_RGB_BUFFER, EGL_LUMINANCE_BUFFER.

Special: by larger total number of color bits (for an RGB color buffer, this is the sum of EGL_RED_SIZE, EGL_GREEN_SIZE, EGL_BLUE_SIZE, and EGL_ALPHA_SIZE; for a luminance color buffer, the sum of EGL_LUMINANCE_SIZE and EGL_ALPHA_SIZE). If the requested number of bits in attrib_list is 0 or EGL_DONT_CARE for a particular color component, then the number of bits for that component is not considered.

This sort rule places configs with deeper color buffers before configs with shallower color buffers, which may be counter-intuitive.

Smaller EGL_BUFFER_SIZE.
Smaller EGL_SAMPLE_BUFFERS.
Smaller EGL_SAMPLES.
Smaller EGL_DEPTH_SIZE.
Smaller EGL_STENCIL_SIZE.
Smaller EGL_ALPHA_MASK_SIZE.
Special: EGL_NATIVE_VISUAL_TYPE (the actual sort order is implementation-defined, depending on the meaning of native visual types).
Smaller EGL_CONFIG_ID (this is always the last sorting rule, and guarantees a unique ordering).

EGLConfigs are not sorted with respect to the attributes; EGL_BIND_TO_TEXTURE_RGB, EGL_BIND_TO_TEXTURE_RGBA, EGL_CONFORMANT, EGL_LEVEL, EGL_NATIVE_RENDERABLE, EGL_MAX_SWAP_INTERVAL, EGL_MIN_SWAP_INTERVAL, EGL_RENDERABLE_TYPE, EGL_SURFACE_TYPE, EGL_TRANSPARENT_TYPE, EGL_TRANSPARENT_RED_VALUE, EGL_TRANSPARENT_GREEN_VALUE, and EGL_TRANSPARENT_BLUE_VALUE.

The emphasis is mine – but what it means is that it will prefer 1) A larger color buffer format than you specify, 2) you might want to choose a depth buffer that a different size depending on the hardware (some have odd sizes that might work better – i.e. 24-bit native might be better than 16-bit) and 3) there are attribs that it won’t sort on at all that you have no control over.

Or you can ignore eglChooseConfig entirely and do you own sorting and selection. In this case you’d just call eglGetConfigs to get all the number of TOTAL configurations (for THAT eglDisplay – yes turtles all the way down). And then, for each config, call eglGetConfigAttrib to query each attribute you care about. Shove them all in a list and THEN sort by desirability.  And this post is already too long, so I’ll leave that bit of code for next time.

Here’s how to query/store all the configs. oglesBufferFormat is a structure that contains the attrib I’m interested in. You need to make your own for your needs.

.
// Get number of all configs, have gotten display from EGL
if ( EGL_FALSE == eglGetConfigs(_eglDisplay, NULL, 0, &numConfigs) )
    {
    queryEGLError();
    return EGL_FALSE;
    }
DebugMsg("there are %d configurations available.\n", numConfigs);

// collect information about the configs
EGLConfig *configs = new EGLConfig[numConfigs];

if ( EGL_FALSE == eglGetConfigs(_eglDisplay,configs,numConfigs,&numConfigs) )
    {
    queryEGLError();
    delete [] configs;
    return EGL_FALSE;
    }

std::vector<oglesBufferFormat> _bufferFormats;

oglesBufferFormat newFormat;

for ( GLint c = 0 ; c < numConfigs ; ++c)
    {
    EGLConfig config = configs[c]; 
    eglGetConfigAttrib( _eglDisplay, config, EGL_ALPHA_SIZE, &(newFormat._alpha_size));
    eglGetConfigAttrib( _eglDisplay, config, EGL_BIND_TO_TEXTURE_RGB, &(newFormat._bind_to_texture_rgb));
    eglGetConfigAttrib( _eglDisplay, config, EGL_BIND_TO_TEXTURE_RGBA, &(newFormat._bind_to_texture_rgba));
    eglGetConfigAttrib( _eglDisplay, config, EGL_BLUE_SIZE, &(newFormat._blue_size));
    eglGetConfigAttrib( _eglDisplay, config, EGL_BUFFER_SIZE, &(newFormat._buffer_size));
    eglGetConfigAttrib( _eglDisplay, config, EGL_CONFIG_CAVEAT, &(newFormat._config_caveat));
    eglGetConfigAttrib( _eglDisplay, config, EGL_CONFIG_ID, &(newFormat._config_id));
    eglGetConfigAttrib( _eglDisplay, config, EGL_DEPTH_SIZE, &(newFormat._depth_size));
    eglGetConfigAttrib( _eglDisplay, config, EGL_GREEN_SIZE, &(newFormat._green_size));
    eglGetConfigAttrib( _eglDisplay, config, EGL_LEVEL, &(newFormat._level));
    eglGetConfigAttrib( _eglDisplay, config, EGL_MAX_PBUFFER_WIDTH, &(newFormat._max_pbuffer_width));
    eglGetConfigAttrib( _eglDisplay, config, EGL_MAX_PBUFFER_HEIGHT, &(newFormat._max_pbuffer_height));
    eglGetConfigAttrib( _eglDisplay, config, EGL_MAX_PBUFFER_PIXELS, &(newFormat._max_pbuffer_pixels));
    eglGetConfigAttrib( _eglDisplay, config, EGL_MAX_SWAP_INTERVAL, &(newFormat._max_swap_interval));
    eglGetConfigAttrib( _eglDisplay, config, EGL_MIN_SWAP_INTERVAL, &(newFormat._min_swap_interval));
    eglGetConfigAttrib( _eglDisplay, config, EGL_NATIVE_RENDERABLE, &(newFormat._native_renderable));
    eglGetConfigAttrib( _eglDisplay, config, EGL_NATIVE_VISUAL_ID, &(newFormat._native_renderable));
    /// etc etc etc for all those that you care about

    if ( majorVersion >= 1 && minorVersion >= 2 )
        {       
        // 1.2
        eglGetConfigAttrib( _eglDisplay, config, EGL_ALPHA_MASK_SIZE, &(newFormat._alpha_mask_size));
        eglGetConfigAttrib( _eglDisplay, config, EGL_COLOR_BUFFER_TYPE, &(newFormat._color_buffer_type));
        eglGetConfigAttrib( _eglDisplay, config, EGL_LUMINANCE_SIZE, &(newFormat._luminance_size));
        eglGetConfigAttrib( _eglDisplay, config, EGL_RENDERABLE_TYPE, &(newFormat._renderable_type));
        }

    if ( majorVersion >= 1 && minorVersion >= 3 )
        {
        // 1.3
        eglGetConfigAttrib( _eglDisplay, config, EGL_CONFORMANT, &(newFormat._conformant));
        }
        _bufferFormats.push_back(newFormat);
    }
.
Posted in OpenGL | Leave a comment

OpenGL-ES 3.0 surpasses 16% of Android market and is accelerating

The Android dashboard continues to show that OpenGL-ES 3.0 adoption is marching on. In fact it seems like the trend over the last few months as been one of accelerated adoptions. We’re on track for 1/3rd of all Android devices to be OpenGL-ES 3.0 capable by years end, and we haven’t even seen the newest hardware due out in a few months.

OGLESJune2014

Posted in Android, Hardware, OpenGL | Leave a comment

Oculus Rift Musings: Part 2 – the Facebook Acquisition

I’m excited to announce that we’ve agreed to acquire Oculus VR, the leader in virtual reality technology.

Mark Zuckerberg March 25, 2014

And that was the 2 billion dollar “cha-ching” heard ’round the world. Now there are two extreme this could spin off to;

Pessimistic View: Zuck attempts to create FBReality.  The VR world is rife with “Friends”, “Likes”, and plenty and plenty of pointless posting about stuff I don’t care about. It can be annoying now, but when a “FBriend”  posts a 3D VR  video of their dog trying to lick peanut butter off  the roof of their mouth and it’s plopped in front of my 3D wall and it NEVER ENDS then I lose my faith in humanity.  It’s a big FU to the kickstarters while the OVR founders and talent go off any buy personal islands. VR dies a second time.  Grrrr.

Optimistic View:  And I’m being pretty optimistic here. $2B in the bank makes it pretty easy to kick back and yell “Miller Time”. But let’s play anyway. Palmer et. al. have said that having FB behind them gives them the weight to dictate what the actual consumer hardware will look like because they suddenly become a tier 1 IHV and not have to rely on scraps. OK I buy that. VR is hard to get right – just read Carmack’s, Abrash’s or Forsyth’s posts.  They have solved problems that haven’t been addressed in nearly 30 years. I’ve played with DK2 and the specs for the consumer headset keep getting better and better. The hardware *will* be killer and *will* be able to win large segments of the population into VR (assuming that they actually deliver).

They are beyond solving the gross problems now and are moving onto the more subtle ones. The tech is viable, the $2B was a wake-up call that this is a serious, serious undertaking and is moving right along and has woken up some other competition that  this indeed might be the next big thing. It’s also given them the opportunity to poach talent (more on that later), so while they have gone somewhat silent, if I received a windfall for a project I’d scrap initial plans and re-scope it out too.  You really don’t want consumer acceptance to be as slow as the initial console market was to get going. (But now they could probably survive a slow ramp-up to acceptance). So yeah, if this is the direction that they were thinking of, and if FB let’s them get on with what they were doing, then this just might work out. It might.

Please Dear God don’t let them screw it up.

Posted in Augmented Reality | Leave a comment