創作內容

8 GP

【程式】倒立的OpenGL貼圖坐標

作者:Shark│2016-10-02 02:24:42│贊助:16│人氣:602


艾莉兒:在OpenGL環境下,我可是顛倒著工作的哦。

2018/12/9 EDIT:增加3D坐標轉換的部分

這次介紹Direct3D和OpenGL的一個重要差異,

OpenGL對貼圖坐標的定義是上下顛倒的。

一般繪圖軟體都以圖的左上角為原點,用外部函式庫讀取圖檔,傳回的記憶體區塊也是從左上角開始,然後往下第二列、第三列……,一直到右下角,Direct3D也採用這個設計。

但OpenGL定義(0,0)是圖的左下角,把貼圖從主記憶體傳給顯示記憶體的函式glTexImage2D,也假設給它的指標是從左下角開始,所以顯示記憶體裡儲存的貼圖其實是倒立的。
而兩者的螢幕坐標定義相同,都是左下角(-1,-1),右上角(1,1)。

(圖中紅字是貼圖坐標,藍字是螢幕坐標)

不過可以看到兩種情況的貼圖,帽子的羽飾都是靠近(0,0),(1,1)都是左耳。
傳入這4個頂點的話
貼圖坐標 螢幕坐標
(0,0) (-1,1)
(1,0) (1,1)
(1,1) (1,-1)
(0,1) (-1,-1)

請看上圖把坐標一個一個對應,D3D和OpenGL都可以畫出正立的鈷寶頭像,此時直接用相同的坐標、相同的矩陣不會有問題。



可是,如果有用到framebuffer object做兩階段畫圖就會出問題了。


以這個紙娃娃系統為例,先在一個buffer把頭和五官重疊再畫到畫面上,第一階段會變成正立,可是再把這個framebuffer畫在主畫面時(假設要用在對話框),使用相同的規則會畫成倒立的。
同理多一個階段又會倒轉一次,如果有些貼圖來自檔案,有些是用framebuffer產生,就會正立、倒立夾雜了。

要是畫之前先檢查貼圖來源,是framebuffer就做特別處理把坐標反向呢?是可以讓坐標正確,但是要多記錄貼圖種類,畫的時候還多出計算坐標的步驟。



對這個問題,我的解法是:
在OpenGL內部完全以倒立的狀態處理。

矩陣stack裡的第一個矩陣,2D繪圖時是把-1~1換成單位是像素,就做y坐標逆轉的處理。

(矩陣的寫法是把向量放在右邊乘)
之後如果要做其他轉換乘上其他矩陣,y坐標逆轉的效果會保留。

3D的坐標轉換是將頂點坐標依序乘以model、view、projection矩陣,我在projection動手腳,將OpenGL的Y坐標逆轉,model和view則是兩個平台相同。

(fovX=橫向視角,fovX=縱向視角,cot是三角函數的cotangent)

至於culling設定,顯示晶片是把矩陣都乘完,算出螢幕坐標後才處理culling,因此兩者的culling設定要相反。
因為PMD模型是順時針為正面,我採用順時針為正。
//Direct3D
ID3D11RasterizerState* cullNoMSRS;
  //名稱由來:有cull,無multisample的rasterizer state
D3D11_RASTERIZER_DESC rsState;
ZeroMemory(&rsState, sizeof(D3D11_RASTERIZER_DESC));
rsState.FillMode = D3D11_FILL_SOLID;
rsState.CullMode = D3D11_CULL_BACK;
rsState.FrontCounterClockwise = 0; //設定順時針為正面
rsState.DepthClipEnable = TRUE;
device->CreateRasterizerState(&rsState, &cullNoMSRS);

//OpenGL設定逆時針為正面
glFrontFace(GL_CCW);

至於如何讓玩家看到的是正立?我的引擎有做一個功能,因為視窗可以縮放,大小不一定和遊戲內定解析度相同,所以先把畫面畫在一個內部buffer,整個畫面畫完才把buffer貼到主畫面,正好可以在這一步做。

過程如下




OpenGL的這個現象,我買的一本介紹D3D和OpenGL的書裡也沒寫,是用了一個工具:GLIntercept觀察它的內部資料才發現的,製作Cyber Sprite紙娃娃系統時也確實造成問題,然後想出了將y坐標顛倒的方法。
這樣以後引擎要做Direct3D版的話,D3D和OpenGL可以用相同的矩陣和頂點坐標,不用準備兩份資料。

關於開頭的圖:還是無線繪比較容易畫,這個畫法描線花了很久,上色倒是很快。
配色沒餘力從頭想了,把以前畫某張圖的記錄拿來用。
還有想小幅修改一下艾莉兒和鈷寶的服裝,但還沒有定案。
引用網址:https://home.gamer.com.tw/TrackBack.php?sn=3340757
All rights reserved. 版權所有,保留一切權利

相關創作

同標籤作品搜尋:程式|OpenGL|Direct3D

留言共 0 篇留言

我要留言提醒:您尚未登入,請先登入再留言

8喜歡★shark0r 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:【程式】OpenGL u... 後一篇:想一下看板娘的設計...

追蹤私訊

作品資料夾

grass891101迷納桑
歡迎來看看繪圖~!看更多我要大聲說昨天14:36


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】