当前位置: 首页 > 工具软件 > Tao Framework > 使用案例 >

c# opengl tao

路奇
2023-12-01

 本文并不是一个Opengl起步教程,本系列教程参考《Opengl 游戏编程》一书


   对于OPENGL,C#有多个库可供选择,http://www.opengl.org/resources/bindings/,自己可以去查询,本系列教程使用The Tao Framework+.net 2.0,作为开发平台

  使用版本:taoframework-2.1.0


  搭建环境有两个方式,一个类似控制台程序 等同于C int main(int argc, char** argv) 。

  原书使用win32方式,我们使用winform项目搭建。

  启动VS,新建一个C# WindowsFormsApplication,然后新建一个class

  引用taoframework 的Tao.OpenGl、Tao.Glfw 、Tao.Platform.Windows


using System;
using System.Collections.Generic;
using System.Text;
using Tao.Glfw;
using Tao.OpenGl;

namespace OpenGL
{
    /// <summary>
    /// 第二章 Opengl程序框架 C# by 大师♂罗莊
    /// </summary>
    class Examplefirst : IDisposable
    {
        internal String title = "第二章 Opengl程序框架";
        ///窗口大小
        internal int windowWidth, windowHeight;
        //鼠标位置
        internal int mouseX, mouseY;
        //是否运行
        internal bool isRunning;
        //当前帧
        internal double currentTime, startTime;

        public Examplefirst()
        {
          // 初始化 GLFW
            Glfw.glfwInit();

            // 创建 OpenGL window
            if (Glfw.glfwOpenWindow(640, 480, 0, 0, 0, 0, 0, 0, Glfw.GLFW_WINDOW) == Gl.GL_FALSE)
            {
                //不成功,退出
                Glfw.glfwTerminate();
                return;
            }
            Glfw.glfwSetWindowTitle(title);

            // 接受按键输入
            Glfw.glfwEnable(Glfw.GLFW_STICKY_KEYS);

            //禁用垂直同步 vertical sync
            Glfw.glfwSwapInterval(0);

            // 主循环
            isRunning = true;
        }
        /// <summary>
        /// 入口点
        /// </summary>
        public void Run()
        {



          

            //使用循环,和原书一致
            while (isRunning)
            {
                // 获得鼠标位置
                Glfw.glfwGetMousePos(out mouseX, out mouseY);

                //获得时间,将来用来做动画
                currentTime = Glfw.glfwGetTime();

                // 获得当前窗口大小,因为是窗口模式,用户可以改变大小
                Glfw.glfwGetWindowSize(out windowWidth, out windowHeight);

                //防止除零问题
                windowHeight = windowHeight > 0 ? windowHeight : 1;

                InitGL(windowWidth, windowHeight);
                DrawGLScene(mouseX, currentTime);
                // 显存交换
                Glfw.glfwSwapBuffers();
                Update((float)(currentTime - startTime));
                startTime = currentTime;
            }

            // 结束
            Glfw.glfwCloseWindow();
            Glfw.glfwTerminate();
        }


        /// <summary>
        /// 更新用
        /// </summary>
        public virtual void Update(float milliseconds)
        {
            //按下ESC结束
            isRunning = ((Glfw.glfwGetKey(Glfw.GLFW_KEY_ESC) == Glfw.GLFW_RELEASE) &&
                Glfw.glfwGetWindowParam(Glfw.GLFW_OPENED) == Gl.GL_TRUE);
        }

        /// <summary>
        /// 原书的初始化方法,C# by 大师♂罗莊
        /// </summary>
        /// <param name="windowWidth">窗口宽</param>
        /// <param name="windowHeight">窗口高</param>
        /// <returns></returns>
        Boolean InitGL(int windowWidth, int windowHeight)
        {
            // 设置视口 viewport
            Gl.glViewport(0, 0, windowWidth, windowHeight);

            //启用阴影平滑
            Gl.glShadeModel(Gl.GL_SMOOTH);

            //启用反走样
            Gl.glHint(Gl.GL_PERSPECTIVE_CORRECTION_HINT, Gl.GL_NICEST);
            // 重置黑色背景
            Gl.glClearColor(0, 0, 0, 0);
            Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);


            // 设置投影模式 projection matrix
            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glLoadIdentity();
            iniView(windowWidth, windowHeight);
            return true;
        }
        /// <summary>
        /// 初始化视口投影,本例子没有采用原书例子,自定义的视口
        /// </summary>
        public virtual void iniView(int windowWidth, int windowHeight)
        {
            Glu.gluPerspective(65, windowWidth / (double)windowHeight, 1, 100);
            // 选择模型观察矩阵 modelview matrix
            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            //重置模型观察矩阵
            Gl.glLoadIdentity();
            Glu.gluLookAt(0, 1, 0,  // 眼睛位置
                0, 20, 0,           // 观察点
                0, 0, 1);           // 怎么看
        }

        /// <summary>
        /// 原书的绘制方法 C# by 大师♂罗莊
        /// <param name="mouseX">鼠标位置</param>
        /// <param name="currentTime">当前帧</param>
        /// </summary>
        public virtual void DrawGLScene(int mouseX, double currentTime)
        {


            // 画三角形
            Gl.glTranslatef(0, 14, 0);
            Gl.glBegin(Gl.GL_TRIANGLES);
            Gl.glColor3f(1, 0, 0);
            Gl.glVertex3f(-5, 0, -4);
            Gl.glColor3f(0, 1, 0);
            Gl.glVertex3f(5, 0, -4);
            Gl.glColor3f(0, 0, 1);
            Gl.glVertex3f(0, 0, 6);
            Gl.glEnd();
        }


        public void Dispose()
        {
            Glfw.glfwCloseWindow();
            Glfw.glfwTerminate();
        }
    }
}




如果没有opengl基础,要看懂上面例子比较困难。这里要求大家学习Opengl基础了。原书用了22-70页讲述框架搭建,你看我们才160行代码。。。

  

  首先我们要理解,我们用win32方式非命令行方式,需要大家学习win32 编程,知道我们使用消息循环,初始化 GLFW就采用这种方式。

   

  接下来我们需要初始化OpenGL变换:

  物体坐标-》模型视点矩阵-》投影矩阵-》视口变换-》屏幕

  

  为了以后教程方便,或者说我想节省代码(XXXX)。。

  我把上述过程拆分为

  InitGL 初始化OpenGL,基本不会变动的

  iniView 初始化 投影矩阵和模型视点矩阵

  DrawGLScene 绘制场景

  Update 数据更新

  这几个方法,都是用virtual 函数,将来我们可以通过重载修改里面的方法实现新场景。


  然后把winform 启动类Program.cs修改为


using System.Collections.Generic;
using System.Text;
using System;

namespace OpenGL
{
    class Program
    {
         [STAThread]
        static void Main(string[] args)
        {
            Examplefirst main = new Examplefirst();
            main.Run();

   
        }
    }
}



也就是我们的Class 就好了。


  但上述方法我们是无法启动程序的,会报缺少glfw.dll,这是因为taoframework封装C代码或者说非托管代码,我们还需要把本地代码glfw.dll拷贝到程序目录才可以运行。

  大家要注意的是,本机代码分X86和X64,也就是32位和64位,taoframework自带的是32位版本,这里有两个办法:

  1、将VS 项目 build- platform target的Any Cpu 修改为x86,然后使用taoframework自带的glfw.dll

  或者

  去glfw官方下载编译好的X86和X64版本,然后制作两个平台的EXE。


  OpenGl参考资料
1.      《 OpenGL Reference Manual 》, OpenGL 参考手册
2.      《 opengl 游戏编程》作者:徐明亮,卢红星,王琬编著,机械工业出版社, 本系列教程代码均参照此书,代码下载http://down.51cto.com/data/201697
3.         《win32 OpenGL编程 》   一个大牛的博客     http://blog.csdn.NET/vagrxie/article/category/628716/3
4.             《OpenGL函数思考 》   里面有很多OpenGL函数的通俗解释     http://blog.csdn.Net/shuaihj





 类似资料: