2015-10-22 194 views
2

我正在嘗試將平鋪從SDL2轉換爲OpenGL。這是來自SDL2的圖像;平鋪+ OpenGL紋理翻轉

SDL2 rendering

而使用沒有紋理在Y軸翻轉的OpenGL呈現的相同的圖像;

OpenGL with no texture flipping

這裏是從OpenGL的紋理在Y軸翻轉渲染圖像;

OpenGL with texture flipped

我應該怎樣Y型翻轉紋理補償的座標,並把它在正確的OpenGL渲染的座標系?這裏是我用來獲取紋理uv渲染第二張圖片(紋理不翻轉)和第三張圖片(翻轉紋理)在OpenGL中的代碼;

glm::vec4 srcRect; 
srcRect.x = (float)((tileLayer->GetTileId(x, y) - (tileY * tilesPerRow))* (tileWidth+ spacing))/imageWidth; 
srcRect.y = (float)(tileY * (tileHeight + spacing)+ margin)/imageHeight; 
srcRect.z = (float)tileWidth/imageWidth; 
srcRect.w = (float)tileHeight/imageHeight ; 
+0

如果我理解正確,那麼你只有y軸的問題。嘗試使用此行爲y:'srcRect.y =(float)(imageHeight - tileY *(tileHeight + spacing) - margin)/ imageHeight'/ –

+0

@Danil,謝謝你的回覆。我剛剛嘗試了您的建議,但仍然失敗(http://imgur.com/DCIrJeE.png)。 – user2924261

+0

好的,這個'srcRect.y =(float)(tileHeight - tileY *(tileHeight + spacing) - margin)/ imageHeight'或'srcRect.y =(float)tileHeight - (float)(tileY *(tileHeight +間距)+邊距)/ imageHeight'? –

回答

0

如果我沒有正確理解問題,請忽略此帖。如果我正確地理解了這個問題,而不是在工作代碼中調整現成的圖形和計算,我會改變OpenGL透視轉換以匹配SDL。 OpenGL對座標系沒有任何偏好,所以你可以自由地調整它以適應你的目的。我假設你正在使用現代OpenGL(可編程着色器,無固定管道)和一些OpenGL數學庫(例如用於C++的glm)。大多數圖書館都使用ortho()來創建具有座標轉換的正交透視圖。語法是:

glm::ortho(left, right, bottom, top, near, far) 

只需翻轉底部和頂部,就可以翻轉y。對於2D圖形,近場和遠場能夠接近任何東西,因爲你的對象都具有零Z座標:

glm::ortho(
    -1, 1, // X goes -1 to 1 
    1, -1, // Y goes 1 (at bottom!) to -1 (at top!) 
    -1, 1)  // -1 < 0 < 1 

但你可以得到更好的。用你的窗口大小參數,你可以使用普通的基於像素的座標(而不是-1 ... 1米範圍):

glm::ortho(
    0, width, // X goes 0 to width 
    height, 0, // Y goes 0 (top) to height (bottom) 
    -1, 1)  // near & far 

了利用固定管道(舊的OpenGL),使其使用glOrtho()。

希望這是問題,如果是這樣,希望這有助於。

編輯:以防萬一...你可以調整透視轉換更適合更好的瓷磚基於2D遊戲。可以說你的對象的「單位大小」是32x32(精靈,背景瓷磚等)。爲了擺脫相乘,並與子畫面寬度除以&長度(轉換地圖數組索引到屏幕座標,並且反之亦然),只是匹配座標「單元大小」,以平鋪尺寸:

glm::ortho(
    0, width/tile.width, // +1 X is +tile.width 
    height/tile.height, 0, // +1 Y is +tile.height 
    -1, 1)     // near & far 

EDIT(見註釋):讓假設您使用正交(0,寬度,高度,0)以像素爲單位獲得「傳統」屏幕座標。到32×32的blit位圖窗口中,你已經從以下兩個三角形構造矩形:

uv (0, 0)    uv(1, 0) 
pos(0, 0)    pos(32, 0) 
    +-----------------+ 
    |A    D| 
    |     | 
    |B    C| 
    +-----------------+ 
pos(0,32)    pos(32, 32) 
uv (0, 1)    uv (1, 1) 

默認繞組是逆時針(三角形ABC,CDA)。 「參考」點也可以使用矩形(-16,-16) - (16,16)更改爲居中。此外:您可以使用「單元箱」(0,0) - (1,1)或(-0.5,-05) - (0.5,0。5),並通過將模型矩陣傳遞給着色器來對其進行縮放以修正尺寸。這使您可以輕鬆使用相同的盒子來塗抹任何尺寸的紋理。

如果你不喜歡改變視角,你也可以通過轉動你使用的矩形來「翻倒」並將位置縮小到32 /寬度和32 /高度來進行翻轉(例如在模型矩陣中)。這會影響纏繞,因此您可能需要調整臉部剔除參數(glCullFace,glFrontFace,glPolygonMode)。

但是IMO更方便2D圖形調整透視並繼續使用您以前使用的「默認」窗口座標。 3D方是不同的野獸。

+0

我會接受你的答覆作爲答案,因爲它是的確是一個有效的解決方法。是不是一個翻轉的OpenGL紋理應該得到srcRect計算的權利和SDL的版本,除了在OpenGL的uv空間規範化的數值沒有改變?或者是我的理解在這方面是錯誤的?謝謝。 – user2924261

+0

嗯,是的,的確,這比有點翻轉的角度更有毛,因爲這也涉及到你用來紋理紋理的矩形的座標。所以,你也可以通過轉動矩形來「翻轉」 - 我添加這個解釋我的答案在第二。但是UV座標無論如何都是標準化的:D – MaKo

+0

我寫了一些關於用於紋理貼圖的多邊形的描述。在OpenGL中,您可以調整座標的許多不同位置:您可以使用任何變換矩陣(模型,視圖透視圖),也可以在設置多邊形時進行調整。我個人更傾向於改變視角以匹配原始SDL代碼中使用的視角:SDL(在OpenGL的頂端)最有可能原本是翻轉座標以便爲您提供「傳統」座標系。 – MaKo