OpenGL with C# (15) : 曲面の描画 [1] - 円
お久しぶりです。
いろいろありまして,前回からかなり間があいてしまいました。
さて,予定通り"OpenGL 球" で検索されてくる方のために,今回から曲面に関して書いていこうと思います。
そんなわけで,今回はまず円を書いてみましょう。
なんで,最初から球を書かないのかですと?
私は割と焦らす派だからですw
あと,基本原理を分かっていた方が応用が利くのでいいですよ。
そんなわけで進めましょう。
とりあえずいつものごとく型枠だけ作ります。
02 using System.Windows.Forms;
03 using System.Drawing;
04
05 using OpenTK;
06 using OpenTK.Graphics.OpenGL;
07
08 namespace BlogOpenGL
09 {
10 public partial class Form1 : Form
11 {
12 public Form1()
13 {
14 InitializeComponent();
15 }
16
17 private void glControl_Load(object sender, EventArgs e)
18 {
19 // 背景色の設定
20 GL.ClearColor(glControl.BackColor);
21
22 // Projection の設定
23 SetProjection();
24
25 // 視界の設定
26 Matrix4 look = Matrix4.LookAt(Vector3.UnitZ, Vector3.Zero, Vector3.UnitY);
27
28 GL.LoadMatrix(ref look);
29 }
30
31 private void glControl_Paint(object sender, PaintEventArgs e)
32 {
33 GL.Clear(ClearBufferMask.ColorBufferBit);
34
35 DrawCircle();
36
37 glControl.SwapBuffers();
38 }
39
40 private void glControl_Resize(object sender, EventArgs e)
41 {
42 // Projection の設定
43 SetProjection();
44
45 // 再描画
46 glControl.Refresh();
47 }
48
49 void SetProjection()
50 {
51 // ビューポートの設定
52 GL.Viewport(0, 0, glControl.Width, glControl.Height);
53
54 // 視体積の設定
55 GL.MatrixMode(MatrixMode.Projection);
56 float h = 2.0f, w = h * glControl.AspectRatio;
57 Matrix4 proj = Matrix4.CreateOrthographic(w, h, 0.1f, 3.0f);
58 GL.LoadMatrix(ref proj);
59
60 // MatrixMode を元に戻す
61 GL.MatrixMode(MatrixMode.Modelview);
62 }
63
64 void DrawCircle()
65 {
66 }
67 }
68 }
DrawCircle に円を描画する処理を追加します。
ここから数学の時間です。
(x, y) = (r cosθ, r sinθ) (0 ≤ θ < 2π) が xy 平面で原点中心,半径 r の円上の点を表すということを覚えていますでしょうか。
こんな感じの図でしたね。
θ は x 軸から測った角度になります。
曲面を描画するときはだいたいこの三角関数を使うので,OpenGL を使う際は好き嫌いせずに使ってみましょう。
さて,円を描画する話に戻ります。
いろいろ描画方法はあると思いますが,ここでは扇形を合わせて描画することを考えましょう。
扇形とは言いましたが,OpenGL では扇形が描画できないので,三角形を合わせて書くことになります。
つまるところ正 n 角形を描画するわけです。
n がおおきくなれば円に近付くというのはよく知られていますね。
通常,三角形を書くときは TriangleStrip を使うのがよいのですが,円の場合は適したものがあります。
ここ に示した TriangleFan というやつです。
まさに先ほどの図の三角形バージョンそのままですね。
さて三角形何個で書くというのを変更できた方がいいので,n 個としておきましょう。
1つ当たりの三角形の角度は 360° / n (= 2π / n) ですね。
そんなわけでやってみましょう。
11 {
31 private void glControl_Paint(object sender, PaintEventArgs e)
32 {
33 GL.Clear(ClearBufferMask.ColorBufferBit);
34
37 glControl.SwapBuffers();
38 }
39
65 {
66 double delta = 2.0 * Math.PI / (double)n;
67
68 GL.Begin(BeginMode.TriangleFan);
69 {
70 GL.Vertex3(Vector3.Zero);
71 for (int i = 0; i <= n; i++)
72 {
73 double x = Math.Cos(delta * i);
74 double y = Math.Sin(delta * i);
75 GL.Vertex3(x, y, 0.0);
76 }
77 }
78 GL.End();
79 }
n に 6 を渡すとちゃんと正六角形が表示できました。
71 行目で i <= n としていることに注意してください。
こうしないと最後の三角形が描画されませんね。
n の値を大きくして,円が描画できることを確認してください。
さて,今回はここまでですが,ここから新システムです。
レベルアップのための課題です。
気が向いたらやってみてください。
【課題】下に示すような半円を描画しましょう。