久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

android 3D系列之基本概念篇

 487qq 2013-09-26

最近不是很忙,,所以打算從這周開始學(xué)習(xí)android3D繪圖,。網(wǎng)絡(luò)上已經(jīng)有大量有關(guān)OpenGL的好教程和書籍。但是,,卻沒有多少是關(guān)于OpenGLES,更加沒有多少是專門針對學(xué)習(xí)android3D編程的,。為了養(yǎng)成良好的學(xué)習(xí)習(xí)慣,,也算是給自己的學(xué)習(xí)過程做一個總結(jié)、筆記,,我決定按照自己的學(xué)習(xí)規(guī)矩,,撰寫一個針對android3D初學(xué)者的博文系列。這是此系列的第一篇文章,。

基本概念

為了方便后邊的編程,,我們第一篇文章主要是介紹一些關(guān)于OpenGLES基本的概念。

點(diǎn)

3D圖像的最小單位稱為點(diǎn)(point或者頂點(diǎn)vertex,。它們代表三維空間中的一個點(diǎn)并用來建造更復(fù)雜的物體,。多邊形就是由點(diǎn)構(gòu)成,而物體是由多個多邊形組成,。盡管通常OpenGL支持多種多邊形,,但OpenGLEs只支持三邊形(即三角形)所以即使我們要繪制一個正方形也要把它拆分為兩個三角形繪制。先說說坐標(biāo)系的問題,。

默認(rèn)情況下,,以屏幕中心為坐標(biāo)軸原點(diǎn)。原點(diǎn)左方x為負(fù)值,,右邊為正值,。原點(diǎn)上方y為正,原點(diǎn)下方為負(fù),。垂直屏幕向外為z正,,垂直屏幕向里為z負(fù)。默認(rèn)情況下,,從原點(diǎn)到屏幕邊緣為1.0f,沿各軸增加或減小的數(shù)值是以任意刻度進(jìn)行的–它們不代表任何真實單位,,如英尺,像素或米等,。你可以選擇任何對你的程序有意義的刻度(全局必須保持單位一致,,不能一部分使用米,一部分使用像素),。OpenGL只是將它作為一個參照單位處理,,保證它們具有相同的距離。如圖:

                                                

了解了坐標(biāo)軸,我們來看看怎么在坐標(biāo)系中表示一個點(diǎn),,通常用一組浮點(diǎn)數(shù)來表示點(diǎn),。例如一個正方形的4個頂點(diǎn)可表示為:


  1. float vertices[] = {  

  2.       -1.0f, 1.0f, 0.0f, //左上  

  3.       -1.0f, -1.0f, 0.0f, //左下  

  4.        1.0f, -1.0f, 0.0f, //右下  

  5.        1.0f, 1.0f, 0.0f,  //右上  

  6. };   


為了提高性能,通常還需要將浮點(diǎn)數(shù)組存入一個字節(jié)緩沖中,。所以有了下面的操作:

  1. ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);  //申請內(nèi)存

  2. vbb.order(ByteOrder.nativeOrder());  //設(shè)置字節(jié)順序,,其中ByteOrder.nativeOrder()是獲取本機(jī)字節(jié)順序

  3. FloatBuffer vertexBuffer = vbb.asFloatBuffer();  //轉(zhuǎn)換為float

  4. vertexBuffer.put(vertices);  //添加數(shù)據(jù)

  5. vertexBuffer.position(0);  //設(shè)置緩沖區(qū)起始位置

OpenGLES的很多函數(shù)功能的使用狀態(tài)是處于關(guān)閉的。啟用和關(guān)閉這些函數(shù)可以用glEnableClientState,、glDisableClientState來完成,。

  1. // 指定需要啟用定點(diǎn)數(shù)組  

  2. gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);  

  3. // 說明啟用數(shù)組的類型和字節(jié)緩沖,類型為GL_FLOAT  

  4. gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);  

  5. // 不再需要時,,關(guān)閉頂點(diǎn)數(shù)組  

  6. gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);  



多邊形

多邊形是由點(diǎn)和邊構(gòu)成的單閉合環(huán),。 繪制多邊形時需要特別注意頂點(diǎn)的繪制順序,可以分為順時針和逆時針,。因為方向決定了多邊形的朝向,, 即正面和背面。避免渲染那些被遮擋的部分可以了有效提高程序性能,。默認(rèn)以逆時針次序繪制頂點(diǎn)的構(gòu)成的面是正面,。

可以通過glFrontFace函數(shù)來交換“正面”和“反面”的概念。
glFrontFace(GL_CCW);  // 
設(shè)置CCW方向為“正面”,,CCWCounterClockWise,,逆時針
glFrontFace(GL_CW);   // 
設(shè)置CW方向為“正面”,CWClockWise,,順時針


渲染

      有了以上的概念講解后,,現(xiàn)在要進(jìn)行最主要的工作—渲染。渲染是把物體坐標(biāo)所指定的圖元轉(zhuǎn)化成幀緩沖區(qū)中的圖像,。圖像和頂點(diǎn)坐標(biāo)有著密切的關(guān)系,。這個關(guān)系通過繪制模式給出。常用到得繪制模式有GL_POINTS,、GL_LINE_STRIP,、GL_LINE_LOOPGL_LINES,、GL_TRIANGLES,、GL_TRIANGLE_STRIPGL_TRIANGLE_FAN,。下面分別介紹:

  •  GL_POINTS:把每一個頂點(diǎn)作為一個點(diǎn)進(jìn)行處理,,頂點(diǎn)n即定義了點(diǎn)n,共繪制n個點(diǎn),。

  • GL_LINES:把每一個頂點(diǎn)作為一個獨(dú)立的線段,,頂點(diǎn)2n-12n之間共定義了n個線段,,總共繪制N/2條線段。,,如果N為奇數(shù),,則忽略最后一個頂點(diǎn)。
  

 

  • GL_LINE_STRIP:繪制從第一個頂點(diǎn)到最后一個頂點(diǎn)依次相連的一組線段,,第nn+1個頂點(diǎn)定義了線段n,,總共繪制N-1條線段。

 

  • GL_LINE_LOOP:繪制從定義第一個頂點(diǎn)到最后一個頂點(diǎn)依次相連的一組線段,,然后最后一個頂點(diǎn)與第一個頂點(diǎn)相連,。第nn+1個頂點(diǎn)定義了線段n,然后最后一個線段是由頂點(diǎn)N1之間定義,,總共繪制N條線段。

  • GL_TRIANGLES:把每三個頂點(diǎn)作為一個獨(dú)立的三角形,。頂點(diǎn)3n-2,,3n-13n定義了第n個三角形,總共繪制N/3個三角形,。

 

  • GL_TRIANGLE_STRIP:繪制一組相連的三角形,。對于奇數(shù)點(diǎn)n,頂點(diǎn)n,,n+1n+2定義了第n個三角形,;對于偶數(shù)n,頂點(diǎn)n+1,,nn+2定義了第n個三角形,,總共繪制N-2個三角形。這是最常使用的渲染方式,,第一個三角形條是由前三個頂點(diǎn)構(gòu)成(索引0,1, 2),。第二個三角形條是由前一個三角形的兩個頂點(diǎn)加上數(shù)組中的下一個頂點(diǎn)構(gòu)成,繼續(xù)直到整個數(shù)組結(jié)束,。

  • GL_TRIANGLE_FAN:繪制一組相連的三角形,。三角形是由第一個頂點(diǎn)及其后給定的頂點(diǎn)所確定。頂點(diǎn)1,,n+1n+2定義了第n個三角形,,總共繪制N-2個三角形。

 


繪制圖形步驟:

1.定義頂點(diǎn)并且轉(zhuǎn)換存儲在字節(jié)緩沖中;

2.我們使用頂點(diǎn)數(shù)組繪制圖形,,而opengles是默認(rèn)關(guān)閉這個開關(guān)的,,所以我們要啟用它。gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

3.設(shè)置繪制的顏色,。以下為設(shè)置紅色

  gl.glColor4f(1.0, 0.0, 0.0, 1.0);? //R,,GBA
4.由于我們使用頂點(diǎn)數(shù)組,,我們必須通知OpenGL頂點(diǎn)的數(shù)組在什么地方,。需使用函數(shù):

gl.glVertexPointer(

         3,//每個頂點(diǎn)的坐標(biāo)的維數(shù),這里為3xyz

         GL10.GL_FIXED,//頂點(diǎn)坐標(biāo)值的類型為GL_FIXED

         0,//數(shù)組中數(shù)據(jù)的偏移值

         mVertexBuffer//頂點(diǎn)坐標(biāo)數(shù)據(jù)數(shù)組

       );

        5.開始繪圖

          gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,0, 9);

        函數(shù)原型         voidglDrawArrays(int mode, int first, int count)

mode為繪制式,,GL_POINTS,、GL_LINESGL_TRIANGLES,、GL_TRIANGLE_STRIP等,。first為數(shù)據(jù)在數(shù)組中的起始位置,讀取數(shù)據(jù)的個數(shù)


視圖與透視

我們生活在一個三維的世界——如果要觀察一個物體,,我們可以:
1,、從不同的位置去觀察它。(視圖變換)
2,、移動或者旋轉(zhuǎn)它,,當(dāng)然了,如果它只是計算機(jī)里面的物體,,我們還可以放大或縮小它,。(模型變換)
3、如果把物體畫下來,,我們可以選擇:是否需要一種“近大遠(yuǎn)小”的透視效果,。另外,我們可能只希望看到物體的一部分,,而不是全部(剪裁),。(投影變換)
4、我們可能希望把整個看到的圖形畫下來,,但它只占據(jù)紙張的一部分,,而不是全部。(視口變換)
這些,,都可以在OpenGL中實現(xiàn),。

OpenGL變換實際上是通過矩陣乘法來實現(xiàn)。無論是移動,、旋轉(zhuǎn)還是縮放大小,,都是通過在當(dāng)前矩陣的基礎(chǔ)上乘以一個新的矩陣來達(dá)到目的。

1,、模型變換和視圖變換

即設(shè)置3D模型的位移,,旋轉(zhuǎn)等屬性。由于模型和視圖的變換都通過矩陣運(yùn)算來實現(xiàn),,在進(jìn)行變換前,,應(yīng)先設(shè)置當(dāng)前操作的矩陣為“模型視圖矩陣”,。設(shè)置的方法是以GL_MODELVIEW為參數(shù)調(diào)用glMatrixMode函數(shù),像這樣:
glMatrixMode(GL_MODELVIEW);
通常,,我們需要在進(jìn)行變換前把當(dāng)前矩陣設(shè)置為單位矩陣,。這也只需要一行代碼:
glLoadIdentity();
然后,就可以進(jìn)行模型變換和視圖變換了,。進(jìn)行模型和視圖變換,,主要涉及到三個函數(shù):
glTranslate*,(*表示這個函數(shù)分為float型的glTranslatef和int型的glTranslatex)把當(dāng)前矩陣和一個表示移動物體的矩陣相乘,。三個參數(shù)分別表示了在三個坐標(biāo)上的位移值,。
glRotate*,把當(dāng)前矩陣和一個表示旋轉(zhuǎn)物體的矩陣相乘,。物體將繞著(0,0,0)到(x,y,z)的直線以逆時針旋轉(zhuǎn),,參數(shù)angle表示旋轉(zhuǎn)的角度。
glScale*,,把當(dāng)前矩陣和一個表示縮放物體的矩陣相乘,。x,y,z分別表示在該方向上的縮放比例。


2,、投影變換
投影變換就是定義一個可視空間,可視空間以外的物體不會被繪制到屏幕上,。(注意,,從現(xiàn)在起,坐標(biāo)可以不再是-1.0到1.0了?。?br> OpenGL支持兩種類型的投影變換,,即透視投影和正投影。投影也是使用矩陣來實現(xiàn)的,。如果需要操作投影矩陣,,需要以GL_PROJECTION為參數(shù)調(diào)用glMatrixMode函數(shù)。
glMatrixMode(GL_PROJECTION);
通常,,我們需要在進(jìn)行變換前把當(dāng)前矩陣設(shè)置為單位矩陣,。
glLoadIdentity();

透視投影所產(chǎn)生的結(jié)果類似于照片,有近大遠(yuǎn)小的效果,,比如在火車頭內(nèi)向前照一個鐵軌的照片,,兩條鐵軌似乎在遠(yuǎn)處相交了。
使用glFrustum函數(shù)可以將當(dāng)前的可視空間設(shè)置為透視投影空間,。其參數(shù)的意義如下圖:
http://image64.360doc.com/DownloadImg/2013/09/2614/35466157_2.gif
聲明:該圖片來自www.opengl.org,,該圖片是《OpenGL編程指南》一書的附圖,由于該書的舊版(第一版,,1994年)已經(jīng)流傳于網(wǎng)絡(luò),,我希望沒有觸及到版權(quán)問題,。
也可以使用更常用的gluPerspective函數(shù)。其參數(shù)的意義如下圖:
http://image64.360doc.com/DownloadImg/2013/09/2614/35466157_3.gif
聲明:該圖片來自www.opengl.org,,該圖片是《OpenGL編程指南》一書的附圖,,由于該書的舊版(第一版,1994年)已經(jīng)流傳于網(wǎng)絡(luò),,我希望沒有觸及到版權(quán)問題,。

正投影相當(dāng)于在無限遠(yuǎn)處觀察得到的結(jié)果,它只是一種理想狀態(tài),。但對于計算機(jī)來說,,使用正投影有可能獲得更好的運(yùn)行速度。
使用glOrtho函數(shù)可以將當(dāng)前的可視空間設(shè)置為正投影空間,。其參數(shù)的意義如下圖:
http://pubimage.360doc.com/wz/default.gif
聲明:該圖片來自www.opengl.org,,該圖片是《OpenGL編程指南》一書的附圖,由于該書的舊版(第一版,,1994年)已經(jīng)流傳于網(wǎng)絡(luò),,我希望沒有觸及到版權(quán)問題。

如果繪制的圖形空間本身就是二維的,,可以使用gluOrtho2D,。他的使用類似于glOrgho。


3,、視口變換
當(dāng)一切工作已經(jīng)就緒,,只需要把像素繪制到屏幕上了。這時候還剩最后一個問題:應(yīng)該把像素繪制到窗口的哪個區(qū)域呢,?通常情況下,,默認(rèn)是完整的填充整個窗口,但我們完全可以只填充一半,。(即:把整個圖象填充到一半的窗口內(nèi))
http://pubimage.360doc.com/wz/default.gif
聲明:該圖片來自www.opengl.org,,該圖片是《OpenGL編程指南》一書的附圖,由于該書的舊版(第一版,,1994年)已經(jīng)流傳于網(wǎng)絡(luò),,我希望沒有觸及到版權(quán)問題。

使用glViewport來定義視口,。其中前兩個參數(shù)定義了視口的左下腳(0,0表示最左下方),,后兩個參數(shù)分別是寬度和高度。


追加:

想象一下你站在一個3d世界中,。你的頭頂上有一個朝上的箭頭在跟隨,。然后你抬起頭,看了下掛在碧天上的驕陽,;低下頭,,看到自己的腳踏在褐色的土地上,。然后轉(zhuǎn)動你的頭傾,看到一片片幽幽的麥地直到地平線的盡頭?,F(xiàn)在,,你的眼睛就充當(dāng)了攝像機(jī)。

在opengl中你總是工作在3d世界中,,即使opengles也是如此,。秘密是在2d引擎下,z坐標(biāo)被隱藏了,。所以暫時忘記2d和3d的不同之處,。如下圖,用你的眼睛掃過的地方是一個金字塔形狀的物體(frustum),。所有處在這個梯形中的物體都將是可視的,。
此梯狀物體具有6個變量:near, far, left, right, top and bottom。

  • near:最近的距離,,小于此距離的物體將不可見,。就像是你把一張紙緊貼在眼睛上,是看不到紙上的內(nèi)容一樣
  • far: 最遠(yuǎn)距離,,大于此距離的物體也將不可見,。


那么我們把3D世界轉(zhuǎn)換成2D圖像的這個過程,就叫做投影(projection),。典型的,,有兩種投影方式:正交投影(orthographic projection)和透視投影(perspective projection)

  • 正交投影(orthographic projection)主要用在2D世界中,它不管物體離我們多遠(yuǎn),,都一致處理,比較簡單,。
  • 透視投影是3D固定流水線的重要組成部分,,用在真實的世界中。是將相機(jī)空間中的點(diǎn)從視錐體(frustum)變換到規(guī)則觀察體(Canonical View Volume)中,,待裁剪完畢后進(jìn)行透視除法的行為,。在算法中它是通過透視矩陣乘法和透視除法兩步完成的。透視投影符合人們心理習(xí)慣,,即離視點(diǎn)近的物體大,,離視點(diǎn)遠(yuǎn)的物體小,遠(yuǎn)到極點(diǎn)即為消失,,成為滅點(diǎn),。它的視景體類似于一個頂部和底部都被切除掉的棱椎,也就是棱臺,。

這兩種視圖看起來就像這樣:




一本不錯的電子教程,,OpenGL的,,雖然是使用c++為編程語言,但是函數(shù)都是一樣的,,Nehe的OpenGl入門教程http://download.csdn.net/source/3566454

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多