Delphi下OpenGL2d绘图之初始化流程详解
一、前言:
Delphi默认支持OpenGl,可以使用usesOpenGL单元进行引用,之后就可以使用OpenGL的函数。OpenGl是跨平台的,而且Windows很早就支持并集成在系统中,存在于system32中的opengl32.dll,不需要再额外进行安装。虽然windows本身有d3d,但是其能力有限,相关学习资料页相对较少。
通常OpenGL仅仅支持以下几种基本几何图形:点,线和多边形。没有表面或者更高级的图形(比如球状图形)能被作为基本图形元素绘制。但是它们能够用多边形来完美的模仿出来。随意看看现代3D游戏,你会发现它们几乎完全是由三角形建立的。因此,我们不会被此限制所约束。
二、初始化
在使用OpenGL之前,需要先进行一些相关的参数设置。一般流程为:
“设置匹配的像素格式”(ChoosePixelFormat、SetPixelFormat)
“创建一个新的OpenGL渲染描述表”(wglCreateContext)
“设置OpenGL相关参数”、“绘图”(glBegin、glEnd)
“删除OpenGL渲染描述表”(wglDeleteContext)
procedureTForm1.FormCreate(Sender:TObject); var pfd:TPIXELFORMATDESCRIPTOR; pixelFormat:Integer; begin Withpfddo begin nSize:=sizeof(TPIXELFORMATDESCRIPTOR);//size nVersion:=1;//version dwFlags:=PFD_SUPPORT_OPENGLorPFD_DRAW_TO_WINDOWorPFD_DOUBLEBUFFER;//supportdouble-buffering iPixelType:=PFD_TYPE_RGBA;//colortype cColorBits:=24;//preferredcolordepth cRedBits:=0; cRedShift:=0;//colorbits(ignored) cGreenBits:=0; cGreenShift:=0; cBlueBits:=0; cBlueShift:=0; cAlphaBits:=0; cAlphaShift:=0;//noalphabuffer cAccumBits:=0; cAccumRedBits:=0;//noaccumulationbuffer, cAccumGreenBits:=0;//accumbits(ignored) cAccumBlueBits:=0; cAccumAlphaBits:=0; cDepthBits:=16;//depthbuffer cStencilBits:=0;//nostencilbuffer cAuxBuffers:=0;//noauxiliarybuffers iLayerType:=PFD_MAIN_PLANE;//mainlayer bReserved:=0; dwLayerMask:=0; dwVisibleMask:=0; dwDamageMask:=0; end; FDC:=GetDC(Handle); pixelFormat:=ChoosePixelFormat(FDC,@pfd); ifpixelFormat=0then Exit; ifnotSetPixelFormat(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()。如以下绘制函数procedureDraw;
procedureTForm1.Draw; begin //清空缓冲区 glClear(GL_COLOR_BUFFER_BITorGL_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;
四、最后记得释放。全部代码如下:
unitUnit1;
interface
uses
Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,
Dialogs,OpenGL;
type
TForm1=class(TForm)
procedureFormCreate(Sender:TObject);
procedureFormDestroy(Sender:TObject);
procedureFormPaint(Sender:TObject);
procedureFormResize(Sender:TObject);
private
{Privatedeclarations}
FDC:HDC;
FHRC:HGLRC;
procedureDraw;
public
{Publicdeclarations}
end;
var
Form1:TForm1;
implementation
{$R*.dfm}
procedureTForm1.Draw;
begin
//清空缓冲区
glClear(GL_COLOR_BUFFER_BITorGL_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;
procedureTForm1.FormCreate(Sender:TObject);
var
pfd:TPIXELFORMATDESCRIPTOR;
pixelFormat:Integer;
begin
Withpfddo
begin
nSize:=sizeof(TPIXELFORMATDESCRIPTOR);//size
nVersion:=1;//version
dwFlags:=PFD_SUPPORT_OPENGLorPFD_DRAW_TO_WINDOWorPFD_DOUBLEBUFFER;//supportdouble-buffering
iPixelType:=PFD_TYPE_RGBA;//colortype
cColorBits:=24;//preferredcolordepth
cRedBits:=0;
cRedShift:=0;//colorbits(ignored)
cGreenBits:=0;
cGreenShift:=0;
cBlueBits:=0;
cBlueShift:=0;
cAlphaBits:=0;
cAlphaShift:=0;//noalphabuffer
cAccumBits:=0;
cAccumRedBits:=0;//noaccumulationbuffer,
cAccumGreenBits:=0;//accumbits(ignored)
cAccumBlueBits:=0;
cAccumAlphaBits:=0;
cDepthBits:=16;//depthbuffer
cStencilBits:=0;//nostencilbuffer
cAuxBuffers:=0;//noauxiliarybuffers
iLayerType:=PFD_MAIN_PLANE;//mainlayer
bReserved:=0;
dwLayerMask:=0;
dwVisibleMask:=0;
dwDamageMask:=0;
end;
FDC:=GetDC(Handle);
pixelFormat:=ChoosePixelFormat(FDC,@pfd);
ifpixelFormat=0then
Exit;
ifnotSetPixelFormat(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;
procedureTForm1.FormDestroy(Sender:TObject);
begin
wglMakeCurrent(FDC,FHRC);
wglDeleteContext(FHRC);
ReleaseDC(Handle,FDC);
end;
procedureTForm1.FormPaint(Sender:TObject);
begin
Draw;
end;
procedureTForm1.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.
完整代码点此下载