NullPointerException
NullPointerException

Reputation: 37577

How to read the depth of a pixel with OpenGL ES 1 ? (Z coordinate of a pixel of the screen)

I need to pass to gluUnProject the winZ value of a pixel. to obtain the winZ value I need to read the depth value at a given pixel, this is a normalised z coordinate.

The way to do it is this with C: glReadPixels(winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);

The problem is that I'm programming with Android 1.5 and OpenGL ES 1, then I don't have the possibility to use GL_DEPTH_COMPONENT and glReadPixels.

How can I obtain the depth of a pixel on the screen?

Upvotes: 3

Views: 670

Answers (2)

JY2k
JY2k

Reputation: 2909

Check out this nice post I think it has what your looking for: http://afqa123.com/2012/04/03/fixing-gluunproject-in-android-froyo/

A custom GLunproject which enables you to calculate the near and far vectors:

private boolean unProject(float winx, float winy, float winz,
                      float[] modelMatrix, int moffset,
                      float[] projMatrix, int poffset,
                      int[] viewport, int voffset,
                      float[] obj, int ooffset) {
 float[] finalMatrix = new float[16];
float[] in = new float[4];
float[] out = new float[4];

Matrix.multiplyMM(finalMatrix, 0, projMatrix, poffset,
  modelMatrix, moffset);
if (!Matrix.invertM(finalMatrix, 0, finalMatrix, 0))
return false;

in[0] = winx;
in[1] = winy;
in[2] = winz;
in[3] = 1.0f;

// Map x and y from window coordinates
in[0] = (in[0] - viewport[voffset]) / viewport[voffset + 2];
in[1] = (in[1] - viewport[voffset + 1]) / viewport[voffset + 3];

// Map to range -1 to 1
in[0] = in[0] * 2 - 1;
in[1] = in[1] * 2 - 1;
in[2] = in[2] * 2 - 1;

Matrix.multiplyMV(out, 0, finalMatrix, 0, in, 0);
if (out[3] == 0.0f)
  return false;

out[0] /= out[3];
out[1] /= out[3];
out[2] /= out[3];
obj[ooffset] = out[0];
obj[ooffset + 1] = out[1];
obj[ooffset + 2] = out[2];

return true;
}

In order to get the 3D coordinates of a point x/y on the screen, you only have to call the new method once for each intersection with the near and far clipping planes:

// near clipping plane intersection
float[] objNear = new float[4];
unProject(screenX, screenY, 0.1f,
        viewMatrix, 0, projectionMatrix, 0, view, 0, objNear, 0);

// far clipping plane intersection
float[] objFar = new float[4];
unProject(screenX, screenY, 1.0f,
        viewMatrix, 0, projectionMatrix, 0, view, 0, objFar, 0);

You can then calculate the difference vector (objFar - objNear) and check what location in 3D space corresponds to the screen event. This is a simple function i use to find the distance between the two vectors:

    public float distanceBetweenVectors(float[] vec1, float[] vec2){
    float distance = 0;
    // Simple math
    distance = (float) Math.sqrt(
            Math.pow((vec1[0]-vec2[0]), 2) +
            Math.pow((vec1[1]-vec2[1]), 2) +
            Math.pow((vec1[2]-vec2[2]), 2) +
            Math.pow((vec1[3]-vec2[3]), 2)
            );
    return distance;

}

Upvotes: 1

NullPointerException
NullPointerException

Reputation: 37577

Solved, it is simply impossible to do it on OpenGL ES 1.x

If someone find the way, tell me, but after weeks of searching i simply think that it is impossible.

Upvotes: 1

Related Questions