你的位置:首页 > ASP.net教程

[ASP.net教程]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       else144         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 else201 return false;202 }203 204 }205 }

 

效果如下:

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

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

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

 

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

 

本节源代码下载

 

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