天山玉米 發表於 2014-7-14 11:57:31

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

<p><strong>一、前言:</strong></p>
<p>Delphi默认支持OpenGl,可以使用uses OpenGL单元进行引用,之后就可以使用OpenGL的函数。OpenGl是跨平台的,而且Windows很早就支持并集成在系统中,存在于system32中的opengl32.dll,不需要再额外进行安装。虽然windows本身有d3d,但是其能力有限,相关学习资料页相对较少。</p>
<p><strong>通常OpenGL仅仅支持以下几种基本几何图形:点,线和多边形</strong>。没有表面或者更高级的图形(比如球状图形)能被作为基本图形元素绘制。但是它们能够用多边形来完美的模仿出来。随意看看现代3D游戏,你会发现它们几乎完全是由三角形建立的。因此,我们不会被此限制所约束。</p>
<p><strong>二、初始化</strong></p>
<p>在使用OpenGL之前,需要先进行一些相关的参数设置。一般流程为:</p>
<p>“设置匹配的像素格式”(ChoosePixelFormat、SetPixelFormat)<br />
“创建一个新的OpenGL渲染描述表”(wglCreateContext)<br />
“设置OpenGL相关参数”、“绘图”(glBegin、glEnd)<br />
“删除OpenGL渲染描述表”(wglDeleteContext)</p>
<div class="jb51code">
<pre class="brush:delphi;">
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;

</pre>
</div>
<p><strong>三、绘图</strong></p>
<p>OpenGL的基本图元为点、线、多边形等,每次绘图都需要使用glBegin()与glEnd()。如以下绘制函数procedure Draw;</p>
<div class="jb51code">
<pre class="brush:delphi;">
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;

</pre>
</div>
<p><strong>四、最后记得释放</strong>。全部代码如下:</p>
<div class="jb51code">
<pre class="brush:delphi;">
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.</pre>
</div>
<p>完整代码点此下载</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>python海龟绘图实例教程</li><li>C# GDI在控件上绘图的方法</li><li>纯JavaScript代码实现移动设备绘图解锁</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: Delphi下OpenGL2d绘图之初始化流程详解