Canvas matrix transformation - java

I'm currently developing a game for android.
I have added buttons to allow the user to navigate the camera in the x-axis and zooming in and out.
To do this I'm using the following matrix code:
// c is the canvas..
Matrix m = c.getMatrix();
// Make sure that the ground is always at the bottom of the screen
m.setScale(zoom,zoom,0.0f,height);
m.preTranslate(camera_x, 0); // Change offset in x-direction
c.setMatrix(m);
This works on the emulator but gives me some weird results on my real device.
Can anyone tell me what's wrong with it? I find working with matrixes to be tricky, especially since there are many options available for the Matrix object (pre,post and set).
Thanks

The matrix you get from canvas.getMatrix() in a View's onDraw method already has some manipulations in it (to scale the view to your display size and translate the View's coordinates to the ViewRoot Surface coordinates.
By using matric.setScale(), rather than pre or postScale, you reset the matrix to the identity transform and then apply the scaling. This causes the initial transformation set up for onDraw to be lost. The matrix.preTranslate() is fine.
Alternatively, you could keep the setScale and use canvas.concat(m) to apply your matrix to the existing matrix.
(I can't keep the operation of pre and post applying transformations straight either.)

Related

Programmatically translate chart in MPAndroidChart

I'm trying to implement custom gesture logic for a CombinedChart in MPAndroidChart. Effectively, what I want to accomplish is to have a long press 'enable' highlighting of values but a short press & swipe just control panning / translating the chart (when zoomed). This would allow you to highlight values in a zoomed viewport without translating the chart (by long pressing before scrolling), but would also allow you to translate the chart if you wish by scrolling the view before the long press registers. I have figured out how to do all of the gesture interactions I want however I cannot figure out how to translate the chart.
All I'm really looking for is a API that allows me to translate the chart viewport by (dX, dY) in pixels but I can't seem to find anything. The closest I can find is CombinedChart.centerViewTo(...) but this expects you to center over data point values which if used when translating creates a bit of a staggered translation (as you cannot center over a value in-between two data points.
I can include code if needed, but I figured the code may be overly verbose for a simple API query.
So, I'll delete this when / if a better answer arises, but I found a way that suits my needs (yet may not be 'idiomatic'). What I did was the following:
(Given an offset in pixels of (dX, dY) and a CombinedChart named mChart...)
ViewPortHandler vph = mChart.getViewPortHandler();
Matrix transformation = vph.getMatrixTouch();
transformation.postTranslate(-dX, -dY); // unset the negs to make x / y inverted
vph.refresh(transformation, mChart, true);

OpenGL Objects Position and Physics

I have two simple questions:
First question:
Given is an object in OpenGL in an android application.
I want to apply phyics on the object like Gravtiy.
For this I've implemented a Public PositionVector {x,y,z,1.0f};
In the Object Object. So for example: Sphere.PositionVector = {0f,0f,0f,1f}
for the center of screen.
When I do the movement now, I have a modelMatrix and to update the Position should I multiply the modelMatrix with the PositionVector? But then I will still get 0,0,0,1.
mulitplyMV(tempVector,0,modelMatrix,0,PositionVector,0);
Where is the mistake? Or: What is the usual way to do this?
My goal is to have always the current positionvector of the Sphere.
Second question:
Does the shader have to do anything with the physics? Or may I calculate the gravtiy and the resulting vectors in the javaCode and apply then a translateMatrix to the modelMatrix?
Greetings,
Phil
So the first thing that really jumped out at me, was the question about movement. Normally if the movement was only for a visual effect, multiplying your position with a model matrix would be fine, but obviously you'll be wanting to handle collisions and that sort of thing as well.
What I normally do, is I keep track of each objects position, and update that value whenever it moves. When I draw my object, I first do a pass to leave out all objects that aren't in view and then only draw what my camera is seeing. So in this case, you'll only be drawing what is actually visible on the phone's screen at the moment.
So if you have a view matrix for your camera, to keep it simple for now you can leave out view culling, but you'll multiply your objects current position with the model matrix(in this case it is just an identity so it doesn't have any impact), and additionally with the view matrix and projection matrix. So its something like vec3 viewSpacePosition = projectionMatrix * viewMatrix * modelMatrix * position; (assuming I'm remembering that one correctly.)
Your physics calculations can be done either in your shaders or in your java code, though I recommend doing it on the java side while still getting the hang of things. OpenCL and transform feedback buffers can be quite tricky when you're still learning how some of the stuff works.
For the physics portion of your code, I would highly recommend taking a look an Glen Fiedler's series on game physics, you can find it here.
If you have any more questions, or if there is something you're still uncertain of let me know. :) Good luck!

How can I add a Continuous LOD for a single object?

I have got a single object.
A heightmap.
(Ignore the flag and the water - We have imaginations, right? ;) )
However, the issue is that I display this as a single display list. Therefore, I cannot "check the distance" of the map from the player, nor make the map less detailed, because I am only able to treat the map as a single object.
I have tried using shaders, however these are too late in the pipeline to be able to affect performance (If I use a shader to cut out EVERYTHING in the entire game, the game still lags as if it has everything else).
So, how can I add a Continuous Level Of Detail to the terrain, before it is too late, without splitting it into a ton of different objects (And even that wouldn't work well)?
You can split your map up into squares that you can display independently and only create those mesh objects when the player comes close enough to potentially render, and only render when inside the sight of the player.
besides that you can use a tesselation shader to create the continuous level of detail. it involves drawing flat quads and using the control shader to say how many vertices must be drawn and the evaluation shader to displace them upwards based on the height map (that you pass in as a texture).
or to be radical you can create a flat mesh that is fine grained in the center and decreases in detail further out, then using the vertex shader you can displace the vertices with the height map, the center remains under the camera but you use the position of the camera to offset the sampled coordinates of the height map (and texture map)

LWJGL Camera stretches and shrinks shapes

I've been looking around and i couldn't find an answer to this but what I have done is create a cube / box and the camera will squash and stretch depending on where I am looking at. This all seems to resolve it self when the screen is perfectly square but when I'm using 16:9 it stretches and squashes the shapes. Is it possible to change this?
16:9
and this is 500px X 500px
As a side question would it be possible to change the color of background "sky"?
OpenGL uses a cube [-1,1]^3 to represent the frustum in normalized device coordinates. The Viewport transform strechtes this in x and y direction to [0,width] and [0,height]. So to get the correct output aspect ratio, you have to take the viewport dimensions into account when transfroming the vertices into clip space. Usually, this is part of the projection matrix. The old fixed-function gluPerspective() function has a parameter to directly create a frustum for a given aspect ratio. As you do not show any code, it is hard to suggest what you actually should change, but it should be quite easy, as it boils down to a simple scale operation along x and y.
To the side question: That color is defined by the values the color buffer is set to when clearing the it. You can set the color via glClearColor().

Getting nearest focused object in opengl

I'm making a minecraft-inspired game through Java LWJGL, which is heavy into development already. However, I am not quite sure what method I would use to pick/highlight the nearest block in the exact center of the player's view frustum.
I am already storing frustum and positional data, which I could use.
I had a vague idea about using raycasting, but this seems to be unrelated based on what people have done with raycasting.
So which function or test would I use to determine this?
Raycasting will definitively work. You need to create a ray from the orientation of your camera and its position.
If your camera rotation matrix has no scale, the axis is the third column ( the z-axis ). Now depending on your convention, z axis may point to screen or to the world

Categories

Resources