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