cscの作法 その369

# 概要
cscの作法、調べてみた。
opentkのgamewindow使ってみた。
練習問題、やってみた。

# 練習問題
マウスでカメラを動かせ。

# 参考にしたページ。

https://github.com/MaaikeG/Rasterizer


# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/32b57ffc-d7ec-cf30-509f-770a9a9893b0.png)


# サンプルコード

```

using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;

namespace App
{
	public class Camera {
		public Vector3 position = Vector3.Zero;
		public Vector3 orientation = new Vector3((float) Math.PI, 0f, 0f);
		public float moveSpeed = 0.2f;
		public float sensitivity = 0.01f;
		public Matrix4 GetViewMatrix() {
			Vector3 lookat = new Vector3();
			lookat.X = (float) (Math.Sin(orientation.X) * Math.Cos(orientation.Y));
			lookat.Y = (float) Math.Sin(orientation.Y);
			lookat.Z = (float) (Math.Cos(orientation.X) * Math.Cos(orientation.Y));
			return Matrix4.LookAt(position, position + lookat, Vector3.UnitY);
		}
		public void Move(float x, float y, float z) {
			Vector3 offset = new Vector3();
			Vector3 forward = new Vector3((float) Math.Sin((float) orientation.X), 0, (float) Math.Cos((float) orientation.X));
			Vector3 right = new Vector3(-forward.Z, 0, forward.X);
			offset += x * right;
			offset += y * forward;
			offset.Y += z;
			offset.NormalizeFast();
			offset = Vector3.Multiply(offset, moveSpeed);
			position += offset;
		}
		public void AddRotation(float x, float y) {
			x = x * sensitivity;
			y = y * sensitivity;
			orientation.X = (orientation.X + x) % ((float) Math.PI * 2.0f);
			orientation.Y = Math.Max(Math.Min(orientation.Y + y, (float) Math.PI / 2.0f - 0.1f), (float) -Math.PI / 2.0f + 0.1f);
		}
	}
	class Gwin: GameWindow {
		int b = 0;
		Camera cam;
		Vector2 lastMousePos = new Vector2();
		public Gwin(int width, int height, GraphicsMode mode, string title): base(width, height, mode, title) {
			this.VSync = VSyncMode.On;
		}
		protected override void OnLoad(EventArgs e) {
			base.OnLoad(e);
			cam = new Camera();
			lastMousePos = new Vector2(OpenTK.Input.Mouse.GetState().X, OpenTK.Input.Mouse.GetState().Y);
			cam.position += new Vector3(0f, 0f, 3f);
		}
		protected override void OnRenderFrame(FrameEventArgs e) {
			base.OnRenderFrame(e);
			GL.Enable(EnableCap.DepthTest);
			GL.MatrixMode(MatrixMode.Modelview);
			Matrix4 modelview = Matrix4.LookAt(Vector3.Zero, Vector3.UnitZ, Vector3.UnitY);
			GL.LoadMatrix(ref modelview);
			Matrix4 perspective = cam.GetViewMatrix() * Matrix4.CreatePerspectiveFieldOfView(1.8f, 1.0f, 1.0f, 200.0f);
			GL.MatrixMode(MatrixMode.Projection);
			GL.LoadMatrix(ref perspective);
			GL.ClearColor(Color.CornflowerBlue);
			GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
			GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Specular, Color4.White);
			GL.Begin(PrimitiveType.Quads);
			GL.Normal3(Vector3.UnitX);
			GL.Vertex3(-10.0f, 10.0f, 10.0f);
			GL.Vertex3(-10.0f, -10.0f, 10.0f);
			GL.Vertex3(10.0f, -10.0f, 10.0f);
			GL.Vertex3(10.0f, 10.0f, 10.0f);
			GL.End();
			this.SwapBuffers();
		}
		protected override void OnMouseDown(OpenTK.Input.MouseButtonEventArgs e) {
			base.OnMouseDown(e);
			//Console.WriteLine("OnMouseDown");
			b = 1;
		}
		protected override void OnMouseUp(OpenTK.Input.MouseButtonEventArgs e) {
			base.OnMouseUp(e);
			//Console.WriteLine("OnMouseUp");
			b = 0;
		}
		protected override void OnMouseMove(OpenTK.Input.MouseMoveEventArgs e) {
			base.OnMouseMove(e);
			//Console.WriteLine("OnMouseMove");
		}
		protected override void OnUpdateFrame (FrameEventArgs e) {
			if (b == 1)
			{
				Vector2 delta = lastMousePos - new Vector2(OpenTK.Input.Mouse.GetState().X, OpenTK.Input.Mouse.GetState().Y);
				lastMousePos += delta;
				cam.AddRotation(delta.X, delta.Y);
				lastMousePos = new Vector2(OpenTK.Input.Mouse.GetState().X, OpenTK.Input.Mouse.GetState().Y);
			}
		}
	}
	class Program {
		static void Main(string[] args) {
			Gwin window = new Gwin(500, 500, OpenTK.Graphics.GraphicsMode.Default, "Test");
			window.Run();
		}
	}
}





```

以上。