国内关于CsGL的资料一直非常少,最近对这方面有些关注,随便写点东西吧,就当是学习记录了。
对于我这样的初学者而言不能苛求太多,如果有错误的话希望大家指出。
-0- 关于CsGL
CsGL是openGL在.NET下的包装。
可以在SF.NET上下载:http://csgl.sourceforge.net/
目前关于CsGL的开发基本上已经停止,官方主页上的说法是认为CsGL对大多数应用而言已经足够稳定了。目前CsGL开发工作基本上集中在Example程序的撰写:
详情见:http://www.randyridge.com/Tao/Default.aspx
-1- Hello, CsGL
在这里首先实现一个最简单的CsGL应用程序:一个旋转的立方体。
下面的步骤其实基本上就是
http://www.c-sharpcorner.com/Code/2002/Oct/SimpleOpenGL.asp
的复述了,只不过不是一对一的翻译而已。
首先建立一个C# WIndows应用程序。在引用中添加csgl.dll。
首先在主窗口创建一个新的线程用来更新窗口
引入名字空间
using System.Threading;
在主窗口类内声明如下私有成员:
private static Thread thrDraw;
而后定义一个私有类成员函数
private void OpenGL_Start()
{
while(true)
{
this.view.Refresh();
}
}
在Form_load方法中添加如下代码,启动线程:
ThreadStart start = new ThreadStart(OpenGL_Start);
thrDraw= new Thread(start);
thrDraw.Start();
在主窗口的Dispose方法中退出线程
thrDraw.Abort();
然后创建一个从OpenGLControl继承下来的类:MyView
using CsGL.OpenGL;
public class MyView : OpenGLControl
{
public MyView() : base(){}
/// <summary>
/// 执行OpenGL初始化
/// </summary>
protected override void InitGLContext()
{
base.InitGLContext ();
GL.glShadeModel(GL.GL_SMOOTH); // Enable Smooth Shading
GL.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
GL.glClearDepth(1.0f); // Depth Buffer Setup
GL.glEnable(GL.GL_DEPTH_TEST); // Enables Depth Testing
GL.glDepthFunc(GL.GL_LEQUAL); // The Type Of Depth Testing To Do
GL.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
// TODO: 在此添加其他初始化动作,比如建立显示列表
}
/// <summary>
/// 窗口大小改变时
/// </summary>
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged (e);
Size s = Size;
// 计算窗口的纵横比
double aspect_ratio = (double)s.Width / (double) s.Height;
GL.glMatrixMode( GL.GL_PROJECTION ); // 设置当前为投影矩阵
GL.glLoadIdentity(); // 重置投影矩阵
GL.gluPerspective( 45.0f, aspect_ratio, 0.1f, 100.0f);
GL.glMatrixMode( GL.GL_MODELVIEW ); // 设置当前为模型视图矩阵
GL.glLoadIdentity(); // 重置模型视图矩阵
}
}
第三步,创建要绘画的Cube类
using CsGL.OpenGL;
public class Cube
{
private const int CUBE = 1;
private float fRotate;
public void Cube(){}
/// <summary>
/// 创建显示列表
/// </summary>
public void glConstructList()
{
GL.glNewList(CUBE, GL.GL_COMPILE); // Start With The box Display List
GL.glBegin(GL.GL_QUADS); // Start Drawing Quads
// Bottom Face
GL.glVertex3f(-1.0f, -1.0f, -1.0f);
GL.glVertex3f( 1.0f, -1.0f, -1.0f);
GL.glVertex3f( 1.0f, -1.0f, 1.0f);
GL.glVertex3f(-1.0f, -1.0f, 1.0f);
// Front Face
GL.glVertex3f(-1.0f, -1.0f, 1.0f);
GL.glVertex3f( 1.0f, -1.0f, 1.0f);
GL.glVertex3f( 1.0f, 1.0f, 1.0f);
GL.glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
GL.glVertex3f(-1.0f, -1.0f, -1.0f);
GL.glVertex3f(-1.0f, 1.0f, -1.0f);
GL.glVertex3f( 1.0f, 1.0f, -1.0f);
GL.glVertex3f( 1.0f, -1.0f, -1.0f);
// Right face
GL.glVertex3f( 1.0f, -1.0f, -1.0f);
GL.glVertex3f( 1.0f, 1.0f, -1.0f);
GL.glVertex3f( 1.0f, 1.0f, 1.0f);
GL.glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
GL.glVertex3f(-1.0f, -1.0f, -1.0f);
GL.glVertex3f(-1.0f, -1.0f, 1.0f);
GL.glVertex3f(-1.0f, 1.0f, 1.0f);
GL.glVertex3f(-1.0f, 1.0f, -1.0f);
GL.glEnd(); // Done Drawing Quads
GL.glEndList(); // Done Building The box Display List
}
/// <summary>
/// 绘制方框
/// </summary>
public void glDraw()
{
GL.glTranslatef(0.0f,0.0f, 6.0f);
GL.glRotatef(90f, 1.0f, 1.0f, 1.0f);
GL.glRotatef(fRotate, 1.0f, 1.0f, 1.0f);
fRotate += 0.5f;
GL.glCallList(CUBE);
}
}
OK,到现在为止,要做的基本上就结束了,接下来让立方体显示出来:
在MyView类中加入私有域成员:
private Cube cube;
在构造函数中初始化之:
cube = new Cube();
而InitGLContext()添加一行,建立显示列表:
cube.glConstructList();
最后增加一个重载成员函数负责绘制:
public override void glDraw()
{
GL.glClear( GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT ); // 清理视窗以及深度缓存
GL.glLoadIdentity(); // 重置当前模型视图矩阵
// 绘图
cube.glDrawCube();
this.SwapBuffer(); // 交换缓存
}
最后一步,在主窗口类中增加私有成员变量
private MyView view;
在InitializeComponent()中加入view初始化:
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.view = new MyView();
this.SuspendLayout();
//
// view
//
this.view.Dock = System.Windows.Forms.DockStyle.Fill;
this.view.Location = new System.Drawing.Point(0, 0);
this.view.Name = "view";
this.view.Size = new System.Drawing.Size(292, 266);
this.view.TabIndex = 0;
//
// MainWindow
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.view);
this.Name = "MainWindow";
this.Text = "Simple CsGL App";
this.Load += new System.EventHandler(this.MainWindow_Load);
this.ResumeLayout(false);
}
大功告成。