Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
213 views
in Technique[技术] by (71.8m points)

Using gluUnProject to map touches to x,y cords on z=0 plane in Android OpenGL ES 2.0

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?

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

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:

    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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

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

          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:

               NDCZ = 2.0 × ScreenZ - 1.0


Step 2:

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

          (Projection Matrix)-1  × NDCXYZ1  = ViewXYZW

          (ModelView Matrix)-1 × ViewXYZW = ObjectXYZW

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


                           ObjectXYZw = (Projection Matrix × ModelView Matrix)-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.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...