/////////////////////////////////////////////
// GameWindow_Sample01.cpp
// Copyrignt (c) 2024 byYsama
/////////////////////////////////////////////
using System;
using OpenTK;						//OpenTKを使用する際に必須
using OpenTK.Graphics;				//OpenTKのグラフィックを使用する際に必須
using OpenTK.Graphics.OpenGL;		//OpenGLを使用する際に必要
using OpenTK.Input;					//OpenTKで入力を行う際に必要（例：Keyboiard）
using OpenTK_Primitives;			//OpenTK自作図形ライブラリー

namespace GameWindow_Sample01
{
	//アプリケーションクラス
	public class App
	{
		[STAThread]
		public static void Main()
		{
			gWindow gw = new gWindow();
			gw.Run();
		}
	}

	class gWindow : GameWindow	//GameWindowクラスからユーザーウィンドウを派生させる
	{
		OTKPrims pv = new OTKPrims();					//otkPrimitivesクラスインスタンス
		float RotateX = 0, RotateY = 0, RotateZ = 0;	//球の回転角
		bool SorW = true;								//Solidか、Wireかのフラグ
		bool drawStop = false;							//描画停止

		public gWindow() : base(640, 480, GraphicsMode.Default, "OpenTK GameWindow")	//既定引数
		{
			//Mouse割込み
			this.MouseDown += gW_MouseDown;
			this.MouseMove += gW_MouseMove;
			this.MouseUp += gW_MouseUp;
			//Key割込み
			this.KeyUp += gW_KeyUp;
			this.KeyDown += gW_KeyDown;
			this.KeyPress += gW_KeyPress;
		}

		//ウィンドウの起動時に実行される
		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);								//既定処理
			GL.ClearColor(Color4.Black);				//画面消去色の設定
			GL.Enable(EnableCap.DepthTest);				//深度チェックを有効化する
			//光源の使用
			GL.Enable(EnableCap.Lighting);
			//ライト0の設定
			GL.Enable(EnableCap.Light0);
			float[] pos = new float[] { 0.8f, 1.0f, 1.2f, 0.0f };
			//float[] pos = new float[] {50.0f, 50.0f, 10.0f, 0.0f };
			GL.Light(LightName.Light0, LightParameter.Position, pos);
		}

		//ウィンドウのサイズが変更された場合に実行される
		protected override void OnResize(EventArgs e)
		{
			base.OnResize(e);							//既定処理
			//ビューポートの設定
			GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height);
			//視体積の設定
			GL.MatrixMode(MatrixMode.Projection);
			Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, (float)Width / (float)Height, 1.0f, 64.0f);	//glPerspective(fov, aspect, near, far);
			GL.LoadMatrix(ref projection);
		}

		//ウィンドウイベントが更新された場合に実行される（OnRenderFrameの前に実行される）
		protected override void OnUpdateFrame(FrameEventArgs e)
		{
			base.OnUpdateFrame(e);
			//ESCキーが押されたら終了
			if(Keyboard.GetState().IsKeyDown(Key.Escape))
			{
				Exit();
			}
		}

		//ウィンドウ描画が更新された場合に実行される
		protected override void OnRenderFrame(FrameEventArgs e)
		{
			base.OnRenderFrame(e);
			if(drawStop)
				return;									//描画停止
			GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
			GL.MatrixMode(MatrixMode.Modelview);		//モデルビューモードを選択
			//視点を設定して原点(0, 0, 0)を見る
			Vector3 eye = new Vector3(0.0f, 0.0f, 5.0f);
			Matrix4 modelview = Matrix4.LookAt(eye, Vector3.Zero, Vector3.UnitY);	//gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);
			GL.LoadMatrix(ref modelview);				//現在の変換マトリックスに設定
			//以下に描画処理を行う

			GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
			//球を描画−移動と回転(double radius, double x, double y, double z, double RotateX, double RotateY, double RotateZ)
			GL.PushMatrix();
			{
				GL.Translate(1.0, 0.0, 0.0);
				GL.Rotate(RotateX, 1, 0, 0);
				GL.Rotate(RotateY, 0, 1, 0);
				GL.Rotate(RotateZ, 0, 0, 1);
				GL.Material(MaterialFace.Front, MaterialParameter.Ambient, Color4.Red);
				pv.Cube(SorW);
			}
			GL.PopMatrix();
			GL.PushMatrix();
			{
				GL.Translate(-1.0, 0.0, 0.0);
				GL.Rotate(RotateX, 1, 0, 0);
				GL.Rotate(RotateY, 0, 1, 0);
				GL.Rotate(RotateZ, 0, 0, 1);
				GL.Material(MaterialFace.Front, MaterialParameter.Ambient, Color4.Blue);
				pv.Triangular(SorW);
			}
			GL.PopMatrix();
			RotateX += 1.5f; 
			RotateY += 5.0f; 
			RotateZ += 1.0f; 
			this.SwapBuffers();
		}

		//Mouse割込み
		private void gW_MouseDown(object sender, MouseButtonEventArgs e)
		{
			if(e.Button == MouseButton.Left)
				SorW = !SorW;
			else if(e.Button == MouseButton.Right)
				drawStop = !drawStop;
		}

		private void gW_MouseMove(object sender, MouseMoveEventArgs e)
		{
		}

		private void gW_MouseUp(object sender, MouseEventArgs e)
		{
		}

		//Key割込み
		private void gW_KeyUp(object sender, KeyboardKeyEventArgs e)
		{
		}

		private void gW_KeyDown(object sender, KeyboardKeyEventArgs e)
		{
		}

		private void gW_KeyPress(object sender, KeyPressEventArgs e)
		{
		}
	}
}
