`
gidlsl
  • 浏览: 14624 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

delphi中opengl程序设计

阅读更多

delphi中opengl程序设计
2011年06月07日
  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_WINDOW 图形绘在屏幕或设备表面
  PFD_DRAW_TO_BITMAP 在内存中绘制位图
  PFD_SUPPORT_GDI 支持GDI绘图
  PFD_SUPPORT_OPENGL 支持OPENGL函数
  PFD_DOUBLEBUFFER 使用双缓存
  PFD_STEREO 立体缓存
  PFD_NEED_PALLETTE 使用RGBA调色板
  PFD_GENERIC_FORMAT 选择GDI支持的格式绘图
  PFD_NEED_SYSTEM_PALETTE 使用OPENGL支持的硬件调色板
  iPixelType设置像素颜色模式:PFD_TYPE_RGBA或PFD_TYPE_INDEX.。
  cColorBits设置颜色的位,如是9表示有256种颜色表示点的颜色。
  cRedBits、cGreenBits、cBlueBits 使用RGBA时,三原色所使用的位数。
  cRedShitfs、cGreenShifts、cBlueShifts 使用RGBA时,三原色可以调节的位数。
  cAlphaBits、cAlphaShifts 使用RGBA时,Alpha使用的位数与可调节的位数。
  cAccumBits设置累积缓存区的位面总数。
  cAccumRedBits、cAccumGreenBits、cAccumBlueBits设置累积缓存区的三原色位面总数。
  cAccumAlphaBits设置累积缓存区的Alpha位面总数。
  cDepthBits设置浓度缓存的深度。
  cStencilBits设置Stencil缓存的深度。
  cAuxBuffers指辅助缓存的大小。
  iLayerType指定层的类型。
  bReserved不使用,必须是零。
  dwLayerMask指定覆盖层的屏蔽。
  dwDamageMask设置在相同的框架缓存下是否共用同一种像素模式。
  2、OPENGL的初始化步骤
  A 使用Canvas.Handle获得窗口句柄。
  B 创建一个TPixelFormatDescriptor变量定义像素格式。
  C 使用ChoosePixelFormat函数选择像素格式。
  D 使用SetPixelFormat函数使用像素格式生效。
  E 使用wglCreateContext函数建立翻译描述表。
  F 使用wglMakeCurrent函数把建立的翻译描述表作为当前翻译描述表。
  3、资源释放
  A 使用wglDeleteContext过程删除像素描述表。
  B 使用ReleaseDC过程释放窗口内存。
  在窗口的OnDestroy事件中:
  begin
  if hrcnull then
  wglDeleteCurrent(hrc);
  if hdcnull then
  ReleaseDC(Handle,hdc);
  end;
  五、OPENGL基本图形的绘制
  1、图形的颜色
  注意底色的设置,颜色设置通常与像素描述变量有关,即与TPixelFormatDescriptor定义中的iPixelType成员有关。
  iPixelType:=PFD_TYPE_COLORINDEX;
  则只能使用glIndexd,glIndexf,glIndexi,glIndexs,glIndexv,glIndexfv,glIndexiv,glIndexsv过程设置图形颜色。
  iPixelType:=PFD_TYPE_RGBA;
  则只能使用 glColor3b,glColor3f,glColor4b,glColor4f,glColor4fv设置图形颜色。
  A 图形底色:屏幕与窗口的颜色,即颜色缓冲区的颜色。改变图形底色首先应使用glClearColor过程设定底色,然后使用glClear过程以这种底色刷新窗口和屏幕。
  procedure glClearColor(red:GLClampf,green:GLClampf,blue:GLClampf,alpha:GLClampf);
  procedure glClear(mask:GLBitField);
  red,green,blue,alpha是准备设置的底色,它们的取值是0到1。mask是刷新底色的方式。
  例:将绘声绘色图窗口设置为绿色
  glClearColor(0,1,0,1);
  glClear(GL_COLOR_BUFFER_BIT);
  mask的取值和意义:
  GL_COLOR_BUFFER_BIT 设置当前的颜色缓冲
  GL_DEPTH_BUFFER_BIT 设置当前的深度缓冲
  GL_ACCUM_BUFFER_BIT 设置当前的积累缓冲
  GL_STENCIL_BUFFER_BIT 设置当前的STENCIL(模板)缓冲
  绘图窗口设置为灰色
  glClearColor(0.3,0.3,0.3,1);
  glClear(GL_COLOR_BUFFER_BIT);
  B 图形颜色
  使用glClear3f与glClear4f可以设置图形的绘制颜色。若用三个参数,则分别指设置红、蓝、绿三色光。若用四个参数,则第四个表示RGBA值。
  例设置当前的绘图颜色为蓝色:
  glColor3f(0,0,1);
  设置绘图颜色为白色:
  glColor3f(1,1,1);
  2、简单图形的绘制
  在glBegin与glEnd过程之间绘制简单图形,如点、线、多边形等。
  glBegin(mode:GLenum);{绘制过程}glEnd;
  mode的取值:
  GL_POINTS 画多个点
  GL_LINES 画多条线,每两点绘制一条直线
  GL_LINE_STRIP 绘制折线
  GL_LINE_LOOP 绘制首尾相接的封闭多边形
  GL_TRIANGLES 绘制三角形
  GL_TRIANGLE_STRIP 绘制三边形,每三个点绘制绘制一个三边形
  GL_TRIANGLE_FAN 绘制三角形
  GL_QUADS 绘制四边形
  GL_QUAD_STRIP 绘制四边条,每四点绘制一个四边条
  GL_POLYGON 绘制多边形
  例绘制三个点:
  begin
  glPushMatrix;
  glBegin(GL_POINT);
  glVertex2f(0.1,0.1);
  glVertex2f(0.5,0.5);
  glVertex2f(0.1,0.3);
  glEnd;
  SwapBuffers(Canvas.Handle);
  end;
  如果将GL_POINT改为GL_LINES,则将画一条线.第三个点无效.在glVertex2f之前执行glColor3f(0,0,1)则将线条的颜色改为绿色. 如果将GL_LINES改为GL_LINE_STRIP则可以绘制两条直线.
  使用glPointSize过程可以设置点的大小;使用glLineWidth过程可以设置线的宽度.
  使用glLineStipple过程设置点划线的样板,使用glEnable(GL_LINE_STIPPLE)过程和对应参数使绘图能够绘制点划线.glDisable(GL_LINE_STIPPLE)过程和对应参数关闭点划线.
  procedure glLineStipple(factor:GLint,pattern:GLushort);
  参数factor表示点划线样板Pattern的重复次数,factor取值1255,Pattern是二进制序列.
  glLineStipple(1,0,0x11C);{0x11C表示为10001110,0表示不画点,1表示画点}
  例:   begin
  glColor3f(1,0,0);
  glLineWidth(2);
  glLineStipple(1,$11C);
  glEnable(GL_LINE_STIPPLE);
  glBegin(GL_LINES);
  glVertex2f(-0.9,0.3);
  glVertex2f(0.9,0.3);
  glEnd;
  glDisable(GL_LINE_STIPPLE);
  glColor3f(1,0,1);
  glLineStipple(2,$11C);
  glEnable(GL_LINE_STIPPLE);
  glBegin(GL_LINES);
  glVertex2f(-0.9,0.1);
  glVertex2f(0.9,0.1);
  glEnd;
  glDisable(GL_LINE_STIPPLE);
  SwapBuffers(Canvas.Handle);
  end;
  多边形绘制与点线相似,要改变参数为GL_POLYGON,GL_QUADS,GL_TRANGLES.在绘制时的注意事项:
  A 多边形的边与边只在顶点相交
  B 多边形必须是凸多边形,如果是凹多边形,用户只有折成凸多边形,加快绘制速度.
  例: glBegin(GL_POLYGON);
  glVertex2f(-0.9,0.3);
  glVertex2f(0.9,0.3);
  glVertex2f(0.9,-0.6);
  glVertex2f(0.5,-0.6);
  glVertex2f(-0.9,-0.2);
  glEnd;
  多边形有正面与反面,与之相关的过程:
  glPolygonMode 控制多边形正,反面绘图模式
  glFrontface 指定多边形的正面
  glCullFace 显示多边形是设置消除面
  glPolygonStripple 形成多边形填充的样式
  3、简单二次曲面
  圆柱,圆环和球都属于二次曲面.
  A 圆柱
  gluCylinder(qobj:GLUquadricObj,baseRadius:GLdouble,topRadius:GLdouble,height:GLdouble,
  slices:GLint,stacks:GLint);
  qobj指定一个二次曲面,baseRadius为圆柱的底半径;topRadius为所绘制圆柱的上顶面半径;height为圆柱的高;slices为绕Z轴的分割线数;stacks为沿Z轴的分割线数.
  如果baseRadius和topRadius不相等,则可以绘制锥台与圆锥.
  procedure TfrmMain.MyDraw;
  var
  qObj:GLUQuadricObj;
  begin
  glPushMatrix;
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glColor3f(1,0,0);
  qObj:=gluNewQuadric;
  gluQuadricDrawStyle(qObj,GLU_LINE);
  gluCylinder(qObj,0.5,0.1,0.2,10,10);
  end;
  B 圆环
  gluDisk(qobj:GLUquadricObj,innerRadius:GLdouble,outerRadius:GLdouble,slices:GLint,
  loops:GLint);
  procedure TfrmMain.MyDraw;
  var
  qObj:GLUQuadricObj;
  begin
  glPushMatrix;
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glColor3f(1,0,0);
  qObj:=gluNewQuadric;
  gluQuadricDrawStyle(qObj,GLU_LINE);
  gluDisk(qObj,0.2,0.5,10,5);
  SwapBuffers(Canvas.Handle);
  end;
  C 半圆环
  gluPartialDisk(qobj:GLUquadricObj,innerRadius:GLdouble,outerRadius:GLdouble,slices:GLint,
  loops:GLint,startAngle:GLdouble,sweepAngle:GLdouble);
  startAngle,sweepAngle是半圆环的起始角与终止角.
  procedure TfrmMain.MyDraw;
  var
  qObj:GLUQuadricObj;
  begin
  glPushMatrix;
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glColor3f(1,0,0);
  qObj:=gluNewQuadric;
  gluQuadricDrawStyle(qObj,GLU_LINE);
  gluPartialDisk(qObj,0.2,0.5,10,5,90,190);
  SwapBuffers(Canvas.Handle);
  end;
  D 球体
  function gluSphere(qObj:GLUquadricObj,radius:GLdouble,slices:GLint,stacks:GLint);
  procedure TfrmMain.MyDraw;
  var
  qObj:GLUQuadricObj;
  begin
  glPushMatrix;
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glColor3f(1,0,0);
  qObj:=gluNewQuadric;
  gluQuadricDrawStyle(qObj,GLU_LINE);
  { silhouette[ silu(:)5et ]n.侧面影象, 轮廓}
  gluSphere(qObj,0.5,20,20);
  SwapBuffers(Canvas.Handle);
  end;
  E 关于二次曲面的过程
  gluNewQuadric 创建一个新的二次曲面对象
  gluDeleteQuadric 删除一个二次曲面对象
  gluQuadricDrawStyle 指定要绘制的二次曲面类型
  gluQuadricNormal 设置二次曲面的法矢量
  gluQuadricOrientation 设置二次曲面是内旋还是外旋转
  gluQuadricTexture 设置二次曲面是否使用纹理
  F 绘制二次曲面的一般步骤
  首先定义一个GLUquadricObj对象;
  其次创建一个曲面对象gluNewQuadric;
  再次设置二次曲面的特性(gluQuadricDrawStyle, gluQuadricTexture)
  绘制二次曲面(gluCylinder,gluSphere,gluDisk, gluPartialDisk)
  六、OPENGL中的变换
  变换是动画设计的基础,包括图形的平移,旋转,缩放等操作,在数学上是通过矩阵来实现的。
  1 glLoadIdentity过程
  能够把当前矩阵变为单位矩阵。
  2 glLoadMatrix过程
  能够把指定的矩阵设为当前矩阵。
  procedure glLoadmatrixd(m:GLdouble);
  procedure glLoadmatrixf(m:GLfloat);
  m表示4X4矩阵,下面的代码定义并使之成为当前矩阵
  M:array[1..4,1..4] of GLfloat;
  glLoadMatrix(@M);
  3 glMultMatrix过程
  能够将当前矩与指定矩阵相乘,并把结果作为当前矩.
  procedure glMultMatrixd(M:GLdouble);
  procedure glMultMatrixf(M:GLfloat);
  4 glPushMatrix和glPopmatrix
  glPushMatrix能够把当前矩压入矩阵堆栈, glPopMatrix能够把当前矩弹出矩阵堆栈.
  glPushMatrix能够记忆矩阵当前位置,glPopmatrix能够返回以前所在的位置.
  注:glPushMatrix与glPopMatrix必须放在glBegin与glEnd之外.
  5 投影变换
  A glOrtho能够创建一个正投影矩阵,把当前矩乘以该正投影矩阵,其结果作为当前矩阵.
  function glOrtho(left:GLdouble,right:GLdouble,bottom:GLdouble,top:GLdouble,
  near:GLdouble,far:GLdouble);
  procedure TfrmMain.FormResize(Sender: TObject);
  var
  nRange:GLfloat;
  begin
  nRange:=50.0;
  w:=clientWidth;
  h:=clientHeight;
  if h=0 then
  h:=1;
  glViewPort(0,0,w,h);
  if wnull then
  wglDeleteContext(hrc);
  end;
  end.
  七、OPENGL的光照与纹理
  都是增强三维立体效果和色彩效果的手段,光照能够增加图形的亮度和三维效果,纹理能够使用图形更加趋近现实。通过使用光照,可以将物体的外观很强列的表现出来,纹理则可以使物体显示多种多样的外观。
  1 光照和光源过程及应用
  A glIndex过程能够使颜色索引表中的某一种颜色成为当前颜色。
  procedure glIndexd(c:GLdouble);
  procedure glIndexf(c:GLdouble);
  procedure glIndexi(c:GLdouble);
  procedure glIndexs(c:GLdouble);
  参数C为索引值,如果使用glIndex过程,则TPiexlFormatDescriptor结构中的iPixelType成员设置为PFD_TYPE_COLORINDEX。
  B glShadeModel过程
  glShadeModel过程设置填充模式,取值:GL_SMOOTH.
  procedure  glShadeModel(mode:GLenum);
  注:以上两个过程只能在glBegin.....glEnd之外使用。
  C glLight过程定义光源
  procedure glLightf(light:GLenum,pname:GLenum,param:GLfloat);
  procedure glLighti(light:GLenum,pname:GLenum,param:GLfloat);
  参数light定义光源,其值可取:GL_LIGHT0.....GL_LIGHTN,N值小于GL_MAX_LIGHT.
  参数pname指定光源参数:
  GL_AMBIENT 环境光的分量强度
  GL_DIFFUSE 散射光的分量强度
  GL_SPECULAR 反射光的分量强度
  GL_POSITION 光源位置
  GL_SPOT_DIRECTION 光源的聚光方向
  GL_SPOT_EXPONENT 光源的聚光指数
  GL_SPOT_CUTOFF 光源的聚光方向
  GL_CONSTANT_ATTENUATION 光常数衰退因子
  GL_LINEAR_ATTENUATION 光二次衰减因子
  启用和关闭光源使用glEnable()与glDisable()过程
  glEnable(GL_LIGHTING);  //启用光源
  glDisable(GL_LIGHTING); //关闭光源
  glEnable(GL_LIGHT0);       //启用第0个光源
  glDisable(GL_LIGHT0);      //关闭第0个光源
  设置光源的实例:
  var
  sdirection:Array[1..4] of GLfloat:={0.0,1.0,0.0,0.0};
  glLightfv(GL_LIGHT0,GL_SPOT_CUTOFF,60);
  glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,sdirection);
  2 材质和光照模型
  A glMaterial过程设置材质参数
  procedure  glMaterialf(face:GLenum,pname :GLenum,param:GLfloat);
  procedure  glMateriali(face:GLenum,pname :GLenum,param:GLfloat);
  procedure  glMaterialfv(face:GLenum,pname :GLenum,param:GLfloat);
  procedure  glMaterialiv(face:GLenum,pname :GLenum,param:GLfloat);
  参数face指定物体表面,它的取值:GL_FRONT,GL_BACK,GL_FRONT_BACK.
  pname,param本资料没作介绍.
  B glLightModel过程
  procedure glLightModelf(pname:GLenum,param:GLfloat);
  参数pname为光源模型参数,可以取值GL_LIGHT_MODEL_AMBIENT,
  GL_LIGHT_MODEL_LOCAL_VIEWER,GL_LIGHT_MODEL_TWO_SIDE.
  实例代码:
  procedure TfrmMain.SetLighting;
  var
  MaterialAmbient:array[1..4] of GLfloat;
  MaterialDiffuse:Array[1..4] of GLfloat;
  MaterialSpecular:Array[1..4] of GLfloat;
  AmbientLightPosition:Array[1..4] of GLfloat;
  LightAmbient:Array[1..4] of GLfloat;
  MaterialShininess:GLfloat;
  begin
  MaterialAmbient[1]:=0.5;
  MaterialAmbient[2]:=0.8;
  MaterialAmbient[1]:=0.2;
  MaterialAmbient[1]:=1.0;
  MaterialDiffuse[1]:=0.4;
  MaterialDiffuse[2]:=0.8;
  MaterialDiffuse[3]:=0.1;
  MaterialDiffuse[4]:=1.0;
  MaterialSpecular[1]:=1.0;
  MaterialSpecular[2]:=0.5;
  MaterialSpecular[3]:=0.1;
  MaterialSpecular[4]:=1.0;
  materialShininess:=50.0;
  AmbientLightPosition[1]:=0.5;
  AmbientLightPosition[2]:=1.0;
  AmbientLightPosition[3]:=1.0;
  AmbientLightPosition[4]:=0.0;
  LightAmbient[1]:=0.5;
  LightAmbient[2]:=0.2;
  LightAmbient[3]:=0.8;
  LightAmbient[4]:=1.0;
  glMaterialfv(GL_FRONT,GL_AMBIENT,@MaterialAmbient);
  glMaterialfv(GL_FRONT,GL_DIFFUSE,@MaterialDiffuse);
  glMaterialfv(GL_FRONT,GL_SPECULAR,@MaterialSpecular);
  glMaterialfv(GL_FRONT,GL_SHININESS,@MaterialShininess);
  glLightfv(GL_LIGHT0,GL_POSITION,@AmbientLightPosition);
  glLightModelfv(GL_LIGHT_MODEL_AMBIENT,@LightAmbient);
  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);
  GLShadeModel(GL_SMOOTH);
  end;
  3 纹理的应用
  A glTexImage1D定义一维纹理映射.
  procedure glTexImage1D(target:GLenum,level:GLint,components:GLint,width:GLsizei,
  border:GLint,format:GLenum,type:GLenum,pixels:GLvoid);
  参数targer值为GL_TEXTURE_1D,定义为纹理映射,level为多级分辨率的纹理图像的等级,width为纹理宽,值为2n,n取值为32,64,129等.border为纹理的边界,其值为0或1,Pixel为纹理在内存中的位置.Component指定RGBA的混合和调整:
  1 选择B成分
  2 选择B,A成分
  3 选择R,G,B成分
  4 选择R,G,B,A成分
  B glTexImage2D定义二维纹理映射
  procedure glTexImage2D(target:GLenum,level:GLint,components:GLint,width:GLsizei,
  border:GLint,format:GLenum,type:GLenum,pixels:GLvoid);
  若参数target为GL_TEXTURE_2D,意义为二维纹理映射,height为纹理的高,函数中的其它参数与glTexImage1D相同.component参数取值同上.
  实例代码:
  procedure TfrmMain.SetTextures;
  var
  bits:Array[1..64,1..64,1..64] of GLubyte;
  bmp:TBitmap;
  i,j:Integer;
  begin
  bmp:=TBitmap.Create;
  bmp.LoadFromFile(d:\dsoft\1119\01\logon.bmp);
  for i:=1 to 64 do
  for j:=1 to 64 do
  begin
  bits[i,j,1]:=GLbyte(GetRValue(bmp.Canvas.Pixels[i,j]));
  bits[i,j,2]:=GLbyte(GetRValue(bmp.Canvas.Pixels[i,j]));
  bits[i,j,3]:=GLbyte(GetRValue(bmp.Canvas.Pixels[i,j]));
  bits[i,j,4]:=255;
  end;
  {0代表为单色着色水平,GL_RGBA表示混合值
  64X64代表纹理的高和宽,0表示无边界,
  GL_RGBA代表纹理类型,GL_UNSIGNED_TYPE代表数据类型,@代对象地址}
  glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,64,64,0,GL_RGBA,
  GL_UNSIGNED_BYTE,@bits);
  glEnable(GL_TEXTURE_2D);
  end;
  C glTexParameter过程设置纹理参数
  procedure glTexParameterf(target:GLenum,pname:GLenum,param:GLfloat);
  procedure glTexParameteri(target:GLenum,pname:GLenum,param:GLfloat);
  参数target代表GL_TEXTURE_1D或GL_TEXTURE_2D,param为纹理值.
  D glTexEnv函数设置纹理的环境参数
  function glTexEnvf(target:GLenum,pname:GLenum,param:GLfloat);
  function glTexEnvi(target:GLenum,pname:GLenum,param:GLfloat);
  参数target为GL_TEXTURE_ENV,
  参数pname为纹理参数值,取值为GL_TEXTURE_ENV_MODE
  参数param为环境值,取值为GL_MODULATE,GL_DECAL和GL_BLEND.
  本程序示例代码:
  unit MainFrm;
  interface
  uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, OpenGL, ExtCtrls;
  type
  TfrmMain = class(TForm)
  Timer1: TTimer;
  procedure FormCreate(Sender: TObject);
  procedure FormDestroy(Sender: TObject);
  procedure FormPaint(Sender: TObject);
  procedure FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
  procedure FormResize(Sender: TObject);
  procedure Timer1Timer(Sender: TObject);
  procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
  { Private declarations }
  hrc:HGLRC;
  w,h:Integer;
  latitude,longitude:GLfloat;
  radius:GLdouble;
  public
  { Public declarations }
  procedure SetLighting;
  procedure SetTextures;
  procedure MyDraw;
  procedure InitializeGL(var width:GLsizei;height:GLsizei);
  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:=ClientRect.Right;
  h:=ClientRect.Bottom;
  InitializeGL(w,h);
  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);
  SetTextures;
  MyDraw;
  SetLighting;
  glFlush;
  end;
  procedure TfrmMain.MyDraw;
  var
  qObj:GLUQuadricObj;
  begin
  glPushMatrix;
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glColor3f(1,0,0);
  glRotated(0.5,0.0,1.0,0.0);
  glRotated(-latitude,1.0,0.0,0.0);
  glrotated(longitude,0.0,0.0,1.0);
  qObj:=gluNewQuadric;
  gluQuadricDrawStyle(qObj,GLU_LINE);
  gluSphere(qObj,0.5,20,20);
  SwapBuffers(Canvas.Handle);
  SetLighting;
  SetTextures;
  end;
  {procedure TfrmMain.FormResize(Sender: TObject);
  var
  nRange:GLfloat;
  begin
  nRange:=50.0;
  w:=clientWidth;
  h:=clientHeight;
  if h=0 then
  h:=1;
  glViewPort(0,0,w,h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity;
  if wnull then
  wglDeleteContext(hrc);
  end;
  procedure TfrmMain.SetLighting;
  var
  MaterialAmbient:array[1..4] of GLfloat;
  MaterialDiffuse:Array[1..4] of GLfloat;
  MaterialSpecular:Array[1..4] of GLfloat;
  AmbientLightPosition:Array[1..4] of GLfloat;
  LightAmbient:Array[1..4] of GLfloat;
  MaterialShininess:GLfloat;
  begin
  MaterialAmbient[1]:=0.5;
  MaterialAmbient[2]:=0.8;
  MaterialAmbient[1]:=0.2;
  MaterialAmbient[1]:=1.0;
  MaterialDiffuse[1]:=0.4;
  MaterialDiffuse[2]:=0.8;
  MaterialDiffuse[3]:=0.1;
  MaterialDiffuse[4]:=1.0;
  MaterialSpecular[1]:=1.0;
  MaterialSpecular[2]:=0.5;
  MaterialSpecular[3]:=0.1;
  MaterialSpecular[4]:=1.0;
  materialShininess:=50.0;
  AmbientLightPosition[1]:=0.5;
  AmbientLightPosition[2]:=1.0;
  AmbientLightPosition[3]:=1.0;
  AmbientLightPosition[4]:=0.0;
  LightAmbient[1]:=0.5;
  LightAmbient[2]:=0.2;
  LightAmbient[3]:=0.8;
  LightAmbient[4]:=1.0;
  glMaterialfv(GL_FRONT,GL_AMBIENT,@MaterialAmbient);
  glMaterialfv(GL_FRONT,GL_DIFFUSE,@MaterialDiffuse);
  glMaterialfv(GL_FRONT,GL_SPECULAR,@MaterialSpecular);
  glMaterialfv(GL_FRONT,GL_SHININESS,@MaterialShininess);
  glLightfv(GL_LIGHT0,GL_POSITION,@AmbientLightPosition);
  glLightModelfv(GL_LIGHT_MODEL_AMBIENT,@LightAmbient);
  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);
  GLShadeModel(GL_SMOOTH);
  end;
  procedure TfrmMain.SetTextures;
  var
  bits:Array[1..64,1..64,1..64] of GLubyte;
  bmp:TBitmap;
  i,j:Integer;
  begin
  bmp:=TBitmap.Create;
  bmp.LoadFromFile(d:\dsoft\1119\02\logon.bmp);
  for i:=1 to 64 do
  for j:=1 to 64 do
  begin
  bits[i,j,1]:=GLbyte(GetRValue(bmp.Canvas.Pixels[i,j]));
  bits[i,j,2]:=GLbyte(GetRValue(bmp.Canvas.Pixels[i,j]));
  bits[i,j,3]:=GLbyte(GetRValue(bmp.Canvas.Pixels[i,j]));
  bits[i,j,4]:=255;
  end;
  glPixelStorei(GL_UNPACK_ALIGNMENT,4);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
  {0代表为单色着色水平,GL_RGBA表示混合值
  64X64代表纹理的高和宽,0表示无边界,
  GL_RGBA代表纹理类型,GL_UNSIGNED_TYPE代表数据类型,@代对象地址}
  glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,64,64,0,GL_RGBA,
  GL_UNSIGNED_BYTE,@bits);
  glEnable(GL_TEXTURE_2D);
  glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
  end;
  end.
分享到:
评论

相关推荐

    Delphi中OpenGL程序设计(一)

    Delphi中OpenGL程序设计(一)

    OPengl程序设计

    delphi的Opengl开发教程。可视化的opengl程序设计。适合初学者学习Opengl

    Delphi编程技巧.rar

    Delphi之快速设计(程序设计篇) Delphi之快速设计(界面设计篇) 在DELPHI2.0/3.0中直接操作端口 开 发AS/400 应 用 系 统: PB5 与Delphi3 的 比 较 检查驱动器是否就绪 在Delphi应用程序中拖动控件 用修改...

    Delphi 7.0编程实例五十讲-pdf版

    第五篇多媒体程序设计 第二十五讲 CD播放器 第二十六讲 播放动画 第二十七讲 RealPlayer音频播放器 第二十八讲 图片浏览器 第六篇高级编程技巧 第二十九讲 使用OLE对象 第三十讲 创建和使用对象 第三十一讲 多线程...

    Delphi XE2的OpenCL控件(可以象TQuery一样使用OpenCL)

    OpenCL的设计思路和OpenGL类似,对于大部分Delphi的设计者来说,非常不习惯,而且使用起来并不十分方便 设计这个TOpenCL控件的目的不是替代OpenCL的原生使用方式,而是为了开发者能够快速对OpenCL进行应用并且可以 ...

    80例上手Delphi7编程(完全版)+源码

     如何在Delphi中操作Excel  实现应用程序的文件拖放功能  将EXE文件转换成SWF文件  将SWF文件转换成EXE文件  文件捆绑  统计中英文字个数  06图形图像多媒体  实例一--艺术字效果  实例七---...

    cgi纹理图片查看器

    可视化OPENGL程序设计中需要用到cgi格式图片,做纹理映射,该程序用于查看cgi格式图片,源码基于delphi

    Delphi 6集成开发环境

    1.4 一个简单的Delphi 程序........................... 12 1.5 本章小结.................................................... 13 第2 章 Object Pascal 语言..........14 2.1 Object Pascal 语言基础...............

    TeeChart(.net 图型控件)

     支持25种语言,经过翻译的对话框和常量在程序设计阶段(如果你重新编译包)和程序运行阶段(只需要重新编译你的应用程序)均可以使用。一旦你的应用程序编译完成,终端用户在程序运行时只需要简单地一个调用,比如...

    2018 猎豹网校 教程大全 资源难找赶紧保存吧

    猎豹网校 Windows程序设计 初级课程(二)[MP4] 攻防[MP4] 北风网 C++反汇编基础:Win32平台(逆向实例、动态调试实例)[MP4] 安卓 Android 游戏编程入门(上)[MP4] Word排版高级技巧[MP4] Word 零基础入门[MP4] ...

    TeeChart应用技术详解-快速图表制作工具

    本书编写过程侧重各组件应用中核心问题的解决即关键代码实现,并附有测试实例,同时,以问答形式给出程序设计过程中可能遇到的问题的解决方法,便于程序员快速查看。 本书适合对图表组件感兴趣的读者,也可作为科研...

    KSDev ThemeEngine v7.02 FullSource

    KSDev ThemeEngine v7.02 FullSource <br/>ThemeEngine可以使Delphi/BCB编译的程序具Windows XP界面等诸多风格, 附带的编辑器可以为你的程序设计独有的漂亮界面。 完整支持微软 Theme API。 <br/>...

    易语言程序免安装版下载

    OpenGL支持库中的部分英文名称常量已改为中文,并统一在所有常量名称之前加前缀“GL_”,以减少与其它库的冲突机率。 3. 互联网支持库中的“FTP目录列表”命令返回的文件时间改为FTP服务器返回的原始时间,不做...

    Code Blocks

     Code::Blocks支持语法彩色醒目显示,支持代码完成(目前正在重新设计过程中)支持工程管理、项目构建、调试。  Code::Blocks支持插件,目前的插件包括代码格式化工具AStyle;代码分析器;类向导;代码补全;代码...

    Code::Blocks 8.02 GCC 4.40 汉化包

     Code::Blocks支持语法彩色醒目显示,支持代码完成(目前正在重新设计过程中)支持工程管理、项目构建、调试。  Code::Blocks支持插件,目前的插件包括代码格式化工具AStyle;代码分析器;类向导;代码补全;代码...

    AutoREALM:专为RPG设计的基于矢量的绘图软件-开源

    但是目前(自2012年1月以来)使用这些技术进行了尝试或重写:_ C ++ 11 _ wxWidgets 2.9(发布时将为3.0)_ openGL _ pluma框架(位于bitbucket上的固定版本)实际C ++代码库的设计主要针对干净的源代码和高度的源...

Global site tag (gtag.js) - Google Analytics