• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Shuffy

            不斷的學(xué)習(xí),不斷的思考,才能不斷的進(jìn)步.Let's do better together!
            posts - 102, comments - 43, trackbacks - 0, articles - 19

            《基于MFC的OpenGL編程》Part 17 Shadows

            Posted on 2010-03-31 20:52 Shuffy 閱讀(421) 評論(0)  編輯 收藏 引用 所屬分類: MFC,OpenGL

            Shadows

            Conceptually drawing a shadow is quite simple. A shadow is produced when an object keeps light from a source from striking some object or surface behind the object, casting the shadow. The area on the shadowed object's surface outlined by the object casting the shadow appears dark. We can produce a shadow programatically by flattening the original object into the plane of the surface in which the object lies. The object is then drawn in black or some other color. This is a very simple method which works when casting shadows on a flat surface.

            從這一篇開始將用到一個第三方庫PixieLib,本文先對這個庫的使用做簡單介紹,后續(xù)文章中將不再贅述。

            Paul DiLascia是兼職軟件顧問和資深的 Web/UI 設(shè)計師。他是《Windows++: Writing Reusable Windows Code in C++》(Windows++:在 C++ 中編寫可重用 Windows 代碼)一書(Addison-Wesley1992)的作者。Paul 在其業(yè)余時間里開發(fā)出了 PixieLib,可通過他的網(wǎng)站 www.dilascia.com 來獲取該 MFC 類庫。

            將下載下來的源代碼編譯后會生成Lib目錄,我們需要用到的就是IncludeLib這兩個目錄,當(dāng)然你也可以看看它自帶的Samples。由于使用的是最新PixieLib7.1版,因此接下來幾篇文章都在VS2005下進(jìn)行開發(fā)。

            1,LibInclude目錄拷貝到新建的MFC 項目目錄下,配置如下:

            1)c/c++à附加包含目錄,這里加入”."include”

            2)鏈接器à附加庫目錄,這里加入”."lib”

            3)輸入à附加依賴項,這里加入PixieLib71.lib

            2,在stdafx.h中包含進(jìn)PixieLib庫文件:

            #include <PixieLib.h>         //Pixel Library

             

            3,在CCY457OpenGLView類中加入下述變量:

              int m_PixelFormat;       //Pixel Format

                  
            //Position and Direction

                  GLfloat m_PosX;

                  GLfloat m_PosY;

                  GLfloat m_PosZ;

                  GLfloat m_DirX;

                  GLfloat m_DirY;

                  GLfloat m_DirZ;

                  
            //Rotation

                  GLfloat m_xRot, m_yRot;
            //繞x,y軸旋轉(zhuǎn)的角度,隨時間不斷變化

                  
            //Increment for Keyboard Control

                  GLfloat m_PosIncr;       
            //Positional Increment

                  GLfloat m_AngIncr;      
            //Angular Increment

                  
            //Angle of Camera With X Axis

                  GLfloat m_AngleX;

                  GLdouble m_texWrap, m_texFilter, m_texMode; 

                  GLfloat m_ShadowMat[
            4][4];

                  
            //All Texture Names

                 GLuint m_Texture[
            4];

            并在構(gòu)造函數(shù)中初始化如下:

            CCY457OpenGLView::CCY457OpenGLView()

            {

                  
            //Rotation

                  m_xRot 
            = 0.0f;

                  m_yRot 
            = 0.0f;

                  
            //Position Increment

                  m_PosIncr 
            = 0.25f;

                  
            //Angle Increment

                  m_AngIncr 
            = 5.0f;

                  
            //Set Initial Camera Position - looking down negative Z

                  m_PosX 
            = 0.0f;

                  m_PosY 
            = 0.5f;

                  m_PosZ 
            = 2.5f;     

                  
            //Set Initial Viewing Direction - Pointing Down the -ve Z Axis

                  m_DirX 
            = m_PosX;

                  m_DirY 
            = m_PosY;

                  m_DirZ 
            = m_PosZ-m_PosIncr;

                  
            //Angle of Camera with X Axis

                  m_AngleX 
            = 90.0f;

                  m_texWrap 
            = GL_CLAMP;

                  m_texMode 
            = GL_DECAL;

                  m_texFilter 
            = GL_NEAREST;

            }

            4InitializeOpenGL函數(shù)修改如下:

            BOOL CCY457OpenGLView::InitializeOpenGL()

            {

                  
            //Get a DC for the Client Area

                  m_pDC 
            = new CClientDC(this);

                  
            //Failure to Get DC

                  
            if(m_pDC == NULL)

                  {

                       MessageBox(
            "Error Obtaining DC");

                       
            return FALSE;

                  }

                  
            //Failure to set the pixel format

                  
            if(!SetupPixelFormat())

                  {

                       
            return FALSE;

                  }

                  
            //Create Rendering Context

                  m_hRC 
            = ::wglCreateContext (m_pDC->GetSafeHdc ());

                  
            //Failure to Create Rendering Context

                  
            if(m_hRC == 0)

                  {

                       MessageBox(
            "Error Creating RC");

                       
            return FALSE;

                  }

                  
            //Make the RC Current

                  
            if(::wglMakeCurrent (m_pDC->GetSafeHdc (), m_hRC)==FALSE)

                  {

                       MessageBox(
            "Error making RC Current");

                       
            return FALSE;

                  }

                  
            // specify black as clear color

                  ::glClearColor(
            0.0f0.0f0.0f0.0f);

                  
            // specify the back of the buffer as clear depth

                  ::glClearDepth(
            1.0f);

                  
            // enable depth testing

                  ::glEnable(GL_DEPTH_TEST);

                  
            //Enable Color Tracking

                  ::glEnable(GL_COLOR_MATERIAL);

                  ::glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);

                  ::glShadeModel(GL_SMOOTH);

                  
            //Setup Lighting Here

                  SetupLighting();

                  LoadGLTextures();

                  
            //Effects

                  
            //Shadow

                  
            //Calulate Shadow Matrix

                  GLfloat lightPos[] 
            = {1.0f,1.5f,-1.0f,0.0f};

                  GLfloat points[][
            3= {

                       {
            -2.0f,0.0f,0.0f},

                       {
            2.0f,0.0f,0.0f},

                       {
            2.0f,0.0f,-2.0f}

                  };

                  MakeShadowMatrix(points, lightPos, m_ShadowMat);

                  
            return TRUE;

            }

            5,設(shè)置燈光的代碼修改如下:

            void CCY457OpenGLView::SetupLighting ()

            {

                  
            //Enable Lighting

                  glEnable(GL_LIGHTING);

                  
            //Set up the Light Model

                  
            //Infinite Viewer

                  glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);

                  
            //Single Sided Lighting

                  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);

                  
            //Set up the lights

                  
            //Light 1

                  
            //Directional Light from Front

                  GLfloat m_SceneAmbient1[] 
            = {0.5f,0.5f,0.5f,1.0f};

                  GLfloat m_SceneDiffuse1[] 
            = {1.0f,1.0f,1.0f,1.0f};

                  GLfloat m_SceneSpecular1[] 
            = {1.0f,1.0f,1.0f,1.0f};

                  GLfloat m_ScenePosition1[] 
            = {1.0f,1.5f,-1.0f,1.0f};

                  GLfloat m_SceneDirection1[]
            = {0.0f,0.0f,-1.0f,1.0f};

                  glLightfv(GL_LIGHT0,GL_AMBIENT,m_SceneAmbient1);

                  glLightfv(GL_LIGHT0,GL_DIFFUSE,m_SceneDiffuse1);

                  glLightfv(GL_LIGHT0,GL_SPECULAR,m_SceneSpecular1);

                  glLightfv(GL_LIGHT0,GL_POSITION,m_ScenePosition1);

                  glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,
            75.0f);

                  glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,m_SceneDirection1);

                  glEnable(GL_LIGHT0);

            }

            6,繪制代碼修改如下:

            void CCY457OpenGLView::RenderScene ()

            {
            //繪制函數(shù)

                  
            //Position Camera

                  gluLookAt(m_PosX,m_PosY,m_PosZ,m_DirX,m_DirY,m_DirZ,
            0.0f,1.0f,0.0f);

                  
            //Draw the Scene

                  
            //Draw the floor

                  
            // Draw the ground,

                  glEnable(GL_TEXTURE_2D);

                  glBindTexture(GL_TEXTURE_2D, m_Texture[
            3]);

                  glBegin(GL_POLYGON);

                  glColor3ub(
            0,255,0);

                  glTexCoord2f(
            0.0f0.0f);

                  glVertex3f(
            -2.0f0.0f0.0f);

                  glTexCoord2f(
            1.0f0.0f);

                  glVertex3f(
            2.0f,0.0f0.0f);

                  glColor3ub(
            0,100,0);   

                  glTexCoord2f(
            1.0f1.0f);

                  glVertex3f(
            2.0f0.0f-2.0f);

                  glTexCoord2f(
            0.0f1.0f);

                  glVertex3f(
            -2.0f,0.0f-2.0f);

                  glEnd();

                  glDisable(GL_TEXTURE_2D);

                  
            //Draw the Cube

                  
            // Save the matrix state and do the rotations

                  glPushMatrix();

                  glTranslatef(
            -1.0f,0.6f,-1.0f);

                  
            // Draw jet at new orientation, put light in correct position

                  
            // before rotating the jet

                  glRotatef(m_xRot,
            1.0f,0.0f,0.0f);

                  glRotatef(m_yRot,
            0.0f,1.0f,0.0f);

                  DrawCube(FALSE);

                  
            // Restore original matrix state

                  glPopMatrix();  

                  
            // Get ready to draw the shadow and the ground

                  
            // First disable lighting and save the projection state

                  glDisable(GL_DEPTH_TEST);

                  glDisable(GL_LIGHTING);

                  glPushMatrix();

                  
            // Multiply by shadow projection matrix

                  glMultMatrixf((GLfloat 
            *)m_ShadowMat);

                  glTranslatef(
            -1.0f,0.6f,-1.0f);

                  glRotatef(m_xRot,
            1.0f,0.0f,0.0f);

                  glRotatef(m_yRot,
            0.0f,1.0f,0.0f);

                  
            // Pass true to indicate drawing shadow

                  DrawCube(TRUE); 

                  
            // Restore the projection to normal

                  glPopMatrix();

                  
            // Restore lighting state variables

                  glEnable(GL_DEPTH_TEST);

                  glEnable(GL_LIGHTING);

                  
            // Draw the light source

                  glPushMatrix();

                  glTranslatef(
            1.5f,1.5f,-1.0f);

                  glColor3ub(
            255,255,0);

                  glutSolidSphere(
            0.01f,10,10);

                  glPopMatrix();

            }

            7,用來計算平面法向量,繪制物體,計算陰影矩陣的輔助函數(shù):


            void CCY457OpenGLView::ReduceToUnit(GLfloat vector[3])

            {

                  
            float length;

                  
            // Calculate the length of the vector          

                  length 
            = (float)sqrt((vector[0]*vector[0]) +

                       (vector[
            1]*vector[1]) +

                       (vector[
            2]*vector[2]));

                  
            // Keep the program from blowing up by providing an exceptable

                  
            // value for vectors that may calculated too close to zero.

                  
            if(length == 0.0f)

                       length 
            = 1.0f;

                  
            // Dividing each element by the length will result in a

                  
            // unit normal vector.

                  vector[
            0/= length;

                  vector[
            1/= length;

                  vector[
            2/= length;

            }

            void CCY457OpenGLView::CalcNormal(GLfloat v[3][3],GLfloat out[3])

            {

                  
            float v1[3],v2[3];

                  
            static const int x = 0;

                  
            static const int y = 1;

                  
            static const int z = 2;

                  
            // Calculate two vectors from the three points

                  v1[x] 
            = v[0][x] - v[1][x];

                  v1[y] 
            = v[0][y] - v[1][y];

                  v1[z] 
            = v[0][z] - v[1][z];

                  v2[x] 
            = v[1][x] - v[2][x];

                  v2[y] 
            = v[1][y] - v[2][y];

                  v2[z] 
            = v[1][z] - v[2][z];

                  
            // Take the cross product of the two vectors to get

                  
            // the normal vector which will be stored in out

                  
            out[x] = v1[y]*v2[z] - v1[z]*v2[y];

                  
            out[y] = v1[z]*v2[x] - v1[x]*v2[z];

                  
            out[z] = v1[x]*v2[y] - v1[y]*v2[x];

                  
            // Normalize the vector (shorten length to one)

                  ReduceToUnit(
            out);

            }

            //Effects

            //Shadow

            // Create shadow matrix from the plane equation coeff's and pos of light

            void CCY457OpenGLView::MakeShadowMatrix(GLfloat points[3][3], GLfloat lightPos[4], GLfloat destMat[4][4])

            {

                  GLfloat planeCoeff[
            4];

                  GLfloat dot;

                  
            // Find the plane equation coefficients

                  
            // Find the first three coefficients the same way we

                  
            // find a normal.

                  CalcNormal(points,planeCoeff);

                  
            // Find the last coefficient by back substitutions

                  planeCoeff[
            3= - (

                       (planeCoeff[
            0]*points[2][0]) + (planeCoeff[1]*points[2][1]) +

                       (planeCoeff[
            2]*points[2][2]));

                  
            // Dot product of plane and light position

                  dot 
            = planeCoeff[0* lightPos[0+

                       planeCoeff[
            1* lightPos[1+

                       planeCoeff[
            2* lightPos[2+

                       planeCoeff[
            3* lightPos[3];

                  
            // Now do the projection

                  
            // First column

                  destMat[
            0][0= dot - lightPos[0* planeCoeff[0];

                  destMat[
            1][0= 0.0f - lightPos[0* planeCoeff[1];

                  destMat[
            2][0= 0.0f - lightPos[0* planeCoeff[2];

                  destMat[
            3][0= 0.0f - lightPos[0* planeCoeff[3];

                  
            // Second column

                  destMat[
            0][1= 0.0f - lightPos[1* planeCoeff[0];

                  destMat[
            1][1= dot - lightPos[1* planeCoeff[1];

                  destMat[
            2][1= 0.0f - lightPos[1* planeCoeff[2];

                  destMat[
            3][1= 0.0f - lightPos[1* planeCoeff[3];

                  
            // Third Column

                  destMat[
            0][2= 0.0f - lightPos[2* planeCoeff[0];

                  destMat[
            1][2= 0.0f - lightPos[2* planeCoeff[1];

                  destMat[
            2][2= dot - lightPos[2* planeCoeff[2];

                  destMat[
            3][2= 0.0f - lightPos[2* planeCoeff[3];

            // Fourth Column

                  destMat[
            0][3= 0.0f - lightPos[3* planeCoeff[0];

                  destMat[
            1][3= 0.0f - lightPos[3* planeCoeff[1];

                  destMat[
            2][3= 0.0f - lightPos[3* planeCoeff[2];

                  destMat[
            3][3= dot - lightPos[3* planeCoeff[3];

            }

            void CCY457OpenGLView::DrawCubeTex ()

            {

                  glScalef(
            0.3f0.3f0.3f);              

                  glEnable(GL_TEXTURE_2D);

                  glBindTexture(GL_TEXTURE_2D,m_Texture[
            0]);

                  
            //Front Face

                  glBegin(GL_POLYGON);

                  glTexCoord2f(
            0,0);

                  glVertex3f(
            -1.0f,-1.0f,0.0f);

                  glTexCoord2f(
            1,0);

                  glVertex3f( 
            1.0f,-1.0f,0.0f);

                  glTexCoord2f(
            1,1);

                  glVertex3f( 
            1.0f1.0f,0.0f);

                  glTexCoord2f(
            0,1);

                  glVertex3f(
            -1.0f1.0f,0.0f);

                  glEnd();

                  
            //Back Face

                  glBegin(GL_POLYGON);

                  glTexCoord2f(
            1,0);

                  glVertex3f(
            -1.0f,-1.0f,-1.0f);

                  glTexCoord2f(
            1,1);

                  glVertex3f(
            -1.0f1.0f,-1.0f);

                  glTexCoord2f(
            0,1);

                  glVertex3f( 
            1.0f1.0f,-1.0f);

                  glTexCoord2f(
            0,0);

                  glVertex3f( 
            1.0f,-1.0f,-1.0f);

                  glEnd();

                  glBindTexture(GL_TEXTURE_2D,m_Texture[
            1]);

                  
            //Left Face

                  glBegin(GL_POLYGON);

                  glTexCoord2f(
            1,0);

                  glVertex3f(
            -1.0f,-1.0f0.0f);

                  glTexCoord2f(
            1,1);

                  glVertex3f(
            -1.0f1.0f0.0f);

                  glTexCoord2f(
            0,1);

                  glVertex3f(
            -1.0f1.0f,-1.0f);

                  glTexCoord2f(
            0,0);

                  glVertex3f(
            -1.0f,-1.0f,-1.0f);

                  glEnd();

                  
            //Right Face

                  glBegin(GL_POLYGON);

                  glTexCoord2f(
            0,0);

                  glVertex3f(
            1.0f,-1.0f0.0f);

                  glTexCoord2f(
            1,0);

                  glVertex3f(
            1.0f,-1.0f,-1.0f);

                  glTexCoord2f(
            1,1);

                  glVertex3f(
            1.0f1.0f,-1.0f);

                  glTexCoord2f(
            0,1);

                  glVertex3f(
            1.0f1.0f0.0f);

                  glEnd();

                  glBindTexture(GL_TEXTURE_2D,m_Texture[
            2]);

                  
            //Top Face

                  glBegin(GL_POLYGON);

                  glTexCoord2f(
            0,0);

                  glVertex3f(
            -1.0f1.0f0.0f);

                  glTexCoord2f(
            0,1);

                  glVertex3f( 
            1.0f1.0f0.0f);

                  glTexCoord2f(
            1,1);

                  glVertex3f( 
            1.0f1.0f-1.0f);

                  glTexCoord2f(
            1,0);

                  glVertex3f(
            -1.0f1.0f-1.0f);

                  glEnd();

                  
            //Botton Face

                  glBegin(GL_POLYGON);

                  glTexCoord2f(
            0,1);

                  glVertex3f(
            -1.0f-1.0f0.0f);

                  glTexCoord2f(
            0,0);

                  glVertex3f(
            -1.0f-1.0f-1.0f);

                  glTexCoord2f(
            1,0);

                  glVertex3f( 
            1.0f-1.0f-1.0f);

                  glTexCoord2f(
            1,1);

                  glVertex3f( 
            1.0f-1.0f0.0f);

                  glEnd();

                  glDisable(GL_TEXTURE_2D);

            }

            void CCY457OpenGLView::DrawCubeNoTex ()

            {

                  glScalef(
            0.3f0.3f0.3f);              

                  
            //Front Face

                  glBegin(GL_POLYGON);

                  glVertex3f(
            -1.0f,-1.0f,0.0f);

                  glVertex3f( 
            1.0f,-1.0f,0.0f);

                  glVertex3f( 
            1.0f1.0f,0.0f);

                  glVertex3f(
            -1.0f1.0f,0.0f);

                  glEnd();

                  
            //Back Face

                  glBegin(GL_POLYGON);

                  glVertex3f(
            -1.0f,-1.0f,-1.0f);

                  glVertex3f(
            -1.0f1.0f,-1.0f);

                  glVertex3f( 
            1.0f1.0f,-1.0f);

                  glVertex3f( 
            1.0f,-1.0f,-1.0f);

                  glEnd();

                  
            //Left Face

                  glBegin(GL_POLYGON);

                  glVertex3f(
            -1.0f,-1.0f0.0f);

                  glVertex3f(
            -1.0f1.0f0.0f);

                  glVertex3f(
            -1.0f1.0f,-1.0f);

                  glVertex3f(
            -1.0f,-1.0f,-1.0f);

                  glEnd();

                  
            //Right Face

                  glBegin(GL_POLYGON);

                  glVertex3f(
            1.0f,-1.0f0.0f);

                  glVertex3f(
            1.0f,-1.0f,-1.0f);

                  glVertex3f(
            1.0f1.0f,-1.0f);

                  glVertex3f(
            1.0f1.0f0.0f);

                  glEnd();

                  
            //Top Face

                  glBegin(GL_POLYGON);

                  glVertex3f(
            -1.0f1.0f0.0f);

                  glVertex3f( 
            1.0f1.0f0.0f);

                  glVertex3f( 
            1.0f1.0f-1.0f);

                  glVertex3f(
            -1.0f1.0f-1.0f);

                  glEnd();

                  
            //Botton Face

                  glBegin(GL_POLYGON);

                  glVertex3f(
            -1.0f-1.0f0.0f);

                  glVertex3f(
            -1.0f-1.0f-1.0f);

                  glVertex3f( 
            1.0f-1.0f-1.0f);

                  glVertex3f( 
            1.0f-1.0f0.0f);

                  glEnd();

            }

             

            作者:洞庭散人

            出處:http://phinecos.cnblogs.com/    

            本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。
            原文鏈接:
            久久91精品国产91久久户| 欧美国产成人久久精品| 久久亚洲精品国产亚洲老地址| 国产69精品久久久久9999| 久久精品成人免费网站| 天堂久久天堂AV色综合| 91精品国产综合久久婷婷| 麻豆精品久久久一区二区| 欧美与黑人午夜性猛交久久久| 狠狠色丁香久久婷婷综合蜜芽五月 | 性做久久久久久久| 热99RE久久精品这里都是精品免费| 亚洲国产成人精品久久久国产成人一区二区三区综 | 精品精品国产自在久久高清| 欧美喷潮久久久XXXXx| 亚洲国产成人久久精品动漫| 蜜臀久久99精品久久久久久| 狠狠人妻久久久久久综合蜜桃| 精品久久久中文字幕人妻 | 国产一级做a爰片久久毛片| 久久人妻少妇嫩草AV无码专区| 精品欧美一区二区三区久久久| 精品国产一区二区三区久久蜜臀| 伊人久久大香线蕉精品| 久久久人妻精品无码一区| 亚洲伊人久久综合影院| 秋霞久久国产精品电影院| 9999国产精品欧美久久久久久| 大美女久久久久久j久久| 欧美与黑人午夜性猛交久久久 | 亚洲精品乱码久久久久久蜜桃图片| 777午夜精品久久av蜜臀| 久久精品国产只有精品66 | 99精品国产在热久久无毒不卡| 久久99国产精品久久久| 久久精品18| 精品久久久无码21p发布 | 久久精品国产91久久麻豆自制| 国产高潮国产高潮久久久91| 思思久久99热免费精品6| 亚洲午夜久久久久久久久电影网 |