2015-12-16 105 views
1

我使用右手座標(x = right,y = up)在世界空間中使用我的對象。是否SFML ::查看倒Y軸標準?如何解決它?

當我必須使用SFML呈現它們時我遇到了問題,因爲我無法在sf :: View中使用(y = up)矩陣設置View矩陣,然後全部呈現y翻轉。

一個解決方案,我的想法是使前翻轉的每一個對象在y軸:

ObjectTransformMatrix * MatrixScale(1.0f,-1.0f) 

但我想我必須將SF ::查看中心移動到:

y = y - (view_size.y/2.0) 

爲什麼sf :: View是y倒置的?我的解決方案正確嗎?

+0

Ooooh sorrry是的,我會編輯它。 – FrameBuffer

+0

如果您有興趣學習2D變換,[HTML5演示文稿](https://github.com/legends2k/2d-transforms-101/#2d-transforms-101)試圖直觀地理解這個想法。它有動畫來說明每個轉換的效果,並且應該是理解該主題的好的入門書。 – legends2k

回答

4

爲什麼sf :: View是y-inverted?

大多數圖形軟件包/庫的屏幕空間座標系統的起點位於左上角,其中X向右,Y向下。這只是一個慣例,而SFML恰好選擇了這一點。請注意,這不是左撇子或右撇子;這取決於第三軸,如果有的話。我將把你所指的另一個座標系統稱爲傳統的數學座標系統。

使其

不這樣做之前翻轉每個對象在y軸!你有一個方便的世界。爲什麼在改變攝像頭(sf::View)時會改變這種變化,它將隱式應用到所有渲染對象的內部。從the documentation

sf :: View在2D場景中定義了一個攝像頭。

這是一個非常強大的概念:您可以滾動,旋轉或縮放整個場景,而不會改變繪製可繪製對象的方式。 [...] 要應用視圖,必須將其分配給渲染目標。然後,在此渲染目標中繪製的每個對象都將受到視圖的影響,直到您使用另一個視圖。

本質上你會設置下面派生的矩陣作爲相機的變換,但通過sf::View公開的功能。

我的解決方案是否正確?

部分正確,你猜對了其餘的。翻轉軸只是解決方案的一部分,您還應該將原點翻譯到正確的位置。你需要的是M 米→s其中m是數學空間和s是屏幕空間。要找到您需要轉換屏幕空間座標系以與數學座標系對齊。由於兩個座標系中的比例相同,我們可以原樣使用寬度W和高度H(最初來自屏幕空間)的值。

我們已經這樣:

 
       S--->---- W ---------+ 
       |     | 
       v     | 
       |     | 
       |     | 
       |     | 
       | 
       |     H 
       | 
       |     | 
       |     | 
      ^     | 
       |     | 
       M--->----------------+ 

當我們一切都做得那麼 1,-1即規模X軸1和Y軸-1(翻轉Y),我們有

 
      ^
       | 
       S--->---- W ---------+ 
       |     | 
       |     | 
       |     | 
       |     | 
       |     | 
       | 
       |     H 
       | 
       |     | 
       |     | 
      ^     | 
       |     | 
       M--->----------------+ 

這個新系統不再是S,因爲它的Y翻轉了;我們稱之爲S'。現在我們必須翻譯(移動)它的原點到達M.因爲我們正在轉換座標系而不是點,所以我們必須對S'進行轉換,即轉換後的中間座標系,而不是S.

我們做T 0,-H即待着負Y. h爲單位,我們將結束與

 
       +-------- W ---------+ 
       |     | 
       |     | 
       |     | 
       |     | 
       |     | 
       | 
       |     H 
       | 
       |     | 
       |     | 
      ^     | 
       |     | 
       O--->----------------+ 

where both M and S are at O. 

我們已經來連接S和T,以獲得最終的中號米→S。由於我們正在轉換座標系,而不是點,因此我們必須進行後乘法(假設您使用的是列向量約定)。

中號米→S = S 1,-1Ť 0,-H

 
| 1 0 0 | | 1 0 0 | | 1 0 0 | 
| 0 −1 0 | | 0 1 −H | = | 0 −1 H | 
| 0 0 1 | | 0 0 1 | | 0 0 1 | 

說,我們已經在屏幕這是5×5(爲簡單起見) 。在世界空間變換點(1,1)到屏幕空間:

 
| 1 0 0 | |1| |1| 
| 0 −1 5 | |1| = |4| 
| 0 0 1 | |1| |1| 

(1,4)是在屏幕空間點的座標。

如果你以下行向量約定,您對置式,M = AB即,M 牛逼 = B 牛逼一個牛逼。那會給我們

 
| 1 0 0 | | 1 0 0 | | 1 0 0 | 
| 0 1 0 | | 0 −1 0 | = | 0 −1 0 | 
| 0 −H 1 | | 0 0 1 | | 0 H 1 | 
+0

謝謝,但是當你說「不要這樣做!你有一個爲了方便而定義的世界。當你改變相機(sf :: View)轉換時爲什麼改變它」。問題是我無法設置或不知道如何使用當前sf :: View接口更改sf :: View中的矩陣。 http://www.sfml-dev.org/documentation/2.3.2/classsf_1_1View.php 在那裏,我不能改變內部矩陣做你說的話,縮放和轉換,或者我失蹤了什麼? 我可以做到這一點的唯一方法是使用view.getTransform()並在類之外應用轉換。:(無? – FrameBuffer

+0

您可以使用'sf :: View :: setCentre'進行翻譯,但它似乎缺少函數來設置比例尺。也許['sf :: RenderStates'](http://www.sfml-dev.org/documentation/2.3.2/classsf_1_1RenderStates.php)是你想要的嗎?它有一個構造函數接受變換。 – legends2k

+0

sf :: RenderStates是渲染對象時傳遞的模型矩陣。在SFML內部,這個矩陣將被乘以sf :: View矩陣(View和Projection矩陣)。 所以我的解決方案涉及獲取模型矩陣,並在我將它傳遞給sf :: RenderStates之前,我通過(1,-1)縮放它來更改y軸。然後這將被乘以由(y = y - (view_size.y/2.0)移動的sf :: View) SFML在sf :: View中沒有基本的功能? – FrameBuffer

0

我只是顛倒了窗口的高度。我認爲就是這樣。

sf::View view = window.getDefaultView(); 
view.setSize(WINDOW_WIDTH, -WINDOW_HEIGHT); 
window.setView(view);