I'm don't understand how we can positioning objects with opengl. All transformation values is between "-1.0f" - "1.0f". I'm made some game using with surfaceview. And I can simply change and defined objects x and y position. example; if android screen width is 480px, so my box max x values is 480. but how can I do this on opengl? How make the limits and how use pixel or dpi metrics? how can I change a box position on my finger touch place?
First off, glTranslate and most if not all transformation values are not restricted to values between "-1.0" to "1.0". Being able to move an object 10px to the left or right is going to require setting up your transformation matrices properly. Below is the order of how OpenGL manipulates vertexes you give it.
[(4x4) Projection][(4x4) View][(4x4) Model]*[(4x1) your vertex]
You would probably want to use glOrtho(0.0,width,0.0,height,-1.0,1.0) to setup your Projection matrix. You can leave the View matrix as the identity matrix. Finally, you can use your model matrix to translate, rotate, and scale your objects at a pixel scale. Now a glTranslatef(10.0,0.0,0.0) on the Model matrix should move your object 10px in the x direction. Alternatively, you could leave the Model matrix as the identity matrix, and let your vertexes represent pixel coordinates.
You can look at this powerpoint, and on slide 4 you can see a nice graphic detailing whats happening to your vertexes. https://wiki.engr.illinois.edu/download/attachments/195761441/OpenGL.pptx?version=1&modificationDate=1326820017000
to change the position of an item in openGL you use glTranslate and for the size you can set the size of the rectangle you are using whenever you are drawing it but as far as I know, you cannot limit the size of an object, but you could do some check before drawing the rectangle/box to know if the size the user want to resize is bigger than your Android device screen, and if so then do nothing (or you could show a toast telling the user that it cannot get bigger)
Also this could help you, relation between pixels and gl.gltranslatef(floatx,y,z)? but allow me to quote a bit of it:
As such, when you do a glTranslate, the distance by which a particular
object will move (in terms of pixels) will depend on its distance from
the viewer. The further away it is from the viewer, the fewer pixels a
particular sideways or up/down will translate to.
Related
Over the past few weeks I've been attempting to learn the libGDX library. I'm finding it hard, especially for my first endeavor toward game development, to comprehend the system of Camera/viewport relationships. One line of code that I've been told to use, and the API mentions, is:
batch.setProjectionMatrix(camera.combined);
Despite a good 4 hours of research, I'm still lacking a complete understanding of the functionality of this code. It is to my basic understanding that it "tells" the batch where the camera is looking. My lack of comprehension is depressing and angering, and I'd appreciate if anyone could assist me. Another issue with the code snippet is that I'm unsure of when it's necessary to implement (in the render method, create method, etc).
Consider taking a picture with a camera. E.g. using your smartphone camera taking a picture of a bench in the park. When you do that, then you'll see the bench in the park on the screen of your smartphone. This might seem very obvious, but let's look at what this involves.
The location of the bench on the picture is relative to where you were standing when taking the photo. In other words, it is relative to the camera. In a typical game, you don't place object relative to the object. Instead you place them in your game world. Translating between your game world and your camera, is done using a matrix (which is simply a mathematical way to transform coordinates). E.g. when you move the camera to the right, then the bench moves to the left on the photo. This is called the View matrix.
The exact location of the bench on the picture also depends on the distance between bench and the camera. At least, it does in 3D (2D is very similar, so keep reading). When it is further away it is smaller, when it is close to the camera it is bigger. This is called a perspective projection. You could also have an orthographic projection, in which case the size of the object does not change according to the distance to the camera. Either way, the location and size of the bench in the park is translated to the location and size in pixels on the screen. E.g. the bench is two meters wide in the park, while it is 380 pixels on the photo. This is called the projection matrix.
camera.combined represents the combined view and projection matrix. In other words: it describes where things in your game world should be rendered onto the screen.
Calling batch.setProjectionMatrix(cam.combined); instruct the batch to use that combined matrix. You should call that whenever the value changes. This is typically when resize is called and also whenever you move or otherwise alter the camera.
If you are uncertain then you can call that in the start of your render method.
The other answer is excellent, but I figure a different way of describing it might help it to click.
You generally deal with your game in "world space", a coordinate system that is analogous to the real world. In linear algebra, you can convert points in space from one coordinate system to another by multiplying the point's coordinates by a matrix that represents the relation between two coordinate systems.
The view matrix is multiplied by a point to convert it from world space to camera space (the camera's point of view). The projection matrix is used to convert a point from camera space to screen space (the flat 2D rectangle of your device's screen). When you call update() on a camera in Libgdx, it applies your latest changes to position, orientation, viewport size, field of view, etc. to its view and projection matrices so they can be used in shaders.
You rarely need to deal with stuff in camera space in 2D, so SpriteBatch doesn't need separate view and projection matrices. They can be combined into a single matrix that converts straight from world space to screen space, which is already done automatically in the Camera, hence the camera.combined matrix.
SpriteBatch has a default built-in shader that multiplies this projection matrix by all the vertices of your sprites so they will be properly mapped to the flat screen.
You should call setProjectionMatrix whenever you have moved the camera or resized the screen.
There is a third type of matrix called a model matrix that is used for 3D stuff. A model matrix describes the model's orientation, scale, and position in world space. So it is multiplied by coordinates in the model to move them from local space to world space.
Take for example a basic sidescrolling game. As the player moves to the side, the camera pans to follow them. This means that where objects are in the world doesn't necessarily correspond to where they are on the screen, since the screen and the world move relative to each other.
Here's an example: say your screen is 100px*100px square (for some reason). You place an object at position (50, 0), so it's now in the middle and at the bottom of the screen. Now say you move your player over to the right, and the whole screen pans to follow the player. This means that the object you placed earlier should have moved left on the screen. So it's still at (50, 0) in the world, since it didn't actually move relative to the rest of the scenery, but it should now be drawn at, say, (10, 0) on the screen, since which part of the world the screen is looking at has changed. This is the difference between "worldspace" (where an object is in the world) and "screenspace" (where the object is drawn on the actual display).
When you try to draw with a SpriteBatch, it is by default going to assume worldspace coordinates are the same as screenspace coordinates: when you say "draw at (50, 0)", it's going to draw the object at (50, 0) on the screen. Even if the camera moves, it's always going to draw at (50, 0) on the screen, so as the camera pans, the object will follow and stay stuck to the same place on the screen.
Since you usually don't want that, you give the SpriteBatch a projection matrix, which is a transformation matrix that tells how to convert screenspace coordinates to worldspace coordinates, and vice versa. This way, when you tell the batch "draw at (50, 0)", it can look at the matrix it got from the camera and see that, since the camera has moved, (50, 0) in the world actually means (10, 0) on the screen, and it will draw your sprite in the right place.
While working on Projectiles I thought that it would be a good idea to rotate the sprite as well, to make it look nicer.
I am currently using a 1-Dimensional Array, and the sprite's width and height can and will vary, so it makes it a bit more difficult for me to figure out on how to do this correctly.
I will be honest and straight out say it: I have absolutely no idea on how to do this. There have been a few searches that I have done to try to find some stuff, and there were some things out there, but the best I found was this:
DreamInCode ~ Rotating a 1-dimensional Array of Pixels
This method works fine, but only for square Sprites. I would also like to apply this for non-square (rectangular) Sprites. How could I set it up so that rectangular sprites can be rotated?
Currently, I'm attempting to make a laser, and it would look much better if it didn't only go along a vertical or horizontal axis.
You need to recalculate the coordinate points of your image (take a look here). You've to do a matrix product of every point of your sprite (x, y) for the rotation matrix, to get the new point in the space x' and y'.
You can assume that the bottom left (or the bottom up, depends on your system coordinate orientation) of your sprite is at (x,y) = (0,0)
And you should recalculate the color too (because if you have a pure red pixel surrounded by blue pixel at (x,y)=(10,5) when you rotate it can move for example to (x, y)=(8.33, 7.1) that it's not a real pixel position because pixel haven't float coordinate. So the pixel at real position (x, y)=(8, 7) will be not anymore pure red, but a red with a small percentage of blue)... but one thing for time.
It's easier than you think: you only have to copy the original rectangular sprites centered into bigger square ones with transparent background. .png files have that option and I think you may use them.
I'm experimenting with LibGDX and 3D in a projection view. Right now I'm looking at how to determine the outermost bounds of my viewport in world space at z=0.0, in order to draw coordinate grid no larger than necessary. However, I seem to have outpaced my education in that I haven't taken a formal linear algebra class and am still a little fuzzy on matrix math.
Is there a way to determine where I should start and stop drawing lines without resorting to using picking and drawing a transparent plane to intersect with?
LibGDX's unproject function takes screen coordinates in a Vector3 and returns a Vector3 in world space from the near clipping plane to the far, given the provided z. However, given that I have a translated and rotated Camera (an encapsulation of the viewprojection matrix and a slew of convenience methods), it occurs to me that I can't pick an arbitrary z to put in the window coordinate vector and just set it to 0.0 after unprojection, as that point probably won't be the furthest viewable point in the viewport. So how do I know what z value to use in the window coordinate that will give the the x and y I need in world space that's at z=0.0?
EDIT (UPDATE):
So apparently it looks like the problem I'm looking at is plane intersection, which would require ray tracing. So now I suppose my question is this: is ray tracing 4 times per render loop (or, I suppose whenever the camera has moved) worth the payoff of being able to dynamically draw a worldspace coordinate grid no larger than the viewport? If not, is there a cheaper algorithm I can use to estimate where I should start and stop drawing lines?
I'm working on making a 2D isometric engine in Java because I like suffering, I guess. Anyways, I'm getting into collision detection and I've hit a bit of a problem.
Characters in-game are not restricted to movement from tile to tile - they move freely. My problem is that I'm not sure how to stop a player from colliding with, say, a crate, without denying them access to the tile.
For instance, say the crate was on .5 of a tile, and then the rest of the crate was off the tile, I'd like the player to be able to move on to the free .5 of the tile instead of the entire tile becoming blocked.
The problem I've hit is that I'm not sure how to approximate the size of the footprint of the object. Using the image's dimensions don't work very well, since the object's "height" in gamespace translates to additional floorspace being taken up by the image.
How should I estimate an object's size? Mind, I don't need pixel-perfect detection. A rhombus would work fine.
I'm happy to provide any code you might need, but this seems like a math issue.
From the bounding rectangle of the sprite, you can infer the height of a rhombus that fits inside, but you cannot precisely determine the two dimensions on the floor, as each dimension contributes equally to width and height of the sprite. However, if you assume that the base of the rhombus square then you can determine the length of its side as well.
If the sprite is W pixels wide and H pixels high, the square base of the rhombus has a side of W / sqrt(3) and the height of the rhombus will be H - (W / sqrt(3)). This image of some shapes in isometric projection can be helpful to understand why these formulas work.
I am generating very large hex grids (up to 120k total hexes at 32px wide hexes results in over 12k wide images) and I'm trying to find an efficient way to bind these to OpenGL textures in libgdx. I was thinking of using multiple FBOs and breaking the grid up as necessary into tiles, but I'm not sure how to ensure continuity between the FBOs. I can't start with one massive FBO, because that is backed up by a texture so it would fail from trying to load it to video memory. I can't use a standard bitmap on the heap because I need the drawing functionality of an OpenGL surface.
So what I was thinking was I would need to overdraw on the FBOs and somehow pick up on the next FBO exactly where the previous left off. However I'm not sure how to go about this. I'm drawing the hex grid with a series of hexagonal meshes, FYI.
Of course, there's probably some other much simpler and more efficient way to do this that I'm not even thinking of, which is why I pose this question to you fine people!
You have to draw it in pieces. You need to be able to draw your hex grid from an arbitrary position. This means being able to compute which hexes to draw based on a rectangle overlaid over the map. This isn't a hard problem, and I wouldn't worry too much about drawing extra stuff off-screen. You should master this ability to view the hexmap from any position before moving on.
Once you've mastered that, it's really simple.
Draw the top-left corner and store the pixel data. Then move the area you're drawing over exactly one image width. Draw and store that. Move the area over one image width. Draw and store it. Keep doing that until you've covered the entire width.
Move down one image height and repeat the process. Once you've run out of width and height, you're done. Save your mega-huge image.
You don't need FBOs for this. You could draw it to the screen if you wanted. Though if you want maximum performance, I would suggest using FBOs, double buffering them, and using glReadPixels though a pixel buffer object. That should cut down a lot on latency.