他猛地把電子書(shū)窗口一關(guān),心情久久不能平靜,這簡(jiǎn)直就是武林絕學(xué),如果說(shuō)以前所學(xué)只是零零碎碎的招式,這下絕對(duì)算大招了!他正在盤(pán)算啥時(shí)可以耍耍。。。不急!趕緊給同道中人推薦,不過(guò)估計(jì)他們這會(huì)都還在奮筆疾書(shū)中。
作者太帥了!招招要害,沒(méi)有一句廢話,很對(duì)他的胃口。這種人要膜拜下,忽然他想起在某群里似乎有此大名!十幾個(gè)群,每個(gè)群三四百人,慢慢來(lái)。。。
終于,在一個(gè)灌水群里,目標(biāo)出現(xiàn)了,雖然是名字的拼音縮寫(xiě),但是對(duì)于他這行的人來(lái)說(shuō),已經(jīng)足夠標(biāo)記身份了。但是群里水貨多,這哥們?yōu)樯兑爝@個(gè)群?他在想此人會(huì)不會(huì)像他以前的老大那樣,有一種仰視數(shù)學(xué)老師的感覺(jué)。如果拿圍棋做比喻此人能算幾段?
這哥們似乎不在線,也許還在第一線創(chuàng)作。先看看簽名,說(shuō)的太TM對(duì)了!特別最后那句,程序決定生死,說(shuō)出了自己的心聲。他要加好友,大俠和高手兩個(gè)詞反復(fù)挑選,最后選了高手二字做稱呼發(fā)了過(guò)去。
他忍不住又把電子書(shū)打開(kāi),再過(guò)一遍,感覺(jué)寫(xiě)得太TM好了,其意義簡(jiǎn)直是促進(jìn)人類(lèi)進(jìn)步啊!那些花前月下,喝酒吹牛的的人,你們?cè)闾A四切┪淖帧?
忽然好友申請(qǐng)通過(guò)了!高手在線!他毫不猶豫地把那個(gè)QQ拖到了“真正高手”好友組。。。
"又改!"對(duì)面的那位哥們已經(jīng)失控了,只見(jiàn)他坦然一笑,好像見(jiàn)過(guò)成百上千次似的。他知道,寫(xiě)這東西,就算寫(xiě)的再好,碰見(jiàn)外行,也是對(duì)牛彈琴。你只要把結(jié)果整對(duì),他就閉嘴了。想到這他把最后一個(gè)分號(hào)打上,一切準(zhǔn)確無(wú)誤。
"不行,我的意思是這樣這樣",他有點(diǎn)不高興,剛才明明不是這樣說(shuō)的,電視里說(shuō)做人要厚道。但是改起來(lái)不麻煩,他賭氣般地找到幾處文字,退格,打字,哦了。
"這邊還要加點(diǎn)東西,要不然太難看了",他知道電視里說(shuō)暴躁不好,但是此時(shí)明顯有一股無(wú)名怒火在燃燒。加上應(yīng)該就沒(méi)事了,應(yīng)該是最后一次了。他放慢打字速度,喝了點(diǎn)水,用這招來(lái)壓制情緒。
正要發(fā)起反擊,突然邊上有人喊:"你看別人是這樣做的,我覺(jué)得他們好NB。"于是。。。他預(yù)感一分鐘以后會(huì)發(fā)生什么。。。他不想那么被動(dòng),干脆提前改掉,他要證明我們和他們一樣NB,這樣就清靜了。
電腦鎖屏,安心小解,哼著小曲,輕松愜意。他在想我就不生氣就不生氣?;貋?lái)路上遠(yuǎn)遠(yuǎn)看見(jiàn)有人在等他了,他想對(duì)方一定會(huì)很驚訝怎么這么快就搞定了。。。
"這功能想了一下,還是不要了",他知道這次他忍不住了。。。
這一夜,他翻來(lái)覆去睡不著,黑暗中的天花板越來(lái)越清晰。上次出現(xiàn)這情況還是三年前,那時(shí)他還是個(gè)菜鳥(niǎo),很多東西似懂非懂。但是這次不一樣,他已經(jīng)答應(yīng)了別人,千萬(wàn)不能搞砸了。
他隱隱約約記得U盤(pán)里似乎有他師兄給的一個(gè)文件,當(dāng)時(shí)沒(méi)看懂直接存在code目錄下了。師兄好像說(shuō)過(guò)這是他熬夜研究出來(lái)的東西,發(fā)給師弟欣賞下,但是版權(quán)要?dú)w他。當(dāng)他雙擊那個(gè)EXE看到里面的畫(huà)面之后,對(duì)師兄的佩服油然而生,從此暗下決心要像他那樣。
但是師兄好久沒(méi)消息了,上次師兄說(shuō)過(guò)覺(jué)得累了,不打算繼續(xù)干了,兩人的話題也就越來(lái)越少了。
他知道,寫(xiě)這東西是需要靈感的,有時(shí)候死磕一天也比不上那靈光一閃!靈光呢?靈光呢?他無(wú)法想象明天別人的目光。他對(duì)自己說(shuō):這一切是不可能發(fā)生的!
突然他坐起來(lái)了,右手伸向了電源鍵,休眠中的電腦傳來(lái)了標(biāo)準(zhǔn)的開(kāi)機(jī)聲音。很快,在他面前出現(xiàn)了新加卷里的那個(gè)文件。他飛快地做了個(gè)快捷方式,然后切回桌面。
“師兄果然是師兄!”,那一刻他由衷贊嘆卻又思緒萬(wàn)千,他覺(jué)得師兄的選擇太草率了,如果大家都能堅(jiān)持下來(lái),想切磋就切磋,豈非人生快事!
十分鐘之后,電腦關(guān)上了,這回不是休眠,是關(guān)機(jī)。。。
凌晨3點(diǎn),在一間狹窄的屋子里,光線昏暗,煙味濃重,一個(gè)掛接在機(jī)箱外的硬盤(pán)不時(shí)閃著藍(lán)色光芒??勘骋紊献粋€(gè)胡子拉茬,滿眼血絲的人,他披著一件一個(gè)多月沒(méi)洗的外套,走火入魔般地敲打著鍵盤(pán)。“難道是這里?”,他喃喃自語(yǔ)地按下了F5,這一次又要等上半個(gè)小時(shí)。他習(xí)慣性地伸出雙腳往桌子上一搭,忽然想起了剛才在網(wǎng)上和他爭(zhēng)吵的那個(gè)菜鳥(niǎo),“這都不懂?!”,緊繃的臉上露出了詭異的微笑。。。
但是一瞬間他好像感覺(jué)到了什么,鼠標(biāo)拖動(dòng)一番之后,僵硬的表情凝固了足足十秒鐘。“不可能??!”他狠狠吸了一口煙,雙手在鍵盤(pán)上一陣搗騰,一分鐘,兩分鐘。。。五分鐘,終于緊皺的眉頭慢慢舒展,仿佛一切又回到了他的控制之中。只見(jiàn)他打字越來(lái)越快,越來(lái)越快,直到戛然而止。。。
原來(lái)是QQ消息來(lái)了,他有些后悔沒(méi)把QQ關(guān)了,F(xiàn)-Word脫口而出,顯然他不喜歡三更半夜被別人打斷思路。他瞥了一眼閃爍的頭像,頓時(shí)眼冒怒光:這菜鳥(niǎo)還沒(méi)搞定嗎?心煩意亂之余他點(diǎn)開(kāi)了頭像。。。
“大俠,我錯(cuò)了,搞定了”,他很不耐煩聽(tīng)到這些,正準(zhǔn)備拉黑,消息又響了:“但是我發(fā)現(xiàn)還有更好的辦法。。。”一種說(shuō)不出來(lái)的感覺(jué),是憤怒?是好奇?他決定不回消息,看看那菜鳥(niǎo)怎么說(shuō)。。。
笑了,他笑了,顯然他發(fā)現(xiàn)了一個(gè)愚蠢的錯(cuò)誤,于是毫不猶豫的打了幾個(gè)字發(fā)了過(guò)去,那邊是沉默,久久的沉默。他估計(jì)菜鳥(niǎo)正在努力理解那幾個(gè)字,便切回剛才的窗口,卻想不起剛才寫(xiě)到哪了。。。
終于打字聲再次響起,他完全沉浸在了自己的世界里,一切都是那么的井然有序,太完美了。激動(dòng)人心的時(shí)刻來(lái)到了,他把左手食指停在F5上方,想了幾秒鐘,按下去了!
他閉上眼睛,想象著半個(gè)小時(shí)之后的喜悅。這時(shí)一陣饑餓感突然襲來(lái),晚飯吃過(guò)了嗎?現(xiàn)在幾點(diǎn)了?一時(shí)想不起來(lái)。趁著這會(huì)有空他想去找點(diǎn)吃的,但是。。。QQ又響了!
不錯(cuò),還是那位菜鳥(niǎo),還是稱呼他“大俠”,對(duì)他豎了一個(gè)大拇指。突然他覺(jué)得菜鳥(niǎo)不那么煩人,貌似還有點(diǎn)自己若干年前的影子。。。
五年前入行就是從Torque Shader Engine開(kāi)始的,當(dāng)時(shí)的Torque摻雜了若干C語(yǔ)言的實(shí)現(xiàn),架構(gòu)比較混亂.它的編輯器還算強(qiáng)大,另有一本專(zhuān)門(mén)介紹如何用Torque腳本編寫(xiě)游戲的書(shū),并且還有一個(gè)像樣的論壇(VIP用戶要花錢(qián)).當(dāng)時(shí)要為它添加一個(gè)特效系統(tǒng),后來(lái)發(fā)現(xiàn)有一個(gè)叫AFX的特效系統(tǒng)是基于Torque開(kāi)發(fā)的可供參考,就花了一個(gè)月時(shí)間把它移植了過(guò)來(lái).再然后就離開(kāi)Torque陣營(yíng)加入OGRE陣營(yíng).
后來(lái)一直陸陸續(xù)續(xù)地關(guān)注著Torque的發(fā)展,聽(tīng)說(shuō)過(guò)它的維護(hù)者GarageGames和微軟合作了,搞了個(gè)XNA,應(yīng)該其中包含了Torque的技術(shù)(我沒(méi)研究過(guò)XNA),再后來(lái)Torque 3D出現(xiàn),聲勢(shì)浩大,但是要收費(fèi),所以沒(méi)下也不知道它長(zhǎng)啥樣.只是感覺(jué)這五年來(lái)但凡有印象的大小游戲沒(méi)聽(tīng)說(shuō)過(guò)有用Torque做的,不免讓人遺撼.
這五年以來(lái)先后出現(xiàn)了UE3,CE3這種次世代引擎,Torque選擇在這時(shí)候開(kāi)源是明智的(Gamebryo都快撐不住了,OGRE就更別說(shuō)了),它可以做為一款比較適合入門(mén)的引擎.它的技術(shù)經(jīng)過(guò)這么多年這么多人的發(fā)展肯定也有可取之處(當(dāng)年還贊嘆它能把OGL和D3D統(tǒng)一起來(lái)),所以既然開(kāi)源了沒(méi)有不下的道理.架構(gòu)一定要看下,希望不要再讓人糾結(jié)了.
在某些情況下需要做網(wǎng)格的輪廓檢測(cè),例如ShadowVolume,勾邊渲染等,具體算法如下:
假設(shè)參考邊為uv,u和v是兩個(gè)端點(diǎn)所有共享邊uv的面集合記為sides,則:
1.遍歷網(wǎng)格的索引緩存,對(duì)每條邊構(gòu)建sides;
2.對(duì)每個(gè)sides集合,檢查dot(normal(side[i]),view),view是視線方向,如果結(jié)果中有正有負(fù),則該邊為輪廓邊,將輪廓邊加入一個(gè)圖結(jié)構(gòu)graph;
3.在graph中使用深度優(yōu)先算法檢測(cè)回環(huán),如果有回環(huán)就是輪廓.
減面算法一般分減點(diǎn)和減邊兩種,前者減一點(diǎn)會(huì)影響好幾個(gè)面,網(wǎng)格形狀變化會(huì)比較大,所以研究后者比較有意義,一種參考算法如下:
假設(shè)參考邊為uv,u和v是兩個(gè)端點(diǎn),所有共享點(diǎn)u的面集合記為faces,所有共享邊uv的面集合記為sides,則cos(u,v)=max(min(dot(face[i].normal,sides[j].normal)))*length(uv).
接觸極限編程一段時(shí)間,找到以下四點(diǎn)反駁它的理由:
[1]代碼質(zhì)量
極限編程運(yùn)用測(cè)試驅(qū)動(dòng)開(kāi)發(fā)(TDD),其理論基礎(chǔ)是需求應(yīng)該是可測(cè)試的,其目的在于保證軟件系統(tǒng)的正確性和健壯性(測(cè)試用例足夠充分的話)。可以這么認(rèn)為:極限編程關(guān)心的是結(jié)果,不關(guān)心過(guò)程。因此它忽略了軟件系統(tǒng)的結(jié)構(gòu)性和開(kāi)放性。我們知道結(jié)構(gòu)性有助于修改,開(kāi)放性有助于擴(kuò)展,而極限編程卻放棄這種追求,導(dǎo)致的結(jié)果就是產(chǎn)生一大堆丑陋的代碼,而且隨時(shí)有可能被徹底拋棄。
極限編程解決效率,結(jié)構(gòu)性和開(kāi)放性問(wèn)題的對(duì)策是重構(gòu),它宣稱重構(gòu)無(wú)處不在,但是重構(gòu)是一種補(bǔ)救的方式,為什么不在設(shè)計(jì)初期進(jìn)行預(yù)防呢?極限編程回避不了這些問(wèn)題,而只是將它們推到了后面的階段,但是付出的代價(jià)可能會(huì)更高。
[2]工作進(jìn)度
極限編程直接將代碼作為文檔,弱化傳統(tǒng)文檔的作用。既然如此,那么代碼就應(yīng)該有規(guī)范的格式和詳盡的注釋?zhuān)员闾岣咚目勺x性,但是由于極限編程采用的是團(tuán)隊(duì)合作方式,代碼規(guī)范很難得到統(tǒng)一。那么通過(guò)注釋吧,可是極限編程認(rèn)為注釋是一種負(fù)擔(dān),無(wú)法適應(yīng)頻繁修改的代碼。
極限編程解決溝通問(wèn)題的對(duì)策是結(jié)對(duì)編程,它認(rèn)為頻繁的溝通勝過(guò)面面俱到的文檔,但是文檔是永久的,溝通卻是短暫的,大家可以看同一份文檔,卻要進(jìn)行多次兩兩溝通,所需時(shí)間也許并不比寫(xiě)文檔的時(shí)間少。更糟糕的是,經(jīng)常地切換搭檔將極大地破壞工作的延續(xù)性,只能拖慢進(jìn)度。
[3]工作量
測(cè)試驅(qū)動(dòng)開(kāi)發(fā)具體應(yīng)該怎么做呢?測(cè)試驅(qū)動(dòng)決不是說(shuō)代碼從測(cè)試寫(xiě)起,在寫(xiě)測(cè)試用例之前,肯定要對(duì)需求有完整的了解,否則測(cè)試無(wú)從寫(xiě)起,其實(shí)這就是需求分析以及設(shè)計(jì),還是與瀑布模型一樣的流程,只不過(guò)沒(méi)有文檔化而已。唯一不同的是極限編程要求需求都是可測(cè)試的,因此要把這些需求翻譯成系統(tǒng)測(cè)試用例,集成測(cè)試用例,和單元測(cè)試用例。由于寫(xiě)程序必須同時(shí)寫(xiě)它的測(cè)試,因此如果改程序則必須改測(cè)試,這將達(dá)到兩倍的工作量。
[4]目的
極限編程認(rèn)為需求是不斷變化的,因此軟件能滿足當(dāng)前需求就好,沒(méi)有必要構(gòu)造框架之類(lèi)可復(fù)用的東西,它認(rèn)為這是一種過(guò)度設(shè)計(jì)。這種思想是極端的,因?yàn)榭蚣芫褪菫榱私鉀Q需求變化問(wèn)題而出現(xiàn)的。舉個(gè)例子,MFC就是一套框架(盡管我厭惡它),但是基于MFC卻可以開(kāi)發(fā)網(wǎng)絡(luò),多媒體,數(shù)據(jù)庫(kù)甚至游戲應(yīng)用程序。面向?qū)ο蟮哪康木褪菫榱藦?fù)用,而且好的框架能夠做到隔離變化,依賴抽象,如果認(rèn)為軟件系統(tǒng)的一切東西都是暫時(shí)的,無(wú)疑是與面向?qū)ο笏枷氡车蓝Y的。
??? 說(shuō)來(lái)慚愧,學(xué)了這么久的圖形學(xué),今天才動(dòng)手編了自己的第一個(gè)Cg程序,參考的就是那本《The Cg Tutorial》。Cg的GPU概念徹底改變了我對(duì)圖形學(xué)的看法,傳統(tǒng)的程序都是由CPU執(zhí)行的,這種觀念在其它方向的程序員看來(lái)天經(jīng)地義,但是對(duì)于圖形程序員來(lái)說(shuō),從2002年Cg誕生開(kāi)始就已經(jīng)顛覆了。面向GPU編程,讓CPU解放出來(lái),能夠極大地提高了渲染速度。還有,它實(shí)現(xiàn)了可編程的渲染,對(duì)于游戲來(lái)說(shuō),就意味著能夠以腳本的形式來(lái)渲染場(chǎng)景了,如果再配合那些AI腳本,游戲引擎基本上就能夠建立在腳本之上了!大部分的C++程序員都會(huì)對(duì)Cg有種似曾相識(shí)的感覺(jué),因?yàn)樗敲嫦驁D形的C語(yǔ)言,配置和編程都很符合習(xí)慣。對(duì)于使用DirectX的游戲程序員來(lái)說(shuō),Cg與HLSL其實(shí)上同一種語(yǔ)言。我個(gè)人認(rèn)為DirectX的所有組件其實(shí)都可以使用別的工具代替,而Cg則是其中最高級(jí)的替代品,決定用它了。
??????? 畢業(yè)論文的初稿已經(jīng)出來(lái)了,暫時(shí)可以先喘一口氣,我做的是《射擊類(lèi)三維游戲引擎》,總的感覺(jué)是“麻雀雖小,五臟倶全”。我將引擎分成了七塊:界面包、資源包、設(shè)備包、實(shí)體包、實(shí)用包、工具包和一個(gè)程序框架。界面包負(fù)責(zé)顯示視圖,資源包負(fù)責(zé)調(diào)度資源,設(shè)備包負(fù)責(zé)虛擬設(shè)備,實(shí)體包管理游戲中有意義的實(shí)體,實(shí)用包包括物理系統(tǒng)、效果系統(tǒng)、媒體系統(tǒng)和腳本系統(tǒng),工具包包含一些數(shù)學(xué)和圖形學(xué)的數(shù)據(jù)結(jié)構(gòu),程序框架采用Windows的消息驅(qū)動(dòng)和消息映射機(jī)制。體系結(jié)構(gòu)比較清晰,但是技術(shù)含量還有待提高。當(dāng)前主流的游戲引擎都支持圖形兩套引擎(OpenGL和Direct3D)以及一門(mén)高級(jí)渲染語(yǔ)言Cg,而我的引擎只用了OpenGL,只能感嘆自己學(xué)藝不精。圖形學(xué)方面從來(lái)就不缺牛人,而且很多都是從數(shù)學(xué)轉(zhuǎn)過(guò)來(lái)的,不過(guò)我也是從數(shù)學(xué)科班出身,也許幾年之后...不管那么多,向人家取經(jīng)吧。