I'm having difficulties understanding about the OpenGL perspective view. I've read tons of information however it didn't help me trying to achieve what I'm after. Which is making sure my 3d scene is filling the entire screen on every Android device.
To test this, I will be drawing a quad in 3d space which in the end should touch every corner, filling up the whole device's screen. I could then use this quad, or actually its coordinates to specify a bounding box at a certain Z distance which I could use to put my geometry and making sure those fill up my screen. When the screen resizes, or I am to run it on another screen resolution, I would recalculate this bounding box and geometry. I'm not talking about static geometry, but for instance say I want to fill the screen with balls and it doesn't matter how big or how many balls there are, the only important thing is the screen is filled and there are no redundant balls outside the visible frustum.
As far as I understand when specifying the viewport you actually bind pixel values to the frustum's boundaries. I know that you can actually set an orthographic view in a way your window pixels match 3d geometry position but I'm not sure how this works in perspective view.
Here I'm assuming the viewport width and height to be mapped to the nearZ. So when a ball is at Z=1f it has it's original size
When moving the ball into the screen so into the direction of farZ, the ball would be scaled down in order for the perspective to work. So a ball at Z=51f for instance, would appear smaller on my screen and I would need more balls to fill up the entire screen.
Now in order to do so, I'm looking for the purple boundaries
Actually I need these boundaries to fill the entire screen on different frustum sizes (width x height) while the frustum angle and Z distance for the balls is always the same
I guess I could use trig to calculate these purple boundaries (see blue triangle note)
Am I correctly marking the frustum angle, it being the vertical angle of the frustum?
Could someone elaborate on the green 1f and -1f values as I seem to have read something about it? Seems like some scalar that is used to resize the geometry within the frustum?
I actually want to be able to programmaticaly position geometry against the viewport borders within 3d space at any resolution/window for any arbitrary Android device.
Note: I have a flash background which uses a stage (visual area) with a known width x height at any resolution which makes it easy to position/scale assets either using absolute measurements or percentual measurements. I guess I'm trying to figure out how this system applies to OpenGL's perspective view.
I guess this post using gluUnproject answers the question.
Related
I am using OpenGLES20 with android and I would like to know how to do the following:
I think it's easier to explain with a picture...
How can I rectify this stretching. Note: I am working in 2D.
I've heard this problem is solved using something called a projection matrix. I have also read a StackOverflow question saying that the android documentation for setting up a projection matrix is not good. I have tried it personally and couldn't get it to work.
This question is extremely poorly put. On the left image you have rectangular view with coordinate system [0,1]x[0,1] and a correctly drawn triangle while on the right you have the same view with view coordinate system and stretched triangle... Taking this 2 things into consideration your triangle coordinates are already stretched to begin with (or there is an extra model view matrix). If they weren't stretched the triangle would be drawn correctly on the right image.
It is a very common issue your scene is stretched when dealing with different view ratios. In general to solve this you are looking for something like glOrtho which can define your coordinate system. The input parameters for this method are left, right, top and bottom and it is easiest to simply use screen coordinates (like presented on the right image). Another approach is to normalise this input to either [0,1]x[0,height/width] or [0,width/height]x[0,1]. These two methods represent "fit" and "fill" and which is which depends on width of view being smaller or larger then height (portrait, landscape).
When using a correct orthographical matrix your square will always be a square without using any additional matrices or multiplying the vertex arrays... In your case it seems you already multiplied your vertices so I suggest you remove that, all of it. If you can not and those vertices will continue to be scaled incorrectly I suggest you use model view matrix to rescale them.
I have a Android program which you type in equation and them program display you in "new" layout a graph, its like coordinate system.You have function line, x line, y line... like school basic, you know, easy one.
But if your equation numbers are to hight like: "x*x*40" your graph line is to big to be on display. So here i need yur help.
In android you can move picture up, down, left, right, zoom,... and i what to do same with a graph.I found a tutorails like this one:http://obviam.net/index.php/displaying-graphics-with-android/
,but this contains picture and i dont have picture!I have no picture or what so ever. Program works in Canvas and draw lines with command like this:"g.drawLine(x1, y1, x2, y2, color);" and the and it looks somethink like this in full screen:
http://grockit.com/blog/collegeprep/files/2009/12/14.JPG
So here is problem how to move like picture but its not a picture. In a lot of examples you must have a picture like R.drawable.image, but here are just calculated lines.
I have one idea how to do it, but its probably stupid:
-if you made a graph bigger than your screen (much bigger) and than do a screenshot, save like picture and than move like picture as in example
(if you need more explanation i can do it) sry if my English was bad :(
Thank you
Well, your best bet here is to use OpenGL. Otherwise, not only will you have problems with lines sometimes being to big or to small for a given screen, but also with different screen resolutions (your line might be too big for a 320x480 screen, but it will very well become too small for some of the new 1280x720 screens).
Here's what I would do:
make an opengl surface view with ORTHOGONAL projection
make orthogonal projection's "far side" be of high resolution, with fixed width, like maybe 1600
when surface is initialized, the opengl viewport is initted to screen's width and height
also the surface's far side's height will be set to keep the proportions with those of the screen.
you can then use Canvas and its drawxxx() methods to create a bitmap with your graph and text and whatever else you want to display.
then you use that bitmap to make a texture for a rectangular poligon that you draw in your orthogonal perspective.
now the size of the graph will always scale properlly with the user's screen size (like fit in all the time)
also now you can easily add zoom and scroll options
I'm working on a small app that uses sprites which are rendered using a canvas and simple drawBitmap.
Once the user touch the screen I need to know which sprite was clicked on.
I'm able to achieve this goal when I treat each sprite as a rectangular which has the width and height of the image.
However, some of the sprites takes only small portion of the entire rectangular and I would like to ignore when user clicked inside the rectangular but not on the internal shape.
Any ideas what could be a good method to do that?
Edit: Just to be more clear, lets say I have a sprite with size of 200x200, the sprite is an image of an airplane from above and the airplane has long long wings. Since the wings are long there will lots of "dead" areas in the sprite.
I would like to detect when user clicks the airplane itself only and not the "dead" area.
Thanks.
You will need to create a 2d array of all the pixels in the bitmap. Mask the pixels to either a 0(transparent) or a 1(has color). Then when you click inside of a rectangle you will just need to get the width offset and the height offset within the rectangle. This gives you your indices for mapping to the pixel array. Then check and see if the index in the pixel array contains a 1 for a value. If so then you clicked on the actual image. Does that make sense?
You have to check for the area where your Bitmap gets drawn, not another rectangular shape. Just treat every sprite (which may have different sizes) as a single rectangle, whose width and height equals to the width and height of the sprites.
Since you elaborated your question I'll give another suggestion.
When you have detected a click on the sprite, simply check (in the Bitmap's area) the current pixel via the Bitmap.getPixel() function. You can then easily check if the color at the specified position is something you're interested in, otherwise you can just skip detecting the touch.
I am trying to emulate point sprites in Android using OpenGL, specifically the characteristic of the size staying the same if the view is zoomed.
I do not want to use point sprites themselves as they pop out of the frustum when the "point" reaches the edge, regardless of size. I do not want to go down the route of Orthographic projection either.
Say I have a billboard square with a size of 1, when the use zooms in, I would need to decrease the size of the square so it looks the same size, if the user zooms out, I increase it. I have the projection and model matrices to hand if these are required as well as the FOV. My head just goes blank every time I sit down and think about it! Any ideas on the necessary algorithm?
Ok, By changing field of view to zoom into the environment I divide the quad size by (max_fov / current_fov). It works for me.
How to draw, say, a rectangle on the screen with it being proportional to the current device?
e.g. a rectangle, centered on the viewport, one pixel smaller than the screen on each border.
I can live with Orthogonal, but would like perspective (basically everything at Z=something should be proportional to the screen, and the upper parts of the elements being distorted by perspective)
I can calculate everything on my own if i know the relation... but i don't have a starting point.
I could experiment and get to a relation myself... i even resorted to that while coding for the Wii, but that's a really bad decision on Android and all the screen ratios/sizes out there...
seems that at z=1 you can fit in the screen all -1,-1-1,1 quads.