創作內容

1 GP

【程式】OpenGL uniform buffer object試用

作者:Shark│2016-09-08 19:58:08│巴幣:2│人氣:573
接續前一篇研究D3D11的,發現OpenGL有個uniform buffer object功能,可以代替uniform變數,來試驗一下。

找到的參考資料
官方說明
一個範例

其實前兩篇裡兩位電子妖精只是幫忙收集資料,這次才請她們測試新招式(實際修改引擎)。



使用OpenGL的某個功能得注意有哪些顯卡支援,不像Direct3D有強制力,要求顯卡廠商非實做這個功能不可,所以只要說明文件裡有寫就確定能用。
調查一下,Intel內顯要sandy bridge架構以後才有這個功能,是2011~2012年出的。
AMD所有APU都可以用。

首先要取出擴充函式,OpenGL有個特性是很多函式作業系統API裡沒有定義,要用wglGetProcAddress取出指標。
不過,我有做一套工具解決這個問題。
在一個Python程式碼裡加入glGetUniformBlockIndex、glBindBufferBase等名稱。

funcList=(
…………
Func("glBufferData"),
Func("glBindBufferBase"),
Func("glGetUniformBlockIndex"),
Func("glBufferSubData"),
…………
)

鈷寶,動手。
鈷寶:…………(工作中)

static PFNGLBUFFERDATAPROC glBufferData;
static PFNGLBINDBUFFERBASEPROC glBindBufferBase;
static PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex;
static PFNGLBUFFERSUBDATAPROC glBufferSubData;

自動產生C函式定義,之後的步驟也有自動化。

再來修改shader,宣告一個uniform區塊
layout(std140) uniform ShaderState{
 vec4 globalColor;
 vec2 texSizeRcp;
};

前篇說到要把shader嵌入程式裡,這一步也是請鈷寶幫忙。
鈷寶:(處理中)…………,包裝好了。
艾莉兒:再來換我這邊準備了。

C++裡宣告一個對等的struct
struct{
 float globalColor[4];
 float texSizeRcp[2];
};

C++端使用方法如下
1.用glGenBuffers和glBufferData,產生buffer物件並配置空間。
2.用glGetUniformBlockIndex取得index,再用glBindBufferBase把index和buffer物件關聯起來。
3.之後用glBufferSubData把資料傳給shader。
這方法可減少很多glGetUniformLocation和glUniformXXX的呼叫。
而且照上面網站的說法,同一個uniform buffer可以給不同的shader共用,而uniform變數各個shader是分開儲存的。



改好了,用開發中的Cyber Sprite 2試試看
艾莉兒:好,來吧。
開始時沒問題,但進入標題畫面後
艾莉兒:咦,怎麼回事?


………完全想不到是哪裡出問題,還是不要用Cyber Sprite 2這麼複雜的程式測,寫個比較小的程式測試。

…………
初步測試看起來是沒事。
我的電腦有兩個顯示晶片,在Intel可以用,但再用nVidia的試試看,會有compile error


查了一下shader語法說明,在shader前面加個#version看看
艾莉兒:再試試看,……還是不行。


…………

再研究一下,好像可以在創建context的時候設定成compatibility profile,但想完全解決得全部改用新規格。
剛剛畫面很奇怪的原因也心裡有數了,混合uniform buffer和這些gl_變數實際上是會出問題的,只是Intel的compiler沒有把error回報。

原來沒那麼簡單,雖然已經知道OpenGL 3.0以後把一些東西列為deprecated,全部改完要做的工不少。
鈷寶:我想……,先不要用吧。

查了一下目前有哪些顯卡,還有哪個版本的Android支援uniform buffer object之後,還是繼續用以前的uniform變數吧,可能等Cyber Sprite 2的下一個作品再換新方法。



關於第一篇說的OpenGL驅動程式沒寫好的問題,是個人在幾台電腦上用OpenGL做遊戲的經驗,可能是顯卡廠商對較少人用的平台就比較少維護的關係。

顯示晶片的性能不只要看晶片本身,也跟驅動程式有關係,即使晶片有某個功能,驅動程式不開放你用的話你的程式裡也不能用。
在Windows上有時一個功能在Direct3D上可以用(表示晶片有這個功能),但相同的功能OpenGL就不能用,Intel的晶片常有這種事。

事實上最近發現一個問題,在雙螢幕上開Cyber Sprite,如果視窗在第二個螢幕上遊戲就會頓,個人認為是驅動程式的問題所以不想修了,因為nVidia晶片不會這樣,用Intel晶片執行Direct3D程式也沒事。

另一個個人經驗是,如果分別在Windows和Linux跑OpenGL程式,Intel晶片在Linux上的表現往往比Windows好,因為Linux的驅動程式不是Intel開發的,是open source社群按照官方公開的規格做的。
反之AMD和nVidia的Linux版驅動程式也是官方開發的,這兩家的晶片在Windows表現比較好。
引用網址:https://home.gamer.com.tw/TrackBack.php?sn=3316488
All rights reserved. 版權所有,保留一切權利

相關創作

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

留言共 0 篇留言

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

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

前一篇:【程式】Direct3D... 後一篇:【程式】倒立的OpenG...

追蹤私訊切換新版閱覽

作品資料夾

airsky00大家
與一個罪犯談判的方式,就他媽誰理他!看更多我要大聲說11小時前


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

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