Friday, December 09, 2005

Under the water but in the boat

It seem I've finally dealt the killing blow to a bug that caused me extreme pain. I actually noted down a small fraction of my hunt for it here's the fraction.

Wait first let me explain the bug.

I'm making, like many others a simple tilebased game in Direct3D. I'm using Direct3D because we all know direct draw is the devil. Microsoft makes this rather hard. If I was doing it again I'd definetly go for allegro or some wonderful preexisting C# 2D engine.

Anyway in the 3D world there's the pesky extra z co-ordinate and there are cameras looking on to your 2D world. Also texturing isn't straight forward - it's not pixels anymore it's texels, the pixels evil cousin, he starts from the middle of all pixels and was designed by a crack team of scientists to make you cry. So you have to construct your tiles from vertices and rarara

I did this and at some point I got black lines, gaps, between my tiles. I hacked this away in what was now in retrospect a terrible bodge. My rendering code was like a dark jungle where one dared not venture. The black lines dissapeared and their was much dancing and rejoicing - I have no idea what I did but it was something hideous where the vertices spacing of the quad was changing depending on the size of the window. All I know is it wasn't a solution by pre-determined design, rather it was by pure bloody bruteforce.

Anyway the lines dissapeared but soon there where some overlaps and they appeared randomly every few tiles. Overlaps - why that's obviously something wrong with the tile plotter, one would think. Well it wasn't and after lots of confusion I decided it must be crazy 3D camera and floating point rounding errors creating gaps. Far too hard for me to bother win - I'll deal with it later.

Some months later on a monday was later. I decided I'd pull the graphics system out, simplify it and discover exactly where the problems came from. Now here's the log:

O Pulled out the graphics subsystem and madea simpler seperate program
-Revealed a drawing bug.
+Bug was fixed

O Fix is add to main code
-Problem remains

O A new game state was created in the main code to demonstrate the tile plot
+One tile plots fine, as the seperate program
-Using the RenderSubSection plots there's a bug
O Some pixels lines are stretched or clipped ~> a texture bug?
O It happens in the plotting funcion ~> a plotting bug?

Tests to run through

Plot a number of tiles behind hand PREDICT: No Problem

A tile rendered next to the original seems to over lap it! By one pixel.
Even when rendered apart the second tile seems to be missing, it's left most pixel column!
(turn off all other tile rendering and do it again)x
This does nothing

Thoughts For Prediction 1

Are the same tile render functions being used?
Trace through render function
Rewrite the plotting function so that's it's more efficent.
Check a certain conversion function ... currently I'm thinking it's floating point error.

O Remove the +0.03f patch
+horizontal overlap dissapears from both test and example
+all top row squares are the same
-two rows down on the top subsection render a tile seems to overlap another

O Test this in full screen
-no top row or bottom row
-green pixels are twice as thick as blue lines
-top rows are missing from the first two rows.

Editing the textures results in uniform one pixel gapped tiles but with a single errant pixel.

This seems to shout texture problem.
Fiddle with UV textures?

O Fiddle with textures applying different corrections to different axis
+Seems to work on hand plot
-Not tested in full screen
+Hand plot works in full screen
-Doesn't work on long plot.
-Both vert and horizon problems.

-> See if automantic plot can be recreated by hand and if similar problems appear.

O Surrounded texture with pink
+A new pink line appers under tiles
+Obviously current settings require adjustment.

O Adjusted single tile plot seems fine
-Auto plot has same problems
-Not tested full screen

O Added tiles below and above
+Hand plot no problems
-Seems to be an autplot problem.
O A little hard to say but full screen also seems good.
-Full screen has double pixel of the leftmost side (;_;)
+On the sunny side seems like the problems becoming isolated and a fix is within reach.
+It's hacky but if it works it's wonderful.

O Write own render
+Have pink lines from over sampling texture
+Has to be some function in the render function that doesn't occur with hand placement.
O Do hand placement in the exact same place to ensure it's something in the rendering function.

O Moving the render function around proves it's LOCATION as well as a rendering error.
+If location matters than its something to do with the camera
+So I go into camera (;_;) I've been avoid this.
+I change the screen coordinates so that they're ratios of the actual window
+This *uniforms the problem*
+I also hard code the tile size. This wasn't hard coded as I was hoping bigger windows would have more tiles ... it seemed this never worked.
~> Potentially there's only one problem to solve

O First let's test full screen.
:o fullscreen actually seems to work now :o

My code is like an unexplored jungle; there are scary parts you just don't venture into.

O Let's check the actual game ... preparing self to cry.
+Same problems as before pretty much, just looks better now.
+I think now it must be texture problems.

(Solved earlier code mystery - characters where never scaled but tiles where, that's why characters didn't look awful)

Anyway so you see at the end of here things where starting to look hopefuly. But I was once again on the wrong track closer examinings proved there where still graphical glitches.

The seperate program that was suppose to locate the bugs was curiously bug free it worked a treat. So I pulled in some of the cleaner structures - bugs remained. So I pain stakingly ensure the camera and device where all set up exactly alike. The same.

Some lines where a little thicker than others in certain places. There seemed to be less and less places where there could be a problem.

Drumroll please: Eventually I looked to the form. The form itself is a bit of trickyness if you're using it as your device canvas. Let's say you want your game to have an 800x600 view - pretty standard for old school style.

Well you don't set the form to that no because the form includes the little lines of GUI niceness at the sizes and the size of the header bar. All this I knew and thought I had accounted for. Obviously I was somehat mistaken. The only difference between the two programs at this point seemed to be that I was running the main code directly upon the form while the test program be rendered on to a panel control. So I threw in a new control set it 800x600, perfectly fitting the form, and what do you know sharp crisp prefectly aligned graphics. Wonderful.

I found these two links helpful in solving parts of my graphics bug:

Directly Mapping Texels To Pixels (MSDN)

2D Tile Engine Problems, a post on the message board of The Game Programming Wiki.

I'm quite happy, but I'll be happier once the codes all locked down again and performed as expected.

EDIT: Increasing desperation prompts GameDev posting.

EDIT2: ...and now Game Dev Wiki too

No comments: