一如往常的進(jìn)度文,寫成筆者和手下的電子妖精研究的過程。
這次寫得簡略一些,不想花很多時(shí)間寫。
同時(shí)發(fā)在官網(wǎng)雖然兩位電子妖精已經(jīng)登場好幾次,最近才寫了篇介紹讓人認(rèn)識(shí)她們,並把外型定個(gè)標(biāo)準(zhǔn)規(guī)格。
C.S.Lab看板娘介紹再說明一次程式碼框的顏色,粉紅色框是引擎本體,黃色框是shader。
FF33前後解決了幾個(gè)疑難雜癥。
FF33前一天檢查設(shè)備時(shí),開一代1.05版測試,發(fā)現(xiàn)兩個(gè)問題。
1. 一開遊戲就會(huì)當(dāng)?shù)簟?br>用map檔檢查看看哪裡有問題。艾莉兒,來幫忙吧。
…………
是初始化WIC時(shí)這一行。
CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (void**)&gpfd->wicFactory); |
查了一下MSDN
What's New in WIC如果使用Windows 8 SDK編譯,CLSID_WICImagingFactory會(huì)等於CLSID_WICImagingFactory2,這個(gè)class在Windows 8系統(tǒng)內(nèi)建,但是Windows 7要更新到新版才有。WIC初始化失敗之後就不能正常執(zhí)行了。
要改成這樣才行
CoCreateInstance(CLSID_WICImagingFactory1, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (void**)&gpfd->wicFactory); |
至於WIC是什麼?是Windows內(nèi)建的函式庫,我用它來讀取圖檔,以前寫過一篇用法教學(xué)。
【程式】讀取圖檔的方法-Windows篇————————
2. 顯示關(guān)卡名稱的欄位變成這樣。
此欄位換字時(shí)是先把圖清除,再畫新的字上去,但似乎「把圖清除」這一步?jīng)]成功,之後畫的字就疊在上面。
遊戲裡有哪個(gè)地方code寫錯(cuò)嗎?看一下。
艾莉兒:嗯……好像沒有啊,而且在其他電腦上跑不是都沒問題嗎?這臺(tái)是專門在活動(dòng)時(shí)展示的小筆電,作業(yè)系統(tǒng)是Windows 7,已有大約兩年沒更新,跑一下Windows Update看看。
…………
(Windows Update有夠久,還好我是電腦放在那邊跑,人去做其他事)
…………
(3小時(shí)後)
艾莉兒:咦,這樣就沒事了。遊戲code一個(gè)字都沒改。
艾莉兒:那個(gè),上次展出之後有修改什麼地方嗎?我想一下,有把畫字的底層從GetGlyphOutline()換成DirectWrite,或許是那一版Windows 7的DirectWrite有問題。
不過「把圖清除」我是用memset()清除一塊記憶體的方式,沒有用Direct2D和DirectWrite的函式,不知為何跟DirectWrite有關(guān)。
然後試一下第一個(gè)問題的CLSID_WICImagingFactory2,結(jié)果更新Windows之後CLSID_WICImagingFactory2也可以用了。
總之確定兩個(gè)問題都是更新Windows就可以解決,遊戲不用急著發(fā)1.06版。
本社團(tuán)人力有限,我也想全力做二代而儘量不要分出心力弄一代。
————————
3. 回來弄二代,要把shadow map實(shí)裝進(jìn)遊戲了。
另一個(gè)bug,下半部有多餘的影子。
FF33有帶筆電去攤位上弄,但一直查不出原因。
回家之後再查發(fā)現(xiàn)是個(gè)粗心的錯(cuò)誤:zFar不夠大。
(這跟3D坐標(biāo)轉(zhuǎn)換有關(guān),計(jì)算投影矩陣時(shí)要給Z最大和最小值)
————————
4. 在Linux上跑一下看看。在Windows上每做好一些部分就移到Linux開發(fā)機(jī),做Linux對應(yīng)的部分,如果修改的地方太多才來弄Linux版就不好改了。
艾莉兒:咦,沒有畫面。用之前找到的debug工具:apitrace看看
左邊會(huì)列出執(zhí)行過程中有呼叫的OpenGL函式,點(diǎn)選其中一個(gè)函式,右邊會(huì)顯示此時(shí)的貼圖和framebuffer狀態(tài)。
看起來載入貼圖、建立framebuffer沒問題,只是glDrawElement()畫不出東西。
找個(gè)純2D,不畫3D的程式來試試看。
艾莉兒:用哪一個(gè)程式呢?用這個(gè)好了,以前測試碰撞判定演算法用的。有畫面。
艾莉兒:另一個(gè)桯式,測試複合型plane的。畫不出東西。
兩者差別是前者用uniform變數(shù)指定顏色,後者有讀貼圖。
修改一下shader,把讀取貼圖的指令拿掉就可以在畫面上顯示東西了,確定是shader不能讀取貼圖的問題。
不過是哪裡出問題呢?以前讓我卡關(guān)兩天的 GL_TEXTURE_MAX_LEVEL 確定沒有設(shè)錯(cuò)。
把引擎裡建立貼圖的地方,或是shader修改一下看有什麼變化……,還是找不到。
艾莉兒、鈷寶:(討論中)
你們有發(fā)現(xiàn)什麼嗎?
艾莉兒:那個(gè),我好像找到了。
shader裡有這一段,鈷寶,給主人看。鈷寶:
layout(location=0) in vec2 pos; layout(location=1) in vec2 texCoord; layout(location=2) in vec4 color; |
艾莉兒:但我這裡是這樣。
enum{ VERTEXATTR_POS2 = 0, //2D position VERTEXATTR_POS3, //3D position VERTEXATTR_TEXCOORDP, //以pixel為單位 VERTEXATTR_TEXCOORDN, //normalized VERTEXATTR_COLOR, VERTEXATTR_NORMAL, }; |
原來在這裡,以前修改一個(gè)地方,改了C++但忘了改shader裡對應(yīng)的部分。
為了簡化vertex attribute的設(shè)定,把2D和3D的attribute ID用不重覆的整數(shù)定義,但忘了改shader裡的ID設(shè)定。
2D要改成這樣,location要跟上面enum裡的數(shù)值對應(yīng)。
layout(location=0) in vec2 pos; layout(location=2) in vec2 texCoord; layout(location=4) in vec4 color; |
3D要這樣
layout(location=1) in vec3 inPos; layout(location=3) in vec2 inTexCoord; layout(location=5) in vec3 inNormal; |
也是自己不小心造成的,不過分享一下經(jīng)驗(yàn),提醒大家哪裡要小心。
之後就如「
如果辭職在家做獨(dú)立遊戲?」說的,覺得長期一個(gè)人關(guān)在家裡製作會(huì)累積焦慮感,不調(diào)整生活不行了。
檢討一下發(fā)現(xiàn)我焦慮的最大原因是「沒有正職工作」,於是三月頭幾天先處理找工作的事,然後做一些做遊戲以外的事轉(zhuǎn)換心情,畫畫可愛的看板娘,就是開頭那篇看板娘介紹。
把生活調(diào)整一下,且跟一些朋友聊過後勇氣漸漸恢復(fù)了,做遊戲的事反正工作之餘有時(shí)間就繼續(xù)弄。
繼續(xù)工作,把延宕很久的第二關(guān)背景拿出來弄,結(jié)果一弄就碰到幾件鳥事。
- 鈷寶:那個(gè),主人,OBJ轉(zhuǎn)PMD……有80000個(gè)頂點(diǎn),不能轉(zhuǎn)換。
PMD只能存……65536個(gè)頂點(diǎn)。
艾莉兒:OBJ檔裡只有約30000個(gè)頂點(diǎn)不是嗎?
鈷寶:可是……PMD不支援flat shading,拆頂點(diǎn)之後……就變80000個(gè)。
要把OBJ轉(zhuǎn)成D3D和OpenGL能吃的格式,結(jié)果頂點(diǎn)太多了,為何頂點(diǎn)會(huì)增加在下一篇介紹。
我後來幫艾莉兒和鈷寶做了PMX支援,用PMX就可以儲(chǔ)存超過65536個(gè)頂點(diǎn)。不過一個(gè)模型用到30000個(gè)頂點(diǎn)是太多了點(diǎn),要叫美術(shù)修改一下。
- 3D美術(shù)不會(huì)改的話,我自己改也可以,但因?yàn)锽lender讀取OBJ檔法線會(huì)錯(cuò),沒辦法在Blender裡修改模型。
有追進(jìn)度文就會(huì)知道我弄3D時(shí)常抱怨現(xiàn)成的工具有問題,現(xiàn)在覺得有兩個(gè)問題還是要從根本解決,不能一直逃避。
1.支援flat shading。
2.解決Blender讀取OBJ,和輸出PMD,PMX會(huì)出錯(cuò)的問題。
待續(xù),下一篇就來解決這兩個(gè)問題。