程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> DELPHI中OPENGL程序設計

DELPHI中OPENGL程序設計

編輯:Delphi
  OPENGL是一個三維圖形和模型庫,由於它在三維圖形方面的傑出性能,目前許多高級語言都提供了與OPENGL的接口,如:VC、Delphi、C++Builder等。使用OPENGL可以極大地減少用戶開發圖形、圖像的難度,使用戶制作高水准的商業廣告、圖形CAD、三維動畫、圖形仿真和影視采集。

  一、OPENGL的功能
   OPENGL原來是工作站上的一個圖形軟件庫,由於它在商業、軍事、醫學、航天航空等領域的廣泛應用,目前在低檔電腦也可以開發出符合用戶要求的圖形。OPENGL不僅可以繪制基本圖像,而且提供了大量處理圖形圖像的函數與過程。
  1、圖形變換
   是圖形顯示與制作的基礎,動畫設計和動畫顯示都離不開圖形的變換,圖形變換在數學上是由矩形的乘法來實現的,變換一般包括平移、旋轉和縮放。按圖形的顯示性質來分:視點變換、模型變換、投影變換、剪裁變換和視口變換等。
  2、光照效果
   不發光的物體的顏色是由物體反射外界光所形成的,這是光照。在三維圖形中,如果光照使用不當,三維圖形就會失去真實的立體感,OPENGL把光照分為:輻射光、環境光、散射光、反射光等。
  3、紋理映射
   通過紋理映射可以在三維表面添加顯示現實世界中的紋理。如:一個矩形它不能表示真實世界中的物體,如果填上"本質"紋理,就逼真了。
  4、圖形特效
   混合函數、反走樣函數和霧函數,可以處理三維圖形聽之任之物體的透明和半透明、使用線段理加光滑以及提供霧化的效果。
  5、圖像特效
   處理位圖的基本函數:圖像繪制、圖像拷貝和存儲、映射和轉移、圖像的縮放等。位圖操作函數可以人繪圖原的低層說明中文字符的形成過程。

  二、創建OPENGL應用程序
  1、一般原則
   A 有uses中添加OPENGL支持單元:OpenGL;
   B 在窗體的OnCreate事件過程中初始化OPENGL;
   C 在窗口的OnPaing 事件過程中初始化OPENGL;
   D 在窗口的OnResize事件過程中初始化OPENGL;
   E 在窗口的OnDestroy 事件過程中初始化 OPENGL;
  2、簡單實例
   A 創建一個工程FILE->New Application
  B 在OnCreate事件中添加代碼:
  procedure TfrmMain.FormCreate(Sender: TObject);
  var
    pfd:TPixelFormatDescriptor;   //設置描述表
    PixelFormat:Integer;
  begin
    ControlStyle:=ControlStyle+[csOpaque];
    FillChar(pfd,sizeof(pfd),0);
    with pfd do
    begin
      nSize:=sizeof(TPixelFormatDescriptor);
      nVersion:=1;
      dwFlags:=PFD_DRAW_TO_WINDOW or
          PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
      iPixelType:=PFD_TYPE_RGBA;
      cColorBits:=24;
      cDepthBits:=32;
      iLayerType:=PFD_MAIN_PLANE;
    end;
    PixelFormat:=ChoosePixelFormat(Canvas.Handle,@pfd);
    SetPixelFormat(Canvas.Handle,PixelFormat,@pfd);
    hrc:=wglCreateContext(Canvas.Handle);
    w:=ClIEntWidth;
    h:=ClIEntHeight;
  end;
  C 在OnDestroy事件中的代碼
  procedure TfrmMain.FormDestroy(Sender: TObject);
  begin
    wglDeleteContext(hrc);
  end;
  D 在OnPaint事件中的代碼
  procedure TfrmMain.FormPaint(Sender: TObject);
  begin
    wglMakeCurrent(Canvas.Handle,hrc);
    glClearColor(1,1,1,1);
    glColor3f(1,0,0);
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
    MyDraw;
    glFlush;
    SwapBuffers(Canvas.Handle);
  end;
  E 在OnResize事件中的代碼
  procedure TfrmMain.FormResize(Sender: TObject);
  begin
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity;
    glFrustum(-1.0,1.0,-1.0,1.0,3.0,7.0);
    glViewPort(0,0,ClientWidth,ClIEntHeight);
    MyDraw;
  end;
  F 在MyDraw函數中的代碼(用戶在窗口類中聲明)
  procedure TfrmMain.MyDraw;
  begin
    glPushMatrix;
    Sphere:=gluNewQuadric;
    gluQuadricDrawStyle(Sphere,GLU_LINE);
    gluSphere(Sphere,0.5,25,25);
    glPopMatrix;
    SwapBuffers(Canvas.handle);
    gluDeleteQuadric(Sphere);
  end;

  附本程序原碼:
  unit MainFrm;

  interface

  uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, OpenGL;

  type
    TfrmMain = class(TForm)
      procedure FormCreate(Sender: TObject);
      procedure FormDestroy(Sender: TObject);
      procedure FormPaint(Sender: TObject);
      procedure FormResize(Sender: TObject);
    private
      { Private declarations }
      hrc:HGLRC;
      w,h:glFloat;
      Sphere:GLUquadricObj;
    public
      { Public declarations }
      procedure MyDraw;
    end;

  var
    frmMain: TfrmMain;

  implementation

  {$R *.dfm}

  procedure TfrmMain.FormCreate(Sender: TObject);
  var
    pfd:TPixelFormatDescriptor;
    PixelFormat:Integer;
  begin
    ControlStyle:=ControlStyle+[csOpaque];
    FillChar(pfd,sizeof(pfd),0);
    with pfd do
    begin
      nSize:=sizeof(TPixelFormatDescriptor);
      nVersion:=1;
      dwFlags:=PFD_DRAW_TO_WINDOW or
          PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
      iPixelType:=PFD_TYPE_RGBA;
      cColorBits:=24;
      cDepthBits:=32;
      iLayerType:=PFD_MAIN_PLANE;
    end;
    PixelFormat:=ChoosePixelFormat(Canvas.Handle,@pfd);
    SetPixelFormat(Canvas.Handle,PixelFormat,@pfd);
    hrc:=wglCreateContext(Canvas.Handle);
    w:=ClIEntWidth;
    h:=ClIEntHeight;
  end;

  procedure TfrmMain.FormDestroy(Sender: TObject);
  begin
    wglDeleteContext(hrc);
  end;

  procedure TfrmMain.FormPaint(Sender: TObject);
  begin
    wglMakeCurrent(Canvas.Handle,hrc);
    glClearColor(1,1,1,1);
    glColor3f(1,0,0);
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
    MyDraw;
    glFlush;
    SwapBuffers(Canvas.Handle);
  end;

  procedure TfrmMain.MyDraw;
  begin
    glPushMatrix;
    Sphere:=gluNewQuadric;
    gluQuadricDrawStyle(Sphere,GLU_LINE);
    gluSphere(Sphere,0.5,25,25);
    glPopMatrix;
    SwapBuffers(Canvas.handle);
    gluDeleteQuadric(Sphere);
  end;

  procedure TfrmMain.FormResize(Sender: TObject);
  begin
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity;
    glFrustum(-1.0,1.0,-1.0,1.0,3.0,7.0);
    glViewPort(0,0,ClientWidth,ClIEntHeight);
    MyDraw;
  end;

  end.

  三、OPENGL變量和函數的約定
  1、OPENGL的庫約定
   它共三個庫:基本庫、實用庫、輔助庫。在Delphi中,基本庫由OpenGL單元實現,在Windows環境中,一般不使用輔助庫。
  2、OPENGL常數約定
   OPENGL常數均使用大寫字母,以"GL"開頭,詞匯之間使用下劃線分隔,如:GL_LINES,表示使用基本庫繪制直線。
  3、OPENGL函數的命名約定
   A 第一部分以gl或wgl開頭,如glColor3f中的gl。
   B 第二部分是用英文表示的函數功能,單詞的首字母大寫出。
   C 第三部分是數字,表示函數的參數。
   D 第四部分是小寫字母,表示函數的類型。
  b 9位整數
  s 16位整數
  i 32位整數
  f 32位浮點數
  d 64位浮點數
  ub 9位無符號整數
  例:glVertex2f(37,40);  {兩個32位的浮點數作參數}
  glVertex3d(37,40,5); {三個64位的浮點數作參數}
     p[1..3]:array of glFloat;
  glVertes3fv(p);     {3f表示三個浮點數,v表示調用一個數組作為頂點坐標輸入}

  四、OPENGL的初始化
  1、PIXELFORMATDESCRIPTOR結構
   主要描述像素點的性質,如像素的顏色模式和紅、綠、藍顏色構成方式等。
    tagPIXELFORMATDESCRIPTOR = packed record
      nSize: Word;
      nVersion: Word;
      dwFlags: DWord;
      iPixelType: Byte;
      cColorBits: Byte;
      cRedBits: Byte;
      cRedShift: Byte;
      cGreenBits: Byte;
      cGreenShift: Byte;
      cBlueBits: Byte;
      cBlueShift: Byte;
      cAlphaBits: Byte;
      cAlphaShift: Byte;
      cAccumBits: Byte;
      cAccumRedBits: Byte;
      cAccumGreenBits: Byte;
      cAccumBlueBits: Byte;
      cAccumAlphaBits: Byte;
      cDepthBits: Byte;
      cStencilBits: Byte;
      cAuxBuffers: Byte;
      iLayerType: Byte;
      bReserved: Byte;
      dwLayerMask: DWord;
      dwVisibleMask: DWord;
      dwDamageMask: DWord;
    end;
    TPixelFormatDescriptor = tagPIXELFORMATDESCRIPTOR;
     dwFlags代表點格式的屬性:
  PFD_DRAW_TO_WINDOW 圖形繪在屏幕或設備表面
  PFD_DRAW_TO_BITMAP 在內存中繪制位圖
  PFD_SUPPORT_GDI 支持GDI繪圖
  PFD_SUPPORT_OPENGL 支持OPENGL函數
  PFD_DOUBLEBUFFER 使用雙緩存
  PFD_STEREO 立體緩存
  PFD_NEED_PALLETTE 使用RGBA調色板
  PFD_GENERIC_FORMAT 選擇GDI支持的格式繪圖
  PFD_NEED_SYSTEM_PALETTE 使用OPENGL支持的硬件調色板
     iPixelType設置像素顏色模式:PFD_TYPE_RGBA或PFD_TYPE_INDEX.。
     cColorBits設置顏色的位,如是9表示有256種顏色表示點的顏色。
     cRedBits、cGreenBits、cBlueBits 使用RGBA時,三原色所使用的位數。
     cRedShitfs、cGreenShifts、cBlueShifts 使用RGBA時,三原色可以調節的位數。
     cAlphaBits、cAlphaShifts 使用RGBA時,Alpha使用的位數與可調節的位數。
   cAccumBits設置累積緩存區的位面總數。
   cAccumRedBits、cAccumGreenBits、cAccumBlueBits設置累積緩存區的三原色位面總數。
   cAccumAlphaBits設置累積緩存區的Alpha位面總數。
   cDepthBits設置濃度緩存的深度。
   cStencilBits設置Stencil緩存的深度。
   cAuxBuffers指輔助緩存的大小。
   iLayerType指定層的類型。
   bReserved不使用,必須是零。
   dwLayerMask指定覆蓋層的屏蔽。
   dwDamageMask設置在相同的框架緩存下是否共用同一種像素模式。
  2、OPENGL的初始化步驟
   A 使用Canvas.Handle獲得窗口句柄。
   B 創建一個TPixelFormatDescriptor變量定義像素格式。
   C 使用ChoosePixelFormat函數選擇像素格式。
   D 使用SetPixelFormat函數使用像素格式生效。
   E 使用wglCreateContext函數建立翻譯描述表。
   F 使用wglMakeCurrent函數把建立的翻譯描述表作為當前翻譯描述表。
  3、資源釋放
   A 使用wglDeleteContext過程刪除像素描述表。
   B 使用ReleaseDC過程釋放窗口內存。
   在窗口的OnDestroy事件中:
   begin
    if hrc<>null then
     wglDeleteCurrent(hrc);
    if hdc<>null then
     ReleaseDC(Handle,hdc);
   end;

  五、OPENGL基本圖形的繪制
  1、圖形的顏色
   注意底色的設置,顏色設置通常與像素描述變量有關,即與TPixelFormatDescriptor定義中的iPixelType成員有關。
   iPixelType:=PFD_TYPE_COLORINDEX;
   則只能使用glIndexd,glIndexf,glIndexi,glIndexs,glIndexv,glIndexfv,glIndexiv,glIndexsv過程設置圖形顏色。
   iPixelType:=PFD_TYPE_RGBA;
   則只能使用 glColor3b,glColor3f,glColor4b,glColor4f,glColor4fv設置圖形顏色。
  A 圖形底色:屏幕與窗口的顏色,即顏色緩沖區的顏色。改變圖形底色首先應使用glClearColor過程設定底色,然後使用glClear過程以這種底色刷新窗口和屏幕。
   procedure glClearColor(red:GLClampf,green:GLClampf,blue:GLClampf,alpha:GLClampf);
   procedure glClear(mask:GLBitFIEld);
   red,green,blue,alpha是准備設置的底色,它們的取值是0到1。mask是刷新底色的方式。
  例:將繪聲繪色圖窗口設置為綠色
  glClearColor(0,1,0,1);
  glClear(GL_COLOR_BUFFER_BIT);
  mask的取值和意義:
  GL_COLOR_BUFFER_BIT 設置當前的顏色緩沖
  GL_DEPTH_BUFFER_BIT 設置當前的深度緩沖
  GL_ACCUM_BUFFER_BIT 設置當前的積累緩沖
  GL_STENCIL_BUFFER_BIT 設置當前的STENCIL(模板)緩沖
  繪圖窗口設置為灰色
  glClearColor(0.3,0.3,0.3,1);
  glClear(GL_COLOR_BUFFER_BIT);
  B 圖形顏色
   使用glClear3f與glClear4f可以設置圖形的繪制顏色。若用三個參數,則分別指設置紅、藍、綠三色光。若用四個參數,則第四個表示RGBA值。
   例設置當前的繪圖顏色為藍色:
   glColor3f(0,0,1);
   設置繪圖顏色為白色:
   glColor3f(1,1,1);
  2、簡單圖形的繪制
   在glBegin與glEnd過程之間繪制簡單圖形,如點、線、多邊形等。
   glBegin(mode:GLenum);{繪制過程}glEnd;
   mode的取值:
  GL_POINTS 畫多個點
  GL_LINES 畫多條線,每兩點繪制一條直線
  GL_LINE_STRIP 繪制折線
  GL_LINE_LOOP 繪制首尾相接的封閉多邊形
  GL_TRIANGLES 繪制三角形
  GL_TRIANGLE_STRIP 繪制三邊形,每三個點繪制繪制一個三邊形
  GL_TRIANGLE_FAN 繪制三角形
  GL_QUADS 繪制四邊形
  GL_QUAD_STRIP 繪制四邊條,每四點繪制一個四邊條
  GL_POLYGON 繪制多邊形
   例繪制三個點:
   begin
    glPushMatrix;
    glBegin(GL_POINT);
     glVertex2f(0.1,0.1);
     glVertex2f(0.5,0.5);
     glVertex2f(0.1,0.3);
    glEnd;
    SwapBuffers(Canvas.Handle);
   end;
  如果將GL_POINT改為GL_LINES,則將畫一條線.第三個點無效.在glVertex2f之前執行glColor3f(0,0,1)則將線條的顏色改為綠色. 如果將GL_LINES改為GL_LINE_STRIP則可以繪制兩條直線.
   使用glPointSize過程可以設置點的大小;使用glLineWidth過程可以設置線的寬度.
   使用glLineStipple過程設置點劃線的樣板,使用glEnable(GL_LINE_STIPPLE)過程和對應參數使繪圖能夠繪制點劃線.glDisable(GL_LINE_STIPPLE)過程和對應參數關閉點劃線.
   procedure glLineStipple(factor:GLint,pattern:GLushort);
   參數factor表示點劃線樣板Pattern的重復次數,factor取值1255,Pattern是二進制序列.
   glLineStipple(1,0,0x11C);{0x11C表示為10001110,0表示不畫點,1表示畫點}
  例:   begin
    glColor3f(1,0,0);
    glLineWidth(2);
    glLineStipple(1,$11C);
    glEnable(GL_LINE_STIPPLE);
    glBegin(GL_LINES);
     glVertex2f(-0.9,0.3);
     glVertex2f(0.9,0.3);
    glEnd;
    glDisable(GL_LINE_STIPPLE);
    glColor3f(1,0,1);
    glLineStipple(2,$11C);
    glEnable(GL_LINE_STIPPLE);
    glBegin(GL_LINES);
     glVertex2f(-0.9,0.1);
     glVertex2f(0.9,0.1);
    glEnd;
    glDisable(GL_LINE_STIPPLE);
    SwapBuffers(Canvas.Handle);
   end;
   多邊形繪制與點線相似,要改變參數為GL_POLYGON,GL_QUADS,GL_TRANGLES.在繪制時的注意事項:
   A 多邊形的邊與邊只在頂點相交
   B 多邊形必須是凸多邊形,如果是凹多邊形,用戶只有折成凸多邊形,加快繪制速度.
  例: glBegin(GL_POLYGON);
    glVertex2f(-0.9,0.3);
    glVertex2f(0.9,0.3);
    glVertex2f(0.9,-0.6);
    glVertex2f(0.5,-0.6);
    glVertex2f(-0.9,-0.2);
   glEnd;
  多邊形有正面與反面,與之相關的過程:
  glPolygonMode 控制多邊形正,反面繪圖模式
  glFrontface 指定多邊形的正面
  glCullFace 顯示多邊形是設置消除面
  glPolygonStripple 形成多邊形填充的樣式
  3、簡單二次曲面
   圓柱,圓環和球都屬於二次曲面.
  A 圓柱
  gluCylinder(qobj:GLUquadricObj,baseRadius:GLdouble,topRadius:GLdouble,height:GLdouble,
  slices:GLint,stacks:GLint);
  qobj指定一個二次曲面,baseRadius為圓柱的底半徑;topRadius為所繪制圓柱的上頂面半徑;height為圓柱的高;slices為繞Z軸的分割線數;stacks為沿Z軸的分割線數.
  如果baseRadius和topRadius不相等,則可以繪制錐台與圓錐.
  procedure TfrmMain.MyDraw;
  var
    qObj:GLUQuadricObj;
  begin
    glPushMatrix;
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
    glColor3f(1,0,0);
    qObj:=gluNewQuadric;
    gluQuadricDrawStyle(qObj,GLU_LINE);
    gluCylinder(qObj,0.5,0.1,0.2,10,10);
  end;
  B 圓環
  gluDisk(qobj:GLUquadricObj,innerRadius:GLdouble,outerRadius:GLdouble,slices:GLint,
  loops:GLint);
  procedure TfrmMain.MyDraw;
  var
    qObj:GLUQuadricObj;
  begin
    glPushMatrix;
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
    glColor3f(1,0,0);
    qObj:=gluNewQuadric;
    gluQuadricDrawStyle(qObj,GLU_LINE);
    gluDisk(qObj,0.2,0.5,10,5);
    SwapBuffers(Canvas.Handle);
  end;
  C 半圓環
  gluPartialDisk(qobj:GLUquadricObj,innerRadius:GLdouble,outerRadius:GLdouble,slices:GLint,
  loops:GLint,startAngle:GLdouble,sweepAngle:GLdouble);
  startAngle,sweepAngle是半圓環的起始角與終止角.
  procedure TfrmMain.MyDraw;
  var
    qObj:GLUQuadricObj;
  begin
    glPushMatrix;
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
    glColor3f(1,0,0);
    qObj:=gluNewQuadric;
    gluQuadricDrawStyle(qObj,GLU_LINE);
    gluPartialDisk(qObj,0.2,0.5,10,5,90,190);
    SwapBuffers(Canvas.Handle);
  end;
  D 球體
  function gluSphere(qObj:GLUquadricObj,radius:GLdouble,slices:GLint,stacks:GLint);
  procedure TfrmMain.MyDraw;
  var
    qObj:GLUQuadricObj;
  begin
    glPushMatrix;
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
    glColor3f(1,0,0);
    qObj:=gluNewQuadric;
    gluQuadricDrawStyle(qObj,GLU_LINE);
  { silhouette[ silu(:)5et ]n.側面影象, 輪廓}
    gluSphere(qObj,0.5,20,20);
    SwapBuffers(Canvas.Handle);
  end;
  E 關於二次曲面的過程
  gluNewQuadric 創建一個新的二次曲面對象
  gluDeleteQuadric 刪除一個二次曲面對象
  gluQuadricDrawStyle 指定要繪制的二次曲面類型
  gluQuadricNormal 設置二次曲面的法矢量
  gluQuadricOrIEntation 設置二次曲面是內旋還是外旋轉
  gluQuadricTexture 設置二次曲面是否使用紋理
  F 繪制二次曲面的一般步驟
   首先定義一個GLUquadricObj對象;
   其次創建一個曲面對象gluNewQuadric;
   再次設置二次曲面的特性(gluQuadricDrawStyle, gluQuadricTexture)
   繪制二次曲面(gluCylinder,gluSphere,gluDisk, gluPartialDisk)

  六、OPENGL中的變換
   變換是動畫設計的基礎,包括圖形的平移,旋轉,縮放等操作,在數學上是通過矩陣來實現的。
  1 glLoadIdentity過程
   能夠把當前矩陣變為單位矩陣。
  2 glLoadMatrix過程
   能夠把指定的矩陣設為當前矩陣。
   procedure glLoadmatrixd(m:GLdouble);
   procedure glLoadmatrixf(m:GLfloat);
   m表示4X4矩陣,下面的代碼定義並使之成為當前矩陣
   M:array[1..4,1..4] of GLfloat;
   glLoadMatrix(@M);
  3 glMultMatrix過程
   能夠將當前矩與指定矩陣相乘,並把結果作為當前矩.
   procedure glMultMatrixd(M:GLdouble);
   procedure glMultMatrixf(M:GLfloat);
  4 glPushMatrix和glPopmatrix
   glPushMatrix能夠把當前矩壓入矩陣堆棧, glPopMatrix能夠把當前矩彈出矩陣堆棧.
   glPushMatrix能夠記憶矩陣當前位置,glPopmatrix能夠返回以前所在的位置.
   注:glPushMatrix與glPopMatrix必須放在glBegin與glEnd之外.
  5 投影變換
  A glOrtho能夠創建一個正投影矩陣,把當前矩乘以該正投影矩陣,其結果作為當前矩陣.
  function glOrtho(left:GLdouble,right:GLdouble,bottom:GLdouble,top:GLdouble,
  near:GLdouble,far:GLdouble);
   procedure TfrmMain.FormResize(Sender: TObject);
  var
    nRange:GLfloat;
  begin
    nRange:=50.0;
    w:=clIEntWidth;
    h:=clIEntHeight;
    if h=0 then
      h:=1;
    glVIEwPort(0,0,w,h);
    if w<=h then
      glOrtho(-nRange,nRange,-nRange*h/w,nRange*h/w,
        -nRange,nRange)
    else
      glOrtho(-nRange*h/w,nRange*h/w,-nRange,nRange,
        -nRange,nRange);
    repaint;
  end;
  B glOrtho2D只定義正投影視景體前,後,左,右.
   procedure glOrtho(left:GLdouble,right:GLdouble,bottom:GLdouble,top:GLdouble);
  C glMatrixMode過程
   能夠設置當前操作矩陣的類型
   procedure glMatrixMode(mode:GLenum);
   mode的取值:
  GL_MODELVIEW 指定以後的矩陣操作為模型矩陣堆棧
  GL_PROJECTION 指定以後的矩陣操作為投影矩陣堆棧
  GL_TEXTURE 指定以後的矩陣操作為紋理矩陣堆棧
  D glFrustum過程
   創建一個透視斜投影矩陣,並把當前矩陣乘以該斜投影矩陣,其結果為當前矩陣.
   procedure glFrustum(left:GLdouble,right:GLdouble,bottom:GLdouble,top:GLdouble,
    next:GLdouble,far:GLdouble);
   這些參數定義了斜投影的左,右,上,下,前,後剪裁面.
  E gluPerspective過程
   能夠定義一個以Z軸為中線的四稜台視景體.
   procedure gluPerspetive(fovy:GLdouble,ASPect:GLdouble,zNear:GLdouble,zFar:GLdouble);
   fovy定義了xoz平面的視角,ASPect定義了x和y方向上的比例,zNear和zFar分別定義了視點到剪裁面和後剪裁面的距離.
   procedure TfrmMain.FormResize(Sender: TObject);
  var
    ASPect:GLfloat;
  begin
    w:=ClIEntWidth;
    h:=ClIEntHeight;
    if h=0 then
      h:=1;
    glViewPort(0,0,clientWidth,ClIEntheight);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity;
    ASPect:=w/h;
    gluPerspective(30.0,ASPect,1.0,50.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity;
  end;
  6 幾何變換矩陣
   三維物體的運動姿態變換,是指物體的平移,旋轉,縮放.
  A glTranslate過程能夠把坐標原點移到(x,y,z),它的聲明語法:
   procedure  glTranslated(x:GLdouble,y:GLdouble,z:GLdouble);
   procedure  glTranslatef(x:GLdouble,y:GLdouble,z:GLdouble);
  B glRotate能夠使物體旋轉一定的角度,它的聲明語法:
   procedure glRotated(angle:GLdobule,x:GLdouble,y:GLdouble,z:GLdouble);
   procedure glRotatef(angle:GLdobule,x:GLdouble,y:GLdouble,z:GLdouble);
   其中angle為旋轉角,旋轉的中心軸是由(0,0,0)與(x,y,z)兩點的連線.
  C glScale能夠對坐標系進行縮放,它的聲明語法為:
   procedure glScaled(x:GLdouble,y:GLdoble,z:GLdouble);
   procedure glScalef(x:GLdouble,y:GLdoble,z:GLdouble);
  x,y,z的值大於1表示放大,小於1表示縮小.

  例子原代碼:
  unit MainFrm;

  interface

  uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, OpenGL, ExtCtrls;

  type
    TfrmMain = class(TForm)
      Timer1: TTimer;
      procedure FormCreate(Sender: TObject);
      procedure FormDestroy(Sender: TObject);
      procedure FormPaint(Sender: TObject);
      procedure FormKeyDown(Sender: TObject; var Key: Word;
        Shift: TShiftState);
      procedure FormResize(Sender: TObject);
      procedure Timer1Timer(Sender: TObject);
      procedure FormClose(Sender: TObject; var Action: TCloseAction);
    private
      { Private declarations }
      hrc:HGLRC;
      w,h:Integer;
      latitude,longitude:GLfloat;
      radius:GLdouble;
    public
      { Public declarations }
      procedure MyDraw;
      procedure InitializeGL(var width:GLsizei;height:GLsizei);
    end;

  var
    frmMain: TfrmMain;

  implementation

  {$R *.dfm}

  procedure TfrmMain.FormCreate(Sender: TObject);
  var
    pfd:TPixelFormatDescriptor;
    PixelFormat:Integer;
  begin
    ControlStyle:=ControlStyle+[csOpaque];
    FillChar(pfd,sizeof(pfd),0);
    with pfd do
    begin
      nSize:=sizeof(TPixelFormatDescriptor);
      nVersion:=1;
      dwFlags:=PFD_DRAW_TO_WINDOW or
          PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
      iPixelType:=PFD_TYPE_RGBA;
      cColorBits:=24;
      cDepthBits:=32;
      iLayerType:=PFD_MAIN_PLANE;
    end;
    PixelFormat:=ChoosePixelFormat(Canvas.Handle,@pfd);
    SetPixelFormat(Canvas.Handle,PixelFormat,@pfd);
    hrc:=wglCreateContext(Canvas.Handle);
    w:=ClIEntRect.Right;
    h:=ClIEntRect.Bottom;
    InitializeGL(w,h);
  end;

  procedure TfrmMain.FormDestroy(Sender: TObject);
  begin
    wglDeleteContext(hrc);
  end;

  procedure TfrmMain.FormPaint(Sender: TObject);
  begin
    wglMakeCurrent(Canvas.Handle,hrc);
    glClearColor(1,1,1,1);
    glColor3f(1,0,0);
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
    MyDraw;
    glFlush;
  end;

  procedure TfrmMain.MyDraw;
  var
    qObj:GLUQuadricObj;
  begin
    glPushMatrix;
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
    glColor3f(1,0,0);
    glRotated(0.5,0.0,1.0,0.0);
    glRotated(-latitude,1.0,0.0,0.0);
    glrotated(longitude,0.0,0.0,1.0);
    qObj:=gluNewQuadric;
    gluQuadricDrawStyle(qObj,GLU_LINE);
    gluSphere(qObj,0.5,20,20);
    SwapBuffers(Canvas.Handle);
  end;

  {procedure TfrmMain.FormResize(Sender: TObject);
  var
    nRange:GLfloat;
  begin
    nRange:=50.0;
    w:=clIEntWidth;
    h:=clIEntHeight;
    if h=0 then
      h:=1;
    glVIEwPort(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity;
    if w<=h then
      glOrtho(-nRange,nRange,-nRange*h/w,nRange*h/w,
        -nRange,nRange)
    else
      glOrtho(-nRange*h/w,nRange*h/w,-nRange,nRange,
        -nRange,nRange);
    glMatrixMode(GL_MODELVIEW);
    glLoadidentity;
    repaint;
  end;
  }
  procedure TfrmMain.FormKeyDown(Sender: TObject; var Key: Word;
    Shift: TShiftState);
  begin
    if Key=VK_ESCAPE then
      Close;
    if Key=VK_UP then
      glRotatef(-5,1.0,0.0,0.0);
    if Key=VK_DOWN then
      glRotatef(5,1.0,0.0,0.0);
    if Key=VK_LEFT then
      glRotatef(-5,0.0,1.0,0.0);
    if Key=VK_RIGHT then
      glRotatef(5.0,0.0,1.0,0.0);
    repaint;
  end;

  procedure TfrmMain.FormResize(Sender: TObject);
  begin
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity;
    glFrustum(-1.0,1.0,-1.0,1.0,3.0,7.0);
    glViewPort(0,0,clientWidth,clIEntHeight);
    repaint;
    invalidate;
  end;

  procedure TfrmMain.InitializeGL(var width: GLsizei; height: GLsizei);
  var
    maxObjectSize,ASPect:GLfloat;
    near_plane:GLdouble;
  begin
    glClearindex(0);
    glClearDepth(1.0);
    glEnable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    ASPect:=1.0;
    gluPerspective(45.0,ASPect,3.0,7.0);
    glmatrixMode(GL_MODELVIEW);
    near_plane:=0.3;
    maxObjectSize:=0.3;
    radius:=near_plane+maxObjectSize/2.0;
    latitude:=0.3;
    longitude:=0.6;
  end;

  procedure TfrmMain.Timer1Timer(Sender: TObject);
  begin
    timer1.Enabled:=false;
    MyDraw;
    YIEld;
    Timer1.Enabled:=true;
  end;

  procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
  begin
    timer1.Enabled:=false;
    if hrc<>null then
      wglDeleteContext(hrc);
  end;

  end.

  七、OPENGL的光照與紋理
   都是增強三維立體效果和色彩效果的手段,光照能夠增加圖形的亮度和三維效果,紋理能夠使用圖形更加趨近現實。通過使用光照,可以將物體的外觀很強列的表現出來,紋理則可以使物體顯示多種多樣的外觀。
  1 光照和光源過程及應用
  A glIndex過程能夠使顏色索引表中的某一種顏色成為當前顏色。
   procedure glIndexd(c:GLdouble);
   procedure glIndexf(c:GLdouble);
   procedure glIndexi(c:GLdouble);
   procedure glIndexs(c:GLdouble);
   參數C為索引值,如果使用glIndex過程,則TPIExlFormatDescriptor結構中的iPixelType成員設置為PFD_TYPE_COLORINDEX。
  B glShadeModel過程
   glShadeModel過程設置填充模式,取值:GL_SMOOTH.
   procedure  glShadeModel(mode:GLenum);
   注:以上兩個過程只能在glBegin.....glEnd之外使用。
  C glLight過程定義光源
   procedure glLightf(light:GLenum,pname:GLenum,param:GLfloat);
   procedure glLighti(light:GLenum,pname:GLenum,param:GLfloat);
   參數light定義光源,其值可取:GL_LIGHT0.....GL_LIGHTN,N值小於GL_MAX_LIGHT.
   參數pname指定光源參數:
  GL_AMBIENT 環境光的分量強度
  GL_DIFFUSE 散射光的分量強度
  GL_SPECULAR 反射光的分量強度
  GL_POSITION 光源位置
  GL_SPOT_DIRECTION 光源的聚光方向
  GL_SPOT_EXPONENT 光源的聚光指數
  GL_SPOT_CUTOFF 光源的聚光方向
  GL_CONSTANT_ATTENUATION 光常數衰退因子
  GL_LINEAR_ATTENUATION 光二次衰減因子
   啟用和關閉光源使用glEnable()與glDisable()過程
   glEnable(GL_LIGHTING);  //啟用光源
   glDisable(GL_LIGHTING); //關閉光源
   glEnable(GL_LIGHT0);       //啟用第0個光源
   glDisable(GL_LIGHT0);      //關閉第0個光源
   設置光源的實例:
   var
    sdirection:Array[1..4] of GLfloat:={0.0,1.0,0.0,0.0};
    glLightfv(GL_LIGHT0,GL_SPOT_CUTOFF,60);
    glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,sdirection);
  2 材質和光照模型
  A glMaterial過程設置材質參數
   procedure  glMaterialf(face:GLenum,pname :GLenum,param:GLfloat);
   procedure  glMateriali(face:GLenum,pname :GLenum,param:GLfloat);
   procedure  glMaterialfv(face:GLenum,pname :GLenum,param:GLfloat);
   procedure  glMaterialiv(face:GLenum,pname :GLenum,param:GLfloat);
   參數face指定物體表面,它的取值:GL_FRONT,GL_BACK,GL_FRONT_BACK.
   pname,param本資料沒作介紹.
  B glLightModel過程
   procedure glLightModelf(pname:GLenum,param:GLfloat);
   參數pname為光源模型參數,可以取值GL_LIGHT_MODEL_AMBIENT,
   GL_LIGHT_MODEL_LOCAL_VIEWER,GL_LIGHT_MODEL_TWO_SIDE.
  實例代碼:
  procedure TfrmMain.SetLighting;
  var
    MaterialAmbIEnt:array[1..4] of GLfloat;
    MaterialDiffuse:Array[1..4] of GLfloat;
    MaterialSpecular:Array[1..4] of GLfloat;
    AmbIEntLightPosition:Array[1..4] of GLfloat;
    LightAmbIEnt:Array[1..4] of GLfloat;
    MaterialShininess:GLfloat;
  begin
    MaterialAmbIEnt[1]:=0.5;
    MaterialAmbIEnt[2]:=0.8;
    MaterialAmbIEnt[1]:=0.2;
    MaterialAmbIEnt[1]:=1.0;

    MaterialDiffuse[1]:=0.4;
    MaterialDiffuse[2]:=0.8;
    MaterialDiffuse[3]:=0.1;
    MaterialDiffuse[4]:=1.0;

    MaterialSpecular[1]:=1.0;
    MaterialSpecular[2]:=0.5;
    MaterialSpecular[3]:=0.1;
    MaterialSpecular[4]:=1.0;

    materialShininess:=50.0;

    AmbIEntLightPosition[1]:=0.5;
    AmbIEntLightPosition[2]:=1.0;
    AmbIEntLightPosition[3]:=1.0;
    AmbIEntLightPosition[4]:=0.0;

    LightAmbIEnt[1]:=0.5;
    LightAmbIEnt[2]:=0.2;
    LightAmbIEnt[3]:=0.8;
    LightAmbIEnt[4]:=1.0;

    glMaterialfv(GL_FRONT,GL_AMBIENT,@MaterialAmbIEnt);
    glMaterialfv(GL_FRONT,GL_DIFFUSE,@MaterialDiffuse);
    glMaterialfv(GL_FRONT,GL_SPECULAR,@MaterialSpecular);
    glMaterialfv(GL_FRONT,GL_SHININESS,@MaterialShininess);

    glLightfv(GL_LIGHT0,GL_POSITION,@AmbIEntLightPosition);
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,@LightAmbIEnt);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    GLShadeModel(GL_SMOOTH);
  end;
  3 紋理的應用
  A glTexImage1D定義一維紋理映射.
   procedure glTexImage1D(target:GLenum,level:GLint,components:GLint,width:GLsizei,
    border:GLint,format:GLenum,type:GLenum,pixels:GLvoid);
   參數targer值為GL_TEXTURE_1D,定義為紋理映射,level為多級分辨率的紋理圖像的等級,width為紋理寬,值為2n,n取值為32,64,129等.border為紋理的邊界,其值為0或1,Pixel為紋理在內存中的位置.Component指定RGBA的混合和調整: 
  1 選擇B成分
  2 選擇B,A成分
  3 選擇R,G,B成分
  4 選擇R,G,B,A成分
  B glTexImage2D定義二維紋理映射
   procedure glTexImage2D(target:GLenum,level:GLint,components:GLint,width:GLsizei,
    border:GLint,format:GLenum,type:GLenum,pixels:GLvoid);
  若參數target為GL_TEXTURE_2D,意義為二維紋理映射,height為紋理的高,函數中的其它參數與glTexImage1D相同.component參數取值同上.
  實例代碼:
  procedure TfrmMain.SetTextures;
  var
    bits:Array[1..64,1..64,1..64] of GLubyte;
    bmp:TBitmap;
    i,j:Integer;
  begin
    bmp:=TBitmap.Create;
    bmp.LoadFromFile('d:dsoft11191logon.bmp');
    for i:=1 to 64 do
      for j:=1 to 64 do
      begin
        bits[i,j,1]:=GLbyte(GetRValue(bmp.Canvas.Pixels[i,j]));
        bits[i,j,2]:=GLbyte(GetRValue(bmp.Canvas.Pixels[i,j]));
        bits[i,j,3]:=GLbyte(GetRValue(bmp.Canvas.Pixels[i,j]));
        bits[i,j,4]:=255;
      end;
    {0代表為單色著色水平,GL_RGBA表示混合值
     64X64代表紋理的高和寬,0表示無邊界,
     GL_RGBA代表紋理類型,GL_UNSIGNED_TYPE代表數據類型,@代對象地址}
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,64,64,0,GL_RGBA,
      GL_UNSIGNED_BYTE,@bits);
    glEnable(GL_TEXTURE_2D);
  end;
  C glTexParameter過程設置紋理參數
   procedure glTexParameterf(target:GLenum,pname:GLenum,param:GLfloat);
   procedure glTexParameteri(target:GLenum,pname:GLenum,param:GLfloat);
   參數target代表GL_TEXTURE_1D或GL_TEXTURE_2D,param為紋理值.
  D glTexEnv函數設置紋理的環境參數
   function glTexEnvf(target:GLenum,pname:GLenum,param:GLfloat);
   function glTexEnvi(target:GLenum,pname:GLenum,param:GLfloat);
   參數target為GL_TEXTURE_ENV,
  參數pname為紋理參數值,取值為GL_TEXTURE_ENV_MODE
  參數param為環境值,取值為GL_MODULATE,GL_DECAL和GL_BLEND.
  本程序示例代碼:
  unit MainFrm;

  interface

  uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, OpenGL, ExtCtrls;

  type
    TfrmMain = class(TForm)
      Timer1: TTimer;
      procedure FormCreate(Sender: TObject);
      procedure FormDestroy(Sender: TObject);
      procedure FormPaint(Sender: TObject);
      procedure FormKeyDown(Sender: TObject; var Key: Word;
        Shift: TShiftState);
      procedure FormResize(Sender: TObject);
      procedure Timer1Timer(Sender: TObject);
      procedure FormClose(Sender: TObject; var Action: TCloseAction);
    private
      { Private declarations }
      hrc:HGLRC;
      w,h:Integer;
      latitude,longitude:GLfloat;
      radius:GLdouble;
    public
      { Public declarations }
      procedure SetLighting;
      procedure SetTextures;
      procedure MyDraw;
      procedure InitializeGL(var width:GLsizei;height:GLsizei);
    end;

  var
    frmMain: TfrmMain;

  implementation

  {$R *.dfm}

  procedure TfrmMain.FormCreate(Sender: TObject);
  var
    pfd:TPixelFormatDescriptor;
    PixelFormat:Integer;
  begin
    ControlStyle:=ControlStyle+[csOpaque];
    FillChar(pfd,sizeof(pfd),0);
    with pfd do
    begin
      nSize:=sizeof(TPixelFormatDescriptor);
      nVersion:=1;
      dwFlags:=PFD_DRAW_TO_WINDOW or
          PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
      iPixelType:=PFD_TYPE_RGBA;
      cColorBits:=24;
      cDepthBits:=32;
      iLayerType:=PFD_MAIN_PLANE;
    end;
    PixelFormat:=ChoosePixelFormat(Canvas.Handle,@pfd);
    SetPixelFormat(Canvas.Handle,PixelFormat,@pfd);
    hrc:=wglCreateContext(Canvas.Handle);
    w:=ClIEntRect.Right;
    h:=ClIEntRect.Bottom;
    InitializeGL(w,h);
  end;

  procedure TfrmMain.FormDestroy(Sender: TObject);
  begin
    wglDeleteContext(hrc);
  end;

  procedure TfrmMain.FormPaint(Sender: TObject);
  begin
    wglMakeCurrent(Canvas.Handle,hrc);
    glClearColor(1,1,1,1);
    glColor3f(1,0,0);
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
    SetTextures;
    MyDraw;
    SetLighting;
    glFlush;
  end;

  procedure TfrmMain.MyDraw;
  var
    qObj:GLUQuadricObj;
  begin
    glPushMatrix;
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
    glColor3f(1,0,0);
    glRotated(0.5,0.0,1.0,0.0);
    glRotated(-latitude,1.0,0.0,0.0);
    glrotated(longitude,0.0,0.0,1.0);
    qObj:=gluNewQuadric;
    gluQuadricDrawStyle(qObj,GLU_LINE);
    gluSphere(qObj,0.5,20,20);
    SwapBuffers(Canvas.Handle);
    SetLighting;
    SetTextures;
  end;

  {procedure TfrmMain.FormResize(Sender: TObject);
  var
    nRange:GLfloat;
  begin
    nRange:=50.0;
    w:=clIEntWidth;
    h:=clIEntHeight;
    if h=0 then
      h:=1;
    glVIEwPort(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity;
    if w<=h then
      glOrtho(-nRange,nRange,-nRange*h/w,nRange*h/w,
        -nRange,nRange)
    else
      glOrtho(-nRange*h/w,nRange*h/w,-nRange,nRange,
        -nRange,nRange);
    glMatrixMode(GL_MODELVIEW);
    glLoadidentity;
    repaint;
  end;
  }
  procedure TfrmMain.FormKeyDown(Sender: TObject; var Key: Word;
    Shift: TShiftState);
  begin
    if Key=VK_ESCAPE then
      Close;
    if Key=VK_UP then
      glRotatef(-5,1.0,0.0,0.0);
    if Key=VK_DOWN then
      glRotatef(5,1.0,0.0,0.0);
    if Key=VK_LEFT then
      glRotatef(-5,0.0,1.0,0.0);
    if Key=VK_RIGHT then
      glRotatef(5.0,0.0,1.0,0.0);
    repaint;
  end;

  procedure TfrmMain.FormResize(Sender: TObject);
  begin
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity;
    glFrustum(-1.0,1.0,-1.0,1.0,3.0,7.0);
    glViewPort(0,0,clientWidth,clIEntHeight);
    repaint;
    invalidate;
  end;

  procedure TfrmMain.InitializeGL(var width: GLsizei; height: GLsizei);
  var
    maxObjectSize,ASPect:GLfloat;
    near_plane:GLdouble;
  begin
    glClearindex(0);
    glClearDepth(1.0);
    glEnable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    ASPect:=1.0;
    gluPerspective(45.0,ASPect,3.0,7.0);
    glmatrixMode(GL_MODELVIEW);
    near_plane:=0.3;
    maxObjectSize:=0.3;
    radius:=near_plane+maxObjectSize/2.0;
    latitude:=0.3;
    longitude:=0.6;
  end;

  procedure TfrmMain.Timer1Timer(Sender: TObject);
  begin
    timer1.Enabled:=false;
    MyDraw;
    YIEld;
    Timer1.Enabled:=true;
  end;

  procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
  begin
    timer1.Enabled:=false;
    if hrc<>null then
      wglDeleteContext(hrc);
  end;

  procedure TfrmMain.SetLighting;
  var
    MaterialAmbIEnt:array[1..4] of GLfloat;
    MaterialDiffuse:Array[1..4] of GLfloat;
    MaterialSpecular:Array[1..4] of GLfloat;
    AmbIEntLightPosition:Array[1..4] of GLfloat;
    LightAmbIEnt:Array[1..4] of GLfloat;
    MaterialShininess:GLfloat;
  begin
    MaterialAmbIEnt[1]:=0.5;
    MaterialAmbIEnt[2]:=0.8;
    MaterialAmbIEnt[1]:=0.2;
    MaterialAmbIEnt[1]:=1.0;

    MaterialDiffuse[1]:=0.4;
    MaterialDiffuse[2]:=0.8;
    MaterialDiffuse[3]:=0.1;
    MaterialDiffuse[4]:=1.0;

    MaterialSpecular[1]:=1.0;
    MaterialSpecular[2]:=0.5;
    MaterialSpecular[3]:=0.1;
    MaterialSpecular[4]:=1.0;

    materialShininess:=50.0;

    AmbIEntLightPosition[1]:=0.5;
    AmbIEntLightPosition[2]:=1.0;
    AmbIEntLightPosition[3]:=1.0;
    AmbIEntLightPosition[4]:=0.0;

    LightAmbIEnt[1]:=0.5;
    LightAmbIEnt[2]:=0.2;
    LightAmbIEnt[3]:=0.8;
    LightAmbIEnt[4]:=1.0;

    glMaterialfv(GL_FRONT,GL_AMBIENT,@MaterialAmbIEnt);
    glMaterialfv(GL_FRONT,GL_DIFFUSE,@MaterialDiffuse);
    glMaterialfv(GL_FRONT,GL_SPECULAR,@MaterialSpecular);
    glMaterialfv(GL_FRONT,GL_SHININESS,@MaterialShininess);

    glLightfv(GL_LIGHT0,GL_POSITION,@AmbIEntLightPosition);
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,@LightAmbIEnt);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    GLShadeModel(GL_SMOOTH);
  end;

  procedure TfrmMain.SetTextures;
  var
    bits:Array[1..64,1..64,1..64] of GLubyte;
    bmp:TBitmap;
    i,j:Integer;
  begin
    bmp:=TBitmap.Create;
    bmp.LoadFromFile('d:dsoft11192logon.bmp');
    for i:=1 to 64 do
      for j:=1 to 64 do
      begin
        bits[i,j,1]:=GLbyte(GetRValue(bmp.Canvas.Pixels[i,j]));
        bits[i,j,2]:=GLbyte(GetRValue(bmp.Canvas.Pixels[i,j]));
        bits[i,j,3]:=GLbyte(GetRValue(bmp.Canvas.Pixels[i,j]));
        bits[i,j,4]:=255;
      end;
    glPixelStorei(GL_UNPACK_ALIGNMENT,4);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    {0代表為單色著色水平,GL_RGBA表示混合值
     64X64代表紋理的高和寬,0表示無邊界,
     GL_RGBA代表紋理類型,GL_UNSIGNED_TYPE代表數據類型,@代對象地址}
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,64,64,0,GL_RGBA,
      GL_UNSIGNED_BYTE,@bits);
    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
  end;

  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved