Lines

For me first week of full-time work on MMORPG Tycoon 2, I’ve been upgrading the VectorStorm engine to render using an OpenGL 3 core profile.  This gives a number of benefits;  most notably a vast simplification to managing the capabilities of different drivers.  Previously, we supported two different rendering paths (OpenGL 1.2 or 2.1), and the 2.1 rendering path had a whole suite of different extensions which may or more not be supported on any particular piece of hardware, and so needed to be detected and wrangled individually.

For VectorStorm, there is one big downside to switching to OpenGL 3, though — in version 3, OpenGL has deprecated the ability to render wide lines.  Note that ‘deprecated’ is OpenGL code for ‘removed with caveats’.  This is a shame, because we were using OpenGL’s wide line drawing in order to draw our bold lines;  under OpenGL 3, we can only draw lines which are a single pixel wide..  So I’ve been working on a new line rendering system which will treat lines more nicely.

The leftmost image here shows a magnified version of the cursor from the current development trunk of MMORPG Tycoon 2.  The outline of the cursor is okay (or at least, I’ve been happy enough with it to ship three milestone builds using it), but the corners are a little odd, particularly when viewed this close;  it’s pretty obvious that the outline is made up of a bunch of rectangles.

So while setting up OpenGL 3, I spent some time trying to be smart about building rectangles to represent a thick line.  The middle image shows my first attempt at it, which I thought was mostly okay, apart from being oddly thin around sharp corners.  To a casual glance, the irregularity was pretty subtle and probably acceptable, but under magnification, it’s pretty obviously doing something very strange and bad.  This version is basically triangulating line as if it was a smooth ribbon;  bending it around as it goes, trying to make it face the camera as best as possible at each point.  I use this approach for lots and lots of things, including for the body of the cursor itself.  But it turns out that this approach simply doesn’t work reliably for lines.  So my next attempt (the rightmost image) did things properly;  the line segments are treated as absolutely straight, and maintain width precisely, including performing collision tests to find where the edges of a wide line intersect, at corners.  I think this is a much better approach!

If you view that third image full-size, you’ll see that the tip of the arrow isn’t yet being handled correctly;  that’s because the outline is drawn as a loop, both starting and ending at that point.  The code doesn’t yet realise that the cursor outline is a loop, so it just puts square rectangular ends on both ends of the line.  Fixing that is next up on my list.

I still need to do a little more work to figure out exactly how this line-drawing system will best fit into the VectorStorm library.  It’s complicated because some lines (2D ones, mostly) could theoretically be built just once, and then remain static, whereas 3D ones need to be re-generated each time the camera moves, in order to make sure their triangles are always facing the camera.  The raw ‘LineList’, and ‘LineStrip’ rendering commands probably go away entirely, and you’ll instead need to create lines using some new drawing primitive which is able to do these calculations on the fly, to build renderable line geometry on demand.