gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > 3d grid and coordinates

#170748 - danny - Fri Oct 16, 2009 6:47 pm

Hi,
I started programming on DS a few weeks ago. I have been working with DirectX for a year, so moving to OpenGL is quite difficult for me.. :)

I have a problem with drawing a simple grid. I wrote this:

Code:

glMatrixMode(GL_MODELVIEW);
      glPushMatrix();

glLoadIdentity();
      glPolyFmt(POLY_ALPHA(31) | POLY_CULL_NONE);

gluLookAt(   objCamera.pos.x, objCamera.pos.y, objCamera.pos.z,      
      objCamera.view.x, objCamera.view.y, objCamera.view.z,      
                objCamera.up.x, objCamera.up.y, objCamera.up.z);      

for(float i = 0.0f; i < 15.0f; i += 1.0f)
     {
               glBegin(GL_TRIANGLES);
               
               glColor3f(0.0f, 1.0f, 0.0f);
               glVertex3f(-7.0f+i, 0.0f, -7.0f);
               glVertex3f(-7.0f+i, 0.0f, 7.0f);
               glVertex3f(-7.0f+i, 0.0f, -7.0f);
               
               glEnd();
     }
     
     for(float i = 0.0f; i < 15.0f; i += 1.0f)
     {
               glBegin(GL_TRIANGLES);
               
               glColor3f(0.0f, 0.0f, 1.0f);
               glVertex3f(-7.0f, 0.0f, -7.0f+i);
               glVertex3f(7.0f, 0.0f, -7.0f+i);
               glVertex3f(-7.0f, 0.0f, -7.0f+i);
               
               glEnd();
     }

in the main loop. It works fine and displays 15 linesx15 lines grid, but when I try to increase that value (and display 17x17, 19x19 and so on), changing, of course, all 7s to 8s, 9s and so on, the program doesn't work (I see only 15x15).

(I wrote a CCamera class, which stores the actual position, view and up vectors' values.)

What's the problem?
(sorry for my english)

#170754 - zeruda - Fri Oct 16, 2009 10:38 pm

The call:
glVertex3f(7.0f, 0.0f, -7.0f+i);

calls
glVertex3v16();
with the floats converted to v16 which DS processes as 1.3.12 fixed point format. This is 1 sign bit, 3 integer bits and 12 fractional bits and goes from -7.9 to +7.9. So you are going from -7 to +7 which is 15 values and then the 16th value overflows and so it doesn't work. So use smaller increment i.e. i/10 instead of i.

#170758 - danny - Sat Oct 17, 2009 6:25 pm

I understand, but does it mean that I have to draw my whole game betweet 7 and -7?
What if I want to draw these lines using this increment? How can I keep the distance between each line = 1.0f?

#170761 - elhobbs - Sun Oct 18, 2009 12:43 pm

Yes, youdo need to draw between 7.9 and -7.9 as that is what the hardware requires. However you have 12 fractional bits of precision to play with so you can scale everything. You could design everything from 8192 to -8192 and then divide everything by 2048.which would scale every thing from 4 to -4 , well within the ds range.You just need to be careful when you convert you values az you do not want to lose the fractional value.

#170764 - LOst? - Sun Oct 18, 2009 11:01 pm

Sorry for being so obvious. The code is kinda nasty because of the for loop using floating point while doing just integer addition:
Code:

for(float i = 0.0f; i < 15.0f; i += 1.0f)


Especially when the DS doesn't support floating point.

But even if it had, that's just a bad idea. Floating point appears differently on different CPUs. Nothing guarantees that 1.0f will actually end at 15.0f. Not that it matters in rendering (in OpenGL, which is inaccurate on different hardware as well).

This code is better, and will always generate the same result:
Code:

for(int i = (0 << 12); i < (15 << 12); i += (1 << 12))


This post was just about the for loop, and was kinda obvious, so I'll apologize for it ;)
_________________
Exceptions are fun

#170765 - Miked0801 - Mon Oct 19, 2009 12:56 am

Actually that loop will work fine in all cases - it doesn't check floats for equality, which is the thing it has issues with.

For a PC with a co-processor to handle floats, there is nothing wrong with this and in some cases it will even be faster than integers.

#170767 - Dwedit - Mon Oct 19, 2009 4:52 am

Aren't floats identical to integers for integer values up to about 8 million?
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#170769 - wintermute - Mon Oct 19, 2009 4:38 pm

zeruda wrote:
The call:

This is 1 sign bit, 3 integer bits and 12 fractional bits and goes from -7.9 to +7.9.


This is not 1 sign bit and 3 integer bits, it's 4 signed integer bits. The range is -8.0 to 7.999755859375. It's a standard 16bit 2s complement number, the "sign bit" is an integral part of the number which can't really be separated.

danny, if you're having trouble with the range it may be helpful to look at it in terms of the integer range - -32768 to +32767
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#170773 - sajiimori - Mon Oct 19, 2009 10:10 pm

Dwedit wrote:
Aren't floats identical to integers for integer values up to about 8 million?
Yes! There's actually a lot you can assume about a platform that uses standard (IEEE 754) floating point, bugs notwithstanding.

Floats on the DS are nice and predictable. It'll give you the correct answer... eventually. ;)

#170775 - LOst? - Mon Oct 19, 2009 11:43 pm

Miked0801 wrote:
Actually that loop will work fine in all cases - it doesn't check floats for equality, which is the thing it has issues with.

For a PC with a co-processor to handle floats, there is nothing wrong with this and in some cases it will even be faster than integers.

Yea, so I have heard. But I have experienced other results in my projects, even if it is very rare.

And about floats being equal to integers up to some high number... It doesn't really matter for constants, but for calculations. I have had results in floating point that should have been 40.0f but ended up as 39.999999f instead. The worst part about those answers is that 39.99999f can never be 40 when cast to integer (guess what, it truncates down to 39). 39.999999 might "technically" be considered 40, but still not even "equal" to the floating point value 40.f when compared using ==.
I don't have an example of this calculation, but I promise I will come back here one day when I discover it again. I only know that the calculation I used (has happen many times before in different projects of mine) could never be fixed by just adding a small number to it, since it would screw up all the other propper results.

I only use floating point numbers when they are mandatory, or where the dot product of a vector can't be represented by a fixed point number because it being too large, overflowing, getting negative.

I just don't like something that is supposed to be faster, but is randomly inaccurare. Is that something wrong with me??? :P
_________________
Exceptions are fun

#170794 - sajiimori - Wed Oct 21, 2009 1:24 am

There's nothing random about fixed point arithmetic. Whether you're using fixed point or floating point, you really need to understand how it works, or you're going to get unpleasant surprises on occasion.

If you work around an arithmetic problem by using floats, and it's fast enough, then more power to you! If you do run into framerate issues at some point, you can do some measurements to decide whether it's worthwhile to switch to fixed-point, or if it's better to spend your optimization hours elsewhere.

Just don't design your data structures or algorithms to require floating point, or you'll have a harder time optimizing it, in the event that you need to. =)

#170818 - Miked0801 - Wed Oct 21, 2009 4:31 pm

You are correct Lost, checking for very close equality or less than will also run into problems on occasion. I've not used floats professionally since the 386 days so there are a few things I will miss. Still, modern PCs with modern vector floating point units (either in core or on a graphics card) are in many (dare I say most) cases faster than integer calcs. That's where I was going with the speed thing. On DS/DSi, float == slow and that's an equality that does work.

#170825 - sajiimori - Wed Oct 21, 2009 10:11 pm

Hey Mike, watch out to assert(DSi != 0.f), or you'll throw an exception. ;o)

Oh man, I crack myself up.

#170851 - a128 - Fri Oct 23, 2009 9:32 am

I use this fix point C++ class for my "Oh I need float" stuff

http://www.storage.to/get/R1ffu5FE/fixed_nds.tar.gz
_________________
"Hey! It compiles! Ship it!"

#171135 - danny - Mon Nov 02, 2009 8:21 pm

OK, I understand how 4.12 fixed format works and I know that i'm going out of range and due to this I can't draw correctly, but I just can't figure out how to fix it... -.-
Do I have to change it to glVertex3v16(), int, unsigned, v16, use inttov16() or just scale everything?
I know that's a lame question but I won't get anywhere without this..

#171137 - elhobbs - Mon Nov 02, 2009 10:24 pm

yes, you need to scale everything. what is the range of the coordinates that you are currently using? both min and max values.

#171161 - danny - Tue Nov 03, 2009 10:00 pm

but what do you mean by 'scale' ? using glScalef(), changing coordinates manually or using some other techniques?

#171162 - elhobbs - Tue Nov 03, 2009 10:13 pm

it depend on how you have your data stored. ultimately you need to send the vertex data to the ds using 3 x 16 bit values for each coordinate. so, if your values exceed -32768 through 32767 then you may have some decisions to make as this exceeds the precision of a 16 bit value.

however, say your values are stored as floats and they range from -8191 through 8191. 8191 fits in 13 bits so that leaves two bits for fractional values (roughly). so you could multiply all of your floats by 4 and convert to a short and it would still fit in the 16 bit data type without loosing too much precision.

#171191 - danny - Thu Nov 05, 2009 10:55 am

As yet, I don't display/draw anything.
I understand all these type-range calculations, but I still can't interpret them.
Give me an example: what would you do to display a grid I mentioned in 1st post?

#171326 - danny - Fri Nov 13, 2009 8:20 pm

Oh, please. Do you find me noob or sth?
This forum is one of its kind and only you can help me.

#171345 - sajiimori - Sat Nov 14, 2009 8:16 pm

Why not download a simple demo, and experiment with it? Modify it in different ways to see what happens.

Of course, people will help you here, too.

#171353 - danny - Sun Nov 15, 2009 6:38 pm

for example?
the only demo that shows moving in 3D (included in libnds examples) uses values up to 6.0 so doesn't require scaling (or whatever) and so it doesn't explain anything ;/