OpenGL學習筆記(八)

龍雲堯個人博客,轉載請註明出處。

CSDN地址:http://blog.csdn.net/michael753951/article/details/71702311

個人blog地址:http://yaoyl.cn/nehexue-xi-bi-ji-ba/


前言

本部分單獨講Lesson10的內容,本次講述重點將不再是作者在代碼中各種方法如何如何調用,比如如何實現旋轉,如何繪製圖像,如何實現透明,如何實現步進等等,這個在我前面7篇筆記中已經有詳細的說明了,本篇筆記將不再重複,如果有什麼疑問可以翻我之前的筆記或者上網查詢。

本次實驗參變量不少,作者通過代碼帶我們真正的實現了一個3D世界,我們可以在這個3D世界裏面自由的走動和觀察。(也是我們玩的譬如《我的世界》這樣的第一視角遊戲的世界構建的基本)

文中給出了幾個數據結構——tagVERTEX,tagTRIANGLE,tagSECTOR。vertex用來存放每一個座標點的空間直角座標系中的位置(x, y, z)和需要展示的圖像的位置(u, v),trandgle表示三角形中存在的3個點,包含3個tagVERTEX(事實上,現今大多數人都是用無數這樣的三角形來近似/逼近一個曲面),然後sector表示一個由許多三角形構成的體的結構。文中,所有的與體相關的三角形都放在一個文件中,通過讀寫文件來對體進行操作。

代碼分析

好了,大致的介紹已經完成,我們接着看看作者是如何一步一步完成這個3D世界的建設的。(晚上課程中已經解釋的地方我這裏不再重複,而還未解釋清楚的地方我將重點解釋)

作者首先定義了一個readstr方法,用來讀取文件f中的內容,將其讀進string指向的內存空間。接着定義了一個SetupWorld方法,將”data/world.txt”中的內容調用readstr方法讀取內容,並將其寫進 tagSECTOR 類的變量 sector1 中,關於txt中數據格式需要在這裏說明一下——每一行代表一個座標點的信息,包含5個變量,分別爲該點的x軸座標、y軸座標、z軸座標、該點對應的渲染圖片的點的x座標,該點對應的渲染圖片的點的y座標。每3行(即3個點)構成一個3角形。前3個變量各位可能還有印象,後兩個點可以回去看看《nehe學習筆記(五)》,找找glTexCoord2f方法的說明。

然後是和以前一樣的LoadBMP以及LoadGLTextures方法。InitGL方法中,打開紋理映射和深度測試,同時調用之前定義好的SetupWorld方法讀入所有三角形的信息。

接下來就是第一個重頭戲DrawGLScene了,所有的動作都是在這裏展示出來的,理解這一塊的知識對我們將來自己構建3D世界有莫大的幫助。

該部分首先定義了5個浮點數x_m, y_m, z_m, u_m, v_m,分別用來對應tagVERTEX中的5個5種元素。使用xtrans & ytrans & ztrans 分別表示畫筆起筆處的x座標 & y座標 & z座標(也就是說在glTranslatef中將被用到。),接着定義了xtrans & ztrans & ytrans,這三個值決定了畫筆起點沿X軸、Y軸、Z軸移動的長度,也即決定了畫筆的起點位置(也即整張地圖的位置),sceneroty則據定了角色的視覺角度。

變量中我們需要注意,本次實驗中,沿着某軸移動的長度通常以 pos 結尾作爲變量,而旋轉的角度通常以 ros 結尾作爲變量,謹記這一點對我們後期按鍵控制的理解會有幫助。

接着作者調用兩次glRotatef,先將圖像沿着x軸旋轉一定角度(lookupdown),完成擡頭動作,再將圖像沿着y軸旋轉一定角度(sceneroty),完成正面朝向的轉換。

現在我們已經確定了擡頭角度和視角,接下來就要設定你現在所處的位置了——其實就是反方向移動整個3D模型即可,這也就是爲什麼在trans賦值的時候,會取負數的原因。

在上一步驟調用glTranslatef已經繪點結束之後,我們將開始進行圖像繪製,這個部分就不細說了。我對文本中前3行(第一個三角形)標稍作圖解,剩下的你可以自己嘗試繼續繪製。

座標系

到這一步,繪製完成,接下來的KillGLWindow以及CreateGLWindow以及WndProc和之前一致,不解釋。

第二個重頭戲來了,WinMain。這個部分我們將實現通過按鍵控制你在整個3D世界中的遊蕩(其實是在控制整個3D世界移動)。下面我將仔細解釋。

B鍵設置透明,這個之前筆記解釋過,記得disable深度測試,然後enable透明。F鍵設置畫質,不解釋了。

接下來是按up鍵,這個時候首先會更改xpos和zpos,爲什麼會如此修改,期初我也很疑惑,不過在畫了一張圖解之後,便豁然開朗了。我們根據代碼可以知道heading這個變量代表了你當前正臉朝向與Z軸正向的角度(因爲heading賦值給了yrot,而yrot是繞着y軸旋轉的角度,所以heading就是你轉身的角度啦)。

通過下圖我們便可以知道爲什麼使用UP鍵向前走的時候,作者使用如下兩行代碼實現移動了。

up&down

xpos -= (float)sin(heading*piover180) * 0.05f;
zpos -= (float)cos(heading*piover180) * 0.05f;

接着作者在pos變換完成以後,稍稍微修改walkbias變量,它將影響到ypos,從而模仿人行走的時候的高低起伏,讓人更加自然。

接下來的 left, right, page_up & page_down 按鍵的反饋設置就基本不用解釋啦,你按照右手定則稍稍爲跟着做一下就能夠理解啦。需要注意的是,在WinMain中,所有的pos和trans都是從觀察者的角度進行變換的,真正的變換是在DrawGLScene,在DrawGLScene方法中我們已經對數據做了特殊處理以保證顯示正常自然。

好了,到這裏本章節的代碼也就解釋完畢了,粗讀代碼會覺得很容易,因爲都是我們之前已經掌握的內容,但是細想作者是如何一步一步具體實現的時候,情況就會複雜很多。通過不斷畫圖和翻以前的代碼,我纔不斷的深入理解整個OpenGL的原理,以及3D模型的構建原理和過程。至此,OpenGL應該算是正式入門了吧。

稍稍留一個小問題,你知道爲什麼作者在DrawGLScene方法中,xtrans直接賦值爲xpos的負值,ztrans同樣直接賦值爲zpos的負值,sceneroty也是直接取了yrot的負值(不過爲了嚴謹,又添了一個360作爲進位),偏偏ytrans要在賦值爲walkbias的負值之後,還要減去一個0.25呢?(提示,walkbias乘上sin之後有正有負,如果不添加一個常數,你的“眼睛”就會在地板所在的y=0面上不斷上下抖動,而添加0.25之後,則是將你的“眼睛”提高到了一定的高度,讓你有了身高的感覺,從而更加自然)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章