0

I'm using OpenGL ES 2.0 on Android and I and I initialise my display like so:

float ratio = (float) width / height;
Matrix.orthoM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);  //Using Orthographic as developing 2d

What I'm having trouble understanding is this:

Let's say my app is a 'fixed screen' game (like Pac-Man ie, no scrolling, just the whole game visible on the screen).

Now at the moment, if I draw a quad at -1 to +1 on both x and y I get something like this:

enter image description here

Obviously, this is because I am setting -ratio, ratio as seen above. So this is correct.

But am I supposed to use this as my 'whole' screen? With rather massive letterboxing on the left and right?

I want a rectangular display that is the whole height of the physical display (and as much of the width as possible), but this would mean drawing at less that -1 and more than +1, is this a problem?

I realise the option may be to use clipping if this was a scrolling game, but for this particular scenario I want the whole 'game board' on the screen and to be static (And to use as much of the available screen real estate as possible without 'stretching' thus causing elongation of my sprites).

As I like to work with 0,0 as the top of the screen, basically what I do is pass my draw method something like so:

quad1.drawQuad (10,0);

When the drawQuad method get's this, it basically takes the range from left to right as expressed my openGL and divide the the screen width (so, in my case -1.7 through +1.7 so 3.4/2560 = 0.001328125). And say I specify 10 as my X (as above), it will say something like:

-1.7 + (10*0.001328125) = -1.68671875

It then plots the quad at -1.68671875.

Doing this I am able to work with normal co-ords (and I just subtract rather than add for y axis so I can have 0 at the top).

Is this a good way to do things?

Because with this method, at the moment, if I specify a 100,100 square, it isn't a square, it's rectangle. However, on the plus side, I can fill the whole physical screen by scaling the quad by width x height.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Zippy
  • 3,826
  • 5
  • 43
  • 96

1 Answers1

0

You are drawing a 1x1 quad, so that is why you see a 1x1 quad. Try translating the quad 0.25 to the right or left and you will see that you can draw in that space too.

In graphics, you create an object, like a quad, in your case you made it 1x1. Then you position it wherever you want. If you do not position it, then it will be at the origin, which is what you see.

If you draw a wider shape, you will also see you can draw outside this area on the screen.

By the way, with your ortho matrix function, you aren't just specifying the screen aspect ratio, you are also specifying the coordinate unit size you have to work with. This is why a 1x1 is filling the height the of the screen, because your upper and lower boundaries are set to 1 and -1. Your ratio is a little more than one, since your width is longer than your height, so your left and right boundaries are essentially something like -1.5 and 1.5 (whatever your ratio happens to be).

But you can also do something like this;

Matrix.orthoM(mProjMatrix, 0, -width/2, width/2, -height/2, height/2, 3, 7);

Here, your ratio is the same, but you are sending it to your ortho projection with screen coordinates. (Disclaimer: I don't use the same math library you do, but these appears to be a conventional ortho matrix function based on the arguments you are passing to it).

So lets say you have a 1000x500 pixel resolution. In OpenGL your origin of 0,0 is in the middle. So now your left edge is at (-500,y), right edge at (500,y) and your top is (x,250). So if you draw your 1x1 quad, it will be very tiny, but if you draw a 250x250 square, it will look like your 1x1 quad in your previous ortho projection.

So you can specify the coordinates you want, the ratio, the unit size, etc for how you want to work. Personally, I dont't like specifying coordinates as fractions between 0 and 1, I like to think about them in the same sense as the screen pixels.

But whether or not you choose to do this, hopefully you understand what you are actually passing to these matrix functions.

One of the best ways to learn is draw an object to the screen and just play around with different numbers you send to your modelview and projection matrices so you can see what it is they are actually doing.

johnbakers
  • 24,158
  • 24
  • 130
  • 258
  • Thanks @SebbyJohanns, I've put an edit at the end of my original question, please could you comment? Many thanks for you help so far!! – Zippy Apr 07 '13 at 17:11
  • I recommend that if you draw a 100x100 square, you get a square without having to go through any intermediary functions. For now, while you are learning, setup your projections properly, the way it is designed. When you start to really feel how this stuff works, you can consider abstracting things away for yourself, but I personally wouldn't do it the way you've stated in your edit. You should get familiar with the OpenGL coordinate system where (0,0) is the center of the screen. – johnbakers Apr 07 '13 at 23:59
  • And if your device's operating system reports coordinate differently than OpenGL (as is the case with iOS), just write a simple function that converts these coordinates into OpenGL coordinates first, but when you actually do drawing, etc, you should be passing OpenGL coordinates or you are opening yourself up to bugs and confusing code. – johnbakers Apr 08 '13 at 00:00
  • OK but say I want to draw a whole screen background - how would I do that? If I pass the width of the screen, I will only get a square, not whole background if you see what I mean? How would I specify that I was width the equal the actual physical width? – Zippy Apr 08 '13 at 00:06
  • depends on the projection you are using. with my example, if you draw a quad with a width of your screenwidth and a height of your screenheight, you will get a quad that fills the entire screen. Using your projection, your quad's width would be something like 1.5 or whatever your ratio is, and its height would be 1. That would also fill the whole screen. – johnbakers Apr 08 '13 at 00:32
  • by the way I'm referring to screenwidth as the long part of your aspect ratio since that is how your image is orientated above, but you can switch width and height in my example if necessary. – johnbakers Apr 08 '13 at 00:35
  • Hmmmm I'm not understanding something or going wrong somewhere. If I want to draw a quad filling the whole screen, using normalised coordinates (openGL coordinates), what would I specify, lets say I have a setSize method that grabs the width and height (which will be in pixels as that's how onSurfaceChanged give it) and then pass that into my setSize method which has to convert to OGL. It does this correctly and draws the quad at -1 to + 1 (as that is what I'm specifying as my left edge), so it basically draws a perfect square as my picture above, not a rectangle that fills the entire screen? – Zippy Apr 08 '13 at 00:38
  • Actually I have done some more testing and I am satisfied with the results I have! Thanks very much once again - I will accept you answer @SebbyJohanns - I never realised coordinates could get so messy!! :-) – Zippy Apr 08 '13 at 00:49
  • You keep referring to normalized coordinates but that is not how *you* should position your objects. You should position them using screen coordinates. It doesn't make sense to draw a 1x1 and expect a rectangle, like your screen's shape -- you draw a square, you get a square. Your projections should be set up to make this possible for you, as it makes the developer's life much easier and more intuitive. – johnbakers Apr 08 '13 at 00:50
  • Yep sorry maybe I wasn't making myself clear. (I was just testing with normalised coords to help me understand) I am actually specifying screen co-ordinates, but if I understand it correctly, OpenGL uses Normalised Device Coordinates itself as that's it's native coordinate system. But yeah, I am passing in screen co-ordinates when I draw my quads. It is actually working. If I specify a 100 px by 100 px quad, it is actually displaying a square, so that's great. I'm moving onto try to work out how to set up my viewport now to retain the same aspect ratio's on any device. – Zippy Apr 08 '13 at 01:39