我需要传递gluUnProject
像素的winZ值。为了获得winZ值,我需要读取给定像素的深度值,这是一个标准化的z坐标。
这样做的方法是使用C:glReadPixels(winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
问题是我使用Android 1.5和OpenGL ES 1进行编程,然后我无法使用GL_DEPTH_COMPONENT
和glReadPixels
。
如何获得屏幕上像素的深度?
答案 0 :(得分:1)
解决了,在OpenGL ES 1.x
上完全不可能如果有人找到了方法,请告诉我,但经过数周的搜索,我认为这是不可能的。
答案 1 :(得分:1)
看看这篇不错的帖子我觉得它有你想要的东西: http://afqa123.com/2012/04/03/fixing-gluunproject-in-android-froyo/
自定义GLunproject,可用于计算近和远向量:
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;
}
为了在屏幕上获得点x / y的3D坐标,您只需要为与近剪裁平面和远剪裁平面的每个交点调用一次新方法:
// 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);
然后,您可以计算差异向量(objFar - objNear)并检查3D空间中的哪个位置对应于屏幕事件。 这是一个简单的函数,我用它来找到两个向量之间的距离:
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;
}