本文基础: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 无法显示