zoukankan      html  css  js  c++  java
  • 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. 

      

  • 相关阅读:
    button标签和input button
    获取select标签的值
    window.loaction和window.location.herf
    数组重复计数,对象方法
    js对象详解
    面试经典题型整理
    一些js小知识点整理
    事件委托能够优化js性能
    网页加载的一般顺序
    http状态码
  • 原文地址:https://www.cnblogs.com/China3S/p/3535967.html
Copyright © 2011-2022 走看看