2012-06-11 53 views
20

Tôi đang tạo ứng dụng Android sử dụng OpenGL ES 2.0 và tôi đã chạy vào tường. Tôi đang cố gắng chuyển đổi tọa độ màn hình (nơi người dùng chạm) vào tọa độ thế giới. Tôi đã cố gắng đọc và chơi xung quanh với GLU.gluUnProject nhưng tôi hoặc là làm điều đó sai hoặc chỉ không hiểu nó.Màn hình Android OpenGL ES 2.0 tọa độ theo tọa độ thế giới

Đây là nỗ lực của tôi ....

public void getWorldFromScreen(float x, float y) { 
    int viewport[] = { 0, 0, width , height}; 

    float startY = ((float) (height) - y); 
    float[] near = { 0.0f, 0.0f, 0.0f, 0.0f }; 
    float[] far = { 0.0f, 0.0f, 0.0f, 0.0f }; 

    float[] mv = new float[16]; 
    Matrix.multiplyMM(mv, 0, mViewMatrix, 0, mModelMatrix, 0); 

    GLU.gluUnProject(x, startY, 0, mv, 0, mProjectionMatrix, 0, viewport, 0, near, 0); 
    GLU.gluUnProject(x, startY, 1, mv, 0, mProjectionMatrix, 0, viewport, 0, far, 0); 

    float nearX = near[0]/near[3]; 
    float nearY = near[1]/near[3]; 
    float nearZ = near[2]/near[3]; 

    float farX = far[0]/far[3]; 
    float farY = far[1]/far[3]; 
    float farZ = far[2]/far[3]; 
} 

Số Tôi nhận được dường như không đúng, đây là cách đúng đắn để sử dụng phương pháp này? Nó có hoạt động với OpenGL ES 2.0 không? Tôi có nên làm cho ma trận mô hình một ma trận nhận dạng trước khi tính toán này (Matrix.setIdentityM (mModelMatix, 0))?

Theo dõi, nếu điều này đúng, làm cách nào để chọn đầu ra Z? Về cơ bản, tôi luôn biết khoảng cách mà tôi muốn thế giới tọa độ, nhưng tham số Z trong GLU.gluUnProject dường như là một dạng nội suy nào đó giữa mặt phẳng gần và xa. Nó chỉ là một nội suy tuyến tính?

Cảm ơn trước

Trả lời

21
/** 
    * Calculates the transform from screen coordinate 
    * system to world coordinate system coordinates 
    * for a specific point, given a camera position. 
    * 
    * @param touch Vec2 point of screen touch, the 
     actual position on physical screen (ej: 160, 240) 
    * @param cam camera object with x,y,z of the 
     camera and screenWidth and screenHeight of 
     the device. 
    * @return position in WCS. 
    */ 
    public Vec2 GetWorldCoords(Vec2 touch, Camera cam) 
    { 
     // Initialize auxiliary variables. 
     Vec2 worldPos = new Vec2(); 

     // SCREEN height & width (ej: 320 x 480) 
     float screenW = cam.GetScreenWidth(); 
     float screenH = cam.GetScreenHeight(); 

     // Auxiliary matrix and vectors 
     // to deal with ogl. 
     float[] invertedMatrix, transformMatrix, 
      normalizedInPoint, outPoint; 
     invertedMatrix = new float[16]; 
     transformMatrix = new float[16]; 
     normalizedInPoint = new float[4]; 
     outPoint = new float[4]; 

     // Invert y coordinate, as android uses 
     // top-left, and ogl bottom-left. 
     int oglTouchY = (int) (screenH - touch.Y()); 

     /* Transform the screen point to clip 
     space in ogl (-1,1) */  
     normalizedInPoint[0] = 
     (float) ((touch.X()) * 2.0f/screenW - 1.0); 
     normalizedInPoint[1] = 
     (float) ((oglTouchY) * 2.0f/screenH - 1.0); 
     normalizedInPoint[2] = - 1.0f; 
     normalizedInPoint[3] = 1.0f; 

     /* Obtain the transform matrix and 
     then the inverse. */ 
     Print("Proj", getCurrentProjection(gl)); 
     Print("Model", getCurrentModelView(gl)); 
     Matrix.multiplyMM(
      transformMatrix, 0, 
      getCurrentProjection(gl), 0, 
      getCurrentModelView(gl), 0); 
     Matrix.invertM(invertedMatrix, 0, 
      transformMatrix, 0);  

     /* Apply the inverse to the point 
     in clip space */ 
     Matrix.multiplyMV(
      outPoint, 0, 
      invertedMatrix, 0, 
      normalizedInPoint, 0); 

     if (outPoint[3] == 0.0) 
     { 
      // Avoid /0 error. 
      Log.e("World coords", "ERROR!"); 
      return worldPos; 
     } 

     // Divide by the 3rd component to find 
     // out the real position. 
     worldPos.Set(
      outPoint[0]/outPoint[3], 
      outPoint[1]/outPoint[3]); 

     return worldPos;  
    } 

Thuật toán được giải thích thêm here.

+2

giải pháp của tôi là tất cả trong C++. Chỉ cần quét qua câu trả lời này, có vẻ đúng với tôi. Vì vậy, tôi sẽ không đăng câu trả lời. :] – TheBuzzSaw

1

Hy vọng rằng câu hỏi của tôi (và câu trả lời) sẽ giúp bạn ra ngoài:

How to find absolute position of click while zoomed in

Nó đã không chỉ mã nhưng cũng có sơ đồ và sơ đồ và sơ đồ giải thích nó :) Hãy cho tôi lứa tuổi để tìm ra nó là tốt.

1

IMHO không cần phải thực hiện lại chức năng này ... Tôi đã thử nghiệm với giải pháp của Erol và nó hoạt động, vì vậy cảm ơn rất nhiều vì nó Erol. Hơn nữa, tôi chơi với

 Matrix.orthoM(mtrxProjection, 0, left, right, bottom, top, near, far); 

và nó hoạt động tốt cũng như trong ví dụ Noob nhỏ của tôi dự án 2D OpenGL ES 2.0:

Các vấn đề liên quan