I am trying to develop a simple game app for Android using OpenGL as my base. So far, I have a very basic setup with some shapes and an object class that instantiates a square. The camera can be panned by touching and dragging, and zoomed using two fingers. I have been trying to look at many tutorials on how to use gluUnProject to take touch coordinates and transform them into world coordinates. So far, I have been getting very mixed results, such as inaccurate coordinates as the touch reaches the screen edges. Here is the base of my touch detection code for reference:
public int selectEntity(float x, float y)
{
//x and y parameters are the raw touch coordinates
for(GameObj entity: entities)
{
System.out.println("Coordinates of touch before matrix transformation: X: " + x + ", Y: " + y);
y = mView[3] - y; //flipping y to match y origin
System.out.println("Coordinates of touch after flipping Y: X: " + x + ", Y: " + y);
//I have used two matrices to hold unprojected transforms:
//nearPos is calculated using nearPlane value of 1
//farPos is calculate using farPlane value of 10
float[] nearPos = new float[4];
float[] farPos = new float[4];
//I pass the MVPMatrix as the 4th parameter currently, although
//everywhere else that I've seen, the modelView matrix is used,
//but I have no idea how that is acquired. I have tried using
//GLES11 to fetch it but that gave me no results. I have also
//tried passing the View Matrix, but that gave worse results.
//mView holds [0,0,width,height] of screen
boolean unprojectedNear = (GLU.gluUnProject(x, y, 1,
mMVPMatrix, 0, mProjectionMatrix, 0,
mView, 0, nearPos, 0) == GLES20.GL_TRUE);
boolean unprojectedFar = (GLU.gluUnProject(x, y, 10,
mMVPMatrix, 0, mProjectionMatrix, 0,
mView, 0, farPos, 0) == GLES20.GL_TRUE);
if (unprojectedNear && unprojectedFar)
{
System.out.println("Converted point coords at farpos: X: " + farPos[0]/farPos[3] + ", Y: " + farPos[1]/farPos[3] + ", Z(?): " + farPos[2]/farPos[3] );
System.out.println("Converted point coords at nearpos: X: " + nearPos[0]/nearPos[3] + ", Y: " + nearPos[1]/nearPos[3] + ", Z(?): " + nearPos[2]/nearPos[3] );
//dividing by the w component
nearPos[0] /= nearPos[3];
nearPos[1] /= nearPos[3];
nearPos[2] /= nearPos[3];
nearPos[3] /= nearPos[3];
farPos[0] /= farPos[3];
farPos[1] /= farPos[3];
farPos[2] /= farPos[3];
farPos[3] /= farPos[3];
//It is to my belief that the correct (x,y) world coordinates should be contained in either
//(nearPos[0],nearPos[1]), or in (farPos[0],farPos[1])
}
//I have tried to use farPos instead of nearPos here with inconcusive results
if(entity.touched(nearPos[0], nearPos[1]))
{
System.out.println("I AM AN OBJECT AND I HAVE BEEN TOUCHED");
}
}
return -1;
}
I am not too familiar with the intricacies of OpenGL, but I think my issue may lie in not being able to properly import the modelView matrix. The concept itself still confuses me also, is it just the multiplication of the object's model by the view matrix? Would it not be sufficient to pass the view matrix? Also, I'm planning to make my game in 2D, so in this case, would I really need to worry about using the far and near plane values due to the orthographic projection?
If any other piece of my code would help understand this problem better, I'd be happy to provide it.
Thank you.