• SharpGL学习笔记(十六) 多重纹理映射


     多重纹理就把多张贴图隔和在一起.比如下面示例中,一个表现砖墙的纹理,配合一个表现聚光灯效果的灰度图,就形成了砖墙被一个聚光灯照亮的效果,这便是所谓的光照贴图技术.

    多重纹理只在OpenGL扩展库中才提供的.OpenGL和D3D比较起来,最大的一个优点是有扩展机制.

    显卡硬件厂商开发出一项新功能,就可以针对新功能开发OpenGL扩展,软件开发人员通过这个扩展就可以使用新的硬件功能,而不用等新的OpenGL版来公布才能使用这个新功能.而D3D则必须等到新版本的DirectX发布后才能支持硬件的新功能.

    下面的代码演示了如何使用扩展函数 GL_ARB_multitexture();

    示例源代码:

      1 using System;
      2 using System.Collections.Generic;
      3 using System.ComponentModel;
      4 using System.Data;
      5 using System.Drawing;
      6 using System.Linq;
      7 using System.Text;
      8 using System.Windows.Forms;
      9 using SharpGL;
     10 
     11 namespace SharpGLWinformsApplication1
     12 {
     13   //原创文章,出自"博客园, 猪悟能'S博客" : http://www.cnblogs.com/hackpig/
     14     public partial class SharpGLForm : Form
     15     {
     16         static float wrap = 0;      // 用于雾的流动
     17         SharpGL.SceneGraph.Assets.Texture[] textureAry = new SharpGL.SceneGraph.Assets.Texture[4];
     18         float[] fLightPosition = new float[4] { 0.0f, 0.0f, 8.0f, 1.0f}; // 光源位置 
     19         float[] fLightAmbient = new float[4] { 1f,1f, 1f, 1f };         // 环境光参数 
     20         float[] fLightDiffuse = new float[4] { 1f,1f, 1f, 1f };         // 漫射光参数
     21 
     22         bool multitexturing = true;  
     23         public SharpGLForm()
     24         {
     25             InitializeComponent();
     26         }
     27 
     28         private void openGLControl_OpenGLDraw(object sender, PaintEventArgs e)
     29         {
     30             OpenGL gl = openGLControl.OpenGL;
     31             gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
     32             gl.LoadIdentity();
     33             draw(gl);
     34         }
     35 
     36 
     37         private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
     38         {
     39             OpenGL gl = openGLControl.OpenGL;
     40             String[] fileName = new String[4] { "wall.bmp", "lightmap.bmp", "bitmap.bmp", "fog.bmp" };
     41             for (int i = 0; i < fileName.Length; i++)
     42             {
     43                 textureAry[i] = new SharpGL.SceneGraph.Assets.Texture();
     44                 if (textureAry[i].Create(gl, fileName[i]))
     45                 {
     46                     textureAry[i].Id = i;
     47                     textureAry[i].Name = fileName[i];
     48                   
     49                 }
     50             }
     51             
     52             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_AMBIENT, fLightAmbient);//环境光源 
     53             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_DIFFUSE, fLightDiffuse);//漫射光源 
     54             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, fLightPosition);//光源位置 
     55             gl.Enable(OpenGL.GL_LIGHTING);//开启光照 
     56             gl.Enable(OpenGL.GL_LIGHT0);
     57 
     58             gl.ClearColor(0.0f, 0.0f, 0.0f, 0.5f);
     59             gl.ClearDepth(1.0f);
     60             gl.DepthFunc(OpenGL.GL_LEQUAL);
     61             gl.Enable(OpenGL.GL_DEPTH_TEST);
     62             gl.ShadeModel(OpenGL.GL_SMOOTH);
     63             
     64             gl.Hint(OpenGL.GL_PERSPECTIVE_CORRECTION_HINT, OpenGL.GL_NICEST);
     65             gl.Enable(OpenGL.GL_NORMALIZE);
     66 
     67             if (!initMultiTexture(gl))
     68             {
     69                 MessageBox.Show("您的硬件和驱动不支持多重纹理");
     70                 return;
     71             }
     72         }
     73 
     74         private void openGLControl_Resized(object sender, EventArgs e)
     75         {
     76             OpenGL gl = openGLControl.OpenGL;
     77             gl.MatrixMode(OpenGL.GL_PROJECTION);
     78             gl.LoadIdentity();
     79             gl.Perspective(45f, (double)Width / (double)Height, 1, 100.0);
     80             gl.MatrixMode(OpenGL.GL_MODELVIEW);
     81             draw(gl);
     82         }
     83 
     84         private void draw(OpenGL Gl)
     85         {
     86             Gl.LoadIdentity();
     87             Gl.Translate(0.0f, 0.0f, -10.0f);
     88 
     89             //激活纹理0,并绑定纹理
     90             Gl.ActiveTextureARB(OpenGL.GL_TEXTURE0_ARB);
     91             Gl.Enable(OpenGL.GL_TEXTURE_2D);
     92             textureAry[0].Bind(Gl);
     93 
     94             Gl.ActiveTextureARB(OpenGL.GL_TEXTURE1_ARB);
     95             //如果多重纹理启用,则启用该纹理
     96             if (multitexturing)
     97                 Gl.Enable(OpenGL.GL_TEXTURE_2D);
     98             else
     99                 Gl.Disable(OpenGL.GL_TEXTURE_2D);
    100             textureAry[1].Bind(Gl);
    101 
    102             // 绘制一个四方形墙面
    103             Gl.PushMatrix();
    104             {
    105                 Gl.Translate(-2.5f, 0f, 0f);
    106                 Gl.Scale(2.0f, 2.0f, 2.0f);
    107                 Gl.Begin(OpenGL.GL_QUADS);
    108                 {
    109                     //左上点
    110 
    111                     Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE0_ARB, 0.0f, 1.0f);
    112                     Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE1_ARB, 0.0f + wrap, 1.0f);
    113                     Gl.Vertex(-1, 1, 0);
    114 
    115                     // 左下点
    116                     Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE0_ARB, 0.0f, 0.0f);
    117                     Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE1_ARB, 0.0f + wrap, 0.0f);
    118                     Gl.Vertex(-1, -1, 0);
    119 
    120                     // 右下点
    121                     Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE0_ARB, 1.0f, 0.0f);
    122                     Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE1_ARB, 1.0f + wrap, 0.0f);
    123                     Gl.Vertex(1, -1, 0);
    124 
    125                     // 右上点
    126                     Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE0_ARB, 1.0f, 1.0f);
    127                     Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE1_ARB, 1.0f + wrap, 1.0f);
    128                     Gl.Vertex(1, 1, 0);
    129                 }
    130                 Gl.End();
    131             }
    132             Gl.PopMatrix();
    133 
    134 
    135 
    136             Gl.ActiveTextureARB(OpenGL.GL_TEXTURE0_ARB);
    137             Gl.Enable(OpenGL.GL_TEXTURE_2D);
    138             textureAry[2].Bind(Gl);
    139 
    140             Gl.ActiveTextureARB(OpenGL.GL_TEXTURE1_ARB);
    141             if (multitexturing)
    142                 Gl.Enable(OpenGL.GL_TEXTURE_2D);
    143             else
    144                 Gl.Disable(OpenGL.GL_TEXTURE_2D);
    145             textureAry[3].Bind(Gl);
    146 
    147 
    148             Gl.PushMatrix();
    149             {
    150                 Gl.Translate(2.5f, 0, 0);
    151                 Gl.Scale(2.0f, 2.0f, 2.0f);
    152                 Gl.Begin(OpenGL.GL_QUADS);
    153                 {
    154                     // 左上点
    155                     Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE0_ARB, 0.0f, 1.0f);
    156                     Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE1_ARB, 0.0f - wrap, 1.0f);
    157                     Gl.Vertex(-1, 1, 0);
    158 
    159                     // 左下点
    160                     Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE0_ARB, 0.0f, 0.0f);
    161                     Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE1_ARB, 0.0f - wrap, 0.0f);
    162                     Gl.Vertex(-1, -1, 0);
    163 
    164                     // 右下点
    165                     Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE0_ARB, 1.0f, 0.0f);
    166                     Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE1_ARB, 1.0f - wrap, 0.0f);
    167                     Gl.Vertex(1, -1, 0);
    168 
    169                     // 右上点
    170                     Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE0_ARB, 1.0f, 1.0f);
    171                     Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE1_ARB, 1.0f - wrap, 1.0f);
    172                     Gl.Vertex(1, 1, 0);
    173                 }
    174                 Gl.End();
    175                 wrap += 0.01f;
    176             }
    177             Gl.PopMatrix();
    178 
    179             Gl.Flush();
    180         }
    181 
    182         /// <summary>
    183         /// 检查多重纹理支持
    184         /// </summary>
    185         /// <param name="input"></param>
    186         /// <returns></returns>
    187         bool isExtensionSupported(OpenGL gl, string input)
    188         {
              //GetSting获取显卡所支持的全部扩展的信息
    189 string extension = gl.GetString(OpenGL.GL_EXTENSIONS); 190 return extension.IndexOf(input) >= 0; 191 } 192 193 bool initMultiTexture(OpenGL gl) 194 { 195 //检查是否支持扩展 196 if (isExtensionSupported(gl,"GL_ARB_multitexture")) 197 { 198 return true; 199 } 200 else 201 return false; 202 } 203 204 } 205 }

    效果如下:

    左边的四边形贴上了地砖和灯光效果的两张贴图.

    右边的四边形贴上了风景和雾效果的两张贴图.

    通过移动多重纹理X坐标实现了水平移动的效果.

    代码基本和和普通的纹理映射没有非常大的区别,我没有什么好解析的.

    本节源代码下载

    原创文章,出自"博客园, 猪悟能'S博客" : http://www.cnblogs.com/hackpig/

  • 相关阅读:
    Mono 开发者会议
    PHP正在死亡?
    区域设置 ID (LCID) 表
    OpenSource 的 Free是自由 非免费
    搭建.net framwork 3.0开发环境的一篇文章
    Rainbow的相关资料
    利用VS2005中的Code Snippets提高开发效率
    判定是否为IPv4
    我的MVVM框架 v3教程——流程相关
    查询json数据结构的8种方式
  • 原文地址:https://www.cnblogs.com/hackpig/p/5836470.html
Copyright © 2020-2023  润新知