C#+OpenGL编程之OpenGL 多重纹理

 本文基础: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();
        }
    }
}

你可能感兴趣的:(C#,OpenGL,多重纹理)