在Android OpenGL ES 2.0中,使用gluUnProject将触摸映射到x,y连线在z=0平面上

时间:2022-12-25 19:15:53

I've drawn a grid at z=0 in OpenGL 2.0 ES, and just want to convert touch inputs to x/y coordinates on that plane. It seems like this is best done through ray tracing, which involves running gluUnProject on 0 and 1, then creating a ray, solving that ray for z=0?

我在OpenGL 2.0 ES中画了一个z=0的网格,我只想把触摸输入转换为平面上的x/y坐标。这似乎是最好的通过射线追踪来完成的,它涉及到在0和1上运行gluUnProject,然后创建一个射线,在z=0时解决这个射线?

I found this code, but it is OpenGL ES 1.0: i-schuetz / Android_OpenGL_Picking

我找到了这个代码,但它是OpenGL ES 1.0: I -schuetz / android_opengl_。

Screenshot of app running so you can see camera distortion.

应用程序的屏幕截图,你可以看到摄像机的失真。

My code on Github, only 4 files. The unproject function I'm trying to write is in MyGLRenderer.java:

我在Github上的代码,只有4个文件。我正在尝试编写的unproject函数是myglrender .java:

    public float[] unproject(float rx, float ry) {
            float rz = 1;
        float[] xyzw = {0, 0, 0, 0};
        int[] viewport = {0, 0, mDisplayWidth, mDisplayHeight};
        android.opengl.GLU.gluUnProject(
                        rx, ry, rz, // window coordinates
                        mViewMatrix, 0,
                        mProjectionMatrix, 0, 
                        viewport, 0,
                        xyzw, 0);
        xyzw[0] /= xyzw[3];
        xyzw[1] /= xyzw[3];
        xyzw[2] /= xyzw[3];
        xyzw[3] = 1;
        return xyzw;
    }

I would like this function to take an rx and ry for the screen, and return an rx and ry for the z=0 plane.

我希望这个函数在屏幕上取一个rx和ry,在z=0平面上返回一个rx和ry。

1 个解决方案

#1


2  

There is nothing particularly special about what gluUnProject (...) does. If you have all of the matrices and the viewport dimensions (x,y and width,height) I can walk you through the process of implementing it yourself.

gluUnProject(…)没有什么特别之处。如果你有所有的矩阵和viewport维度(x,y和宽度,高度),我可以带你走过实现它的过程。

NOTE: I tend to call each coordinate space by a different name than you might be used to, understand that screen space is another name for window space, view space is another name for eye space, object space is another name for model space.

注意:我倾向于对每个坐标空间使用不同的名称,理解屏幕空间是窗口空间的另一个名称,视图空间是眼睛空间的另一个名称,对象空间是模型空间的另一个名称。


Step 1:

   Screen Space to NDC space (Undo Viewport Transform)

          NDCX = (2.0 × (ScreenX - ViewportX) / ViewportW) - 1.0

NDCX =(2.0×(ScreenX - ViewportX)/ ViewportW)- 1.0

          NDCY = (2.0 × (ScreenY - ViewportY) / ViewportH)  - 1.0

NDCY =(2.0×(ScreenY - ViewportY)/ ViewportH)- 1.0

   Screen Space to NDC space (Undo Depth Range Mapping)

         Typically in screen space, the Depth Range will map z=0 to near and z=1 to far:

在屏幕空间中,深度范围将z=0映射到near, z=1映射到far:

               NDCZ = 2.0 × ScreenZ - 1.0

NDCZ = 2.0×ScreenZ - 1.0


Step 2:

   NDC space to Object space (Undo Projection, View and Model Transforms)

          (Projection Matrix)-1  × NDCXYZ1  = ViewXYZW

(投影矩阵)1×NDCXYZ1 = ViewXYZW

          (ModelView Matrix)-1 × ViewXYZW = ObjectXYZW

(ModelView矩阵)1×ViewXYZW = ObjectXYZW

                    This can actually be combined into a single step, as you will see below...

这实际上可以组合成单个步骤,如下所示……


                           ObjectXYZ w = (Projection Matrix × ModelView Matrix)-1 × NDCXYZ1

ObjectXYZ w =(投影矩阵×ModelView矩阵)1×NDCXYZ1


Now, you may notice that I crossed-out W in ObjectXYZ, we really do not care about this at all but the math will produce a pesky W value nevertheless. At this point, you can return the individual components of ObjectXYZ as your rX, rY and rZ.

#1


2  

There is nothing particularly special about what gluUnProject (...) does. If you have all of the matrices and the viewport dimensions (x,y and width,height) I can walk you through the process of implementing it yourself.

gluUnProject(…)没有什么特别之处。如果你有所有的矩阵和viewport维度(x,y和宽度,高度),我可以带你走过实现它的过程。

NOTE: I tend to call each coordinate space by a different name than you might be used to, understand that screen space is another name for window space, view space is another name for eye space, object space is another name for model space.

注意:我倾向于对每个坐标空间使用不同的名称,理解屏幕空间是窗口空间的另一个名称,视图空间是眼睛空间的另一个名称,对象空间是模型空间的另一个名称。


Step 1:

   Screen Space to NDC space (Undo Viewport Transform)

          NDCX = (2.0 × (ScreenX - ViewportX) / ViewportW) - 1.0

NDCX =(2.0×(ScreenX - ViewportX)/ ViewportW)- 1.0

          NDCY = (2.0 × (ScreenY - ViewportY) / ViewportH)  - 1.0

NDCY =(2.0×(ScreenY - ViewportY)/ ViewportH)- 1.0

   Screen Space to NDC space (Undo Depth Range Mapping)

         Typically in screen space, the Depth Range will map z=0 to near and z=1 to far:

在屏幕空间中,深度范围将z=0映射到near, z=1映射到far:

               NDCZ = 2.0 × ScreenZ - 1.0

NDCZ = 2.0×ScreenZ - 1.0


Step 2:

   NDC space to Object space (Undo Projection, View and Model Transforms)

          (Projection Matrix)-1  × NDCXYZ1  = ViewXYZW

(投影矩阵)1×NDCXYZ1 = ViewXYZW

          (ModelView Matrix)-1 × ViewXYZW = ObjectXYZW

(ModelView矩阵)1×ViewXYZW = ObjectXYZW

                    This can actually be combined into a single step, as you will see below...

这实际上可以组合成单个步骤,如下所示……


                           ObjectXYZ w = (Projection Matrix × ModelView Matrix)-1 × NDCXYZ1

ObjectXYZ w =(投影矩阵×ModelView矩阵)1×NDCXYZ1


Now, you may notice that I crossed-out W in ObjectXYZ, we really do not care about this at all but the math will produce a pesky W value nevertheless. At this point, you can return the individual components of ObjectXYZ as your rX, rY and rZ.