OpenTK的官方文档是真心的少,他们把怎么去安装OpenTK说的很清楚,但是也就仅限于此,这有一篇learn opentk in 15的教程(链接已经失效,译者注),但是并不完美。你可以在15分钟内做一些简单的事情,但是却很难理解代码的内部机制。本文使用了一部分该教程的代码,使用的是过时的方式(非VBO),但是有助于理解OPENTK/OPENGL的绘图机制。


Part 1:安装

首先,安装OpenTK。 这是一个非常简单的过程,可以参考官方教程,我这里推荐使用Nuget

打开自己喜欢的IDE(集成开发环境)。 我使用Visual Studio,但是MonoDevelop和SharpDevelop应该都可以正常工作。

新建一个控制台(console)程序,右键点击工程,管理nuget引用,输入opentk,安装就ok了。

Part 2: 编程

现在我们有一个空的项目。 我们首先要做的是打开Program.cs文件。现在这是一个基础类,什么都不做。我们将继续为我们的主要功能。要开始显示图形,我们需要制作GameWindow类型的子类。 添加一个名为“Game”的新类。 使它成为GameWindow的子类(您需要为OpenTK添加一个using指令才能使用该类)。

差不多是这样:

using OpenTK;
using OpenTK.Graphics.OpenGL;
using System; namespace OpentkTutorials
{
class Game : GameWindow
{
}
}

回到Program.cs,添加代码:

namespace OpentkTutorials
{
class Program
{
static void Main(string[] args)
{
using (var game = new Game())
{
game.Run(30.0);
}
}
}
}

运行就可以看到效果了:

这是一个空窗口,但是说明我们成功了。

GameWindow的Run方法有多个重载。使用30.0的float类型参数,Run函数会以30次/秒的频率引发窗口的UpdateFrame事件,同样的,计算机将处理相同频率的RenderFrame事件。

现在,我们来让窗口做一些更有趣的事情。 在Game类中,您可以使用几种方法来重载以添加新功能。 我们要重载的第一个是onLoad。如果您使用Visual Studio,只需输入“override”并添加一个空格即可给出一个可用于覆盖的GameWindow类中的方法列表。此方法的基本形式为:

protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
}

我们再写点别的:

protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
//修改窗口标题
Title = "Hello OpenTK!";
//设置背景颜色为,额,不知道什么蓝(需要添加 OpenTK.Graphics.OpenGL and System.Drawing引用)
GL.ClearColor(Color.CornflowerBlue);
}

我们必须再做一件事情,然后才会看到这种颜色变化。 使用以下代码为OnRenderFrame方法添加另一个重载:

protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); SwapBuffers();
}

先上车,以后再解释这部分。我们应该能看到修改效果:

现在的背景是蓝色,标题也改过来了。

接下来,当正确调整窗口大小时,我们将添加代码来处理。我们需要告诉OpenGL如何调整新窗口大小,所以我们需要一些处理它的代码。

protected override void OnResize(EventArgs e)
{ base.OnResize(e); GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height); Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, Width / (float)Height, 1.0f, 64.0f); GL.MatrixMode(MatrixMode.Projection); GL.LoadMatrix(ref projection);
}

这段代码只是告诉OpenGL窗口的位置,以及我们想要绘制的窗口。现在这些不重要,但是当我们实际绘制一些东西,或者做一个真实的游戏时,处理大小调整将非常重要。

我们回到OnRenderFrame方法,并实际绘制一些东西。 我们需要做的第一件事就是告诉OpenGL我们正在从哪个方向看。因为我们实际上有可能会在3D中制作一些东西,所以我们面对的方向(视角)很重要。

在调用SwapBuffers()之前,下一节的所有代码将进入OnRenderFrame。 这是因为我们需要画一些东西才能交换缓冲区。默认情况,我们使用“双缓冲”设置。 当我们要把东西画到屏幕上时,我们首先绘制一个“缓冲区”,后来被“交换”到屏幕内容。 这样可以确保在屏幕更新之前,所有内容都会在屏幕上绘制出来。

以下代码将在准备一个平面,我们可以在上面画三角形。

           Matrix4 modelview = Matrix4.LookAt(Vector3.Zero, Vector3.UnitZ, Vector3.UnitY);

            GL.MatrixMode(MatrixMode.Modelview);

            GL.LoadMatrix(ref modelview);

现在我们要画三角形本身。 第一步是告诉OpenGL我们想画些东西。 我们用GL.Begin函数做到这一点。 它需要一个参数,即使用的绘图模式。 可以选择绘制四边形,三角形,点,多边形和“条”。 我们只是使用一个三角形,所以我们需要的代码是:

GL.Begin(BeginMode.Triangles);

BeginMode有以下几种模式,(现在调用这个方法会显示已经过时,需要使用PrimitiveType代替)可以参考OPENGL文档,或者园子里有人写过:

http://www.cnblogs.com/helloj2ee/archive/2013/03/12/2956181.html

现在我们已经告诉OPENTK如何绘制,我们需要给它形状的顶点。 为此,我们使用GL.Vertex3函数。3D空间中单个点的坐标需要三个浮点数。

 GL.Vertex3(-1.0f, -1.0f, 4.0f);
GL.Vertex3(1.0f, -1.0f, 4.0f);
GL.Vertex3(0.0f, 1.0f, 4.0f);

在将所有点送到显卡之前,我们需要告诉OPENGL我们打完收工了。

GL.End();

跑完,应该是这个效果:

我们再深入一步,添加一点色彩。使用GL.Color3函数,可以设置定点颜色,需要在设置位置之前调用。

GL.Color3(1.0f, 0.0f, 0.0f);
GL.Vertex3(-1.0f, -1.0f, 4.0f); GL.Color3(0.0f, 1.0f, 0.0f);
GL.Vertex3(1.0f, -1.0f, 4.0f); GL.Color3(0.0f, 0.0f, 1.0f);
GL.Vertex3(0.0f, 1.0f, 4.0f);

最后效果差不多是这样:

为什么它是一个渐变的三角形? 这是因我们使用的是默认着色器(shader)。着色器允许许多非常惊人的效果,例如凹凸贴图,照明,phong光照等。默认值在绘制顶点时简单地插入给它们的颜色和位置的值。着色器是一个更复杂的功能(甚至使用自己的脚本语言),以后我们会讲到。


本系列教程翻译自Neo Kabuto's Blog。已经取得作者授权。

本文原文地址http://neokabuto.blogspot.com/2013/02/opentk-tutorial-1-opening-windows-and.html

原文代码可以在github上找到。

OpenTK教程-1绘制一个三角形的更多相关文章

  1. OpenTK教程-2绘制一个三角形(正确的方法)

    上一个教程向我们展示了如何在屏幕上画一个三角形.但是,我说过,那是一种古老的方式,即使它能够正常运行,但是现在这已经不是"正确"的方式.上篇文章中我们将几何发送到GPU的方式是所谓 ...

  2. OpenTK教程-2绘制一个三角形(正确的方式)

    上一个教程向我们展示了如何在屏幕上画一个三角形.但是,我说过,那是一种古老的方式,即使它能够正常运行,但是现在这已经不是"正确"的方式.上篇文章中我们将几何发送到GPU的方式是所谓 ...

  3. WebGL简易教程(三):绘制一个三角形(缓冲区对象)

    目录 1. 概述 2. 示例:绘制三角形 1) HelloTriangle.html 2) HelloTriangle.js 3) 缓冲区对象 (1) 创建缓冲区对象(gl.createBuffer( ...

  4. 【OpenGL4.0】GLSL渲染语言入门与VBO、VAO使用:绘制一个三角形 【转】

    http://blog.csdn.net/xiajun07061225/article/details/7628146 以前都是用Cg的,现在改用GLSL,又要重新学,不过两种语言很多都是相通的. 下 ...

  5. Unity3D学习笔记1——绘制一个三角形

    目录 1. 绪论 2. 概述 3. 详论 3.1. 准备 3.2. 实现 3.3. 解析 3.3.1. 场景树对象 3.3.2. 绘制方法 4. 结果 1. 绪论 最近想学习一下Unity3d,无奈发 ...

  6. [Modern OpenGL系列(三)]用OpenGL绘制一个三角形

    本文已同步发表在CSDN:http://blog.csdn.net/wenxin2011/article/details/51347008 在上一篇文章中已经介绍了OpenGL窗口的创建.本文接着说如 ...

  7. Opentk教程系列-1绘制一个三角形

    本系列教程翻译自Neo Kabuto's Blog.已经取得作者授权. 本文原文地址http://neokabuto.blogspot.com/2013/02/opentk-tutorial-1-op ...

  8. Android快乐贪吃蛇游戏实战项目开发教程-03虚拟方向键(二)绘制一个三角形

    该系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html 一.绘制三角形 在上一篇文章中,我们已经新建了虚拟方向键的自定义控件Direct ...

  9. Stage3D学习笔记(二):使用GPU绘制一个三角形

    我们需要使用到Adobe自家提供的AGALMiniAssembler代码类,可以在网下进行下载: 关于AGAL的入门知识可以参考下面的文章: AGAL介绍系列文章(第一部分)AGAL介绍系列文章(第二 ...

随机推荐

  1. 安装VisualSVN Server 报"Service 'VisualSVN Server' failed to start. Please check VisualSVN Server log in Event Viewer for more details"错误.原因是启动"VisualSVN Server"失败

    安装VisualSVN Server 报"Service 'VisualSVN Server' failed to start. Please check VisualSVN Server ...

  2. format 代码

    #!/bin/bash#file format.sh#将某个源代码文件中的全角符号转换成半角符号#调用astyle 将某个源代码文件转换成linux风格,缩进方式为4个空格 echo $1#将全角空格 ...

  3. 第五章 绘图基础(ALTWIND)

    线上箭头表示画线的方向.WINDING模式和ALTERNATE模式都会填充三个封闭的L型区域,号码从1到3.两个更小的内部区域,号码为4和5,在ALTERNATE模式下不被填充.但是在WINDING模 ...

  4. CTR预估中GBDT与LR融合方案

    1. 背景 CTR预估(Click-Through Rate Prediction)是互联网计算广告中的关键环节,预估准确性直接影响公司广告收入.CTR预估中用的最多的模型是LR(Logistic R ...

  5. Instruments模板介绍(更新中...)

    第一章.Instruments(仪器)快速入门 Instruments可以用来收集关于一个或者多个系统进程的性能和行为的数据,并跟踪睡着时间产生的数据.它提供了好几个分析模板: Blank 任何类型都 ...

  6. Jquery+asp.net实现Ajax方式文件下载实例代码

    如果文件中,需要下载一个文件,一般用超级链接的方式即可. 但是如果是图片,浏览器会默认打开图片浏览,不是实现下载. 考虑可以使用jquery ajax提交form请求的方式. jquery downl ...

  7. Android的进阶学习(六)--理解View事件分发

    http://www.jianshu.com/p/34cb396104a7 有些无奈,期末考试抱佛脚,还好没有挂,现在继续进阶. 好久以前就看到了View的事件分发,但是当时功底不够,源码也不敢深究, ...

  8. js中return,return true,return false三者的用法及区别

    return其实就是return undefined; 1.语法及返回方式 ①返回控制与函数结果 语法为:return 表达式; 语句结果函数的执行,返回调用函数,而且把表达式的值作为函数结果返回出去 ...

  9. 容器中JVM获取真实的CPU核数

    容器中JVM获取真实的CPU核数 基于 libsysconfcpus的方案,可以为各个版本的JDK提供一个通用的解决方案. libsysconfcpus.so的原理是截获JVM获取CPU核数所用的系统 ...

  10. <数据结构与算法分析>读书笔记--最大子序列和问题的求解

    现在我们将要叙述四个算法来求解早先提出的最大子序列和问题. 第一个算法,它只是穷举式地尝试所有的可能.for循环中的循环变量反映了Java中数组从0开始而不是从1开始这样一个事实.还有,本算法并不计算 ...