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.
完整代码点此下载