Как прочитать глубину пикселя с помощью OpenGL ES 1? (координата Z пикселя экрана)

#android #opengl-es

#Android #opengl-es

Вопрос:

Мне нужно передать gluUnProject значение winZ пикселя. чтобы получить значение winZ, мне нужно прочитать значение глубины в данном пикселе, это нормализованная координата z.

Способ сделать это с помощью C: glReadPixels(winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, amp;winZ);

Проблема в том, что я программирую с Android 1.5 и OpenGL ES 1, тогда у меня нет возможности использовать GL_DEPTH_COMPONENT и glReadPixels .

Как я могу получить глубину пикселя на экране?

Комментарии:

1. На Android вы используете OpenGL ES 1.x, а не OpenGL 1.0.

2. что вы имеете в виду? на Android 1.5 ?? ок, но у меня все та же проблема… как я могу получить значение winZ на Android 1.5 и opengl ES 1.x?

3. никто не может мне с этим помочь?

Ответ №1:

Решаемая, это просто невозможно сделать на OpenGL ES 1.x

Если кто-то найдет способ, скажите мне, но после нескольких недель поиска я просто думаю, что это невозможно.

Ответ №2:

Посмотрите этот хороший пост, я думаю, в нем есть то, что вы ищете: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;
}
  

Чтобы получить 3D-координаты точки x / y на экране, вам нужно вызвать новый метод только один раз для каждого пересечения с ближней и дальней плоскостями отсечения:

 // 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;

}
  

Комментарии:

1. Надеюсь, это то, что вы имели в виду 😉