本文基础:C#+OpenGL编程之再见小桃子(The Tao Framework)

 以前几个教程我们讲解了老式OpenGL,今天,你将学习新式OpenGL(OpenGL 3和4)。

 教程原文地址:http://www.opengl-tutorial.org/beginners-tutorials/tutorial-2-the-first-triangle/


  原文是用C方式编写的,我改了改,做出类来,主要可以防止很多新手只会创造,不会Dispose。

  

using System;
using OpenGLDotNet;
using System.Runtime.InteropServices;
namespace OpenGLTK
{

	/// <summary>
	/// 用类封装了三角形顶点,可以防止新手不会释放
	///  C# by 大师♂罗莊
	/// </summary>
    class openGL3Vertex : IDisposable
    {

        IntPtr pName;
        uint[] vertexbuffer;
        uint[] VertexArrayID;
        public void load(float[] g_vertex_buffer_data)
        {
            int size = g_vertex_buffer_data.Length * Marshal.SizeOf(typeof(Single));
            pName = Marshal.AllocHGlobal(size);//注意:Marshal.AllocHGlobal(Int32 cb)中的参数cb是分配的字节数
            Marshal.Copy(g_vertex_buffer_data, 0, pName, g_vertex_buffer_data.Length);


            VertexArrayID = new uint[1];
            GL.GenVertexArrays(1, VertexArrayID);
            GL.BindVertexArray(VertexArrayID[0]);

            // 声明 vertex buffer
            vertexbuffer = new uint[1];

            // 生成1个vertexbuffer
            GL.GenBuffers(1, vertexbuffer);

            // 绑定
            GL.BindBuffer(GL.GL_ARRAY_BUFFER, vertexbuffer[0]);

            //将数组送给OpenGL
            GL.BufferData(GL.GL_ARRAY_BUFFER, size, pName, GL.GL_STATIC_DRAW);

        }
        public virtual void Draw()
        {
            GL.EnableVertexAttribArray(0);
            GL.BindBuffer(GL.GL_ARRAY_BUFFER, vertexbuffer[0]);
            GL.VertexAttribPointer(
               0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
               3,                  // 大小
               GL.GL_FLOAT,           // 类型
               false,           // 是否normalized?
               0,                  // stride
              (IntPtr)0
            );

            // 画三角形
            GL.DrawArrays(GL.GL_TRIANGLES, 0, 3); //从顶点 0开始; 3顶点 -> 1三角形
        
            GL.DisableVertexAttribArray(0);
        }

        public void Dispose()
        {
            Marshal.FreeHGlobal(pName);
            GL.DeleteBuffers(1, vertexbuffer);
            GL.DeleteVertexArrays(1, VertexArrayID);
        }
    }
}


using OpenGLDotNet;
using System;


namespace OpenGLTK
{
    /// <summary>
    ///  C# by 大师♂罗莊
    /// 你将学习新式OpenGL(OpenGL 3和4),而多数网上教程还在讲『老式OpenGL』(OpenGL 1和2)。
    /// 搭建环境要求:
    /// 1、显卡要支持Opengl3.3 类似Vmware 虚拟机是无法显示三角形
    /// 2、  GLConfig.Init(3, 3, title, 25, 25, 1024, 768);
    /// 3、freeglut.dll要新,我用的是2.8.1 自己编译的,tao框架自带那个太老了,你用那个的话也是无法显示三角形
    /// </summary>
    class OpenGL3tutorial2 : Examplefirst
    {
    	
    	  String title = "Opengl3程序之第一个三角形";
        openGL3Vertex Vertex = new openGL3Vertex();
        // An array of 3 vectors which represents 3 vertices
        static float[] g_vertex_buffer_data = new float[] {
   -1.0f, -1.0f, 0.0f,
   1.0f, -1.0f, 0.0f,
   0.0f,  1.0f, 0.0f,
};
        public OpenGL3tutorial2()
            : base()
        {
            Vertex.load(g_vertex_buffer_data);
            //可以用这个检查OpenGL初始化信息 GLConfig.LogDumpToConsole();
             GLUT.SetWindowTitle(title);
        }

        /// <summary>
        /// 重载,使用Draw方法绘图
        /// </summary>
        /// <param name="mouseX"></param>
        /// <param name="currentTime"></param>
        public override void DrawGLScene()
        {
            Draw();
            GLUT.SwapBuffers();
        }
      


        /** 用户自定义的卸载函数 */
        public override void Dispose()
        {
          Vertex.Dispose();
            base.Dispose();
          
        }

        /** 绘制函数 */
        void Draw()
        {


            // 重置蓝色背景
            GL.ClearColor(0.0f, 0.0f, 0.4f, 0.0f);
            GL.Clear(GL.GL_COLOR_BUFFER_BIT);
            GL.Color3f(1, 0, 0);
            Vertex.Draw();

        }
    }
}


  这样的程序是显示一个黑漆漆的窗口,无法显示三角形的。

  为什么?

  大家都知道,windows 只支持OpenGL 1.1,为了要支持更高版本的OpenGL,需要扩展库。

  对于C来说,可以用glext,官方是用glew。

  我们的OpenGL DotNet 已经做了很多工作,就在GLConfig.Init这里面,大家有兴趣可以查看源代码研究下。

  所以我们需要修改基类,Examplefirst,默认GLConfig.Init我使用了0,0, 这将保证最大兼容性,现在需要修改为OPenGL 3.3

 

public Examplefirst()
        {
            GLConfig.Init(3, 3, title, 25, 25, 1024, 768);
            GL.Init(true);
            GLUT.KeyboardFunc(Keyboard);
            GLUT.MouseFunc(Mouse);
            GLUT.IdleFunc(Idle);
            GLUT.ReshapeFunc(Reshape);
            GLUT.MotionFunc(Motion);
            GLUT.DisplayFunc(Display);
         }


  经过这步,很多偷懒的同学估计还只能看到一个蓝色背景,没有三角形,因为tao 自带那个freeglut.dll太老了,自己去官方下载http://freeglut.sourceforge.net/

编译一个DLL,然后就可以了。

  我的机器结果:

  Intel HD 4000  显示一个白色的三角形

  GT 650m 显示一个黑色的三角形

  Vmware SVGA  3D 无法显示