转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
NeHe的opengl教程delphi版(7)----滤波         ★★★★

NeHe的opengl教程delphi版(7)----滤波

作者:闵涛 文章来源:闵涛的学习笔记 点击数:2405 更新时间:2009/4/23 18:37:25

{
这一课我会教您如何使用三种不同的纹理滤波方式。
教您如何使用键盘来移动场景中的对象,还会教您在OpenGL场景中应用简单的光照。
这一课包含了很多内容,如果您对前面的课程有疑问的话,先回头复习一下。
进入后面的代码之前,很好的理解基础知识十分重要。
我们还是在第一课的代码上加以修改。
跟以前不一样的是,只要有任何大的改动,我都会写出整段代码。

首先我们还要加进SysUtils单元和Glaux单元。
}

Uses
   SysUtils,
   opengl,
   windows,
   Messages,
   Glaux In ''''..\..\GLAUX\Glaux.pas'''';

   //下面几行是增加新的变量。

   //我们增加三个布尔变量。
   // light 变量跟踪光照是否打开。
   //变量lp和fp用来存储''''L'''' 和''''F''''键是否按下的状态。
   //后面我会解释这些变量的重要性。现在,先放在一边吧。
   light            : Boolean;          // 光源的开/关
   lp               : Boolean;          // L键按下了么?
   fp               : Boolean;          // F键按下了么?

   //现在设置5个变量来控制绕x轴和y轴旋转角度的步长,
   //以及绕x轴和y轴的旋转速度。
   //另外还创建了一个z变量来控制进入屏幕深处的距离。
   xrot             : GLfloat;          // X 旋转
   yrot             : GLfloat;          // Y 旋转
   xspeed           : GLfloat;          // X 旋转速度
   yspeed           : GLfloat;          // Y 旋转速度

   z                : GLfloat = -5.0 f; // 深入屏幕的距离

   //接着设置用来创建光源的数组。
   //我们将使用两种不同的光。
   //第一种称为环境光。环境光来自于四面八方。
   //所有场景中的对象都处于环境光的照射中。
   //第二种类型的光源叫做漫射光。
   //漫射光由特定的光源产生,并在您的场景中的对象表面上产生反射。
   //处于漫射光直接照射下的任何对象表面都变得很亮,
   //而几乎未被照射到的区域就显得要暗一些。
   //这样在我们所创建的木板箱的棱边上就会产生的很不错的阴影效果。
   //创建光源的过程和颜色的创建完全一致。
   //前三个参数分别是RGB三色分量,最后一个是alpha通道参数。

   //因此,下面的代码我们得到的是半亮(0.5f)的白色环境光。
   //如果没有环境光,未被漫射光照到的地方会变得十分黑暗。
   LightAmbient     : Array[0..3] Of GLfloat = (0.5, 0.5, 0.5, 1.0);  //环境光参数 ( 新增 )
   //下一行代码我们生成最亮的漫射光。
   //所有的参数值都取成最大值1.0f。
   //它将照在我们木板箱的前面,看起来挺好。
   LightDiffuse     : Array[0..3] Of GLfloat = (1.0, 1.0, 1.0, 1.0);  // 漫射光参数 ( 新增 )
   //最后我们保存光源的位置。
   //前三个参数和glTranslate中的一样。
   //依次分别是XYZ轴上的位移。
   //由于我们想要光线直接照射在木箱的正面,所以XY轴上的位移都是0.0。
   //第三个值是Z轴上的位移。
   //为了保证光线总在木箱的前面,
   //所以我们将光源的位置朝着观察者(就是您哪。)挪出屏幕。
   //我们通常将屏幕也就是显示器的屏幕玻璃所处的位置称作Z轴的0.0点。
   //所以Z轴上的位移最后定为2.0。
   //假如您能够看见光源的话,它就浮在您显示器的前方。
   //当然,如果木箱不在显示器的屏幕玻璃后面的话,您也无法看见箱子。
   //『译者注:我很欣赏NeHe的耐心。
   //说真的有时我都打烦了,这么简单的事他这么废话干嘛?
   //但如果什么都清楚,您还会翻着这样的页面看个没完么?』
   //最后一个参数取为1.0f。
   //这将告诉OpenGL这里指定的坐标就是光源的位置,以后的教程中我会多加解释。
   LightPosition    : Array[0..3] Of GLfloat = (0.0, 0.0, 2.0, 1.0);  // 光源位置 ( 新增 )

   //filter 变量跟踪显示时所采用的纹理类型。
   //第一种纹理(texture 0) 使用gl_nearest(不光滑)滤波方式构建。
   //第二种纹理 (texture 1) 使用gl_linear(线性滤波) 方式,
   //离屏幕越近的图像看起来就越光滑。
   //第三种纹理 (texture 2) 使用 mipmapped滤波方式,
   //这将创建一个外观十分优秀的纹理。
   //根据我们的使用类型,filter 变量的值分别等于 0, 1 或 2 。
   //下面我们从第一种纹理开始。
   //texture为三种不同纹理分配储存空间。
   //它们分别位于在 texture[0], texture[1] 和 texture[2]中。

   filter           : GLuint;           // 滤波类型
   texture          : Array[0..2] Of GLuint; // 3种纹理的储存空间

Procedure glGenTextures(n: GLsizei; Var textures: GLuint); stdcall; external
   opengl32;

Procedure glBindTexture(target: GLenum; texture: GLuint); stdcall; external
   opengl32;

Function gluBuild2DMipmaps(target: GLenum; components, width, height: GLint;
   format, atype: GLenum; data: Pointer): Integer; stdcall; external glu32 name
   ''''gluBuild2DMipmaps'''';

{
现在载入一个位图,并用它创建三种不同的纹理。
这一课使用glaux辅助库来载入位图,
因此在编译时您应该确认是否包含了glaux库。
我知道Delphi和VC++都包含了glaux库,但别的语言不能保证都有。
『译者注:glaux是OpenGL辅助库,根据OpenGL的跨平台特性,
所有平台上的代码都应通用。但辅助库不是正式的OpenGL标准库,
没有出现在所有的平台上。但正好在Win32平台上可用。
呵呵,BCB当然也没问题了。』这里我只对新增的代码做注解。
如果您对某行代码有疑问的话,请查看教程六。
那一课很详细的解释了载入、创建纹理的内容。
在上一段代码后面及 glResizeWnd ()之前的位置,
我们增加了下面的代码。这和第六课中载入位图的代码几乎相同。
}

Function LoadBmp(filename: pchar): PTAUX_RGBImageRec;
Var
   BitmapFile       : Thandle;          // 文件句柄
Begin
   If Filename = '''''''' Then                // 确保文件名已提供。
      result := Nil;                    // 如果没提供,返回 NULL
   BitmapFile := FileOpen(Filename, fmOpenWrite); //尝试打开文件
   If BitmapFile > 0 Then               // 文件存在么?
      Begin
         FileClose(BitmapFile);         // 关闭句柄
         result := auxDIBImageLoadA(filename); //载入位图并返回指针
      End
   Else
      result := Nil;                    // 如果载入失败,返回NiL。
End;

Function LoadTexture: boolean;          // 载入位图并转换成纹理
Var
   Status           : boolean;          // Status 指示器
   TextureImage     : Array[0..1] Of PTAUX_RGBImageRec; // 创建纹理的存储空间
Begin
   Status := false;
   ZeroMemory(@TextureImage, sizeof(TextureImage)); // 将指针设为 NULL
   TextureImage[0] := LoadBMP(''''Walls.bmp'''');
   If TextureImage[0] <> Nil Then
      Begin
         Status := TRUE;                // 将 Status 设为 TRUE
         glGenTextures(1, texture[0]);  // 创建纹理
         //第六课中我们使用了线性滤波的纹理贴图。
         //这需要机器有相当高的处理能力,但它们看起来很不错。
         //这一课中,我们接着要创建的第一种纹理使用 GL_NEAREST方式。
         //从原理上讲,这种方式没有真正进行滤波。
         //它只占用很小的处理能力,看起来也很差。
         //唯一的好处是这样我们的工程在很快和很慢的机器上都可以正常运行。
         //您会注意到我们在 MIN 和 MAG 时都采用了GL_NEAREST,
         //你可以混合使用 GL_NEAREST 和 GL_LINEAR。
         //纹理看起来效果会好些,但我们更关心速度,所以全采用低质量贴图。
         //MIN_FILTER在图像绘制时小于贴图的原始尺寸时采用。
         //MAG_FILTER在图像绘制时大于贴图的原始尺寸时采用。

         // 创建 Nearest 滤波贴图
         glBindTexture(GL_TEXTURE_2D, texture[0]);
         // 生成纹理
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);  // ( 新增 )
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);  // ( 新增 )

         glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0].sizeX,
            TextureImage[0].sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,
            TextureImage[0].data);

         //下个纹理与第六课的相同,线性滤波。唯一的不同是这次放在了
         //texture[1]中。因为这是第二个纹理。如果放在
         //texture[0]中的话,他将覆盖前面创建的 GL_NEAREST纹理。
         glBindTexture(GL_TEXTURE_2D, texture[1]);  // 使用来自位图数据生成 的典型纹理
         // 生成纹理
         glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0].sizeX,
            TextureImage[0].sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,
          &nb

[1] [2] [3] [4]  下一页


[系统软件]InstallShield Express for delphi制作安装程序定…  [常用软件]InstallShield Express制作Delphi数据库安装程序
[Delphi程序]为什么选择Delphi.Net ?  [Delphi程序]《关于VisiBroker For Delphi的使用》(4)
[Delphi程序]Delphi 程序员代码编写标准指南  [Delphi程序]转贴:Conversion to Delphi 6: Missing unit Pro…
[Delphi程序]Borland Delphi 9 的新特性  [Delphi程序]Delphi 键盘码表
[Delphi程序]Chuck Jazdzewski的离开意味着Delphi的终结吗?  [Delphi程序]Delphi Access violations 问题的解决之道
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台