OPENGL图形程序设计
OPENGL是一个三维图形和模型库,由于它在三维图形方面的杰出性能,目前许多高级语言都提供了与OPENGL的接口,如:VC、DELPHI、C++Builder等。使用OPENGL可以极大地减少用户开发图形、图像的难度,使用户制作高水准的商业广告、图形CAD、三维动画、图形仿真和影视采集。
一、OPENGL的功能
OPENGL原来是工作站上的一个图形软件库,由于它在商业、军事、医学、航天航空等领域的广泛应用,目前在低档电脑也可以开发出符合用户要求的图形。OPENGL不仅可以绘制基本图像,而且提供了大量处理图形图像的函数与过程。
1、图形变换
是图形显示与制作的基础,动画设计和动画显示都离不开图形的变换,图形变换在数学上是由矩形的乘法来实现的,变换一般包括平移、旋转和缩放。按图形的显示性质来分:视点变换、模型变换、投影变换、剪裁变换和视口变换等。
2、光照效果
不发光的物体的颜色是由物体反射外界光所形成的,这是光照。在三维图形中,如果光照使用不当,三维图形就会失去真实的立体感,OPENGL把光照分为:辐射光、环境光、散射光、反射光等。
3、纹理映射
通过纹理映射可以在三维表面添加显示现实世界中的纹理。如:一个矩形它不能表示真实世界中的物体,如果填上"本质"纹理,就逼真了。
4、图形特效
混合函数、反走样函数和雾函数,可以处理三维图形听之任之物体的透明和半透明、使用线段理加光滑以及提供雾化的效果。
5、图像特效
处理位图的基本函数:图像绘制、图像拷贝和存储、映射和转移、图像的缩放等。位图操作函数可以人绘图原的低层说明中文字符的形成过程。
二、创建OPENGL应用程序
1、一般原则
A 有uses中添加OPENGL支持单元:OpenGL;
B 在窗体的OnCreate事件过程中初始化OPENGL;
C 在窗口的OnPaing 事件过程中初始化OPENGL;
D 在窗口的OnResize事件过程中初始化OPENGL;
E 在窗口的OnDestroy 事件过程中初始化 OPENGL;
2、简单实例
A 创建一个工程FILE->New Application
B 在OnCreate事件中添加代码:
procedure TfrmMain.FormCreate(Sender: TObject);
var
pfd:TPixelFormatDescriptor; //设置描述表
PixelFormat:Integer;
begin
ControlStyle:=ControlStyle+[csOpaque];
FillChar(pfd,sizeof(pfd),0);
with pfd do
begin
nSize:=sizeof(TPixelFormatDescriptor);
nVersion:=1;
dwFlags:=PFD_DRAW_TO_WINDOW or
PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
iPixelType:=PFD_TYPE_RGBA;
cColorBits:=24;
cDepthBits:=32;
iLayerType:=PFD_MAIN_PLANE;
end;
PixelFormat:=ChoosePixelFormat(Canvas.Handle,@pfd);
SetPixelFormat(Canvas.Handle,PixelFormat,@pfd);
hrc:=wglCreateContext(Canvas.Handle);
w:=ClientWidth;
h:=ClientHeight;
end;
C 在OnDestroy事件中的代码
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
wglDeleteContext(hrc);
end;
D 在OnPaint事件中的代码
procedure TfrmMain.FormPaint(Sender: TObject);
begin
wglMakeCurrent(Canvas.Handle,hrc);
glClearColor(1,1,1,1);
glColor3f(1,0,0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
MyDraw;
glFlush;
SwapBuffers(Canvas.Handle);
end;
E 在OnResize事件中的代码
procedure TfrmMain.FormResize(Sender: TObject);
begin
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glFrustum(-1.0,1.0,-1.0,1.0,3.0,7.0);
glViewPort(0,0,ClientWidth,ClientHeight);
MyDraw;
end;
F 在MyDraw函数中的代码(用户在窗口类中声明)
procedure TfrmMain.MyDraw;
begin
glPushMatrix;
Sphere:=gluNewQuadric;
gluQuadricDrawStyle(Sphere,GLU_LINE);
gluSphere(Sphere,0.5,25,25);
glPopMatrix;
SwapBuffers(Canvas.handle);
gluDeleteQuadric(Sphere);
end;
附本程序原码:
unit MainFrm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OpenGL;
type
TfrmMain = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormResize(Sender: TObject);
private
{ Private declarations }
hrc:HGLRC;
w,h:glFloat;
Sphere:GLUquadricObj;
public
{ Public declarations }
procedure MyDraw;
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
procedure TfrmMain.FormCreate(Sender: TObject);
var
pfd:TPixelFormatDescriptor;
PixelFormat:Integer;
begin
ControlStyle:=ControlStyle+[csOpaque];
FillChar(pfd,sizeof(pfd),0);
with pfd do
begin
nSize:=sizeof(TPixelFormatDescriptor);
nVersion:=1;
dwFlags:=PFD_DRAW_TO_WINDOW or
PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
iPixelType:=PFD_TYPE_RGBA;
cColorBits:=24;
cDepthBits:=32;
iLayerType:=PFD_MAIN_PLANE;
end;
PixelFormat:=ChoosePixelFormat(Canvas.Handle,@pfd);
SetPixelFormat(Canvas.Handle,PixelFormat,@pfd);
hrc:=wglCreateContext(Canvas.Handle);
w:=ClientWidth;
h:=ClientHeight;
end;
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
wglDeleteContext(hrc);
end;
procedure TfrmMain.FormPaint(Sender: TObject);
begin
wglMakeCurrent(Canvas.Handle,hrc);
glClearColor(1,1,1,1);
glColor3f(1,0,0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
MyDraw;
glFlush;
SwapBuffers(Canvas.Handle);
end;
procedure TfrmMain.MyDraw;
begin
glPushMatrix;
Sphere:=gluNewQuadric;
gluQuadricDrawStyle(Sphere,GLU_LINE);
gluSphere(Sphere,0.5,25,25);
glPopMatrix;
SwapBuffers(Canvas.handle);
gluDeleteQuadric(Sphere);
end;
procedure TfrmMain.FormResize(Sender: TObject);
begin
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glFrustum(-1.0,1.0,-1.0,1.0,3.0,7.0);
glViewPort(0,0,ClientWidth,ClientHeight);
MyDraw;
end;
end.
三、OPENGL变量和函数的约定
1、OPENGL的库约定
它共三个库:基本库、实用库、辅助库。在DELPHI中,基本库由OpenGL单元实现,在Windows环境中,一般不使用辅助库。
2、OPENGL常数约定
OPENGL常数均使用大写字母,以"GL"开头,词汇之间使用下划线分隔,如:GL_LINES,表示使用基本库绘制直线。
3、OPENGL函数的命名约定
A 第一部分以gl或wgl开头,如glColor3f中的gl。
B 第二部分是用英文表示的函数功能,单词的首字母大写出。
C 第三部分是数字,表示函数的参数。
D 第四部分是小写字母,表示函数的类型。
b 9位整数
s 16位整数
i 32位整数
f 32位浮点数
d 64位浮点数
ub 9位无符号整数
例:glVertex2f(37,40); {两个32位的浮点数作参数}
glVertex3d(37,40,5); {三个64位的浮点数作参数}
p[1..3]:array of glFloat;
glVertes3fv(p); {3f表示三个浮点数,v表示调用一个数组作为顶点坐标输入}
四、OPENGL的初始化
1、PIXELFORMATDESCRIPTOR结构
主要描述像素点的性质,如像素的颜色模式和红、绿、蓝颜色构成方式等。
tagPIXELFORMATDESCRIPTOR = packed record
nSize: Word;
nVersion: Word;
dwFlags: DWORD;
iPixelType: Byte;
cColorBits: Byte;
cRedBits: Byte;
cRedShift: Byte;
cGreenBits: Byte;
cGreenShift: Byte;
cBlueBits: Byte;
cBlueShift: Byte;
cAlphaBits: Byte;
cAlphaShift: Byte;
cAccumBits: Byte;
cAccumRedBits: Byte;
cAccumGreenBits: Byte;
cAccumBlueBits: Byte;
cAccumAlphaBits: Byte;
cDepthBits: Byte;
cStencilBits: Byte;
cAuxBuffers: Byte;
iLayerType: Byte;
bReserved: Byte;
dwLayerMask: DWORD;
dwVisibleMask: DWORD;
dwDamageMask: DWORD;
end;
TPixelFormatDescriptor = tagPIXELFORMATDESCRIPTOR;
dwFlags代表点格式的属性:
PFD_DRAW_TO_WIND