I'm creating a Dice roller app for Android. Using Kotlin, OpenGL-ES and jBullet. I've implemented the dice. Now I need to create walls, because otherwise the dice will roll out of the screen.
Because screens can have different aspect ratios, I'm trying to determine the position for the walls with glUnProject, but I can't figure it out.
The coordinates I receive are not correct.
gl.glViewport(0,0,width,height) //Reset The Current Viewport
gl.glMatrixMode(GL10.GL_PROJECTION) //Select The Projection Matrix
gl.glLoadIdentity() //Reset The Projection Matrix
//Calculate The Aspect Ratio Of The Window
GLU.gluPerspective(gl, 35.0f, width.toFloat() / height.toFloat(), 0.1f, 100.0f)
GLU.gluLookAt(gl,
0.0f, 30.0f, 0.0f, //Pos
0.0f, 0.0f, 0.0f, //Look at
0.0f, 0.0f, 1.0f //Up
);
gl.glMatrixMode(GL10.GL_MODELVIEW) //Select The Modelview Matrix
gl.glLoadIdentity() //Reset The Modelview Matrix
// Get matrices
gl.glGetFloatv(GL11.GL_PROJECTION_MATRIX, glProjectionMatrix,0)
gl.glGetFloatv(GL11.GL_MODELVIEW_MATRIX, glModelMatrix,0)
gl.glGetIntegerv(GL11.GL_VIEWPORT, glViewPort,0)
// Allocate matrices
var modelMatrix = glModelMatrix
var projMatrix = glProjectionMatrix
var view = glViewPort
// Pre allocate wall positions
var wallDown = FloatArray(4)
// The needed point
var wallDownP = Vector3f(view[2].toFloat(), view[3].toFloat(), 0.2888888f)
GLU.gluUnProject(wallDownP.x, wallDownP.y, wallDownP.z, modelMatrix, 0, projMatrix, 0, view, 0, wallDown, 0)
The gluPerspective might be a bit unfortunate in your case. This is a convenience from the frustum operation being defined by the field of view.
It is all doable from the setup you are having at the moment but I suggest you rather use frustum directly as it will be easier to compute:
The frustum is defined by border parameters (top, bottom, left, right), near and far. The rectangle with border parameters with a distance of near will be exactly full-screen. So it is best to start with the board itself. If you define the board to be of size (viewWidth, viewHeight) and want a field of view fov=35 in width then the distance d to this object should be d*tan(35/2)=viewWidth/2 so d=viewWidth/(2*tan(35/2)) which is now a relatively large value. The distance d can now be used as far as I assume that you will be drawing nothing behind the board, but just to be sure rather user d*2. (Increasing the far will decrease the precision of depth buffer but nothing else). So now you can define near as something like 0.1 where then the scale of the object projection is scale=near/d and the border values are then original values multiplied by the scale:
left = -screenWidth/2*scaleright = screenWidth/2*scaletop = screenHeight/2*scalebottom = -screenHeight/2*scaleSo having this setup you will se the rectangle of size (viewWidth, viewHeight) at a distance d as exactly full screen. So insert the d into the lookAt parameters and that should be all. The size of the dice may then be defined by the screen width so it appears similar on all devices. For instance using screenWidth/10 for dice size you will always be able to fit exactly 10 dices horizontally on the screen.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With