計算機圖形學opengl教程第44課3d光暈_第1頁
計算機圖形學opengl教程第44課3d光暈_第2頁
計算機圖形學opengl教程第44課3d光暈_第3頁
計算機圖形學opengl教程第44課3d光暈_第4頁
計算機圖形學opengl教程第44課3d光暈_第5頁
已閱讀5頁,還剩8頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、第 44 課 3D 光暈當鏡頭對準的時候就會出現(xiàn)這種效果,模擬它非常的簡單,一點數(shù)學和紋理貼圖就夠了。好好看看吧。大家好,歡迎來到新的一課,在這一課中擴展 glCamera 類,來實現(xiàn)鏡頭光暈的效果。在日常生活中,當對著光源看時,會發(fā)現(xiàn)反光。為了完成這個效果,需要一些數(shù)學知識。首先,需要一些函數(shù),用來檢測某個點或球是否在當前的視景體內(nèi)。接著需要一些紋理作為的光暈效果,可以把它貼在顯示面上。在上一個機類里把下面函數(shù)寫錯了,現(xiàn)在修正如下:void glCamera:SetPrespective() GLfloat Matrix16; r v;/ 根據(jù)當前的偏轉(zhuǎn)角旋轉(zhuǎn)視線glVectoglRoglR

2、oef(m_HeadingDegrees, 0.0f, 1.0f, 0.0f);ef(m_PitchDegrees, 1.0f, 0.0f, 0.0f);/ 返回模型變換矩陣glGetFloatv(GL_MVIEW_MATRIX, Matrix);/ 獲得視線的方向 m_DirectionVector.i m_DirectionVector.jm_DirectionVector.k=Matrix8; Matrix9;-Matrix10;/ 重置矩陣glLoadIdentity();/ 旋轉(zhuǎn)場景glRoglRoef(m_PitchDegrees, 1.0f, 0.0f, 0.0f);ef(m_H

3、eadingDegrees, 0.0f, 1.0f, 0.0f);/ 設置當前機的位置v = m_DirectionVector;v *= m_ForwardVelocity;m_ m_m_ition.x ition.yition.z+=+=+=v.i;v.j;v.k;/ 變換到新的位置glTranslatef(-m_ition.x, -m_ition.y, -m_ition.z);好了,現(xiàn)在開始吧。我將使用 4 個對立的紋理來制造的鏡頭光暈,第一和二個光暈圖像被放置在光源處,第三和第四個圖像將根據(jù)視點的位置和方向動態(tài)的生成。紋理的圖像如下所示:Big GlowStreaksGlowHalo現(xiàn)

4、在你在頭腦里應該有了一個大慨地圖像了吧。來說說何時應該繪制光暈,一般來說平時是看不見這些光暈的,只有當對準光源的時候才能看見這些。所以首先要獲得視景體的數(shù)據(jù),下面的函數(shù)可以幫完成這個功能。/ 獲得當前視景體的 6 個平面方程的參數(shù) void glCamera:UpdateFrustum()GLfloatt;clip16; GLfloat/返回投影矩陣proj16;GLfloatmodl16;GLfloatglGetFloatv( GL_PROJECTION_MATRIX, proj );/返回模型變換矩陣glGetFloatv( GL_MVIEW_MATRIX, modl);/計算剪切矩陣,即

5、上面兩個矩陣的乘積clip 8clip 9clip 0 +clip1 +0 = modl+ modl 31 = modl+ modl 30 * proj* proj12; 0 * proj* proj13; 0 * proj proj14;0 * projproj15;0+modl1*proj4+modl2*proj1+modl1*proj5+modl2*proj2 =modl 3 =modlmodl 3 * modl3 *2+modl1*proj6+modl2*proj13+modl1*proj7+modl2*proj1clip 8clip 9clip 0 +clip1 +4 =modl4

6、* proj* proj12; 4 * proj* proj13; 4 * proj proj14;4 * projproj15;0+modl5*proj4+modl6*proj+ modl 75 = modl+ modl 71+modl5*proj5+modl6*proj6 =modl 7 =modlmodl 7 * modl7 *2+modl5*proj6+modl6*proj13+modl5*proj7+modl6*proj1clip 8clip 98 =modl8 * proj* proj12; 8 * proj* proj13;0+modl9*proj4+modl10 * proj+

7、 modl11 9 = modl+ modl111+modl9*proj5+modl10 * projclip10 = modl 0 + modl11 * clip11 = modl1 + modl11 *8 * proj 2 + modl 9 proj14;8 * proj 3 + modl 9proj15;* proj 6+ modl10 * proj1* proj 7+ modl10 * proj1clip12 8 +clip13= modl12 modl15 *= modl12* proj 0 + modl13 * proj12;* proj 1 + modl13 *proj 4 +m

8、odl14 * projproj 5 +modl14 * proj 9 + modl15 * proj13;clip14 = modl12 * proj 2 + modl13 * proj 6 + modl14 * proj1 0 + modl15 * proj14;clip15 = modl12 * proj 3 + modl13 * proj 7 + modl14 * proj11 + modl15 * proj15;/提取右面的平面方程系數(shù)m_Frustum00 m_Frustum01 m_Frustum02m_Frustum03=clip 3 - clip 0;clip 7 - cli

9、p 4;clip11 - clip 8;clip15 - clip12;t = GLfloat(sqrt( m_Frustum00 * m_Frustum001 + m_Frustum02 * m_Frustum02 );+m_Frustum01*m_Frustum0m_Frustum00 m_Frustum01 m_Frustum02m_Frustum03/=/=/=/=t;t;t;t;/提取左面的平面方程系數(shù)m_Frustum10 m_Frustum11 m_Frustum12m_Frustum13=clip 3 + clip 0;clip 7 + clip 4; clip11 + cli

10、p 8; clip15 + clip12;t = GLfloat(sqrt( m_Frustum10 * m_Frustum101 + m_Frustum12 * m_Frustum12 );+m_Frustum11*m_Frustum1m_Frustum10 m_Frustum11 m_Frustum12m_Frustum13/=/=/=/=t;t;t;t;/提取下面的平面方程系數(shù)m_Frustum20 m_Frustum21 m_Frustum22m_Frustum23=clip 3 + clip 1;clip 7 + clip 5; clip11 + clip 9; clip15 + c

11、lip13;t = GLfloat(sqrt( m_Frustum20 * m_Frustum201 + m_Frustum22 * m_Frustum22 );+m_Frustum21*m_Frustum2m_Frustum20 m_Frustum21 m_Frustum22m_Frustum23/=/=/=/=t;t;t;t;/提取上面的平面方程系數(shù)m_Frustum30 = clip 3 - clip 1;m_Frustum31 = clip 7 - clip 5;m_Frustum32 = clip11 - clip 9; m_Frustum33 = clip15 - clip13;t

12、 = GLfloat(sqrt( m_Frustum30 * m_Frustum301 + m_Frustum32 * m_Frustum32 );+m_Frustum31*m_Frustum3m_Frustum30 m_Frustum31 m_Frustum32m_Frustum33/=/=/=/=t;t;t;t;/提取遠面的平面方程系數(shù)m_Frustum40 m_Frustum41 m_Frustum42m_Frustum43=clip 3 - clip 2;clip 7 - clip 6;clip11 - clip10;clip15 - clip14;t = GLfloat(sqrt(

13、m_Frustum40 * m_Frustum401 + m_Frustum42 * m_Frustum42 );+m_Frustum41*m_Frustum4m_Frustum40 m_Frustum41 m_Frustum42m_Frustum43/=/=/=/=t;t;t;t;/提取近面的平面方程系數(shù)m_Frustum50 m_Frustum51 m_Frustum52m_Frustum53=clip 3 + clip 2;clip 7 + clip 6; clip11 + clip10; clip15 + clip14;t = GLfloat(sqrt( m_Frustum50 * m

14、_Frustum501 + m_Frustum52 * m_Frustum52 );+m_Frustum51*m_Frustum5m_Frustum50 m_Frustum51 m_Frustum52 m_Frustum53/=/=/=/=t;t;t;t;現(xiàn)在可以測試一個點或圓是否在視景體內(nèi)了。下面的函數(shù)可以測試一個點是否在視景體內(nèi)。BOOL glCamera:PoInFrustum(glPop)i; for(i = 0; i 6; i+) if(m_Frustumi0 * p.x + m_Frustumi1 * p.y + m_Frustumi2 * p.z + m_Frustumi3 =

15、0)return(FALSE); return(TRUE);下面的函數(shù)用來測試某個點是否位于當前場景物體的前面:bool glCamera:IsOccluded(glPop) GLviewport4;GLdouble mvmatrixGLdouble flare16, Z;glGetprojmatrix16;GLdouble winx, winy, winz;GLfloat bufferZ;egerv (GL_VIEWPORT, viewport);glGetDoublev (GL_MVIEW_MATRIX, mvmatrix);glGetDoublev (GL_PROJECTION_MATR

16、IX, projmatrix);/ 返回頂點p 在立方體中的位置gluProject(p.x, p.y, p.z, mvmatrix, projmatrix, viewport,flareZ = winz;&winx, &winy, &winz);/glRe點(winx,winy)的深度坐標ixels(winx, winPONENT, GL_FLOAT, &bufferZ);/ 如果深度坐標小于點的坐標,則返回 true if (bufferZ flareZ)return true;/否則返回 false elsereturn false;通過檢測光源是否正對的視線來決定是否繪制光暈,但如果你

17、的視點超過了光源的位置,則會發(fā)生看不見光暈的現(xiàn)象。為了避免這種現(xiàn)象,在移動視點的使用,也相應的移動的光源。為了在視點和光源之間繪制多個光暈,需要計算之間的向量,下面的代碼完成這個功能:/下面的函數(shù)完成具體的渲染光暈的任務 void glCamera:RenderLensFlare() GLfloh = 0.0f;engt/ 如果的光源在的視線范圍內(nèi),則繪制它if(SphereInFrustum(m_LightSource, 1.0f) = TRUE)vLightSourceToCamera = m_ition - m_LightSource; / 計算光源到視線的距離Length = vLig

18、htSourceToCamera.Magnitude();/下面三個函數(shù)計算光源位置到光暈結(jié)束位置之間的向量ptptersect = m_DirectionVector * Length;ersect += m_ition;vLightSourceToersect = ptersect - m_LightSource;Length = vLightSourceToersect.Magnitude();vLightSourceToersect.Normalize();glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glDisable(

19、GL_DEPTH_TEST);glEnable(GL_TEXTURE_2D);首先需要找到光源位置和視點位置之間的向量,接下來需要在視線的方向設置一個插值點,這個點的距離必須和光源位置和視點位置之間的距離相等。完成以后,找出可以產(chǎn)生光暈的方向,即下圖紅線的方向,在這個線上可以繪制的光暈。if (!IsOccluded(m_LightSource) /如果光暈可見/ 渲染中間的光暈RenderBigGlow(0.60f, 0.60f, 0.8f, 1.0f, m_LightSource, 16.0f);RenderGlow(0.8f,RenderStreaks(0.60f, 0.60f, 0.8

20、f, 1.0f, m_LightSource, 16.0f);0.8f,1.0f,0.5f, m_LightSource, 3.5f);/繪制到光暈結(jié)束位置的 0.1 處的光暈pt = vLightSourceTopt += m_LightSourceersect * (Length;* 0.1f);RenderGlow(0.9f, 0.6f, 0.4f, 0.5f, pt,0.6f);/繪制到光暈結(jié)束位置的 0.15 處的光暈pt = vLightSourceTopt += m_LightSourceersect * (Length;* 0.15f);RenderHalo(0.8f, 0.5

21、f, 0.6f, 0.5f, pt,1.7f);/繪制到光暈結(jié)束位置的 0.175 處的光暈pt = vLightSourceTopt += m_LightSourceersect * (Length;* 0.175f);RenderHalo(0.9f, 0.2f, 0.1f, 0.5f, pt,0.83f);/繪制到光暈結(jié)束位置的 0.285 處的光暈pt = vLightSourceTopt += m_LightSourceersect * (Length;* 0.285f);RenderHalo(0.7f, 0.7f, 0.4f, 0.5f, pt,1.6f);/繪制到光暈結(jié)束位置的 0

22、.2755 處的光暈pt = vLightSourceTopt += m_LightSourceersect * (Length;* 0.2755f);RenderGlow(0.9f, 0.9f, 0.2f, 0.5f, pt,0.8f);/繪制到光暈結(jié)束位置的 0.4755 處的光暈pt = vLightSourceTopt += m_LightSourceersect * (Length;*0.4775f);RenderGlow(0.93f, 0.82f, 0.73f, 0.5f, pt,1.0f);/繪制到光暈結(jié)束位置的 0.49 處的光暈pt = vLightSourceTopt +=

23、 m_LightSourceersect * (Length;*0.49f);RenderHalo(0.7f, 0.6f, 0.5f, 0.5f, pt,1.4f);/繪制到光暈結(jié)束位置的 0.65 處的光暈pt = vLightSourceTopt += m_LightSourceersect * (Length;* 0.65f);RenderGlow(0.7f, 0.8f, 0.3f, 0.5f, pt,1.8f);/繪制到光暈結(jié)束位置的 0.63 處的光暈pt = vLightSourceTopt += m_LightSourceersect * (Length;* 0.63f);Ren

24、derGlow(0.4f, 0.3f, 0.2f, 0.5f, pt,1.4f);/繪制到光暈結(jié)束位置的 0.8 處的光暈pt = vLightSourceTopt += m_LightSourceersect * (Length;* 0.8f);RenderHalo(0.7f, 0.5f, 0.5f, 0.5f, pt,1.4f);/繪制到光暈結(jié)束位置的 0.7825 處的光暈pt = vLightSourceTopt += m_LightSourceersect * (Length;* 0.7825f);RenderGlow(0.8f, 0.5f, 0.1f, 0.5f, pt,0.6f)

25、;/繪制到光暈結(jié)束位置的 1.0 處的光暈pt = vLightSourceTopt += m_LightSourceersect * (Length;* 1.0f);RenderHalo(0.5f, 0.5f, 0.7f, 0.5f, pt,1.7f);/繪制到光暈結(jié)束位置的 0.975 處的光暈pt = vLightSourceTopt += m_LightSourceersect * (Length;* 0.975f);RenderGlow(0.4f, 0.1f, 0.9f, 0.5f, pt,2.0f);glDisable(GL_BLEND ); glEnable(GL_DEPTH_T

26、EST); glDisable(GL_TEXTURE_2D);好了,下面的函數(shù)用來繪制四種不同的光暈/繪制 Halo 形的光暈 void glCamera:RenderHalo(GLfloatr,GLfloat g,GLfloatb, GLfloat a, glPoe);p, GLfloat scale)q0.y =scale);q2.xscale);glPo(p.yq4;- scale);q0.x = (p.x-scalq1.x = e); y = e);ix();(p.x-q1.y = (p.y + scal= (p.x + scale);q2.(p.y-q3.x=(p.x+scalq3.

27、y = (p.y + scale);glTranslatef(p.x, p.y,glPushMatrp.z);glRoef(-m_HeadingDegrees, 0.0f, 1.0f,0.0f); glRoef(-m_PitchDegrees, 1.0f, 0.0f, 0.0f);(r,P);y);f);glBindTexture(GL_TEXTURE_2D,g, b, a);m_HaloTexture);glColor4fglBegin(GL_TRIANGLE_STRIglTexCoord2f(0.0f, 0.0f);glVertex2f(q0.x, q0.glTexCoord2f(0.0f

28、,glVertex2f(q2.x,1.0f);q2.y);glVertex2f(q1.x, q1.y);glTexCoord2f(1.0f, 1.0f); glPopMatrix();glTexCoord2f(1.0f, glVertex2f(q3.x,0.0q3.y); glEnd();/繪制 Gloew 形的光暈void glCamera:RenderGlow(GLfloat t p, GLfloat scale)r,GLfloatg,GLfloatb,GLfloata,glPoinglPoq4;q0.xq0.y=(p.x(p.y-scale);scale);q1.xq1.y=(p.x(p

29、.y-+scale);scale);q2.xq2.y=(p.x(p.y+-scale);scale);q3.xq3.y=(p.x(p.y+scale);scale);glPushMatrix();glTranslatef(p.x, p.y, p.z);glRoglRoef(-m_HeadingDegrees, 0.0f,1.0f, 0.0f);ef(-m_PitchDegrees, 1.0f, 0.0f, 0.0f);glBindTexture(GL_TEXTURE_2D, m_GlowTexture);glColor4f(r, g, b, a);glBegin(GL_TRIANGLE_STR

30、IP);glTexCoord2f(0.0f, glVertex2f(q0.x, glTexCoord2f(0.0f, glVertex2f(q1.x, glTexCoord2f(1.0f, glVertex2f(q2.x, glTexCoord2f(1.0f, glVertex2f(q3.x, glEnd(); glPopMatrix();0.0f); q0.y); 1.0f); q1.y); 0.0f); q2.y); 1.0f);q3.y);/繪制 BigGlow 形的光暈void glCamera:RenderBigGlow(GLfloat t p, GLfloat scale)r,GL

31、floatg,GLfloatb,GLfloata,glPoinglPoq4;q0.xq0.y=(p.x(p.y-scale);scale);q1.xq1.y=(p.x(p.y-+scale);scale);q2.xq2.y=(p.x(p.y+-scale);scale);q3.xq3.y=(p.x(p.y+scale);scale);glPushMatrix();glTranslatef(p.x, p.y, p.z);glRoglRoef(-m_HeadingDegrees, 0.0f,1.0f, 0.0f);ef(-m_PitchDegrees, 1.0f, 0.0f, 0.0f);glBindTexture(GL_TEXTURE_2D, m_BigGlowTexture);glColor4f(r, g, b, a);glBegin(GL_TRIANGLE_STRIP);glTexCoord2f(0.0f, glVertex2f(q0.x, glTexCoord2f(0.0f, glVertex2f(q1.x, glTexCoord2f(1.0f, glVertex2f(q2.x, glTexCoord2f(1.0f, g

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論