2016-06-08 22 views
5

Tôi đang tạo ứng dụng con lăn Dice cho Android. Sử dụng Kotlin, OpenGL-ES và jBullet. Tôi đã triển khai con xúc xắc. Bây giờ tôi cần phải tạo ra bức tường, bởi vì nếu không con xúc xắc sẽ lăn ra khỏi màn hình.Chuyển đổi tọa độ màn hình thành tọa độ OpenGL

Bởi vì màn hình có thể có tỷ lệ khung hình khác nhau, tôi đang cố gắng xác định vị trí cho các bức tường với glUnProject, nhưng tôi không thể tìm ra. Tọa độ tôi nhận được không chính xác.

gl.glViewport(0,0,width,height) //Reset The Current Viewport 
    gl.glMatrixMode(GL10.GL_PROJECTION) //Select The Projection Matrix 
    gl.glLoadIdentity()     //Reset The Projection Matrix 

    //Calculate The Aspect Ratio Of The Window 
    GLU.gluPerspective(gl, 35.0f, width.toFloat()/height.toFloat(), 0.1f, 100.0f) 

    GLU.gluLookAt(gl, 
      0.0f, 30.0f, 0.0f, //Pos 
      0.0f, 0.0f, 0.0f, //Look at 
      0.0f, 0.0f, 1.0f //Up 
    ); 

    gl.glMatrixMode(GL10.GL_MODELVIEW) //Select The Modelview Matrix 
    gl.glLoadIdentity()     //Reset The Modelview Matrix 

    // Get matrices 
    gl.glGetFloatv(GL11.GL_PROJECTION_MATRIX, glProjectionMatrix,0) 
    gl.glGetFloatv(GL11.GL_MODELVIEW_MATRIX, glModelMatrix,0) 
    gl.glGetIntegerv(GL11.GL_VIEWPORT, glViewPort,0) 

    // Allocate matrices 
    var modelMatrix = glModelMatrix 
    var projMatrix = glProjectionMatrix 
    var view = glViewPort 

    // Pre allocate wall positions 
    var wallDown = FloatArray(4) 

    // The needed point 
    var wallDownP = Vector3f(view[2].toFloat(), view[3].toFloat(), 0.2888888f) 

    GLU.gluUnProject(wallDownP.x, wallDownP.y, wallDownP.z, modelMatrix, 0, projMatrix, 0, view, 0, wallDown, 0) 
+0

Bạn nhận được 0.2888888f ở đâu? – 246tNt

+0

Nếu bạn muốn các bức tường, tại sao bạn chia viewport thành 2? Và bởi tường bạn có thể có nghĩa là các mặt của máy ảnh của bạn xem? – Spidfire

Trả lời

2

gluPerspective có thể là một chút không may trong trường hợp của bạn. Đây là một sự thuận tiện từ hoạt động frustum được xác định bởi trường xem.

Đó là tất cả doable từ các thiết lập bạn đang gặp vào lúc này nhưng tôi đề nghị bạn thay vì sử dụng frustum trực tiếp vì nó sẽ được dễ dàng hơn để tính toán:

Các frustum được xác định bởi các thông số biên giới (top, bottom, left , right), nearfar. Hình chữ nhật có tham số đường viền có khoảng cách là near sẽ chính xác ở chế độ toàn màn hình. Vì vậy, tốt nhất là hãy bắt đầu với bảng. Nếu bạn xác định bảng có kích thước (viewWidth, viewHeight) và muốn một trường có chiều rộng fov=35 thì khoảng cách d cho đối tượng này phải là d*tan(35/2)=viewWidth/2 vì vậy d=viewWidth/(2*tan(35/2)) hiện là giá trị tương đối lớn. Khoảng cách d hiện có thể được sử dụng làm far vì tôi giả định rằng bạn sẽ không vẽ gì phía sau bảng, nhưng chỉ để chắc chắn là người dùng d*2. (Tăng far sẽ làm giảm độ chính xác của bộ đệm độ sâu nhưng không có gì khác). Vì vậy, bây giờ bạn có thể định nghĩa near như một cái gì đó giống như 0.1 nơi sau đó quy mô của các dự báo đối tượng là scale=near/d và các giá trị biên giới sau đó được giá trị ban đầu nhân với quy mô:

  • left = -screenWidth/2*scale
  • right = screenWidth/2*scale
  • top = screenHeight/2*scale
  • bottom = -screenHeight/2*scale

Vì vậy, có thiết lập này bạn sẽ có hình chữ nhật có kích thước (viewWidth, viewHeight) ở khoảng cách d chính xác như toàn màn hình. Vì vậy, hãy chèn các thông số d vào thông số lookAt và điều đó sẽ là tất cả. Kích thước của con xúc xắc sau đó có thể được xác định bởi chiều rộng màn hình để nó xuất hiện tương tự trên tất cả các thiết bị. Ví dụ bằng cách sử dụng screenWidth/10 cho kích thước súc sắc, bạn sẽ luôn có thể vừa với chính xác 10 dices theo chiều ngang trên màn hình.

+0

Cảm ơn, làm việc cho tôi. –

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