2012-04-09 25 views
0

我正在嘗試在我的遊戲中使用gluProject。我找到了一種方法來使用它,但我不知道如何處理旋轉。Java - GluProject如何處理旋轉

這裏是我做的代碼:

public static Vector2 getScreenCoordinates(float x, float y, float z, int height, int width) 
{ 
    FloatBuffer screen_coords = GLAllocation.createDirectFloatBuffer(4); 
    IntBuffer viewport = GLAllocation.createDirectIntBuffer(16); 
    FloatBuffer modelview = GLAllocation.createDirectFloatBuffer(16); 
    FloatBuffer projection = GLAllocation.createDirectFloatBuffer(16); 

    GL11.glGetFloat(2982, modelview); 
    GL11.glGetFloat(2983, projection); 
    GL11.glGetInteger(2978, viewport); 

    boolean result = GLU.gluProject(x, y, z, modelview, projection, viewport, screen_coords); 
    if (result) 
    { 
     float screen_x = screen_coords.get(0); 
     float screen_y = screen_coords.get(1); 
     float scrren_z = screen_coords.get(2); 

     screen_y -= height/2; 
     screen_y = -screen_y; 
     screen_y += height/2; 

     return new Vector2(screen_x, screen_y); 
    } 
    else 
    { 
     System.out.printf("Failed to convert 3D coords to 2D screen coords"); 
     return null; 
    } 
} 

所以xyz都在我的3D地圖COORDS。我的窗口大小爲heightwidth

如何修改它以處理旋轉(偏航和俯仰)?

謝謝。


這是我的新代碼:

public Vector2 worldToScreen(double x, double y, double z, int yaw, int pitch) 
{ 
    // Initialize the result buffer 
    FloatBuffer screen_coords = GLAllocation.createDirectFloatBuffer(4); 

    // Init the OpenGL buffers 
    IntBuffer viewport = GLAllocation.createDirectIntBuffer(16); 
    FloatBuffer modelview = GLAllocation.createDirectFloatBuffer(16); 
    FloatBuffer projection = GLAllocation.createDirectFloatBuffer(16); 

    // Add the rotation 
    GL11.glRotatef(yaw, 0, 0, 1); 
    GL11.glRotatef(pitch, 1, 0, 0); 

    // Get the OpenGL data 
    GL11.glGetFloat(2982, modelview); 
    GL11.glGetFloat(2983, projection); 
    GL11.glGetInteger(2978, viewport); 

    // Remove the rotation 
    GL11.glRotatef(-yaw, 0, 0, 1); 
    GL11.glRotatef(-pitch, 1, 0, 0); 

    // Calculate the screen position 
    boolean result = GLU.gluProject(x, y, z, modelview, projection, viewport, screen_coords); 

    if (result) 
    { 
     if ((screen_coords.get(0) < -1.0f) || (screen_coords.get(0) > 1.0f) || (screen_coords.get(1) < -1.0f) || (screen_coords.get(1) > 1.0f)) 
      return null; 

     int window_half_width = getWidth()/2; 
     int window_half_height = getHeight()/2; 

     int screen_x = window_half_width + (window_half_width * -screen_coords.get(0)); 
     int screen_y = window_half_height + (window_half_height * screen_coords.get(1)); 

     System.out.printf("(Full Screen/No bounds) [" +x+ ", " +y+ ", " +z+ "] gives [" +screen_coords.get(0)+ ", " +screen_coords.get(1)+ "]"); 
     System.out.printf("(Every Time) [" +x+ ", " +y+ ", " +z+ "] gives [" +screen_x+ ", " +screen_y+ "]"); 
     return new Vector2(screen_x, screen_y); 
    } 
    else 
    { 
     System.out.printf("Failed to convert 3D coords to 2D screen coords"); 
     return null; 
    } 
} 

是正確的嗎?

+0

我想你的投影矩陣必須包含旋轉。所以你必須在獲得投影矩陣之前應用相關的變換(旋轉)。 – 2012-04-09 21:30:37

+0

感謝您的回答。我的代碼中有以下幾行:'GL11.glRotatef(yaw,0,0,1);'''GL11.glRotatef(pitch,1,0,0);'但我擁有的是旋轉的菜單。(我在GL11.glGetInteger(2978,viewport);' – Manitoba 2012-04-10 07:09:56

+0

'下面添加了這些行:我的地圖座標是這樣的:X,Y代表地面,Z代表高度 – Manitoba 2012-04-10 07:27:42

回答

1

偏航是圍繞y軸的旋轉(指向上),而間距是圍繞x軸的旋轉。

GL11.glRotatef(pitch, 1, 0, 0); 
GL11.glRotatef(yaw, 0, 1, 0); 

推動/彈出投影矩陣也可能更快,並且您應該處於正確的矩陣模式。 (你的模型視圖矩陣和你的投影矩陣必須是正確的)。

GL11.glPushMatrix(); 
// Camera rotations 
GL11.glPopMatrix(); 

但是,爲什麼你需要撤銷相機轉換,這是值得懷疑的。你可能應該每幀或視口應用一次。用該視圖渲染場景,然後獲取投影座標,然後切換到2D渲染模式。

更新

我更喜歡它,如果你使用的相機的側傾,俯仰和偏航意味着他們真正的意思是在OpenGL的座標系 - 相對於相機。重點是,只要您具有相機模型視圖和投影矩陣正確設置,您就可以投影該點。您必須已經在某處設置了相機。您將能夠看到這是否正確,因爲您可以查看結果。應用這個轉換,你會知道它是正確的。

這是正確的嗎?有可能?您必須應用所有轉換。完全相同的轉換可以爲您提供在遊戲中看到的相機視圖。這包括所有翻譯和旋轉。你會知道你是否正確,因爲你應該已經在遊戲中應用這些轉換。

但是,您需要考慮的是手前的相機投影矩陣是什麼?如果您不知道,請調用glLoadIdentity()將其清除,然後調用您的相機轉換邏輯。你需要一個精確的模型視圖和投影矩陣 - 與你在遊戲中使用的完全相同的相機設置。如果你的模型視圖或投影矩陣處於錯誤的狀態,它將不起作用。

+0

在我的遊戲中,z軸是高度,所以不應該是'GL11.glRotatef(yaw,0,0,1);'?我試圖做成這樣的東西:http://i.stack .imgur.com/dQtnm.jpg這將在我的目標點(我的屏幕中心)和玩家之間劃出一條線。 – Manitoba 2012-04-10 11:55:06