青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

  C++博客 :: 首頁 :: 聯(lián)系 ::  :: 管理
  163 Posts :: 4 Stories :: 350 Comments :: 0 Trackbacks

常用鏈接

留言簿(48)

我參與的團(tuán)隊(duì)

搜索

  •  

積分與排名

  • 積分 - 402524
  • 排名 - 59

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

歡迎來到另一個(gè)有些復(fù)雜的課程,陰影。這一課的效果好的有些讓人不可思議,陰影可以變形,混合在其他的物體上。
這一課要求你必須對(duì)OpenGL比較了解,它假設(shè)你知道許多OpenGL的知識(shí),你必須知道蒙板緩存,基本的OpenGL步驟。如果你對(duì)這些不太熟悉,我建議你可以看看前面的教程。當(dāng)然,在這一課里,我們用到了很多數(shù)學(xué)知識(shí),請(qǐng)準(zhǔn)備好一本數(shù)學(xué)手冊(cè)在你的身邊。
首先我們定義陰影體可以延伸的距離。 
  

// 定義陰影體可以延伸的距離
#define INFINITY 100

  
 下面定義一個(gè)3D頂點(diǎn)結(jié)構(gòu) 
  

// 3D頂點(diǎn)結(jié)構(gòu)
struct sPoint
{
 GLfloat x, y, z;
};

  
 定義一個(gè)平面結(jié)構(gòu) 
  

// 平面方程為: ax + by + cz + d = 0
struct sPlaneEq
{
 GLfloat a, b, c, d;
};

  
 下面定義一個(gè)用來投影的三角形的結(jié)構(gòu)
3個(gè)整形索引指定了模型中三角形的三個(gè)頂點(diǎn)
第二個(gè)變量指定了三角形面的法線
平面方程描述了三角所在的平面
臨近的3個(gè)頂點(diǎn)索引,指定了與這個(gè)三角形相鄰的三個(gè)頂點(diǎn)
最后一個(gè)變量指定這個(gè)三角形是否投出陰影
 
  

// 描述一個(gè)模型表面的結(jié)構(gòu)
struct sPlane
{
 unsigned int p[3];   // 3個(gè)整形索引指定了模型中三角形的三個(gè)頂點(diǎn)
 sPoint normals[3];   // 第二個(gè)變量指定了三角形面的法線
 unsigned int neigh[3];   // 與本三角形三個(gè)邊相鄰的面的索引
 sPlaneEq PlaneEq;   // 平面方程描述了三角所在的平面
 bool visible;   // 最后一個(gè)變量指定這個(gè)三角形是否投出陰影?
};

  
 最后我們用下面的結(jié)構(gòu)描述一個(gè)產(chǎn)生陰影的物體。 
  

struct glObject{ GLuint nPlanes, nPoints; sPoint points[100]; sPlane planes[200];};
  
 下面的代碼用來讀取模型,它的代碼本身就解釋了它的功能。它從文件中讀取數(shù)據(jù),并把頂點(diǎn)和索引存儲(chǔ)在上面定義的結(jié)構(gòu)中,并把所有的臨近頂點(diǎn)初始化為-1,它代表這沒有任何頂點(diǎn)與它相鄰,我們將在以后計(jì)算它。 
  

bool readObject( const char *filename, glObject*o)
{
  FILE *file;
  unsigned int i;

  file = fopen(st, "r");
  if (!file) return FALSE;
  //讀取頂點(diǎn)
  fscanf(file, "%d", &(o->nPoints));
  for (i=1;i<=o->nPoints;i++){
    fscanf(file, "%f", &(o->points[i].x));
    fscanf(file, "%f", &(o->points[i].y));
    fscanf(file, "%f", &(o->points[i].z));
  }
  //讀取三角形面
  fscanf(file, "%d", &(o->nPlanes));
  for (i=0;inPlanes;i++){
    fscanf(file, "%d", &(o->planes[i].p[0]));
    fscanf(file, "%d", &(o->planes[i].p[1]));
    fscanf(file, "%d", &(o->planes[i].p[2]));
 //讀取每個(gè)頂點(diǎn)的法線
    fscanf(file, "%f", &(o->planes[i].normals[0].x));
    fscanf(file, "%f", &(o->planes[i].normals[0].y));
    fscanf(file, "%f", &(o->planes[i].normals[0].z));
    fscanf(file, "%f", &(o->planes[i].normals[1].x));
    fscanf(file, "%f", &(o->planes[i].normals[1].y));
    fscanf(file, "%f", &(o->planes[i].normals[1].z));
    fscanf(file, "%f", &(o->planes[i].normals[2].x));
    fscanf(file, "%f", &(o->planes[i].normals[2].y));
    fscanf(file, "%f", &(o->planes[i].normals[2].z));
  }
 return true;
}

  
 現(xiàn)在從setConnectivity函數(shù)開始,事情變得越來越復(fù)雜了,這個(gè)函數(shù)用來查找每個(gè)面的相鄰的頂點(diǎn),下面是它的偽代碼:
 
  

對(duì)于模型中的每一個(gè)面A 對(duì)于面A中的每一條邊  如果我們不只到這條邊相鄰的頂點(diǎn)   那么對(duì)于模型中除了面A外的每一個(gè)面B    對(duì)于面B中的每一條邊     如果面A的邊和面B的邊是同一條邊,那么這兩個(gè)面相鄰      設(shè)置面A和面B的相鄰屬性
  
 下面的代碼完成上面?zhèn)未a中最后兩行的內(nèi)容,你先獲得每個(gè)面中邊的兩個(gè)頂點(diǎn),然后檢測他們是否相鄰,如果是則設(shè)置各自的相鄰頂點(diǎn)信息 
  

 int vertA1 = pFaceA->vertexIndices[edgeA];
 int vertA2 = pFaceA->vertexIndices[( edgeA+1 )%3];

 int vertB1 = pFaceB->vertexIndices[edgeB];
 int vertB2 = pFaceB->vertexIndices[( edgeB+1 )%3];

 // 測試他們是否為同一邊,如果是則設(shè)置相應(yīng)的相鄰頂點(diǎn)信息
 if (( vertA1 == vertB1 && vertA2 == vertB2 ) || ( vertA1 == vertB2 && vertA2 == vertB1 ))
 {
  pFaceA->neighbourIndices[edgeA] = faceB;
  pFaceB->neighbourIndices[edgeB] = faceA;
  edgeFound = true;
  break;
 }

  
 完整的SetConnectivity函數(shù)的代碼如下 
  


// 設(shè)置相鄰頂點(diǎn)信息
inline void SetConnectivity(glObject *o){
 unsigned int p1i, p2i, p1j, p2j;
 unsigned int P1i, P2i, P1j, P2j;
 unsigned int i,j,ki,kj;

 //對(duì)于模型中的每一個(gè)面A
 for(i=0;inPlanes-1;i++)
 {
  //對(duì)于除了此面的其它的面B
  for(j=i+1;jnPlanes;j++)
  {
   //對(duì)于面A中的每一個(gè)相鄰的頂點(diǎn)
   for(ki=0;ki<3;ki++)
   {
    //如果這個(gè)相鄰的頂點(diǎn)沒有被設(shè)置
    if(!o->planes[i].neigh[ki])
    {
     for(kj=0;kj<3;kj++)
     {
      p1i=ki;
      p1j=kj;
      p2i=(ki+1)%3;
      p2j=(kj+1)%3;

      p1i=o->planes[i].p[p1i];
      p2i=o->planes[i].p[p2i];
      p1j=o->planes[j].p[p1j];
      p2j=o->planes[j].p[p2j];
    
      //如果面A的邊P1i->P1j和面B的邊P2i->P2j為同一條邊,則又下面的公式的P1i=P1j,并且P2i=P2j
      P1i=((p1i+p2i)-abs(p1i-p2i))/2;
      P2i=((p1i+p2i)+abs(p1i-p2i))/2;
      P1j=((p1j+p2j)-abs(p1j-p2j))/2;
      P2j=((p1j+p2j)+abs(p1j-p2j))/2;

      //記錄與這個(gè)邊相鄰的面的索引
      if((P1i==P1j) && (P2i==P2j))
      {
       o->planes[i].neigh[ki] = j+1;  
       o->planes[j].neigh[kj] = i+1;  
      }
     }
    }
   }
  }
 }
}

  
 下面的函數(shù)用來繪制模型 
  

// 繪制模型,像以前一樣它繪制組成模型的三角形
void drawObject( const ShadowedObject& object )
{
 glBegin( GL_TRIANGLES );
 for ( int i = 0; i < object.nFaces; i++ )
 {
  const Face& face = object.pFaces[i];

  for ( int j = 0; j < 3; j++ )
  {
   const Point3f& vertex = object.pVertices[face.vertexIndices[j]];

   glNormal3f( face.normals[j].x, face.normals[j].y, face.normals[j].z );
   glVertex3f( vertex.x, vertex.y, vertex.z );
  }
 }
 glEnd();
}

  
 下面的函數(shù)用來計(jì)算平面的方程參數(shù) 
  

void calculatePlane( const ShadowedObject& object, Face& face )
{
 // 獲得平面的三個(gè)頂點(diǎn)
 const Point3f& v1 = object.pVertices[face.vertexIndices[0]];
 const Point3f& v2 = object.pVertices[face.vertexIndices[1]];
 const Point3f& v3 = object.pVertices[face.vertexIndices[2]];

 face.planeEquation.a = v1.y*(v2.z-v3.z) + v2.y*(v3.z-v1.z) + v3.y*(v1.z-v2.z);
 face.planeEquation.b = v1.z*(v2.x-v3.x) + v2.z*(v3.x-v1.x) + v3.z*(v1.x-v2.x);
 face.planeEquation.c = v1.x*(v2.y-v3.y) + v2.x*(v3.y-v1.y) + v3.x*(v1.y-v2.y);
 face.planeEquation.d = -( v1.x*( v2.y*v3.z - v3.y*v2.z ) +
    v2.x*(v3.y*v1.z - v1.y*v3.z) +
    v3.x*(v1.y*v2.z - v2.y*v1.z) );
}

  
 你還可以呼吸么?好的,我們繼續(xù):) 接下來你將學(xué)習(xí)如何去投影,castShadow函數(shù)幾乎用到了所有OpenGL的功能,完成這個(gè)函數(shù)后,把它傳遞到doShadowPass函數(shù)來通過兩個(gè)渲染通道繪制出陰影.
首先,我們看看哪些面面對(duì)著燈光,我們可以通過燈光位置和平面方程計(jì)算出.如果燈光到平面的位置大于0,則位于燈光的上方,否則位于燈光的下方(如果有什么問題,翻一下你高中的解析幾何). 
  

void castShadow( ShadowedObject& object, GLfloat *lightPosition )
{
 // 設(shè)置哪些面在燈光的前面
 for ( int i = 0; i < object.nFaces; i++ )
 {
  const Plane& plane = object.pFaces[i].planeEquation;

  GLfloat side = plane.a*lightPosition[0]+
   plane.b*lightPosition[1]+
   plane.c*lightPosition[2]+
   plane.d;

  if ( side > 0 )
   object.pFaces[i].visible = true;
  else
   object.pFaces[i].visible = false;
 }

  
 下面設(shè)置必要的狀態(tài)來渲染陰影.
首先,禁用燈光和繪制顏色,因?yàn)槲覀儾挥?jì)算光照,這樣可以節(jié)約計(jì)算量.
接著,設(shè)置深度緩存,深度測試還是需要的,但我們不希望我們的陰影體向?qū)嶓w一樣具有深度,所以關(guān)閉深度緩存.
最后我們啟用蒙板緩存,讓陰影體的位置在蒙板中被設(shè)置為1. 
  

 glDisable( GL_LIGHTING );     // 關(guān)閉燈光
 glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );  // 關(guān)閉顏色緩存的寫入 
 glDepthFunc( GL_LEQUAL );     // 設(shè)置深度比較函數(shù)
 glDepthMask( GL_FALSE );     // 關(guān)閉深度緩存的寫入 
 glEnable( GL_STENCIL_TEST );    // 使用蒙板緩存
 glStencilFunc( GL_ALWAYS, 1, 0xFFFFFFFFL );   // 設(shè)置蒙板函數(shù)

  
 現(xiàn)在到了陰影被實(shí)際渲染得地方了,我們使用了下面提到的doShadowPass函數(shù),它用來繪制陰影體的邊界面.我們通過兩個(gè)步驟來繪制陰影體,首先使用前向面增加陰影體在蒙板緩存中的值,接著使用后向面減少陰影體在蒙板緩存中的值. 
  

 // 如果是逆時(shí)針(即面向視點(diǎn))的多邊形,通過了蒙板和深度測試,則把蒙板的值增加1
 glFrontFace( GL_CCW );
 glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
 doShadowPass( object, lightPosition );
 // 如果是順時(shí)針(即背向視點(diǎn))的多邊形,通過了蒙板和深度測試,則把蒙板的值減少1
 glFrontFace( GL_CW );
 glStencilOp( GL_KEEP, GL_KEEP, GL_DECR );
 doShadowPass( object, lightPosition );

  
 為了更好的理解這兩個(gè)步驟,我建議你把第二步注釋掉看看效果,如下所示:

 
圖 1: 步驟1 圖 2: 步驟2


最后一步就是把陰影體所在的位置繪制上陰影的顏色 
  

 glFrontFace( GL_CCW );
 glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); 

 // 把陰影繪制上顏色
 glColor4f( 0.0f, 0.0f, 0.0f, 0.4f );
 glEnable( GL_BLEND );
 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
 glStencilFunc( GL_NOTEQUAL, 0, 0xFFFFFFFFL );
 glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
 glPushMatrix();
 glLoadIdentity();
 glBegin( GL_TRIANGLE_STRIP );
  glVertex3f(-0.1f, 0.1f,-0.10f);
  glVertex3f(-0.1f,-0.1f,-0.10f);
  glVertex3f( 0.1f, 0.1f,-0.10f);
  glVertex3f( 0.1f,-0.1f,-0.10f);
 glEnd();
 glPopMatrix();
}

  
 下面的部分我們繪制構(gòu)成陰影體邊界的四邊形,當(dāng)我們循環(huán)所有的三角形面的時(shí)候,我們檢測它是否是邊界邊,如果是我們繪制從燈光到這個(gè)邊界邊的射線,并衍生它用來構(gòu)成四邊形.
這里要用一個(gè)蠻力,我們檢測物體模型中每一個(gè)三角形面,找出其邊界并連接燈光到邊界的直線,把直線延長出一定的距離,構(gòu)成陰影體.

下面的代碼完成這些功能,它看起來并沒有想象的復(fù)雜.
 
  

void doShadowPass(glObject *o, float *lp)
{
 unsigned int i, j, k, jj;
 unsigned int p1, p2;
 sPoint   v1, v2;

 //對(duì)模型中的每一個(gè)面
 for (i=0; inPlanes;i++)
 { 
  //如果面在燈光的前面
  if (o->planes[i].visible)
  {
   //對(duì)于被燈光照射的面的每一個(gè)相鄰的面
   for (j=0;j<3;j++)
   {
    k = o->planes[i].neigh[j];
    //如果面不存在,或不被燈光照射,那么這個(gè)邊是邊界
    if ((!k) || (!o->planes[k-1].visible))
    {
     // 獲得面的兩個(gè)頂點(diǎn)
     p1 = o->planes[i].p[j];
     jj = (j+1)%3;
     p2 = o->planes[i].p[jj];

     //計(jì)算邊的頂點(diǎn)到燈光的方向,并放大100倍
     v1.x = (o->points[p1].x - lp[0])*100;
     v1.y = (o->points[p1].y - lp[1])*100;
     v1.z = (o->points[p1].z - lp[2])*100;

     v2.x = (o->points[p2].x - lp[0])*100;
     v2.y = (o->points[p2].y - lp[1])*100;
     v2.z = (o->points[p2].z - lp[2])*100;
     
     //繪制構(gòu)成陰影體邊界的面
     glBegin(GL_TRIANGLE_STRIP);
      glVertex3f(o->points[p1].x,
         o->points[p1].y,
         o->points[p1].z);
      glVertex3f(o->points[p1].x + v1.x,
         o->points[p1].y + v1.y,
         o->points[p1].z + v1.z);

      glVertex3f(o->points[p2].x,
         o->points[p2].y,
         o->points[p2].z);
      glVertex3f(o->points[p2].x + v2.x,
         o->points[p2].y + v2.y,
         o->points[p2].z + v2.z);
     glEnd();
    }
   }
  }
 }

}


  
 既然我們已經(jīng)能繪制陰影了,那么我們開始繪制我們的場景吧 
  

bool drawGLScene()
{
 GLmatrix16f Minv;
 GLvector4f wlp, lp;

 // 清空緩存
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

 glLoadIdentity();       // 設(shè)置燈光,并繪制球
 glTranslatef(0.0f, 0.0f, -20.0f);    
 glLightfv(GL_LIGHT1, GL_POSITION, LightPos);   
 glTranslatef(SpherePos[0], SpherePos[1], SpherePos[2]);  
 gluSphere(q, 1.5f, 32, 16);     
  
 下面我們計(jì)算燈光在物體坐標(biāo)系中的位置 
  

 glLoadIdentity();      
 glRotatef(-yrot, 0.0f, 1.0f, 0.0f);    
 glRotatef(-xrot, 1.0f, 0.0f, 0.0f);    
 glTranslatef(-ObjPos[0], -ObjPos[1], -ObjPos[2]);  
 glGetFloatv(GL_MODELVIEW_MATRIX,Minv);    // 計(jì)算從世界坐標(biāo)系變化到物體坐標(biāo)系中的坐標(biāo)
 lp[0] = LightPos[0];      // 保存燈光的位置
 lp[1] = LightPos[1];      
 lp[2] = LightPos[2];      
 lp[3] = LightPos[3];      
 VMatMult(Minv, lp);      // 計(jì)算最后燈光的位置

  
 下面繪制房間,物體和它的陰影 
  

 glLoadIdentity();  
 glTranslatef(0.0f, 0.0f, -20.0f);    
 DrawGLRoom();       // 繪制房間
 glTranslatef(ObjPos[0], ObjPos[1], ObjPos[2]);   
 glRotatef(xrot, 1.0f, 0.0f, 0.0f);    
 glRotatef(yrot, 0.0f, 1.0f, 0.0f);    
 DrawGLObject(obj);       // 繪制物體
 CastShadow(&obj, lp);      // 繪制物體的陰影

  
 下面的代碼繪制一個(gè)黃色的球代表了燈光的位置 
  

 glColor4f(0.7f, 0.4f, 0.0f, 1.0f);    
 glDisable(GL_LIGHTING);      
 glDepthMask(GL_FALSE);      
 glTranslatef(lp[0], lp[1], lp[2]);    
 gluSphere(q, 0.2f, 16, 8);     
 glEnable(GL_LIGHTING);      
 glDepthMask(GL_TRUE);      
  
 最后設(shè)置物體的控制 
  

 xrot += xspeed;       // 增加X軸選擇速度
 yrot += yspeed;       // 增加Y軸選擇速度

 glFlush();       // 強(qiáng)制OpenGL完成所有的命令
 return TRUE;       // 成功返回
}

  
 繪制房間墻面 
  

void DrawGLRoom()        // 繪制房間(盒裝)
{
 glBegin(GL_QUADS);       // 繪制四邊形
  // 地面
  glNormal3f(0.0f, 1.0f, 0.0f);    // 法線向上
  glVertex3f(-10.0f,-10.0f,-20.0f);   
  glVertex3f(-10.0f,-10.0f, 20.0f);   
  glVertex3f( 10.0f,-10.0f, 20.0f);   
  glVertex3f( 10.0f,-10.0f,-20.0f);   
  // 天花板
  glNormal3f(0.0f,-1.0f, 0.0f);    // 法線向下
  glVertex3f(-10.0f, 10.0f, 20.0f);   
  glVertex3f(-10.0f, 10.0f,-20.0f);   
  glVertex3f( 10.0f, 10.0f,-20.0f);   
  glVertex3f( 10.0f, 10.0f, 20.0f);   
  // 前面
  glNormal3f(0.0f, 0.0f, 1.0f);    // 法線向后
  glVertex3f(-10.0f, 10.0f,-20.0f);   
  glVertex3f(-10.0f,-10.0f,-20.0f);   
  glVertex3f( 10.0f,-10.0f,-20.0f);   
  glVertex3f( 10.0f, 10.0f,-20.0f);   
  // 后面
  glNormal3f(0.0f, 0.0f,-1.0f);    // 法線向前
  glVertex3f( 10.0f, 10.0f, 20.0f);   
  glVertex3f( 10.0f,-10.0f, 20.0f);   
  glVertex3f(-10.0f,-10.0f, 20.0f);   
  glVertex3f(-10.0f, 10.0f, 20.0f);   
  // 左面
  glNormal3f(1.0f, 0.0f, 0.0f);    // 法線向右
  glVertex3f(-10.0f, 10.0f, 20.0f);   
  glVertex3f(-10.0f,-10.0f, 20.0f);   
  glVertex3f(-10.0f,-10.0f,-20.0f);   
  glVertex3f(-10.0f, 10.0f,-20.0f);   
  // 右面
  glNormal3f(-1.0f, 0.0f, 0.0f);    // 法線向左
  glVertex3f( 10.0f, 10.0f,-20.0f);   
  glVertex3f( 10.0f,-10.0f,-20.0f);  
  glVertex3f( 10.0f,-10.0f, 20.0f);   
  glVertex3f( 10.0f, 10.0f, 20.0f);   
 glEnd();        // 結(jié)束繪制
}

  
 下面的函數(shù)完成矩陣M與向量V的乘法M=M*V
 
  

void VMatMult(GLmatrix16f M, GLvector4f v)
{
 GLfloat res[4];       // 保存中間計(jì)算結(jié)果
 res[0]=M[ 0]*v[0]+M[ 4]*v[1]+M[ 8]*v[2]+M[12]*v[3];
 res[1]=M[ 1]*v[0]+M[ 5]*v[1]+M[ 9]*v[2]+M[13]*v[3];
 res[2]=M[ 2]*v[0]+M[ 6]*v[1]+M[10]*v[2]+M[14]*v[3];
 res[3]=M[ 3]*v[0]+M[ 7]*v[1]+M[11]*v[2]+M[15]*v[3];
 v[0]=res[0];       // 把結(jié)果保存在V中
 v[1]=res[1];
 v[2]=res[2];
 v[3]=res[3];       
}

  
 下面的函數(shù)用來初始化模型對(duì)象 
  

int InitGLObjects()       // 初始化模型對(duì)象
{
 if (!ReadObject("Data/Object2.txt", &obj))    // 讀取模型數(shù)據(jù)
 {
  return FALSE;      // 返回失敗
 }

 SetConnectivity(&obj);      // 設(shè)置相鄰頂點(diǎn)的信息

 for ( int i=0;i < obj.nPlanes;i++)     // 計(jì)算每個(gè)面的平面參數(shù)
  CalcPlane(obj, &obj.planes[i]);   

 return TRUE;       //成功返回
}


  
 其他的函數(shù)我們不做過多解釋了,這會(huì)分散你的注意力,好好享受陰影帶給你的快感吧.
下面還有一些說明:
球體不會(huì)產(chǎn)生陰影,因?yàn)槲覀儧]有設(shè)置其投影.
如果你發(fā)現(xiàn)程序很慢,買塊好的顯卡吧.

最后我希望你喜歡它,如果有什么好的建議,請(qǐng)告訴我.
 

posted on 2007-12-20 11:52 sdfasdf 閱讀(1535) 評(píng)論(4)  編輯 收藏 引用 所屬分類: OPENGL

Feedback

# re: NEHE的OPENGL中文教程 第27課 影子 2007-12-20 20:49 學(xué)海一人
繼續(xù)努力  回復(fù)  更多評(píng)論
  

# re: NEHE的OPENGL中文教程 第27課 影子 2007-12-20 21:12 修遠(yuǎn)
頂一下,老兄  回復(fù)  更多評(píng)論
  

# re: NEHE的OPENGL中文教程 第27課 影子 2008-05-04 20:28 kxlsc1985
glStencilFunc(GL_NOTEQUAL, 0, 0xffffffff);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glPushMatrix();
glLoadIdentity();
、、、、、、、、、、、、、、、、
glBegin(GL_TRIANGLE_STRIP);
glVertex3f(-0.1f, 0.1f,-0.1f);
glVertex3f(-0.1f,-0.1f,-0.1f);
glVertex3f( 0.1f, 0.1f,-0.1f);
glVertex3f( 0.1f,-0.1f,-0.1f);
glEnd();
glPopMatrix();
glDisable(GL_BLEND);
、、、、、、、、、、、、、、、
不懂為什么要畫矩形  回復(fù)  更多評(píng)論
  

# re: NEHE的OPENGL中文教程 第27課 影子 2008-05-04 20:30 kxlsc1985
是3dobject.h文件中的最后一部分  回復(fù)  更多評(píng)論
  

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲一区二区精品在线| 99国产精品久久久久久久| 久久精品免费播放| 午夜精品亚洲| 亚洲欧美久久久| 亚洲欧美日韩国产| 久久www成人_看片免费不卡| 亚洲欧美国产va在线影院| 午夜欧美大片免费观看| 欧美在线影院| 久久夜色精品国产亚洲aⅴ| 久久久午夜视频| 欧美国产一区视频在线观看| 欧美日韩大陆在线| 国产精品一二一区| 永久91嫩草亚洲精品人人| 亚洲激情影视| 亚洲一区二区三区视频播放| 性xx色xx综合久久久xx| 久久久夜夜夜| 亚洲老司机av| 欧美亚洲一区在线| 欧美.www| 国产美女精品| 99精品欧美一区二区三区| 亚洲欧洲av一区二区| 久久在线免费视频| 亚洲国产精彩中文乱码av在线播放| 欧美国产日本高清在线| 亚洲人成小说网站色在线| 亚洲一区中文| 欧美二区在线观看| 欧美黄在线观看| 国产精品久99| 欧美亚洲日本国产| 久久青青草综合| 欧美日韩中文字幕综合视频| 黄色亚洲大片免费在线观看| 在线综合欧美| 欧美激情一区二区三区在线视频| 在线亚洲自拍| 欧美搞黄网站| 亚洲电影在线播放| 欧美一区免费视频| 99热免费精品| 欧美国产精品| 亚洲国产高清在线| 久久久久综合网| 亚洲综合精品| 欧美色综合网| 日韩视频永久免费| 欧美国产专区| 久久免费黄色| 国内精品美女av在线播放| 亚洲性线免费观看视频成熟| 欧美激情偷拍| 久久久久久9| 好看的av在线不卡观看| 欧美亚洲一区在线| 亚洲一区免费观看| 国产精品久久久99| 亚洲国产日韩欧美在线99| 久久久国产91| 久久国产精彩视频| 狠狠色狠狠色综合日日91app| 先锋影音一区二区三区| 亚洲尤物视频在线| 国产精品亚洲美女av网站| 亚洲欧美日韩一区二区三区在线| 亚洲裸体在线观看| 欧美色精品天天在线观看视频| 亚洲三级电影全部在线观看高清| 男男成人高潮片免费网站| 久久婷婷av| 亚洲精品欧美日韩专区| 亚洲第一精品夜夜躁人人躁| 欧美国产日本| 亚洲已满18点击进入久久| 亚洲激情欧美| 久久久夜夜夜| 国产一区二区精品丝袜| 在线免费观看日本欧美| 欧美一区在线直播| 亚洲一区二区三区精品在线| 欧美精品色综合| 99国产精品99久久久久久| 亚洲国产精品精华液2区45| 久久精品国产成人| 激情欧美日韩一区| 久久免费观看视频| 欧美淫片网站| 国产在线日韩| 久久久久一区二区| aⅴ色国产欧美| 欧美尤物巨大精品爽| 在线视频精品一| 国产精品美女黄网| 欧美a级大片| 欧美日韩国产在线一区| 久久大香伊蕉在人线观看热2| 久久久久久一区二区| 夜夜爽99久久国产综合精品女不卡 | 亚洲精品小视频在线观看| 国产精品毛片| 欧美大片va欧美在线播放| 欧美日韩伊人| 欧美电影在线播放| 国产精品一区二区在线| 亚洲高清资源| 国产精品一级二级三级| 亚洲日本电影在线| 黑人一区二区| 亚洲欧美视频一区二区三区| 亚洲精品一区中文| 久久精选视频| 欧美在线播放| 国产精品成人v| 亚洲第一福利社区| 在线成人av网站| 午夜精品久久久久久| 亚洲性av在线| 欧美日韩国产一中文字不卡| 欧美成人日韩| 韩国v欧美v日本v亚洲v| 亚洲欧美日韩视频一区| 正在播放亚洲| 欧美激情在线| 欧美大成色www永久网站婷| 国产香蕉97碰碰久久人人| 一本久久a久久精品亚洲| 亚洲精品乱码久久久久久蜜桃麻豆 | 最新69国产成人精品视频免费| 亚洲欧美视频在线| 午夜电影亚洲| 国产精品免费网站| 亚洲图片自拍偷拍| 欧美波霸影院| 免费视频亚洲| 在线观看91精品国产麻豆| 欧美亚洲视频在线观看| 午夜一区二区三区不卡视频| 欧美视频精品一区| 亚洲视频播放| 亚洲欧美激情视频在线观看一区二区三区 | 一本色道久久综合狠狠躁篇怎么玩 | 影音先锋在线一区| 亚洲欧美激情诱惑| 欧美在线免费视频| 国产情人综合久久777777| 欧美一区二区三区播放老司机| 欧美一区二区三区久久精品茉莉花 | 噜噜噜噜噜久久久久久91| 久久夜色精品| 亚洲国产专区| 欧美国产日本| 亚洲人www| 一区二区精品在线| 国产精品你懂得| 欧美影院成人| 亚洲福利精品| 亚洲欧美激情视频| 国产一区二区高清| 久久综合999| 亚洲人成网站影音先锋播放| 夜久久久久久| 国产精品嫩草久久久久| 香蕉尹人综合在线观看| 免费看成人av| 亚洲线精品一区二区三区八戒| 国产精品一级| 免费视频一区| 亚洲影院色无极综合| 另类av导航| 一本色道久久综合亚洲精品高清| 国产精品久久久久一区二区| 欧美在线观看视频一区二区| 欧美成人按摩| 亚洲一区免费观看| 伊人夜夜躁av伊人久久| 欧美成人精品一区| 亚洲欧美日韩国产另类专区| 久热综合在线亚洲精品| 亚洲天堂偷拍| 极品av少妇一区二区| 欧美日韩在线观看一区二区三区 | 美腿丝袜亚洲色图| 中日韩男男gay无套| 欧美日韩综合| 免费亚洲一区| 欧美一区午夜精品| 99re热精品| 欧美高清视频www夜色资源网| 亚洲婷婷国产精品电影人久久| 国内久久精品| 国产精品视频成人| 欧美日韩精品免费观看视一区二区 | 亚洲欧洲另类| 免费h精品视频在线播放| 亚洲免费影视第一页| 一本色道久久99精品综合|