Home > OpenGL, Procedural Generation > Building a Better Planet

Building a Better Planet

October 26th, 2009
Part of the series: Terrain Generator»

My little side project of a terrain generator has now once again stepped into being a school project.  This is a good thing though, because now I don’t feel guilty about asking for help from teachers, and will have to spend more time on it.  But, let’s not talk about the grand plans for the future, let’s talk about what’s been accomplished so far.

My first step was an attempt to free up more texture units by combining the textures I already had into one large texture.  While this will generally work, the combination of doing this and using trilinear filtering causes seams to appear at different distances (or texel sizes if you will).  This is pretty much unavoidable, and I’ve been researching different approaches to the problem.  None yet have shown any real promise, but some failed attempts have shown humorous results (screenshots: A Series of Failures).

Putting that aside for a while, I started replacing much of the temporary base code with that of my own.  It’s not that the code was poor, it just wasn’t mine.  In this process I gained a better understanding of the underlying architecture, and got to test out a couple of my own libraries I’d been working on (a 3D math library and a wrapper for Direct Input).  I also did a lot of house cleaning, things like fixing my coord system to actually be right-handed, stopped allocating more memory than need be on the graphics card, optimizing heavy sections of code, etc.

Now that I had a good baseline, I started to add multi-threading to my project.  Multi-threading with OpenGL is a pain.  It can be done, but I don’t think it should be done.  The basic problem with this idea is that OpenGL is a state machine, and it wants to create a new instance of this machine for each thread you spawn off.  What this means is if you want threads to interact with data generated by OpenGL (geometry, shaders, textures, matrix transforms, lights, draw lists, VBOs, etc) then you’re going to have to set up both instances separately, and then get them to play nice with the same device context.  This is what makes it a pain, it’s best (as I eventually found out, after much hair pulling) to just leave all OpenGL calls in one thread.   Multi-threading in this fashion, is much less complicated, and probably the perfect approach for most developers.  However, if you’re using multiple viewports, then this separation of the device contexts will actually come off as a bonus.

The end result of this is that my generator can now stream procedurally created terrain on the fly, creating an infinitely large space to explore.  The next step, is to make it interesting.  This of course means not only additional features such as trees, grass, rocks, etc; but also more varied terrain.  That is the next step in the project, and one I should have completed by this time next month.

One more anecdote I’d like to add before wrapping things up is the ATI vs NVIDIA compiler problem that I ran into. ATI, it seems, is a stickler for detail with GLSL, whereas NVIDIA will overlook some of your little errors and do implicate conversions for you.  I’ve found a surprising lack of information about this anywhere, and my only recourse was to start debugging on my 5 year old desktop.  Currently, on an NVIDIA environment, the generator runs clean and fast.  On an ATI setup however, it’s either an instant crash, or lots of texture artifacts with a crash lurking in the background.  Given, this is old hardware, but I found that Render Monkey would throw up errors at the slightest oversight on an ATI compilation. Thusly,

NVIDIA:

gl_FragColor = texture2D(terrain, vTempTex) * vDeltaTexture.r;

ATI:

gl_FragColor = vec4(texture2D(terrain, vTempTex).xyz * vDeltaTexture.r, 1.0);

Once I get the ATI issue ironed out, I’ll be releasing version 0.2b, which should hopefully run on almost any Windows system with decent hardware.  And so, I’ll leave you with a few screenshots of the overall progress thus far.

Screenshot0084 Screenshot0088 Screenshot0086 Screenshot0085

Zilchius OpenGL, Procedural Generation

blog comments powered by Disqus