OpenGL教程之纹理滤波方式

这篇教程介绍了OpenGL中的纹理滤波方式,包括不光滑滤波(GL_NEAREST)、线性滤波(GL_LINEAR)和Mipmapping滤波,以及如何使用键盘控制场景对象的移动和光照的开启与关闭。通过加载位图,创建并应用3种不同纹理,展示了不同滤波效果对图像质量的影响。同时,教程还涵盖了光源的设置,包括环境光和漫射光,以及如何使用法线来影响光照效果。
摘要由CSDN通过智能技术生成

Jeff Molofee(NeHe)的OpenGL教程
- 纹理滤波方式

原 文Lesson 7: Texture Filters, Lighting & Keyboard Control
译 者CKER

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

  
#include <windows.h>                    // Windows的头文件
  #include <stdio.h>                     // 标准输入/输出库的头文件 (新增)
  #include <gl/gl.h>                     // OpenGL32库的头文件
  #include <gl/glu.h>                     // GLu32库的头文件
  #include <gl/glaux.h>                    // GLaux库的头文件

  HGLRC hRC=NULL;                       // 永久着色描述表
  HDC hDC=NULL;                        // 私有GDI设备描述表
  HWND hWnd=NULL;                       // 保存我们的窗口句柄
  HINSTANCE hInstance;                    // 保存程序的实例

  bool keys[256];                       // 用于键盘例程的数组
  bool active=TRUE;                      // 窗口的活动标志,缺省为TRUE
  bool fullscreen=TRUE;                    // 全屏标志缺省设定成全屏模式

  下面几行是新的。我们增加三个布尔变量。light变量跟踪光照是否打开。变量lpfp用来存储‘L’‘F’键是否按下的状态。后面我会解释这些变量的重要性。现在,先放在一边吧。

  
BOOL light;                         // 光源的开/
  BOOL lp;                          // L键按下了么?
  BOOL fp;                          // F键按下了么?

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

  
GLfloat xrot;                        // X 旋转
  GLfloat yrot;                        // Y 旋转
  GLfloat xspeed;                       // X 旋转速度
  GLfloat yspeed;                       // Y 旋转速度

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

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

  
GLfloat LightAmbient[]= { 0.5f , 0.5f , 0.5f , 1.0f };     // 环境光参数 (新增)

  下一行代码我们生成最亮的漫射光。所有的参数值都取成最大值 1.0f 。它将照在我们木板箱的前面,看起来挺好。

  
GLfloat LightDiffuse[]= { 1.0f , 1.0f , 1.0f , 1.0f };     // 漫射光参数 (新增)

  最后我们保存光源的位置。前三个参数和glTranslate中的一样。依次分别是XYZ轴上的位移。由于我们想要光线直接照射在木箱的正面,所以XY轴上的位移都是 0.0f 。第三个值是Z轴上的位移。为了保证光线总在木箱的前面,所以我们将光源的位置朝着观察者(就是您哪。)挪出屏幕。我们通常将屏幕也就是显示器的屏幕玻璃所处的位置称作Z轴的 0.0f 点。所以Z轴上的位移最后定为 2.0f 。假如您能够看见光源的话,它就浮在您显示器的前方。当然,如果木箱不在显示器的屏幕玻璃后面的话,您也无法看见箱子。最后一个参数取为 1.0f 。这将告诉OpenGL这里指定的坐标就是光源的位置,以后的教程中我会多加解释。

  
GLfloat LightPosition[]= { 0.0f , 0.0f , 2.0f , 1.0f };    // 光源位置 ( 新增 )

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

  
GLuint filter;                       // 滤波类型
  GLuint texture[3];                     // 3种纹理的储存空间
  LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);    // WndProc定义

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

  
AUX_RGBImageRec *LoadBMP(char *Filename)          // 载入位图
  {
      FILE *File=NULL;                  // 文件句柄
      if (!Filename)                   // 确认文件名已初始化
      {
          return NULL;                // 没有返回 NULL
      }

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值