---------- Forwarded message ----------
From: Alexander Pritchard
Date: Tue, Apr 1, 2008 at 1:24 PM
Subject: The Simplicity of Custom Camera Coordinates.
To: Pete Berg
So you don't want to depend on screen resolution for how your
graphics are drawn, eh? You want coordinates that will work no matter
what resolution you have? Alright, well we can do this.
You can do this in one of two ways:
The first is to use OpenGL and gluOrtho2D and set the desired
coordinates after setting your viewport. No matter the resolution of
your display, OpenGL will always render your primitives within the
region (x, x2, y2, y).
Don't know OpenGL? Then let's move on to an FBgfx version. We're
going to develop a very simple coordinate system for our FBgfx window,
which will use (0, 0) as the upper left of the window, and (1, 1) for
the end of the screen. Precision levels will vary with screen
resolutions. Using (1, 1) for our end coordinates makes learning this
topic a lot easier, because when multiplying or dividing by one, you
get the number your started with. The transformation from custom
coordinates to screen coordinates is thus, very simple.
[code]#include once "fbgfx.bi"
'' set up our screen
const as integer w = 640, h = 480
screenres w, h, 32
'' our object dimensions - x, y, width height
dim as double oX = 0.1, oY = 0.1, oW = .8, oH = .8
'' draw our object
line ( w * oX, h * oY ) - _
( w * (oX + oW), h * (oY + oH) ), rgb(255, 255, 255), bf
sleep[/code]
The transformation between custom coordinates, and screen
coordinates, is simple. Since we're using a 1-based system, we don't
have to calculate much anything. Our coordinates will render at the
same respective positions no matter the screen resolution. Let's take
a quick look at what our math's doing here though. We call our line
statement with the following arguments:
(w * oX) - Screen width, times our coordinate. This turns out to
be 640 * .1, which is 64, one tenth of the screen width. Will W * .1
will still be (w/10) no matter the resolution, so we always start at
one tenth the width. The same math applies to (h * oY).
(w * (oX + oW)) - This may be a little trickier for some people.
They would notice that the oX and oW have to be in parenthesis
together for this to work. If you remove the parenthesis, you're
actually doing (w * oX) + oW, due to order of operations. That
definitely won't work. Both variables have to add their values
together *before* being transformed to the screen coordinates.
Because oX and oW are compatible in (1, 1) coordinates, while our w
comes from the screen resolution coordinates.
I hope you understand how our math works now, because we're now
going to add the ability to change your coordinate system. There's a
little additional math explained when doing this, but it's all still
very simple.
[code]#include once "fbgfx.bi"
'' set up our screen
const as integer w = 640, h = 480
'' set up our custom coordinates
const as double customW = 100, customH = 100
screenres w, h, 32
'' our object dimensions - x, y, width height
dim as double oX = 10, oY = 10, oW = 80, oH = 80
'' draw our object
line ( w * (oX / customW), h * (oY / customH) ) - ( w * ((oX + oW) /
customW), h * ((oY + oH) / customH) ), rgb(255, 255, 255), bf
sleep[/code]
Here we added a custom coordinate system which is based on
(100,100) resolution.
Remember how we said that a 1-based system was easiest? Look at
the math. It's the same (w * oX). Due to 1 not changing any values
in multiplication, you can think of the original math as (w * (oX /
1)). 1 is our coordinate system value. We just didn't have to
include the 1 before, because it makes no difference as to the result
of the computation.
We divide by our coordinate system value because we first need to
adjust our object positions to our custom coordinates (remember about
coordinate compatibility). The result of this transformation is how
much of our custom coordinate system our object value is taking up.
That result is then used to compute the screen coordinates.
(oX / customW) - 10 / 100. 10 / 100 is .1. .1 * 640 = ... 64!
Same result as before.
I hope that was simple enough. If not, remember - Group your
coordinates together. Every set of compatible coordinates is enclosed
in parenthesis, and every multiplication or division transforms a
group of coordinates into *another* group. In total, we have three
groups. Our object position coordinates, the transformation
coordinates to our custom coordinate system (meaning that if your
custom values are the same as your real values, no more
transformations are needed - multiplication is the inverse of
division), and the final screen coordinates.
See ya!,
Pritchard