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
gluPerspectivemight be a bit unfortunate in your case. This is a convenience from thefrustumoperation 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
frustumdirectly as it will be easier to compute:The frustum is defined by border parameters (
top,bottom,left,right),nearandfar. The rectangle with border parameters with a distance ofnearwill 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 viewfov=35in width then the distancedto this object should bed*tan(35/2)=viewWidth/2sod=viewWidth/(2*tan(35/2))which is now a relatively large value. The distancedcan now be used asfaras I assume that you will be drawing nothing behind the board, but just to be sure rather userd*2. (Increasing thefarwill decrease the precision of depth buffer but nothing else). So now you can definenearas something like0.1where then the scale of the object projection isscale=near/dand 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 distancedas exactly full screen. So insert thedinto thelookAtparameters 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 usingscreenWidth/10for dice size you will always be able to fit exactly 10 dices horizontally on the screen.