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/

 

posted @ 2016-09-03 10:54  猪悟能  阅读(2620)  评论(0编辑  收藏  举报