[問題] openGL更新部分材質

看板C_and_CPP (C/C++)作者 (東逼)時間13年前 (2013/01/16 22:34), 編輯推噓3(3023)
留言26則, 5人參與, 最新討論串1/1
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) Qt 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) openGL es 2.0 問題(Question): 是這樣子的 我之前寫了openGL相關的程式 code大概長這樣 void load_texture(int width, int height, char* buffer, int idx) { .... .... glBindTexture(GL_TEXTURE_2D, texture[idx]); //更新第idx個材質 } void render() { .... glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //先清除掉frame buffer render_part(texture[0]); render_part(texture[1]); render_part(texture[2]); render_part(texture[3]); //根據不同材質設定不同的頂點、材質座標 } 這段code大意是我有個訊號來源 每次他只要更新一次,就會分別呼叫我的 load_texture、 render 更新的順序不一定 但就是四種材質切換來切換去 (idx = 0~3) 之前我的方法是只要訊號更新一次 我就會重新更新四塊材質(像上面的寫法) 這樣做顯示是沒啥問題 但唯一的問題就是速度太慢 (因為只更新一個材質卻重畫四次) 想請問一下有甚麼方法可以只更新部分的材質呢? 意思是只要收到 idx = 1 我就只會 call render_part(texture[1]) 而不用重新call四次 我有試過這樣的寫法: void load_texture(int width, int height, char* buffer, int idx) { .... .... now_texture = idx; //告知目前是更新哪塊 } render() { .... glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //先清除掉frame buffer render_part(texture[now_texture]); } 但是這樣會有個問題是說 雖然那塊被我更新了 但是其他的材質卻不見了 看一下原因是因為 glclear的關係 我也有試過假如不用glclear來更新 但是這樣畫面反而更奇怪 就感覺有殘影這樣 @@ 因此我的問題是 有沒有甚麼辦法可以讓openGL一次只更新某塊材質 或者是有沒有辦法清除某塊材質就好? 爬了文和找網路似乎也沒有頭緒 因此就來請教大家了 在此也先跟各位說聲謝謝囉! -- ▍ ▍ ╯╰ ╯╰ ◢◣ ◢◣ 我最愛的 柏柏龍~ 柏柏龍~ ◢██◣ ╮╭ ▎▎╮╭ ▎▎ 柏柏龍~ 柏柏龍~ ⊙ ⊙ ⊙ ⊙ 人人心中都有柏柏龍~ ≡ ▼ ≡ ▲▲ ● ● ≡ ▼ ≡ ■ ■ ■ ■ 憤怒就永遠不會消失~ ⊙⊙ ≡皿 ≡ 炸是最美的擁有~ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 59.120.179.30

01/16 22:48, , 1F
你更新時bind那張texture修改就好啦 render的部份不用動
01/16 22:48, 1F

01/16 23:31, , 2F
你的 render_part() 看起來是一個render func, 實際上會
01/16 23:31, 2F

01/16 23:32, , 3F
依參數的不同畫不同的object?
01/16 23:32, 3F

01/17 00:50, , 4F
回一樓 不是很清楚您的意思@@ 可以再說清楚一點嗎? Orz
01/17 00:50, 4F

01/17 00:51, , 5F
to 2F 沒錯,我的四塊材質都有各自的頂點與轉換矩陣
01/17 00:51, 5F

01/17 00:52, , 6F
例如材質0 就用四角形頂點,材質1用六角型頂點 之類的~
01/17 00:52, 6F

01/17 01:12, , 7F
不好意思我誤會你的意思了 我以為你把load和render寫在一起了
01/17 01:12, 7F

01/17 01:16, , 8F
如果你知道更新材質會動到哪些地方 可以用scissor清掉那一塊
01/17 01:16, 8F

01/17 01:16, , 9F
就好 然後把需要更新的部份畫回去 不過這樣看情況...
01/17 01:16, 9F

01/17 01:17, , 10F
原則上不能不clear就直接畫在同一個地方 (會有z-fighting)
01/17 01:17, 10F

01/17 02:02, , 11F
慢應該是慢在把 texture 從主記憶體傳到顯示卡記憶體
01/17 02:02, 11F

01/17 02:04, , 12F
還有從硬碟讀到主記憶體,更慢
01/17 02:04, 12F

01/17 02:05, , 13F
如果 texture 已經在顯示卡記憶體,就算全部重新 render
01/17 02:05, 13F

01/17 02:05, , 14F
應該也是會很快,除非你的面數很多。
01/17 02:05, 14F

01/17 02:07, , 15F
clear 以後就是要全部重新 render,所以你應該減少的應該
01/17 02:07, 15F

01/17 02:08, , 16F
是 load texture,只要重讀需要更新的 texture 就好了。
01/17 02:08, 16F

01/18 02:57, , 17F
除非你的geometry完全不用考慮前後/混疊, 不然恐怕一定
01/18 02:57, 17F

01/18 02:58, , 18F
得clear buffer再整個scene重畫不可; 看你的描述物件似
01/18 02:58, 18F

01/18 02:59, , 19F
乎不複雜? 那時間也許真是卡在load texture, 你可以試著
01/18 02:59, 19F

01/18 02:59, , 20F
只是重複做clear/render看看是不是就快得多.
01/18 02:59, 20F

01/18 03:01, , 21F
如果texture雖然要一直換, 但是已知就是只有那許多張,
01/18 03:01, 21F

01/18 03:03, , 22F
你可以多gen一些texture一次上傳完, 然後依據要用的
01/18 03:03, 22F

01/18 03:04, , 23F
texture bind不同的id, 而原來的idx另外獨立成一個參數
01/18 03:04, 23F

01/18 03:05, , 24F
來控制要畫的東西就好了@_@"
01/18 03:05, 24F

01/18 09:43, , 25F
我比較好奇第一個為啥是先 gen texture 才 glBindTexture
01/18 09:43, 25F

01/18 09:44, , 26F
另外更新 texture 的時候請用 glSubTexImage 系列
01/18 09:44, 26F
文章代碼(AID): #1Gzhg0Xn (C_and_CPP)
文章代碼(AID): #1Gzhg0Xn (C_and_CPP)