OpenTKで立方体を描く初歩を復習するための記録
何かと初歩的なこともすぐ忘れてしまうので、OpenTKで立方体を描いたときのコードを記録しておく。
イメージは以下のようなものが描画される。
コンパイルのために以下の応答ファイル my.rsp を用意しておく。
#
# コンパイルのための応答ファイル
# csc `@my.rsp <target file.cs>
# ※ powershellでは @ は "`" でエスケープしなければならない。
/reference:OpenTK.dll
/reference:OpenTK.GLControl.dll
ソースコードは以下の通り。
// // cc `@my.rsp test1.cs // using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using OpenTK; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; namespace FormsOpenTKTest1 { public class Form1 : Form { /// <summary> /// 必要なデザイナー変数です。 /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// 使用中のリソースをすべてクリーンアップします。 /// </summary> /// <param name="disposing">マネージ リソースを破棄する場合は true を指定し、その他の場合は false を指定します。</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows フォーム デザイナーで生成されたコード /// <summary> /// デザイナー サポートに必要なメソッドです。このメソッドの内容を /// コード エディターで変更しないでください。 /// </summary> private void InitializeComponent() { this.glControl = new OpenTK.GLControl(); this.SuspendLayout(); // // glControl // //this.glControl.BackColor = System.Drawing.Color.Black; this.glControl.BackColor = System.Drawing.Color.Yellow; //this.glControl.Location = new System.Drawing.Point(0, 0); this.glControl.Location = new System.Drawing.Point(10, 10); this.glControl.Margin = new System.Windows.Forms.Padding(7, 6, 7, 6); this.glControl.Name = "glControl"; //this.glControl.Size = new System.Drawing.Size(1696, 603); this.glControl.Size = new System.Drawing.Size(1200, 1000); this.glControl.TabIndex = 0; this.glControl.VSync = false; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(13F, 24F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; //this.ClientSize = new System.Drawing.Size(1741, 647); this.ClientSize = new System.Drawing.Size(1300, 1300); this.Controls.Add(this.glControl); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); } #endregion private OpenTK.GLControl glControl; public Form1() { InitializeComponent(); //イベントの追加 glControl.Load += glControl_Load; glControl.Paint += glControl_Paint; //glControl.Resize += glControl_Resize; } private void glControl_Load(object sender, EventArgs e) { // 背景色の設定 GL.ClearColor(glControl.BackColor); // ビューポートの設定 GL.Viewport(0, 0, glControl.Width, glControl.Height); // 視体積の設定 GL.MatrixMode(MatrixMode.Projection); //GL.MatrixMode(MatrixMode.Modelview); Matrix4 proj = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, glControl.AspectRatio, 0.2f, 5); GL.LoadMatrix(ref proj); // 視界の設定 GL.MatrixMode(MatrixMode.Modelview); //Matrix4 look = Matrix4.LookAt(Vector3.One, new Vector3(0, 0, 0.75f), Vector3.UnitZ); Matrix4 look = Matrix4.LookAt(new Vector3(1, 1, 1.75f), new Vector3(0, 0, 0.75f), Vector3.UnitZ); GL.LoadMatrix(ref look); // デプスバッファの使用 GL.Enable(EnableCap.DepthTest); // 光源の使用 GL.Enable(EnableCap.Lighting); float[] position = new float[] { 1.0f, 2.0f, 3.0f, 0.0f }; GL.Light(LightName.Light0, LightParameter.Position, position); GL.Enable(EnableCap.Light0); } private void glControl_Resize(object sender, EventArgs e) { // ビューポートの設定 GL.Viewport(0, 0, glControl.Width, glControl.Height); } private void glControl_Paint(object sender, System.Windows.Forms.PaintEventArgs e) { //GL.Clear(ClearBufferMask.ColorBufferBit); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Diffuse, Color4.Blue); //tube(1, 0.1f, 0.1f); cube( 0.3, -0.3, 0.6); glControl.SwapBuffers(); // this.pictureBox1.Image = image; // image.Save(saveFileDialog1.FileName,ImageFormat.Jpeg); // // this.glControl. } void cube(double x, double y, double z) { //double w = 1.0, h = 1.0, d = 1.0; double w = 0.2, h = 0.2, d = 0.2; GL.PushMatrix(); GL.Begin(PrimitiveType.TriangleStrip); // right { GL.Normal3( Vector3.UnitX); GL.Vertex3( x+w, y+h, z-d); GL.Vertex3( x+w, y+h, z+d); GL.Vertex3( x+w, y-h, z-d); GL.Vertex3( x+w, y-h, z+d); } GL.End(); GL.Begin(PrimitiveType.TriangleStrip); // left { GL.Normal3(-Vector3.UnitX); GL.Vertex3( x-w, y-h, z-d); GL.Vertex3( x-w, y-h, z+d); GL.Vertex3( x-w, y+h, z-d); GL.Vertex3( x-w, y+h, z+d); } GL.End(); GL.Begin(PrimitiveType.TriangleStrip); // up { GL.Normal3( Vector3.UnitY); GL.Vertex3( x+w, y+h, z-d); GL.Vertex3( x-w, y+h, z-d); GL.Vertex3( x+w, y+h, z+d); GL.Vertex3( x-w, y+h, z+d); } GL.End(); GL.Begin(PrimitiveType.TriangleStrip); // down { GL.Normal3(-Vector3.UnitY); GL.Vertex3( x-w, y-h, z+d); GL.Vertex3( x-w, y-h, z-d); GL.Vertex3( x+w, y-h, z+d); GL.Vertex3( x+w, y-h, z-d); } GL.End(); GL.Begin(PrimitiveType.TriangleStrip); // front { GL.Normal3( Vector3.UnitZ); GL.Vertex3( x+w, y+h, z+d); GL.Vertex3( x-w, y+h, z+d); GL.Vertex3( x+w, y-h, z+d); GL.Vertex3( x-w, y-h, z+d); } GL.End(); GL.Begin(PrimitiveType.TriangleStrip); // back { GL.Normal3(-Vector3.UnitZ); GL.Vertex3( x+w, y-h, z-d); GL.Vertex3( x-w, y-h, z-d); GL.Vertex3( x+w, y+h, z-d); GL.Vertex3( x-w, y+h, z-d); } GL.End(); GL.PopMatrix(); } void tube(float length, float radius1, float radius2) { float rx, ry, theta; GL.PushMatrix(); GL.Begin(PrimitiveType.TriangleStrip); //GL.Normal3(Vector3.One); //for (int deg = 0; deg <= 360; deg = deg + 3) for (int deg = 0; deg <= 360; deg = deg + 36) { theta = (float)Math.PI * deg / 180; //rx = (float)Math.Cos((float)Math.PI * deg / 180); //ry = (float)Math.Sin((float)Math.PI * deg / 180); rx = (float)Math.Cos(theta); ry = (float)Math.Sin(theta); GL.Normal3(rx, ry, 0.0f); GL.Vertex3(rx * radius2, ry * radius2, length / 2 + 0.5); GL.Vertex3(rx * radius1, ry * radius1, -length / 2 + 0.5); } GL.End(); GL.PopMatrix(); } } static class Program { /// <summary> /// アプリケーションのメイン エントリ ポイントです。 /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } }
以上