zoukankan      html  css  js  c++  java
  • Delphi下OpenGL2d绘图(01)-初始化

    一、前言:

    Delphi默认支持OpenGl,可以uses OpenGL单元进行引用,便可以使用OpenGL的函数。OpenGl是跨平台的,而且Windows很早就支持并集成在系统中,存在于system32中的opengl32.dll,不需要额外安装。虽然windows本身有d3d,但能力有限,还没去学习怎么用。

    引用别人的话:OpenGL仅仅支持以下几种基本几何图形:点,线和多边形。没有表面或者更高级的图形(比如球状图形)能被作为基本图形元素绘制。但是它们能够用多边形完美的模仿出来。随意看看现代3D游戏,你会发现它们完全由三角形建立。因此,我们不会被此限制所约束。

    二、初始化

    在使用OpenGL之前,需要先进行一些相关的参数设置。一般流程为“设置匹配的像素格式”(ChoosePixelFormat、SetPixelFormat)、“创建一个新的OpenGL渲染描述表”(wglCreateContext)、“设置OpenGL相关参数”、“绘图”(glBegin、glEnd)、“删除OpenGL渲染描述表”(wglDeleteContext)等。

    procedure TForm1.FormCreate(Sender: TObject);
    var
     pfd:TPIXELFORMATDESCRIPTOR;
      pixelFormat: Integer;
    begin
      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;
      FDC := GetDC(Handle);
      pixelFormat := ChoosePixelFormat(FDC, @pfd);
      if pixelFormat = 0 then
        Exit;
      if not SetPixelFormat(FDC, pixelFormat, @pfd) then
        Exit;
      FHRC := wglCreateContext(FDC);
      wglMakeCurrent(FDC, FHRC);
    
      // 设置背景色为 黑色 参数为 RGBA
      glClearColor(0, 0, 0, 0);
      // 设置视图投影变换矩阵 正投影
      glMatrixMode(GL_PROJECTION);
      // 重置当前指定的矩阵为单位矩阵
      glLoadIdentity;
      // 指定OpenGL在此区域内绘图
      glViewPort(0, 0, ClientWidth, ClientHeight);
      // 设置世界坐标系的范围
      gluOrtho2D(0, ClientWidth, ClientHeight, 0);
      // 将矩阵变换对象切换为模型视图变换
      glMatrixMode(GL_MODELVIEW);
      // 重置当前指定的矩阵为单位矩阵
      glLoadIdentity;
    end;

    三、绘图

    OpenGL的基本图元为点、线、多边形等,每次绘图都需要使用glBegin()与glEnd()。如以下绘制函数procedure Draw;

    procedure TForm1.Draw;
    begin
      // 清空缓冲区
      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(FDC); //交换双缓冲区内容,这将把刚绘制的图形翻印到屏幕上。
    end;

    四、最后记得释放。全部代码如下:

    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, OpenGL;
    
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure FormPaint(Sender: TObject);
        procedure FormResize(Sender: TObject);
      private
        { Private declarations }
        FDC: HDC;
        FHRC: HGLRC;
        procedure Draw;
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm1.Draw;
    begin
      // 清空缓冲区
      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(FDC); //交换双缓冲区内容,这将把刚绘制的图形翻印到屏幕上。
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    var
     pfd:TPIXELFORMATDESCRIPTOR;
      pixelFormat: Integer;
    begin
      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;
      FDC := GetDC(Handle);
      pixelFormat := ChoosePixelFormat(FDC, @pfd);
      if pixelFormat = 0 then
        Exit;
      if not SetPixelFormat(FDC, pixelFormat, @pfd) then
        Exit;
      FHRC := wglCreateContext(FDC);
      wglMakeCurrent(FDC, FHRC);
    
      // 设置背景色为 黑色 参数为 RGBA
      glClearColor(0, 0, 0, 0);
      // 设置视图投影变换矩阵 正投影
      glMatrixMode(GL_PROJECTION);
      // 重置当前指定的矩阵为单位矩阵
      glLoadIdentity;
      // 指定OpenGL在此区域内绘图
      glViewPort(0, 0, ClientWidth, ClientHeight);
      // 设置世界坐标系的范围
      gluOrtho2D(0, ClientWidth, ClientHeight, 0);
      // 将矩阵变换对象切换为模型视图变换
      glMatrixMode(GL_MODELVIEW);
      // 重置当前指定的矩阵为单位矩阵
      glLoadIdentity;
    end;
    
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      wglMakeCurrent(FDC, FHRC);
      wglDeleteContext(FHRC);
      ReleaseDC(Handle, FDC);
    end;
    
    procedure TForm1.FormPaint(Sender: TObject);
    begin
      Draw;
    end;
    
    procedure TForm1.FormResize(Sender: TObject);
    begin
      // 窗口改变大小时重新指定绘图区域
      glClearColor(0, 0, 0, 0);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity;
      glViewPort(0, 0, ClientWidth, ClientHeight);
      gluOrtho2D(0, ClientWidth, ClientHeight, 0);
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity;
    end;
    
    end.

    五、运行效果图如下:

    源码下载:http://files.cnblogs.com/lin557/OpenGL_01.zip

    2014-06-26 by lin

  • 相关阅读:
    微软一站式示例代码库(中文版)2010年12月10日更新
    微软一站式示例代码库(中文版)2011年1月12日更新
    微软一站式示例代码库 MSDN 官方论坛今天正式上线
    微软一站式示例代码浏览器 第二版 CTP发布
    两边固定中间子适应的流式布局
    不使用第三个变量交换两个数字
    身份证号码15位转18位 C#实现
    利用AspNetPager分页
    C#面向对象高级语法(一)
    String.Empty、string=”” 和null的区别
  • 原文地址:https://www.cnblogs.com/lin557/p/3810545.html
Copyright © 2011-2022 走看看