#region OpenTK

OpenTKがGitHubで更新されるようになりました。NuGetから手に入れることができるようになりました。
現在は.NET Coreに対応する機運があるようです。

点と線の描画

原始的なOpenGLプログラム

最近のOpenGLはシェーダがなんだとか、バッファオブジェクトがなんだとか言う話が多いようです。それは最新のOpenGLの仕様に合わせるからで、簡単な学習用プログラムなら最初はそういうものを使わなくても十分動作します。ただ、いろいろな描画効果を使いたかったり、描画する物体のポリゴンが多かったりする場合にはとても耐えられませんが…

というわけで、今回はごくごく簡単なOpenGLのプログラムでいきたいと思います。

点と線の違いはglBeginの違い

Points and Lines
点とグラデーションのある線を描画(色はランダム)

ソースコードは、OpenGLを少しでもかじっていれば特に難しいということはないです。

		Vector2[] position;		//点の位置
		Color4[] color;			//点の色
		const int N = 130;		//点の数
		
		//800x600のウィンドウを作る。タイトルは「1-1:Points and Lines」
		public Game()
			: base(800, 600, GraphicsMode.Default, "1-1:Points and Lines")
		{
			position = new Vector2[N];
			color = new Color4[N];
			

点の位置と色を記憶する配列を作成し、コンストラクタで初期化します。

		//ウィンドウの起動時に実行される。
		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);

			GL.ClearColor(Color4.Black);
			GL.Enable(EnableCap.DepthTest);

			GL.PointSize(3.0f);		//点の大きさを変更

			GL.LineWidth(1.5f);		//線の太さを変更

			Random();
		}

49行目は点の表示の大きさを指定しています。OpenGLのglPointSize関数と同じです。

51行目は線の表示の太さを指定しています。OpenGLのglLineWidth関数と同じです。

Random関数はこのプログラム内で定義したもので、点の位置と色をランダムにします。

		//ウィンドウのサイズが変更された場合に実行される。
		protected override void OnResize(EventArgs e)
		{
			base.OnResize(e);

			GL.Viewport(ClientRectangle);
		}

今まではこの関数内でProjection行列に行列を設定、ということをしていましたが、今回はそこについては何もしません。画面のサイズを変えると描画結果が伸びたり縮んだりします。

GL.Viewportについては、ClientRectangleを渡せばGameWindowの場合は画面いっぱいに描画するのでこのようにしました。

		//画面描画で実行される。
		protected override void OnRenderFrame(FrameEventArgs e)
		{
			base.OnRenderFrame(e);

			GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

			//点をすべて描画
			GL.Begin(BeginMode.Points);
			for (int i = 0; i < N; i++)
			{
				GL.Color4(color[i]);
				GL.Vertex2(position[i]);
			}
			GL.End();

			//線をすべて描画
			GL.Begin(BeginMode.Lines);
			for (int i = 0; i < N; i++)
			{
				GL.Color4(color[i]);
				GL.Vertex2(position[i]);
			}
			GL.End();

			SwapBuffers();
		}

最近のOpenGLのプログラムでは、データをオブジェクトにまとめてから効率よく描画ということをするようです。それとは別に、このコードのようにGL.BeginとGL.Endの間にGL.Color?やGL.Vertex?を入れることで描画させることができます(?は数字)。なお、その間以外でGL.Vertexがある場合、どんな動作をするかわかりません。そのためこの間にインデントを付けている方もいるようです

GL.Beginの引数はBeginMode列挙体で、Pointsなら点、Linesなら線、Trianglesなら三角形を描画します。BeginModeには種類がたくさんあり、他にはQuadsとPolygonsなどがあります。GL.Beginの引数によって、GL.Endとの間の動作が結構変わってきます。(GL.Vertexが点一つに1、線一本に2、三角形一つに3必要となる)

今回の例の場合、点はNコで線は(N/2)コになります。

他にも関数がありますが、OpenGLやOpenTKの機能に直接関係するものではないのでここでは省略します。

記事

外部リンク

Thanks