---------- 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