本文并不是一个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