Delphi下OpenGL2d绘图之初始化流程详解

一、前言:

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.

完整代码点此下载

(0)

相关推荐

  • C# GDI在控件上绘图的方法

    本文以在chart控件上和窗体上画矩形为例子讲述了C# GDI在控件上绘图的方法.分享给大家供大家参考.具体方法如下: 具体的实现方法就不多解释了,备注很详细,代码也很简单. 主要功能代码如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Te

  • 纯JavaScript代码实现移动设备绘图解锁

    移动手机设备上有一个屏幕解锁的应用相信大家都不陌生,在移动设备上,用户可以通过设置锁定图案作为密码对设备用户界面进行锁定,锁定界面如下图所示. 效果图如下所示 JavaScript Code <script> $("#gesturepwd").GesturePasswd({ backgroundColor:"#2980B9", //背景色 color:"#FFFFFF", //主要的控件颜色 roundRadii:50, //大圆点的

  • python海龟绘图实例教程

    本文以实例形式介绍了python turtle模块即海龟绘图的使用方法,对于需要进行图形编程的朋友相信会有一定的借鉴价值. python turtle模块简介:  python2.6版本中引入的一个简单的绘图工具,叫做海龟绘图(Turtle Graphics) 1.使用海龟绘图首先我们需要导入turtle,如下所示: from turtle import * #将turtle中的所有方法导入 2.海龟绘图属性: (1)位置  (2)方向  (3)画笔(画笔的属性,颜色.画线的宽度) 3.操纵海龟

  • Delphi下OpenGL2d绘图之初始化流程详解

    一.前言: Delphi默认支持OpenGl,可以使用uses OpenGL单元进行引用,之后就可以使用OpenGL的函数.OpenGl是跨平台的,而且Windows很早就支持并集成在系统中,存在于system32中的opengl32.dll,不需要再额外进行安装.虽然windows本身有d3d,但是其能力有限,相关学习资料页相对较少. 通常OpenGL仅仅支持以下几种基本几何图形:点,线和多边形.没有表面或者更高级的图形(比如球状图形)能被作为基本图形元素绘制.但是它们能够用多边形来完美的模仿

  • Delphi下OpenGL2d绘图之画点的方法

    一.前言 Delphi图形的绘制可以在glBegin().glEnd()之间完成,绘制的框架代码可以使用Delphi下OpenGL2d绘图的初始化代码,具体内容可参考本站http://www.jb51.net/article/52141.htm.修改的部份为 Draw 函数的内容. 二.画点 使用glPointSize 函数指定栅格化点的直径.默认为1.0,只在GL_POINTS下起作用,关于消锯齿等功能以后再研究.使用glBegin(GL_POINTS)告诉OpenGL画点,参数GL_POIN

  • Delphi下OpenGL2d绘图之画四边形的方法

    一.前言: Delphi实现画四边形的方法基本上与前几遍文字代码是相同的.其区别知识在于glBegin()的参数"GL_QUADS".绘制的框架代码可以使用Delphi下OpenGL2d绘图初始化中的代码,地址为http://www.jb51.net/article/52141.htm.修改的部份为 Draw 函数的内容. 二.画四边形方法: 使用GL_QUADS:绘制由四个顶点组成的一组单独的四边形.顶点4n-3.4n-2.4n-1和4n定义了第n个四边形.总共绘制N/4个四边形.这

  • Delphi下OpenGL2d绘图之画线的方法

    一.前言: Delphi画线方法与画点基本上是相同的.区别在于glBegin()的参数.绘制的框架代码可以参考Delphi下OpenGL2d绘图初始化中的代码,地址为http://www.jb51.net/article/52141.htm.修改的部份为 Draw 函数的内容. 二.画线步骤: GL_LINES:把每一个顶点作为一个独立的线段,顶点2n-1和2n之间共定义了n条线段,总共绘制N/2条线段 GL_LINE_STRIP:绘制从第一个顶点到最后一个顶点依次相连的一组线段,第n和n+1个

  • Spring中Bean的加载与SpringBoot的初始化流程详解

    目录 前言 第一章 Spring中Bean的一些简单概念 1.1 SpingIOC简介 1.2 BeanFactory 1.2.1 BeanDefinition 1.2.2 BeanDefinitionRegistry 1.2.3 BeanFactory结构图 1.3 ApplicationContext 第二章 SpringBoot的初始化流程 2.1 准备阶段 2.2 运行阶段 2.2.1 监听器分析 2.2.2 refreshContext 2.3 总结 前言 一直对它们之间的关系感到好奇

  • 一个简单的Spring容器初始化流程详解

    前言 首先我们初始化一个最简单的容器,用这个容器研究初始化的流程. 下面就是一个再简单不过的IoC容器了,该容器包含了一个名为beanA的bean,我们初始化容器后,取出该Bean,并调用方法. public class BeanA { private String testStr = "Test"; public BeanA(){ System.out.println("Running A"); } public void sayHello(){ System.o

  • Windows下安装Redis的流程详解

    目录 一.简介 二.下载与安装Redis 1.下载 2.解压 3.几个重要的文件 三.环境变量配置 四.验证与连接redis 1.验证 3.连接Redis 4.设置一个key测试一下 一.简介 Redis作为常用开源的非关系型数据库,是开发中常用的数据库之一.Redis底层是使用ANSI C编写的,支持网络可基于内存和可持久化的日志型.Key-Value数据库,提供了多种语言API.(基于内存是Redis快的一个重要因素) 二.下载与安装Redis 1.下载 github上可以下载Windows

  • MVC+DAO设计模式下的设计流程详解

    DAO设计 : DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,DAO层的设计首先是设计DAO的接口,然后在Spring的配置文件中定义此接口的实现类,然后就可在模块中调用此接口来进行数据业务的处理,而不用关心此接口的具体实现类是哪个类,显得结构非常清晰,DAO层的数据源配置,以及有关数据库连接的参数都在Spring的配置文件中进行配置. 在该层主要完成对象-关系映射的建立,通过这个映射,再通过访问业务对象即可实现对数据库的访问,使得开发中不必再用SQL语句编写复杂的

  • C++ 中国象棋的实现流程详解

    中国象棋的中国棋文化,也是中华民族的文化瑰宝,它源远流长,趣味浓厚,基本规则简明易懂.中国象棋在中国的群众中基础远远超过围棋,是普及最广的棋类项目,中国象棋已流传到十几个国家和地区. 中国象棋使用方形格状棋盘,圆形棋子共有32个,红黑二色各有16个棋子,摆放和活动在交叉点上.双方交替行棋,先把对方的将(帅)"将死"的一方获胜. 我们今天就来看看我们自己能不能写出这样一个游戏呢? 今天就不话不多说了,先说一下,今天我们做的是一个简易版的单机中国象棋,希望大家理解,联网对弈的话需要用到的知

  • java存储以及java对象创建的流程(详解)

    java存储: 1)寄存器:这是最快的存储区,位于处理器的内部.但是寄存器的数量有限,所以寄存器根据需求进行分配.我们不能直接进行操作. 2)堆栈:位于通用RAM中,可以通过堆栈指针从处理器那里获取直接支持.堆栈指针往下移动,则分配新的内存.网上移动,则释放内存.但是 在创建程序的时候必须知道存储在堆栈中的所有项的具体生命周期,以便上下的移动指针.一般存储基本类型和java对象引用. 3)堆:位于通用RAM中,存放所有的java对象,不需要知道具体的生命周期. 4)常量存储:常量值通常直接存放在

随机推荐