OpenGL完全教程 第一章 初始化OpenGL


第一章 初始化OpenGL

    無論是什么東西,要使用它,就必須對它進行初始化。如果你之前使用過GDI,你應該也多多少少了解到GDI在繪制圖形之前要為之創建渲染環境。OpenGL也一樣。本章給出的代碼,大家可以不必理解其中的具體意義,反正以后每次初始化是使用這個代碼即可。

    首先,在一個新的應用程序中,我們需要添加對OpenGL庫的引用。Delphi已經為我們寫好了OpenGL的頭文件,因此我們只須直接在單元的uses中添加OpenGL即可:

   ...

   uses Windows, Graphics, OpenGL, ...

   ...

    

    在創建窗口時,應添加如下代碼:

 

procedure Form1.Create(Sender:TObject);
    var DC: HDC;
        HRC :HGLRC ;
    pfd:TPIXELFORMATDESCRIPTOR; pixelFormat:integer;
    begin
      DC := GetDC(Handle);

With pfd do
begin


nSize:=sizeof(TPIXELFORMATDESCRIPTOR); // size
nVersion:=1; // version
dwFlags:=PFD_SUPPORT_OPENGL or PFD_DRAW_to_WINDOW or
         PFD_DOUBLEBUFFER; // support double-buffering
iPixelType:=PFD_TYPE_RGBA; // color type
cColorBits:=24; // preferred color depth
cRedBits:=0;
cRedShift:=0; // color bits (ignored)
cGreenBits:=0;
cGreenShift:=0;
cBlueBits:=0;
cBlueShift:=0;
cAlphaBits:=0;
cAlphaShift:=0; // no alpha buffer
cAccumBits:=0;
cAccumRedBits:=0; // no accumulation buffer,
cAccumGreenBits:=0; // accum bits (ignored)
cAccumBlueBits:=0;
cAccumAlphaBits:=0;
cDepthBits:=16; // depth buffer
cStencilBits:=0; // no stencil buffer
cAuxBuffers:=0; // no auxiliary buffers
iLayerType:=PFD_MAIN_PLANE; // main layer
bReserved:=0;
dwLayerMask:=0;
dwVisibleMask:=0;
dwDamageMask:=0;


end;


pixelFormat := ChoosePixelFormat(DC, @pfd);
if (pixelFormat = 0) then
exit;
if (SetPixelFormat(DC, pixelFormat, @pfd) <> TRUE) then
exit;
hRc := wglCreateContext(DC);
wglMakeCurrent(DC,HRC);

end;

 

上面的代碼是Windows下初始化OpenGL的固定代碼。因為本教程不使用任何第三方庫,所以在初始化上顯得麻煩些。但這些代碼是固定的,每次初始化OpenGL時,照抄代碼即可。下面對上述代碼作簡單的說明。

    首先,我們用GetDC(Handle)獲取當前窗口的設備目錄。然后初始化一個TPIXELFORMATDESCRIPTOR類型的字段,用於描述將要使用的像素格式。在此字段中,dwFlags表示渲染方式,一般情況下使用PFD_SUPPORT_OPENGL or PFD_DRAW_to_WINDOW or PFD_DOUBLEBUFFER。其中,PFD_DOUBLEBUFFER表示支持雙緩沖。這將會在今后的章節中講到。cColorBits表示使用的色深,一般情況下使用24位色深。在今后的教程中,會根據不同的需求而改變TPIXELFORMATDESCRIPTOR字段中的值,而其他代碼一般都是不變的。

    初始化完OpenGL之后,就可以調用OpenGL的繪制函數來繪制圖形了。一般情況下,我們把所有繪制圖形的函數調用寫在一個名為RenderScene的過程中:

   

第一章 初始化OpenGL

    無論是什么東西,要使用它,就必須對它進行初始化。如果你之前使用過GDI,你應該也多多少少了解到GDI在繪制圖形之前要為之創建渲染環境。OpenGL也一樣。本章給出的代碼,大家可以不必理解其中的具體意義,反正以后每次初始化是使用這個代碼即可。

    首先,在一個新的應用程序中,我們需要添加對OpenGL庫的引用。Delphi已經為我們寫好了OpenGL的頭文件,因此我們只須直接在單元的uses中添加OpenGL即可:

   ...

   uses Windows, Graphics, OpenGL, ...

   ...

    

    在創建窗口時,應添加如下代碼:

    procedure Form1.Create(Sender:TObject);
    var DC: HDC;
        HRC :HGLRC ;
    pfd:TPIXELFORMATDESCRIPTOR; pixelFormat:integer;
    begin
      DC := GetDC(Handle);

With pfd do
begin


nSize:=sizeof(TPIXELFORMATDESCRIPTOR); // size
nVersion:=1; // version
dwFlags:=PFD_SUPPORT_OPENGL or PFD_DRAW_to_WINDOW or
         PFD_DOUBLEBUFFER; // support double-buffering
iPixelType:=PFD_TYPE_RGBA; // color type
cColorBits:=24; // preferred color depth
cRedBits:=0;
cRedShift:=0; // color bits (ignored)
cGreenBits:=0;
cGreenShift:=0;
cBlueBits:=0;
cBlueShift:=0;
cAlphaBits:=0;
cAlphaShift:=0; // no alpha buffer
cAccumBits:=0;
cAccumRedBits:=0; // no accumulation buffer,
cAccumGreenBits:=0; // accum bits (ignored)
cAccumBlueBits:=0;
cAccumAlphaBits:=0;
cDepthBits:=16; // depth buffer
cStencilBits:=0; // no stencil buffer
cAuxBuffers:=0; // no auxiliary buffers
iLayerType:=PFD_MAIN_PLANE; // main layer
bReserved:=0;
dwLayerMask:=0;
dwVisibleMask:=0
;
dwDamageMask:=0;


end;


pixelFormat := ChoosePixelFormat(DC, @pfd);
if (pixelFormat = 0) then
exit;
if (SetPixelFormat(DC, pixelFormat, @pfd) <> TRUE) then
exit;
hRc
:= wglCreateContext(DC);
wglMakeCurrent(DC,HRC);

    end;

    上面的代碼是Windows下初始化OpenGL的固定代碼。因為本教程不使用任何第三方庫,所以在初始化上顯得麻煩些。但這些代碼是固定的,每次初始化OpenGL時,照抄代碼即可。下面對上述代碼作簡單的說明。

    首先,我們用GetDC(Handle)獲取當前窗口的設備目錄。然后初始化一個TPIXELFORMATDESCRIPTOR類型的字段,用於描述將要使用的像素格式。在此字段中,dwFlags表示渲染方式,一般情況下使用PFD_SUPPORT_OPENGL or PFD_DRAW_to_WINDOW or PFD_DOUBLEBUFFER。其中,PFD_DOUBLEBUFFER表示支持雙緩沖。這將會在今后的章節中講到。cColorBits表示使用的色深,一般情況下使用24位色深。在今后的教程中,會根據不同的需求而改變TPIXELFORMATDESCRIPTOR字段中的值,而其他代碼一般都是不變的。

    初始化完OpenGL之后,就可以調用OpenGL的繪制函數來繪制圖形了。一般情況下,我們把所有繪制圖形的函數調用寫在一個名為RenderScene的過程中:

 

 

  

procedure TForm1.RenderScene;

   begin

     ...

   end;

   然后,我們使用一個Timer,其Interval屬性設為1,然后在OnTimer事件中調用RenderScene即可。

   在窗體關閉時,我們還必須關閉渲染環境以釋放內存。方法如下:

   procedure TForm1.Form1Close(Sender:TObject;....);

   begin

      wglMakeCurrent(DC,HRC);
      wglDeleteContext(hRc);
      ReleaseDC(Handle,DC);

   end;

   其實,關於OpenGL初始化,我已經寫好了一個類。用這個類初始化,可以讓窗體的代碼簡潔一些。首先,下載glInit.pas,並引用它。然后向單元中加入如下代碼初始化OpenGL。  

  ...

  uses ...,GLInit;

  var

    glInitor:TOpenGLInit;

  implementation

    procedure TForm1.Create(....);

    begin

      glInitor:=TOpenGLInit.Create(Handle,24,stdDoubleBuffer);

    end;

    procedure TForm1.Close(...);

    begin

      glInitor.Free;

    end;

   在本章的示例程序中,我們將初始化OpenGL,並用OpenGL繪制一個三角形。在此程序中,我們還對OpenGL作了其他一些設置,現在你無須理解其中的意義。此程序中,InitOpenGL過程用於初始化OpenGL,FreeOpenGL過程用於銷毀OpenGL,SetView過程用於設置視圖投影(將在今后的章節中講到),在RenderScene過程中,我們使用了一個OpenGL的函數繪制了一個三角形。

   以下就是本章示例程序的代碼。

unit untMainForm;

 

interface

 

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, ExtCtrls, OpenGL;

 

type

  TfrmMain = class(TForm)

    tmrRender: TTimer;

    procedure FormCreate(Sender: TObject);

    procedure FormClose(Sender: TObject; var Action: TCloseAction);

    procedure tmrRenderTimer(Sender: TObject);

  private

    procedure InitOpenGL;

    procedure FreeOpenGL;

    procedure SetView;

    procedure RenderScene;

  public

 

  end;

 

var

  frmMain: TfrmMain;

 

  DC: HDC;

  HRC :HGLRC ;

implementation

 

{$R *.dfm}

 

procedure TfrmMain.FreeOpenGL;

begin

  wglMakeCurrent(DC,HRC);

  wglDeleteContext(hRc);

  ReleaseDC(Handle,DC);

end;

 

procedure TfrmMain.InitOpenGL;

var pfd:TPIXELFORMATDESCRIPTOR; pixelFormat:integer;

begin

  DC := GetDC(Handle);

  with pfd do

  begin

    nSize:=sizeof(TPIXELFORMATDESCRIPTOR); // 此結構尺寸

    nVersion:=1;

    dwFlags:=PFD_SUPPORT_OPENGL or PFD_DRAW_to_WINDOW or

             PFD_DOUBLEBUFFER; // 使用雙緩沖區

    iPixelType:=PFD_TYPE_RGBA; //使用RGBA顏色空間

    cColorBits:=24;     //24位真彩色

    cRedBits:=0;

    cRedShift:=0;

    cGreenBits:=0;

    cGreenShift:=0;

    cBlueBits:=0;

    cBlueShift:=0;

    cAlphaBits:=0;

    cAlphaShift:=0;

    cAccumBits:=0;

    cAccumRedBits:=0;

    cAccumGreenBits:=0;

    cAccumBlueBits:=0;

    cAccumAlphaBits:=0;

    cDepthBits:=16;

    cStencilBits:=0;

    cAuxBuffers:=0;

    iLayerType:=PFD_MAIN_PLANE;

    bReserved:=0;

    dwLayerMask:=0;

    dwVisibleMask:=0;

    dwDamageMask:=0;

  end;                   

  pixelFormat := ChoosePixelFormat(DC, @pfd);

  if (pixelFormat = 0) then

    exit;

  if (SetPixelFormat(DC, pixelFormat, @pfd) <> TRUE) then

    exit;

  hRc := wglCreateContext(DC);

  wglMakeCurrent(DC,HRC);

end;

procedure TfrmMain.FormCreate(Sender: TObject);

begin

  InitOpenGL;

  SetView;

end;

 

procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);

begin

  FreeOpenGL;

end;

 

procedure TfrmMain.tmrRenderTimer(Sender: TObject);

begin

  RenderScene;

end;

 

procedure TfrmMain.RenderScene;

begin

  glLoadIdentity;

  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);//清空緩沖區

  glColor3ub(0,255,0); //將顏色設置為綠色。

  glBegin(GL_TRIANGLES);//告訴OpenGL將要繪制三角形

    glVertex2f(200,300);  //傳輸三角形的三個頂點坐標給OpenGL

    glVertex2f(400,300);

    glVertex2f(300,150);

  glEnd; //結束圖元的繪制。

  SwapBuffers(DC);//交換雙緩沖區內容,這將把剛繪制的圖形翻印到屏幕上。

end;

 

procedure TfrmMain.SetView;

begin

  glClearColor(0,0,0,0);//設置背景顏色為黑色

  glViewPort(0,0,ClientWidth,ClientHeight);//指定OpenGL在此區域內繪圖。

  glMatrixMode(GL_PROJECTION);//設置視圖投影變換矩陣

    glLoadIdentity;//加載單位矩陣。

    glOrtho(0,ClientWidth,ClientHeight,0,1,-1);//創建平行投影空間。

                                           //在平行投影空間中,遠處的物體和近處的物體大小是一致的。

  glMatrixMode(GL_MODELVIEW);//將矩陣變換對象切換為模型視圖變換。

end; 

end. 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM