Monday, November 21, 2011

Tearing my hair out

Ok, I fixed the issue I was having. I'm not really sure what the issue was, but it appears to be gone after a few modifications to the offending code. I can't really say I'm happy about the outcome. I haven't really changed anything fundamental, and I don't even know what the problem was in the first place.

Since I'm sure you're riveted to your seats, wondering what the bug was, I'll tell you. Maybe you can tell me what the cause was. When I changed the path of the program, it crashed. That is, the compiled program would work in the directory I compiled it to, no issues. But change the name of the directory the executable was in, or copy the directory to a different location (keeping the relative paths of the resources intact) and it would fail. Madness.

I did do a couple of things in the program that weren't very nice. I had a nested for loop and I needed to keep track of how many times I run the inner loop, so I declared a variable outside of the loop and incremented it inside the loop, as an index into a dynamically allocated array, then used it again outside after increasing it a couple of times.

The big change I did was not to use it outside the loop. My best guess is I was incrementing it by one more than the size of the array outside the loop, and overwriting some bit of memory that I shouldn't have been messing with. How that could possibly cause the program to work in the compilation directory but not when I changed it's name, I may never know. But then, that's what happens when you play with arrays, and one of the reason to avoid them when possible.

Unfortunately, OpenGL calls want you to give them raw pointers to arrays. I am doing well enough using smart pointers instead, but until I wrap them up in safer structures, some dangers remain. I should look into using vector, I think it might help. I'm just not sure I can get the pointer to the memory, or that vector has to pack the information in a certain manner. Arrays are ugly, but at least I have control over the packing of the bits in there, and that's what I need.

Now that it's working, however, I'm can get to working on something more important. Currently I'm using a noise function that unfortunately I can't easily reinitialize. Basically, I need to add a 'shuffle' function to rearrange the values in an array, which serves as the seed of the noise generator. Shouldn't be too difficult.

EDIT - Curse you, Skyrim! I'm afraid I got slightly sidetracked this past week. Good thing this scheduling thing works.

Monday, November 14, 2011

Giving shape to the world

I finally have an interesting playground to experiment in, so it's about time I focused on what I wanted to do in the first place. The main drive behind this project was procedural content, making use of algorithms to populate the world with variety instead of a fixed number of precomputed models. I've already been doing that, in fact. The distribution of spheres in the demo, for example, and their size, is all deterministically decided by the program at run time.

All I do is decide how many spheres I want, what the range of sizes should be, and the volume of space to use. The program then fills the space. Because the starting conditions are always the same, the program always builds the same scene. I could easily create a different distribution by changing the seed or any of the parameters. I want to go further, though. Right now, all these spheres are kind of boring. And not very asteroid like. To change this, I'll deform the spheres to create more interesting shapes.

My initial plan is to assign each sphere a height map. I'll then use the height map to raise or lower away from the center of the sphere each vertex. One difficulty I expect is how to adjust the normals as the terrain is reshaped, but I'll figure something out. On the height map end, I'll use the simplex noise algorithms I've talked about before to give each asteroid a distinct look. By seeding each asteroid with a distinct value, I ensure they'll all be unique.

A sample of simplex noise

For the height map, I only need it to match one pixel to a vertex. This way I can send the value to the vertex shader as an attribute. I already created the spheres using a gridlike pattern, so I can use the uv coordinates of each pixel for this purpose. This does mean that there will be more detail near the poles that along the equator, but because my source is going to be a 3d density function it should not result in any obvious distortions. The output will go into a Vertex Buffer Object, which will be fed to the video card and called when drawing.

Normally, height maps add a height to points on a grid, which is level with either the XZ or XY planes, meaning Z or Y is treated as height, and that value is replaced with the value of the height map. However, I have a sphere. On a sphere, height is defined as the distance from the center. To apply the height map to a sphere, I have to work a bit more.

The values I have will fall between -1 and 1. If I do straight multiplication of the surface point by the value, I'd have a mess. Instead, what I do is decide what I want the range of heights to be. If I want the highest points to jut out three times the radius of the sphere, for example, and the deepest valleys to reach half way to the center of the sphere, that gives me a range of (3 - 0.5 ) = 2.5 radius. The half point (where the height map is 0) would be 1.25 radius, so I could get the position of every point as ( (1+height)*1.25 + 0.5) * position.

The other complex bit is recalculating the normals. By changing the shape of the sphere, the surface normals all change as well and that impacts the light on each point. If I don't get them right, the lighting will look decidedly odd.

That's getting ahead of me a bit. First I need to be sure I can produce the information and get it into the shader. I had to add an extra attribute to the Model class to do it, but after a few short tweaks I got it up and running. What I'm doing right now is using the height value of each point as a color value, with -1 being black and 1 being white. So higher areas will look brighter.

Looks nicer than blue with red and green dots.

It's working, and I'm pretty happy about that. I'm now struggling with an odd problem; when running the project from a pendrive it works, but copying the project to the hard drive and running it there doesn't. Fixing that is probably going to give me enough for another post itself.

Monday, November 7, 2011

Looking good. Looking real good.

Well, that was quite a bit of wait between updates, but lighting is done. Sort of.

It's helpful for me to see what I need to do to flesh the shaders out. Later on I'll need to add textures, and shadows, and multiple sources of light. The nice thing about space shooters, though, is that you generally only have one big source of light to worry about. Certainly, there is plenty of room for lighting effects all over, but what's going to be illuminating the planets, asteroids and ships for the most part is the big star in the middle.

A concern I'm having is that as I add features, the code is getting a more unwieldy. For the most part I've avoided a serious case of spaghetification, but I really should spend some time consolidating certain pieces of code. Before I do that, however, I want to have a better feel for what works and what doesn't in my design.

I've already identified some decisions that weren't the best. For example, my use of inheritance would in many cases be better suited to templates. I wanted to avoid templates, because they are somewhat arcane in their workings, but already my use of the standard and boost libraries has me working with them. I feel more confident now about using them, and it would simplify some things.

This means I'm going to have to do a bit of a rewrite of several big chunks. Rewrites aren't fun, but on the positive side I'm not going to be starting from zero. That seems like a good opportunity to reassess and redesign, so I want to get a bit more experience in before I undertake that particular task. It's a fragile balance I have to manage between having enough features in there that I know how to design it better and having so much that redesigning it is too daunting to do.

It doesn't help that work has picked up and I'm generally too burned out to focus on this when I get home. That's also part of why I've let the update schedule slip, for which I apologize.

In the interest of making things easier for everyone, I've switched back from 7z to zip files to share the program. 7z was a necessity when I was sharing the program through gmail. Mail programs don't like zipped executable files, and having people rename a file from .jpg to .exe to get around it was more trouble than convincing them to use 7zip. But with the files now hosted in Google Docs, I can go use zip files again.

As always, the folder is Framework Releases, and the project itself is Framework-0.0.8.

Saturday, November 5, 2011

An apology and an explanation

I've spent the past week wrangling with an annoying bug in the code. Turned out to be a simple mistake, but since the lighting code was all new I had to go over it with a fine-toothed comb until I figured out what was wrong. Fixing it was simple enough, but it took me a while. It didn't help that I had a particularly busy month.

As the days passed and it seemed like I would miss my deadline, I had to make a choice. Either release what I had, knowing it was buggy, or let the week pass. I had the post already done, and I could fix the demo in the meantime. I had already slipped into posting on Wednesdays while doing the lighting bit, and I didn't want to completely miss the week.

Really didn't want to be tardy
However, the philosophy of releasing for a deadline, not when it is working, is one of the things I dislike about the programming industry. Seeing as this is something I'm doing for myself, I want it to be done right and follow my own ideals.

One of these ideals is releasing with no known bugs. No program more complex than 'Hello World' is ever bug free, but it's one thing for your users to find bugs, and a very different thing for you to release a bug you know about into the wild. Releasing with the expectation of a patch later is the reason why so much stuff works as badly as it does.

The downside is that if I'm planning to make a release and just missing the demo, a bug that takes too long to fix (an amount of time fundamentally unpredictable) will throw my schedule off and leave me with nothing to post. I do have to apologize for that. I should work on building a buffer of some sort, although that's a bit difficult as what I usually do is write about what I'm doing at the time.

On the other hand, planning what I'll work on with more time can only help avoid these issues.

The bug is fixed, the demo is working, and I'm now working on the focus for the next part. I have scheduled the post with the explanation of the demo to go up at 9:00 GMT on Monday, so as to go back to my regular release day. In the meantime, the demo is up in Google Docs already.

As always, the folder is Framework Releases, and the project itself is Framework-0.0.8. I switched to zip files to make things simpler for everyone.

"I am NOT Tardy" Image by MidoriFlygon