Jul 06 2010

Everywhere I look, Matrices!

Tag: Engine,VectorStormtrevor @ 11:28 pm

Warning:  technical brain-dump post.  I’ll try to have something more interesting to non-techies tomorrow.  :)

So there’s a major VectorStorm engine update that’ll be happening sometime in the near future;  it’s really needed for MMORPG Tycoon 2 (and any other 3D games I might feel like doing in the future).

Here’s the thing.  VectorStorm was written to be a 2D game engine, and so some of the things in it aren’t exactly what you’d want for a full 3D engine.  One example is its render management.  VectorStorm organises a game into a series of “layers”.  Each layer is drawn in front of the previous layer.  Now, in a game like MMORPG Tycoon 1 where your game was entirely 2D, and you wanted to make sure that your UI was being drawn in front of your game map, and tooltips were being drawn in front of the UI, and the cursor was being drawn in front of the tooltips, “layers” is a really sensible way to arrange things.  Within a layer, you couldn’t really predict how things would overlap.  So if it was important that object “A” draw in front of object “B”, you need to put object A in a higher layer than B.

However, in the world of 3D, we have depth buffers which handle this whole “what goes in front of what” thing for us more or less automatically.  Since MMORPG Tycoon 2 is a 3D game with a depth buffer, I mostly don’t need to draw things according to how they will overlap on screen;  the video card handles that for me.  Instead, I really want to draw according to whatever will allow the 3D card to render the game the most quickly.

Continue reading “Everywhere I look, Matrices!”


Jul 02 2010

VectorStorm trunk updated

Tag: Engine,VectorStormtrevor @ 11:50 pm

Latest engine stuff from MMORPG Tycoon 2 development has now been brought into the VectorStorm library development trunk, and the testbed games have been adjusted to work with those changes.

I’ve also uploaded the first new binary builds of those testbeds for the first time in ages.  The last build was of version 164 — this new one is version 1175.  The games themselves aren’t any different, but this now has the “ATI shader” fix which should have modern ATI cards able to use bloom and other shaders.  If you want to have a look, the link is in the sidebar, under “VectorStorm testbed games.”

If you’re interested in seeing the source code for the game library that I’ve written and use for all my games on this site, the source is publicly available under the terms of the GPL.  Details are on the page for the testbed games.

Now, back to MMORPG Tycoon 2 development!


Jul 01 2010

Today

Tag: Engine,VectorStormtrevor @ 12:18 am

So it’s been a day of maintenance.  I’ve been merging all the VectorStorm library changes back into the public library trunk.  I’m about halfway through;  I’ve got the Mac build working, I’ll get the Win32 build going tomorrow.  The screenshot here is the original 3D sample that you may remember from ages back.

Notable changes:

  • vsMaterials are now very important.  Previously, they were a novelty, now they’re a core concept in the VectorStorm library, completely replacing the old “DrawMode”, and mostly supplanting direct setting of colors in display lists.  Materials are now loaded from data, instead of being specified in code.
  • The bloom effect is much more subdued than previously.  This is largely because of work I’ve done in MMORPG2 to make there be a smaller visual difference between bloom-enabled and bloom-disabled builds.
  • Added full lighting/fog/etc shaders — the same ones (currently) being used in MMORPG Tycoon 2.
  • vsOverlays are no longer supported.  They were cool and quirky, but they really don’t fit in with the new focus on performance.
All this isn’t checked in yet.  I’ll put it in tomorrow, along with updated binaries for Win32 and OS X.

May 01 2010

VectorStorm engine improvements

Tag: Engine,VectorStormtrevor @ 1:21 am

I’ve spent a day working on VectorStorm engine improvements, today.  Those who aren’t interested in technical details should probably skip the rest of this post;  sorry, guys!

Here’s the list of improvements:

2D Display lists now correctly calculate their bounding boxes, even if there are transforms applied within the display list.  (previously, transforms within a display list were ignored for the purposes of calculating their visible size.  This probably wouldn’t have affected anyone;  it’s pretty unusual for a transform to be explicitly placed inside a display list that cares about its bounding box.

Bitmap font rendering now uses a vsBuffer to store each font glyph, so their data is stored on the GPU persistently, instead of needing to push explicit vertex positions and texture coordinates into the display list to draw text to the screen.  As a result, font rendering commands now only take up about a third as much system memory as they used to.  (My MMORPG Tycoon example was the string “Monster Type”, which dropped from requiring 1232 bytes of display list data to draw under the old system, to requiring only 352 bytes of display list data now that it’s using vsBuffers to store its vertex data.)

As a quick reminder, vsBuffer is my wrapper around OpenGL’s concept of VBOs (“Vertex Buffer Objects”), which are designed to store blobs of frequently-used data on the GPU.  The vsBuffer will also transparently fall-back to OpenGL’s older “array” functionality, for folks whose 3D cards or drivers don’t support VBOs.   Today, I have implemented interleaved VBOs within vsBuffer.

The old way of using vsBuffer was to give it an array of positions or colors or some other data type, and then put a command onto a display list telling the renderer what to do with the buffer.  (For example, you might tell it to use one buffer as a vertex position buffer, and another one as a normal buffer, and yet another as a texture coordinate buffer, each storing one type of data about each vertex to be drawn.)  That old code will all still work.  However, you can now use the explicit vertex formats exposed by the vsBuffer, such as “PNT”, for vertices which specify a position, a normal, and a texture coordinate.  The vsBuffer places all these bits of data together into a single OpenGL VBO, interleaved for fast access.  You bind these interleaved buffers by giving a “BindBuffer” command to the display list.  When finished, you can either give an “UnbindBuffer”, or “ClearAllArrays” command.

I’ve also converted the vsMesh utility class to automatically use its internal vsBuffers in interleaved mode, when it can.  So if you were already using the vsMesh or the vsMeshMaker (as I do in MMORPG Tycoon 2), you’ll automatically get this improvement.

With that said, I only see a moderate performance improvement on my laptop, but every little bit helps.  And I’m reliably informed that on embedded systems (such as mobile phones) that having interleaved VBOs gives substantially improved performance.  And someday I might want to look into things like that, I suppose.

Anyhow, as is often the case with these sorts of improvements, I’ve done this in my MMORPG Tycoon 2 development branch;  these changes haven’t yet been migrated back into the main publicly accessible VectorStorm trunk.  But I’ll get to that eventually.  :)


Dec 28 2009

Bugs which aren’t bugs

Tag: Engine,VectorStormtrevor @ 4:28 pm

Inside VectorStorm, there’s a function vsClamp;  it looks like this:

#define vsClamp(a,min,max) ( vsMin( max, vsMax( min, a ) ) )

(modified for legibility;  C/C++ coders, no need to warn me about how painfully dangerous that code snippit is. :) )

You’d use it like this:

vsClamp(1, 0, 10)  -> 1
vsClamp(0, 10, 20) -> 10
vsClamp(6, 2, 3)   -> 3

Effectively, you give it a number, and then a minimum and maximum legal value;  the value that pops out of the other end is the original number, clamped to within the requested range.

But what I’ve just discovered is that about half of my code is actually calling this function like this:

vsClamp( min, a, max );

That is, it sandwiches the value to be clamped between the minimum and maximum values.  Which actually makes a weird kind of sense, but isn’t how I actually implemented that function.  ”Oh no,” I thought, “all that code is going to be doing totally the wrong thing”

But as it turns out, calling vsClamp(  a, min, max ) is identical to calling vsClamp( min, a, max ), which is itself identical to calling vsClamp( min, max, a ).  As long as whichever value you intend to act as the ‘min’ is less than whichever value you intend to act as the ‘max’, all three are guaranteed to return the same result.

How bizarre is that?  :)


Next Page »