openTK学习
简介
the Open Tool Kit (OpenTK), 是对 OpenGL、OpenAL、OpenCL 的跨平台的封装,使用 C# 编写,它可以用在Mono、dotNet的语言:c#、VB、C++/CLI、F#、Boo等。
什么是Mono
参考:http://baike.baidu.com/subview/26639/9339264.htm?fr=aladdin
Mono是一个由Novell公司(由Ximian发起,并由Miguel de
lcaza领导的,一个致力于开创.NET在Linux上使用的开源工程。它包含了一个C#语言的编译器,一个CLR的运行时,和一组类库,并实现了
ADO NET和ASP NET。能够使得开发人员在Linux用C#开发程序。)主持的项目.该项目的目标是创建一系列符合标准ECMA
(Ecma-334和Ecma-335)的.Net 工具, 包括C #编译器和共同语言(CL 即 Common
Language)执行平台(Platform).与微软的.Net不同,
Mono项目不仅可以运行于Windows系统内,还可以运行于Linux, FreeBSD, Unix, Mac OS X和Solaris.
什么是C++/CLI
参考:http://baike.baidu.com/link?url=QPwZ5Jga7wKJJKn_NWkbvIucYtgvCHtZ3UZ9sRKD7i-eNGXg8m0nYpWVNSyt0yjQ
简而言之就是如何用C++在·NET中编程
什么是OpenAL
参考:http://baike.baidu.com/view/1355367.htm?fr=aladdin
是开源的跨平台音效API
什么是OpenCL
参考:http://baike.baidu.com/view/2056591.htm
是第一个面向异构系统通用目的并行编程的开放式、免费标准,也是一个统一的编程环境
使用
环境
dotNet IDE可以使用Visual Studio或 MonoDevelop http://monodevelop.com/Download
添加OpenTK.dll:右键“Project”,选择“Add Reference”,找到OpenTK.dll并添加它。
Windows.Forms+GLControl
参考:http://www.opentk.com/doc/chapter/2/glcontrol
向工具箱中添加GLControl控件
在工具箱的空白处右键,选择“Choose Item……”,浏览到OpenTK.GLControl.dll,添加。
创建顺序
he fact that glControl1
'sGLContext
is created in runtime is important to remember however, since you cannot
access or changeglControl1
's properties reliably until theGLContext
has been created. The same is true for anyGL.*
commands (orGlu
for that matter!).
1.运行Windows.Form的构造函数
2.加载form的事件
3.加载GLControl的事件,OK to touch glControl/GL
4.运行事件处理函数 ,ny event handler may touch glControl/GL
.
解决这个问题的一种方法是定义bool loaded=false;在GLControl加载时设置为true。
- using OpenTK.Graphics;
- using OpenTK.Graphics.OpenGL;
- public partial class Form1 : Form
- {
- bool loaded = false;
- public Form1()
- {
- InitializeComponent();
- }
- private void glControl1_Load(object sender, EventArgs e)
- {
- loaded = true;
- }
- }
由OpenTK还没有开发GLControl.Load事件,所以可以使用Form.Load事件
然后在你想使用glControl/GL的事件处理函数中检查loaded
- private void glControl1_Resize(object sender, EventArgs e)
- {
- if (!loaded)
- return;
- }
在VS中事件处理函数是很简单的:
1.在Designer中选择GLControl
2.在属性框中选择事件
3.在相应的事件中设置处理函数
- private void glControl1_Paint(object sender, PaintEventArgs e)
- {
- if (!loaded) // Play nice
- return;
- GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
- glControl1.SwapBuffers();
- }
视口初始
- private void glControl1_Load(object sender, EventArgs e)
- {
- loaded = true;
- GL.ClearColor(Color.SkyBlue);
- SetupViewport();
- }
- private void SetupViewport()
- {
- int w = glControl1.Width;
- int h = glControl1.Height;
- GL.MatrixMode(MatrixMode.Projection);
- GL.LoadIdentity();
- GL.Ortho(0, w, 0, h, -1, 1); // Bottom-left corner pixel has coordinate (0, 0)
- GL.Viewport(0, 0, w, h); // Use all of the glControl painting area
- }
键盘输入
有两种常用的方法:(1)使用Windows.Forms的按键事件(2)使用OpenTK的KeyboardDevice。
glControl1
is not painted all the time,操作系统的窗口管理器会确保绘制事件尽可能少的发生,一般只有在resize、窗口模糊等情况下才会触发绘制事件。如果我们想手动调用重绘,使用Invalidate()
- private void glControl1_KeyDown(object sender, KeyEventArgs e)
- if (!loaded)
- return;
- if (e.KeyCode == Keys.Space)
- {
- x++;
- glControl1.Invalidate();
- }
窗口大小的改变
当GLControl的大小发生变化,我们需要更新的是viewport和projection matrix。
如果我们从右下角缩小窗口时,并不会解发重绘,这是因为窗口管理器认为(0,0)像素还存在(所以如果从左上角缩小就会重绘),解决的方法就是调用Invalidate()
- private void glControl1_Resize(object sender, EventArgs e)
- {
- SetupViewport();
- glControl1.Invalidate();
- }
添加动画
有两种方法:(1)添加一个Timer 控件,使用的其Tick事件(2)使用Thread。
这里使用第三种方式,使用Windows.Forms的Application.idle事件
- private void glControl1_Load(object sender, EventArgs e)
- {
- loaded = true;
- GL.ClearColor(Color.SkyBlue);
- SetupViewport();
- Application.Idle += Application_Idle; // press TAB twice after +=
- }
- void Application_Idle(object sender, EventArgs e)
- {
- }
当窗口比较大时,渲染(render)比较慢
原因是窗口的3d rendering比full-screen rendering一般要慢。那么可以使用一种frame-rate independent animation的技术,思想很简单:根据当前的渲染速度调整变化量,比如旋转量(渲染慢的使用的量大)。可以使用StopWatch来测量一个frame的渲染时间。StopWatch的用法:
- Stopwatch sw = new Stopwatch();
- sw.Start();
- MyAdvancedAlgorithm();
- sw.Stop();
- double milliseconds = sw.Elapsed.TotalMilliseconds;
(不要使用DataTime.Now,因为它的大小是10ms级的,和frame的渲染时间是一个数量级)
- Stopwatch sw = new Stopwatch(); // available to all event handlers
- private void glControl1_Load(object sender, EventArgs e)
- {
- ...
- sw.Start(); // start at application boot
- }
- float rotation = 0;
- void Application_Idle(object sender, EventArgs e)
- {
- // no guard needed -- we hooked into the event in Load handler
- sw.Stop(); // we've measured everything since last Idle run
- double milliseconds = sw.Elapsed.TotalMilliseconds;
- sw.Reset(); // reset stopwatch
- sw.Start(); // restart stopwatch
- // increase rotation by an amount proportional to the
- // total time since last Idle run
- float deltaRotation = (float)milliseconds / 20.0f;
- rotation += deltaRotation;
- glControl1.Invalidate();
- }
FPS计数器
我们怎么知道1s已经过去了呢?
- void Application_Idle(object sender, EventArgs e)
- {
- double milliseconds = ComputeTimeSlice();
- Accumulate(milliseconds);
- Animate(milliseconds);
- }
- private double ComputeTimeSlice()
- {
- sw.Stop();
- double timeslice = sw.Elapsed.TotalMilliseconds;
- sw.Reset();
- sw.Start();
- return timeslice;
- }
- float rotation = 0;
- private void Animate(double milliseconds)
- {
- float deltaRotation = (float)milliseconds / 20.0f;
- rotation += deltaRotation;
- glControl1.Invalidate();
- }
- double accumulator = 0;
- int idleCounter = 0;
- private void Accumulate(double milliseconds)
- {
- idleCounter++;
- accumulator += milliseconds;
- if (accumulator > 1000)
- {
- label1.Text = idleCounter.ToString();
- accumulator -= 1000;
- idleCounter = 0; // don't forget to reset the counter!
- }
- }
使用多个GLControl
假如说我们有glCtrl1和glCtrl2,想要在Paint事件处理函数中使用它们,具体看代码:
- private void glCtrl1_Paint(object sender, PaintEventArgs e)
- if (!loaded)
- return;
- glCtrl1.MakeCurrent(); // Ohh.. It's that simple?
- GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
- ...
- }
尽管每个GLControl有它们自己的GraphicsContext,OpenTK默认是共享OpenGL资源的。你也可以禁止这个行为,能过设置属性GraphicsContext.ShareContexts。
参考:http://www.cnblogs.com/beginor/archive/2009/10/17/1585040.html
openTK学习的更多相关文章
- [转]OpenTK学习笔记(1)-源码、官网地址
OpenTK源码下载地址:https://github.com/opentk/opentk OpenTK使用Nuget安装命令:OpenTK:Install-Package OpenTK -Versi ...
- OpenTK学习笔记(3)-你好!窗体!
参考:http://dreamstatecoding.blogspot.com/2017/01/opengl-4-with-opentk-in-c-part-1.html http://www.cnb ...
- OpenTK学习笔记:C#的中开发OpenGL程序的4种开源封包库SharpGL、CsGL、OpenTK、Tao框架的简单对比
最近要在C#的语言环境下开发OpenGL程序,参考了网上的博客论坛http://www.cnblogs.com/hanyonglu/archive/2012/06/12/2546581.html,总结 ...
- OpenTK学习笔记(1)-源码、官网地址
OpenTK源码下载地址:https://github.com/opentk/opentk OpenTK使用Nuget安装命令:OpenTK:Install-Package OpenTK -Versi ...
- OpenTK学习笔记(2)-工作窗口的三种方法创建方法(winfrom窗体控件形式创建)
参考资料: https://social.msdn.microsoft.com/Forums/zh-TW/1b781685-c670-4338-953d-1957a8f24a66/opentkglco ...
- OpenTK学习笔记(2)-工作窗口的三种方法创建方法(winfrom下类的形式创建)
参考资料: https://www.codeproject.com/Articles/1167212/OpenGL-with-OpenTK-in-Csharp-Part-Initialize-the- ...
- OpenTK学习笔记(2)-工作窗口的三种方法创建方法(控制台)
参考资料: 控制台下类的形式创建:http://www.cnblogs.com/podolski/p/7406628.html 总结: 一.控制台下类的形式创建 1.新建控制台应用 2.连网执行Nug ...
- OpenTK学习笔记
OpenGL定义 OpenGL被定义为"图形硬件的一种软件接口".实质上是3D图形和模型库,具有高度可移植性,具有非常快的速度. OpenGL架构 术语pipeline常用于阐述彼 ...
- GLSL着色语言学习。橙皮书第一个例子GLSL+OpenTK+F#的实现。
Opengl红皮书有选择的看了一些,最后的讲着色语言GLSL的部分看的甚为不理解,然后找到Opengl橙皮书,然后就容易理解多了. 在前面,我们或多或少接触到Opengl的处理过程,只说前面一些处理, ...
随机推荐
- python中 in, any 和 all用法
in if x == 1 or y == 1 or z == 1: print('passed') if 1 in (x, y, z): print('passed') any if x or y o ...
- 基于 <tx> 和 <aop> 命名空间的声明式事务管理
环境配置 项目使用SSH架构,现在要添加Spring事务管理功能,针对当前环境,只需要添加Spring 2.0 AOP类库即可.添加方法: 点击项目右键->Build Path->Add ...
- ms sqlserver数据库主文件特别大怎么办
因为项目中需要复制数据库,作为外网测试的数据库,但是数据库特别大,复制特别费劲,即使只复制主文件,主文件也特别大. 然后百度了下,发现数据库有个收缩功能,数据库右键——任务——收缩,可以对数据库进行收 ...
- 【bzoj3083】遥远的国度 树链剖分+线段树
题目描述 描述zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要zcwwzdjn ...
- 网络流 24 题汇总(LOJ 上只有 22 题???)
太裸的我就不放代码了...(黑体字序号的题表示值得注意) 1.搭配飞行员 [LOJ#6000] 二分图最大匹配. 2.太空飞行计划 [LOJ#6001] 最小割常规套路.输出方案.(注:这题换行符要用 ...
- [国家集训队][bzoj2038] 小Z的袜子 [莫队]
题面: 传送门 思路: 又是一道标准的莫队处理题目,但是这道题需要一点小改动:求个数变成了求概率 我们思考:每次某种颜色从i个增加到i+1个,符合要求的情况多了多少? 原来的总情况数是i*(i-1)/ ...
- SQL死锁
我们操作数据库大量数据时,可能会出现死锁现象. 所谓死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统 ...
- Chrome 浏览器访问 Google 学术出现问题 “but your computer or network may be sending automated queries. ”
问题: Chrome 浏览器访问 Google 学术出现如下的问题 : ... but your computer or network may be sending automated querie ...
- 【11】vue router 之导航钩子
导航钩子 vue-router 提供的导航钩子主要用来拦截导航,让它完成跳转或取消.有多种方式可以在路由导航发生时执行钩子:全局的, 单个路由独享的, 或者组件级的.http://www.jiansh ...
- C/C++学习路线
随着互联网及互联网+深入蓬勃的发展,经过40余年的时间洗礼,C/C++俨然已成为一门贵族语言,出色的性能使之成为高级语言中的性能王者.而在今天,它又扮演着什么样重要的角色呢?请往下看: 后端服务器,移 ...