首页 > 编程语言 >C#+OpenGL编程之OpenGL 纹理载入

C#+OpenGL编程之OpenGL 纹理载入

时间:2023-04-05 10:02:04浏览次数:32  
标签:Gl 1.0 glVertex3f OpenGL C# 0.0 TEXTURE 载入 GL


 本文基础:C#+OpenGL编程之环境搭建

载入一个模型,光秃秃的可不好,这课开始学习纹理载入,纹理载入需要注意的地方就是最好只载入一次纹理,否则容易影响性能。

C# 载入纹理要比C方便多了,问题在于C# 的GDI+不支持TGA载入,我就网上找了个类,这里请大家去原作者那里看了。

如需素材或C代码请参考原书资料下载http://down.51cto.com/data/201697

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 OpenGLTexture : Examplefirst
    {
        float rot = 0;
        TextureLoad texture2 = new TextureLoad(), texture1 = new TextureLoad();

        public OpenGLTexture()
            : base()
        {
            LoadTexture();///原则上材质只应该在初始化时候载入一次,否则会影响性能
            base.title = "第四章 OpenGl 纹理载入";
        }
        /** 载入纹理数据 */
        bool LoadTexture()
        {

            /** 载入位图文件 */
            if (texture1.Load(Path.Combine(Application.StartupPath, @"Image\image.bmp").ToString()) == false)                         /**< 载入位图文件 */
            {
                MessageBox.Show("无法载入");
                return false;
            }

            /** 载入TGA文件 */
            if (texture2.Load(Path.Combine(Application.StartupPath, @"Image\sphere.tga").ToString()) == false)                         /**< 载入TGA文件 */
            {
                MessageBox.Show("无法载入"); /**< 如果载入失败则弹出对话框 */
                return false;
            }

            /** 启用纹理映射 */
            Gl.glEnable(Gl.GL_TEXTURE_2D);

            return true;
        }

        /** 设置光源 */
        void SetLight()
        {
            /** 定义光源的属性值 */
            float[] LightAmbient = new float[] { 0.5f, 0.5f, 0.5f, 1.0f }; 	/**< 环境光参数 */
            float[] LightDiffuse = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };		/**< 漫射光参数 */
            float[] LightSpecular = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };	/**< 镜面光参数 */
            float[] LightPosition = new float[] { 0.0f, 0.0f, 2.0f, 1.0f };	/**< 光源位置 */

            /** 设置光源的属性值 */
            Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_AMBIENT, LightAmbient);		/**< 设置环境光 */
            Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_DIFFUSE, LightDiffuse);		/**< 设置漫射光 */
            Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_SPECULAR, LightSpecular);	/**< 设置漫射光 */
            Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_POSITION, LightPosition);	/**< 设置光源位置 */

            /** 启用光源 */
            Gl.glEnable(Gl.GL_LIGHTING);
            Gl.glEnable(Gl.GL_LIGHT1);
        }

        /// <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.glClearDepth(1.0f);
            Gl.glDepthFunc(Gl.GL_LEQUAL);
            Gl.glEnable(Gl.GL_DEPTH_TEST);

            //反锯齿
            Gl.glHint(Gl.GL_PERSPECTIVE_CORRECTION_HINT, Gl.GL_NICEST);

            Gl.glEnable(Gl.GL_NORMALIZE);
     
            Gl.glEnable(Gl.GL_NORMALIZE);
            /** 设置光源 */
            SetLight();

        }

        /// <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);
            rot =rot+ milliseconds * 10;

        }

        /** 用户自定义的卸载函数 */
        public new void Dispose()
        {
            base.Dispose();
            ///** 用户自定义的卸载过程 */
            texture1.FreeImage();              /** 释放纹理图像占用的内存 */
            Gl.glDeleteTextures(1, texture1.ID); /**< 删除纹理对象 */

            texture2.FreeImage();              /** 释放纹理图像占用的内存 */
            Gl.glDeleteTextures(1, texture2.ID); /**< 删除纹理对象 */

        }




        /** 绘制球体 */
        void DrawSphere()
        {
            Gl.glPushMatrix();
            Gl.glTranslatef(2.0f, 0.0f, -10.0f);
            Gl.glRotatef(rot, 0.0f, 1.0f, 1.0f);

            /** 指定纹理 */
            Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture2.ID[0]);

            Glu.GLUquadric sphere = Glu.gluNewQuadric();
            Glu.gluQuadricOrientation(sphere, Glu.GLU_OUTSIDE);
            Glu.gluQuadricNormals(sphere, Glu.GLU_SMOOTH);
            Glu.gluQuadricTexture(sphere, Gl.GL_TRUE);
            Glu.gluSphere(sphere, 1.5, 50, 50);
            Glu.gluDeleteQuadric(sphere);
            Gl.glPopMatrix();

        }

        /** 绘制木箱 */
        void DrawBox()
        {
            /** 设置材质属性 */
            float[] mat_ambient = new float[] { 0.8f, 0.8f, 0.8f, 1.0f };
            float[] mat_diffuse = new float[] { 0.8f, 0.8f, 0.8f, 1.0f };
            Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, mat_ambient);
            Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, mat_diffuse);

            Gl.glPushMatrix();
            Gl.glTranslatef(-2.0f, 0.0f, -10.0f);
            Gl.glRotatef(rot, 1.0f, 1.0f, 0.0f);

            /** 选择纹理 */
            Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture1.ID[0]);

            /** 开始绘制四边形 */
            Gl.glBegin(Gl.GL_QUADS);

            /// 前侧面
            Gl.glNormal3f(0.0f, 0.0f, 1.0f);								/**< 指定法线指向观察者 */
            Gl.glTexCoord2f(0.0f, 0.0f); Gl.glVertex3f(-1.0f, -1.0f, 1.0f);
            Gl.glTexCoord2f(1.0f, 0.0f); Gl.glVertex3f(1.0f, -1.0f, 1.0f);
            Gl.glTexCoord2f(1.0f, 1.0f); Gl.glVertex3f(1.0f, 1.0f, 1.0f);
            Gl.glTexCoord2f(0.0f, 1.0f); Gl.glVertex3f(-1.0f, 1.0f, 1.0f);

            /// 后侧面
            Gl.glNormal3f(0.0f, 0.0f, -1.0f);								/**< 指定法线背向观察者 */
            Gl.glTexCoord2f(1.0f, 0.0f); Gl.glVertex3f(-1.0f, -1.0f, -1.0f);
            Gl.glTexCoord2f(1.0f, 1.0f); Gl.glVertex3f(-1.0f, 1.0f, -1.0f);
            Gl.glTexCoord2f(0.0f, 1.0f); Gl.glVertex3f(1.0f, 1.0f, -1.0f);
            Gl.glTexCoord2f(0.0f, 0.0f); Gl.glVertex3f(1.0f, -1.0f, -1.0f);

            /// 顶面
            Gl.glNormal3f(0.0f, 1.0f, 0.0f);								/**< 指定法线向上 */
            Gl.glTexCoord2f(0.0f, 1.0f); Gl.glVertex3f(-1.0f, 1.0f, -1.0f);
            Gl.glTexCoord2f(0.0f, 0.0f); Gl.glVertex3f(-1.0f, 1.0f, 1.0f);
            Gl.glTexCoord2f(1.0f, 0.0f); Gl.glVertex3f(1.0f, 1.0f, 1.0f);
            Gl.glTexCoord2f(1.0f, 1.0f); Gl.glVertex3f(1.0f, 1.0f, -1.0f);

            /// 底面
            Gl.glNormal3f(0.0f, -1.0f, 0.0f);								/**< 指定法线朝下 */
            Gl.glTexCoord2f(1.0f, 1.0f); Gl.glVertex3f(-1.0f, -1.0f, -1.0f);
            Gl.glTexCoord2f(0.0f, 1.0f); Gl.glVertex3f(1.0f, -1.0f, -1.0f);
            Gl.glTexCoord2f(0.0f, 0.0f); Gl.glVertex3f(1.0f, -1.0f, 1.0f);
            Gl.glTexCoord2f(1.0f, 0.0f); Gl.glVertex3f(-1.0f, -1.0f, 1.0f);

            /// 右侧面
            Gl.glNormal3f(1.0f, 0.0f, 0.0f);								/**< 指定法线朝右 */
            Gl.glTexCoord2f(1.0f, 0.0f); Gl.glVertex3f(1.0f, -1.0f, -1.0f);
            Gl.glTexCoord2f(1.0f, 1.0f); Gl.glVertex3f(1.0f, 1.0f, -1.0f);
            Gl.glTexCoord2f(0.0f, 1.0f); Gl.glVertex3f(1.0f, 1.0f, 1.0f);
            Gl.glTexCoord2f(0.0f, 0.0f); Gl.glVertex3f(1.0f, -1.0f, 1.0f);

            /// 左侧面
            Gl.glNormal3f(-1.0f, 0.0f, 0.0f);								/**< 指定法线朝左 */
            Gl.glTexCoord2f(0.0f, 0.0f); Gl.glVertex3f(-1.0f, -1.0f, -1.0f);
            Gl.glTexCoord2f(1.0f, 0.0f); Gl.glVertex3f(-1.0f, -1.0f, 1.0f);
            Gl.glTexCoord2f(1.0f, 1.0f); Gl.glVertex3f(-1.0f, 1.0f, 1.0f);
            Gl.glTexCoord2f(0.0f, 1.0f); Gl.glVertex3f(-1.0f, 1.0f, -1.0f);
            Gl.glEnd();

            Gl.glPopMatrix();
        }
        /// <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();

            /** 绘制过程 */
            DrawSphere();
            DrawBox();

            /** 强制执行所有的OpenGl命令 */
            Gl.glFlush();
        }
    }
}



using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using Tao.Glfw;
using Tao.OpenGl;

namespace OpenGL
{
    /// <summary>
    /// 自制的纹理载入类 C# by 大师♂罗莊
    /// </summary>
    class TextureLoad : IDisposable
    {
        public int[] ID = new int[3];
        Bitmap image;
        public bool Load(String fileName)
        {
            ///原则上材质只应该在初始化时候载入一次,否则会影响性能
            if (image != null)
            {
                return true;
            }
            FileInfo file = new FileInfo(fileName);
            if (file.Exists == false)
            {
                MessageBox.Show("无法载入" + fileName);
                return false;
            }
            try
            {
                if (file.Extension.ToUpper() == ".TGA")
                {
                    ///C# 载入TGA 类,自行参考,这里不再列出
                    ImageTGA tga = new ImageTGA(fileName);
                    image = tga.Image;
                }
                else
                {
                    image = new Bitmap(fileName);
                }

            }
            catch (System.ArgumentException)
            {
                MessageBox.Show("无法载入" + fileName);
                return false;
            }

            if (image != null)
            {
                image.RotateFlip(RotateFlipType.RotateNoneFlipY);
                System.Drawing.Imaging.BitmapData bitmapdata;
                Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);

                ///Nearest Linear MipMapped三个纹理实现,本文暂时不考虑
                //bitmapdata = image.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                //Gl.glGenTextures(3, this.texture);

                 Create Nearest Filtered Texture
                //Gl.glBindTexture(Gl.GL_TEXTURE_2D, this.texture[0]);
                //Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);
                //Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST);
                //Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, (int)Gl.GL_RGB, image.Width, image.Height, 0, Gl.GL_BGR_EXT, Gl.GL_UNSIGNED_BYTE, bitmapdata.Scan0);
                 Create Linear Filtered Texture
                //Gl.glBindTexture(Gl.GL_TEXTURE_2D, this.texture[1]);
                //Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
                //Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
                //Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, (int)Gl.GL_RGB, image.Width, image.Height, 0, Gl.GL_BGR_EXT, Gl.GL_UNSIGNED_BYTE, bitmapdata.Scan0);
                 Create MipMapped Texture
                //Gl.glBindTexture(Gl.GL_TEXTURE_2D, this.texture[2]);
                //Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
                //Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR_MIPMAP_NEAREST);
                //Gl.gluBuild2DMipmaps(Gl.GL_TEXTURE_2D, (int)Gl.GL_RGB, image.Width, image.Height, Gl.GL_BGR_EXT, Gl.GL_UNSIGNED_BYTE, bitmapdata.Scan0);
                //image.UnlockBits(bitmapdata);

                /** 生成纹理对象名称 */
                Gl.glGenTextures(3, ID);

                /** 创建纹理对象 */
                Gl.glBindTexture(Gl.GL_TEXTURE_2D, ID[0]);

                /** 控制滤波 */
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_REPEAT);
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_REPEAT);

                bitmapdata = image.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                /** 创建纹理 */
                Glu.gluBuild2DMipmaps(Gl.GL_TEXTURE_2D, Gl.GL_RGB, image.Width,
                                  image.Height, Gl.GL_BGR_EXT, Gl.GL_UNSIGNED_BYTE,
                                  bitmapdata.Scan0);
                image.UnlockBits(bitmapdata);
            }
            return true;
        }

        public void FreeImage()
        {
            /** 释放内存 */
            if (image != null)
            {
                image.Dispose();
            }
        }
        public void Dispose()
        {
            FreeImage();
        }
    }
}



标签:Gl,1.0,glVertex3f,OpenGL,C#,0.0,TEXTURE,载入,GL
From: https://blog.51cto.com/u_696257/6170243

相关文章

  • [leetcode每日一题]4.5
    2427. 公因子的数目提示简单20相关企业给你两个正整数 a 和 b ,返回 a 和 b 的 公 因子的数目。如果 x 可以同时整除 a 和 b ,则认为 x 是 a 和 b 的一个 公因子 。 示例1:输入:a=12,b=6输出:4解释:12和6的公因子是1、2、3、6。示例2:输入:a=25,......
  • AltiumDesigner导入AutoCAD文件DXF,DWG格式
    这里有一篇关于导入DXF的文章,方法还可以。文章......
  • PAT Basic 1069. 微博转发抽奖
    PATBasic1069.微博转发抽奖1.题目描述:小明PAT考了满分,高兴之余决定发起微博转发抽奖活动,从转发的网友中按顺序每隔N个人就发出一个红包。请你编写程序帮助他确定中奖名单。2.输入格式:输入第一行给出三个正整数M(≤1000)、N和S,分别是转发的总量、小明决定的中奖间隔......
  • 动手深度学习pytorch
    <scriptsrc="http://latex.codecogs.com/latex.js"type="text/javascript"></script>引言 一:过去⼗年中取得巨⼤进步的想法1.如dropout(Srivastavaetal.,2014),有助于减轻过拟合的危险。这是通过在整个神经⽹络中应⽤噪声注⼊(Bishop,1995)来实现的,出于训练⽬的,⽤......
  • ChatGPT使用技巧
    清晰沟通的原则编写有效的ChatGPT提示的关键挑战之一是避免行话和歧义。行话或专业语言可能会让不熟悉主题的用户感到困惑或不清楚,而歧义可能会导致误解或误解。为了帮助确保您的提示清晰易懂,请记住以下一些提示:清晰:清晰简洁的提示将有助于确保ChatGPT了解手头的主题或任务......
  • 【花雕学AI】4月5日,ChatGPT中国财经背景分析:昨天沪指重返3300点,这说明了什么?
        附录:一、ChatGPT是一个可以和你聊天的人工智能程序,它可以用文字回答你的问题,也可以根据你的提示写出文章、歌词、代码等内容。ChatGPT是由一个叫OpenAI的机构开发的,它使用了一种叫做GPT的技术,这种技术可以让它从互联网上学习大量的文字信息,然后根据文字之间......
  • ChatGPT推荐最常用的自动化测试、性能、安全测试工具!
    ChatGPT是一种当前被广泛关注的人工智能技术,它具备生成自然语言的能力,能够完成一些简单的文本生成、对话交互等任务。ChatGPT算法的出现,打破了以前自然语言处理的瓶颈,使得机器具备了更加贴合人类想法的表达能力,也让人类在处理海量自然语言数据面前得到了很大的帮助。而ChatGPT也......
  • 【花雕学AI】4月5日,ChatGPT新闻背景分析:马克龙和冯德莱恩组团访华
       附录:一、ChatGPT是一个可以和你聊天的人工智能程序,它可以用文字回答你的问题,也可以根据你的提示写出文章、歌词、代码等内容。ChatGPT是由一个叫OpenAI的机构开发的,它使用了一种叫做GPT的技术,这种技术可以让它从互联网上学习大量的文字信息,然后根据文字之间的关联......
  • 2023.4.5 网络最大流 Dinic算法
    网络最大流Dinic算法省选爆了qwq题目描述给出一个网络图,以及其源点和汇点,求出其网络最大流。网络流,就像水在一个水渠构成的网络中流一样,源点有无限的水,每条边有最大流量限制,求流到汇点的最大流量。更菜一点的EK算法自行了解,此处我们用dinic算法解决问题。这些网络流算法的......
  • cxgrid行内编辑按钮
    cxgrid行内编辑按钮在每行的数据最后一列显示一个按钮,点击按钮删除对应的数据。使用cxGrid能完美实现。1、设置按钮列的properties是buttonedit2、设置properties下的属性 viewStyle=vsButtonsAutoWidth3、设置Options中的 ShowEditButtons=isebAlways4、点击properties下......