本文基础:C#+OpenGL编程之OpenGL 纹理载入
本文继续介绍多重纹理使用。
多重纹理使用和单纹理差不多,不过要注意的是多重纹理不是标准OpenGL 1.1中的函数,需要先测试系统显卡驱动是否支持。
using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Windows.Forms; using Tao.Glfw; using Tao.OpenGl; namespace OpenGL { /// <summary> /// 第四章 OpenGl 多重纹理 C# by 大师♂罗莊 /// </summary> class OpenGLMultiTexture : Examplefirst { TextureLoad[] m_texture = new TextureLoad[4]; bool multitexturing=false; /** 检查是否支持扩展 */ public OpenGLMultiTexture() : base() { for (int i = 0; i < 4; i++) { m_texture[i] = new TextureLoad();//对象数组必须初始化 } LoadTexture(); base.title = "第四章 OpenGl 多重纹理"; } /// <summary> /// 检查多重纹理支持 /// </summary> /// <param name="input"></param> /// <returns></returns> bool isExtensionSupported(string input) { string extension = Gl.glGetString(Gl.GL_EXTENSIONS); return extension.IndexOf(input)>=0; } bool initMultiTexture() { /** 检查是否支持扩展 */ if (isExtensionSupported("GL_ARB_multitexture")) { return true; } else return false; } /** 载入纹理数据 */ bool LoadTexture() { /// 文件名 String[] fileName = new String[4] { "wall.bmp", "lightmap.bmp", "bitmap.bmp", "fog.bmp" }; /// 载入四幅位图 for (int i = 0; i < 4; i++) { if (m_texture[i].Load(Path.Combine(Application.StartupPath, @"Image\" + fileName[i]).ToString()) == false) /**< 载入位图文件 */ { MessageBox.Show("无法载入" + fileName[i]); return false; } } return true; } /// <summary> /// 初始化视口投影,恢复原书的视口 /// </summary> public override void iniView(int windowWidth, int windowHeight) { Glu.gluPerspective(45.0f, windowWidth / windowHeight, 1.0f, 100.0f); Gl.glMatrixMode(Gl.GL_MODELVIEW); Gl.glLoadIdentity(); Gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); Gl.glClearDepth(1.0f); Gl.glDepthFunc(Gl.GL_LEQUAL); Gl.glEnable(Gl.GL_DEPTH_TEST); Gl.glShadeModel(Gl.GL_SMOOTH); Gl.glHint(Gl.GL_PERSPECTIVE_CORRECTION_HINT, Gl.GL_NICEST); /** 初始化 */ if (!initMultiTexture()) { MessageBox.Show("您的硬件和驱动不支持多重纹理"); return; } /** 载入纹理 */ ///这里可以测试我们的材质类有没有造成内存泄漏问题。 if (!LoadTexture()) { MessageBox.Show("无法载入纹理"); return; } } /** 用户自定义的卸载函数 */ public new void Dispose() { base.Dispose(); for (int i = 0; i < 4; i++) { m_texture[i].FreeImage(); Gl.glDeleteTextures(1, m_texture[i].ID); } } float wrap = 0; /**< 用于雾的流动 */ /// <summary> /// 重载 /// </summary> /// <param name="mouseX"></param> /// <param name="currentTime"></param> public override void Update(float milliseconds) { //按下ESC结束 isRunning = ((Glfw.glfwGetKey(Glfw.GLFW_KEY_ESC) == Glfw.GLFW_RELEASE) && Glfw.glfwGetWindowParam(Glfw.GLFW_OPENED) == Gl.GL_TRUE); ///** 当按下空格时,开启或关闭多重纹理 */ if (Glfw.glfwGetKey(Glfw.GLFW_KEY_SPACE ) == Glfw.GLFW_RELEASE) { multitexturing = false; } else { multitexturing = true;//开启 } wrap += milliseconds/10; //动画 } /// <summary> /// 重载,使用Draw方法绘图 /// </summary> /// <param name="mouseX"></param> /// <param name="currentTime"></param> public override void DrawGLScene(int mouseX, double currentTime) { Draw(); } /** 绘制函数 */ void Draw() { /** 用户自定义的绘制过程 */ Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT); Gl.glLoadIdentity(); Gl.glTranslatef(0.0f, 0.0f, -10.0f); /** 激活纹理0,并绑定纹理 */ Gl.glActiveTextureARB(Gl.GL_TEXTURE0_ARB); Gl.glEnable(Gl.GL_TEXTURE_2D); Gl.glBindTexture(Gl.GL_TEXTURE_2D, m_texture[0].ID[0]); /** 激活纹理1,并绑定纹理 */ Gl.glActiveTextureARB(Gl.GL_TEXTURE1_ARB); /** 如果多重纹理启用,则启用该纹理 */ if (multitexturing) Gl.glEnable(Gl.GL_TEXTURE_2D); else Gl.glDisable(Gl.GL_TEXTURE_2D); Gl.glBindTexture(Gl.GL_TEXTURE_2D, m_texture[1].ID[0]); /** 绘制一个四方形墙面 */ Gl.glPushMatrix(); Gl.glTranslatef(-2.5f, 0f, 0f); Gl.glScalef(2.0f, 2.0f, 2.0f); Gl.glBegin(Gl.GL_QUADS); /** 左上点 */ Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE0_ARB, 0.0f, 1.0f); Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE1_ARB, 0.0f, 1.0f); Gl.glVertex3f(-1, 1, 0); /** 左下点 */ Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE0_ARB, 0.0f, 0.0f); Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE1_ARB, 0.0f, 0.0f); Gl.glVertex3f(-1, -1, 0); /** 右下点 */ Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE0_ARB, 1.0f, 0.0f); Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE1_ARB, 1.0f, 0.0f); Gl.glVertex3f(1, -1, 0); /** 右上点 */ Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE0_ARB, 1.0f, 1.0f); Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE1_ARB, 1.0f, 1.0f); Gl.glVertex3f(1, 1, 0); Gl.glEnd(); /**< 绘制结束 */ Gl.glPopMatrix(); /** 激活纹理0,并绑定纹理 */ Gl.glActiveTextureARB(Gl.GL_TEXTURE0_ARB); Gl.glEnable(Gl.GL_TEXTURE_2D); Gl.glBindTexture(Gl.GL_TEXTURE_2D, m_texture[2].ID[0]); /** 激活纹理1,并绑定纹理 */ Gl.glActiveTextureARB(Gl.GL_TEXTURE1_ARB); /** 如果多重纹理启用,则启用该纹理 */ if (multitexturing) Gl.glEnable(Gl.GL_TEXTURE_2D); else Gl.glDisable(Gl.GL_TEXTURE_2D); Gl.glBindTexture(Gl.GL_TEXTURE_2D, m_texture[3].ID[0]); Gl.glTranslatef(2.5f, 0, 0); Gl.glScalef(2.0f, 2.0f, 2.0f); Gl.glBegin(Gl.GL_QUADS); /** 左上点 */ Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE0_ARB, 0.0f, 1.0f); Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE1_ARB, 0.0f - wrap, 1.0f); Gl.glVertex3f(-1, 1, 0); /** 左下点 */ Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE0_ARB, 0.0f, 0.0f); Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE1_ARB, 0.0f - wrap, 0.0f); Gl.glVertex3f(-1, -1, 0); /** 右下点 */ Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE0_ARB, 1.0f, 0.0f); Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE1_ARB, 1.0f - wrap, 0.0f); Gl.glVertex3f(1, -1, 0); /** 右上点 */ Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE0_ARB, 1.0f, 1.0f); Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE1_ARB, 1.0f - wrap, 1.0f); Gl.glVertex3f(1, 1, 0); Gl.glEnd(); Gl.glFlush(); } } }