/************************
 OpenGL Includesファイル
 ************************/
//#include	<GL\gl.h>				//OpenGLをWindowsで使う場合必須
//#include	<GL\glu.h>				//OpenGLユーティリティ ライブラリをWindowsで使う場合必要
//#include	<GL\glext.h>
/*
glutを入手し、本プログラムでコンパイルしたら、glut.hとstdlib.hのexit関数が二重定義になっているというエラーが出た。
解決法はstdlib.h（windows.hに入っている）を先に取り込め、とあったが解決にはならなかった。
結局、glutのサイトからフルバージョンのファイルをダウンロードし、その中のglut.h（エラーが起こったものとは異なる内容）を使って解決した。
*/
#include	<GL\glut.h>			//glutライブラリをWindowsで使う場合必要
#include	<math.h>			//三角関数を使う為

//定数
#define	PAI	3.141592653				//三角関数を使う為

//外部変数("g_")
bool g_GLon = FALSE;			//OpenGLを使用中か否か
HWND g_hWnd;					//OpenGLでグラフィックを表示するウィンドウのハンドル
HDC g_hDC;						//対象ウィンドウのデバイスコンテキストハンドル
HGLRC g_hRC;					//OpenGL用のレン. ダリング・コンテキスト
PIXELFORMATDESCRIPTOR g_pdf;	//ピクセルフォーマット構造体
int g_pixelformat;				//ChoosePixelFormat関数の戻り値：指定されたピクセル形式記述子に最も近いピクセル形式インデックス
int g_DrawMenuNo = IDM_2D01;	//描画関数を選択する描画番号（初期値は2DのSample01）
bool g_Stop = FALSE;			//一時停止フラグ

///////////////////////////////////////
//GetRC－レンダリングコンテキストの取得
//WM_CREATE時に実行する
///////////////////////////////////////
HGLRC GetRC(HWND hWnd) {

	static PIXELFORMATDESCRIPTOR pfd = {
			sizeof(PIXELFORMATDESCRIPTOR),	//この構造体のサイズ
			1,								//OpenGLバージョン（Windowsが利用できるのは1.1のみ）
			PFD_DRAW_TO_WINDOW |			//ウィンドウ描画
			PFD_SUPPORT_OPENGL |			//OpenGL使用
			PFD_DOUBLEBUFFER,				//ダブルバッファ使用
			PFD_TYPE_RGBA,					//RGBAを使用
			24,								//24bit色を使用
			0, 0, 0, 0, 0, 0,				//カラー（RGB）ビット無視
			0, 0,							//アルファ（A）バッファ無し
			0,								//アキュムレーションバッファ不使用
			0, 0, 0, 0,						//アキュムレーションbit無視
			32,								//Zバッファー
			0,								//ステンシルバッファ無し
			0,								//補助バッファ不使用
			PFD_MAIN_PLANE,					//メインレイヤー（レイヤー種類: PFD_MAIN_PLANE、 PFD_OVERLAY_PLANE、 PFD_UNDERLAY_PLANE）
			0,								//予約
			0, 0, 0							//レイヤーマスク不使用
	};
	//出力ウィンドウのデバイスコンテキストを取得
	g_hDC = GetDC(g_hWnd = hWnd);			//対象ウィンドウのハンドルを記録し、デバイスコンテキストを取得
	if(!g_hDC) {
		MessageBox(g_hWnd, "ウィンドウのデバイスコンテキストハンドルの取得に失敗しました。", "エラー", MB_OK | MB_ICONERROR);
		return NULL;
	}
	//同ウィンドウの最適ピクセルフォーマットインデックスを取得
	if((!(g_pixelformat = ChoosePixelFormat(g_hDC, &pfd)))) {	//0が返った場合
		MessageBox(g_hWnd, "ChoosePixelFormat関数が失敗しました。", "エラー", MB_OK | MB_ICONERROR);
		return NULL;
	}
	//最適ピクセルフォーマットの設定
	if(!SetPixelFormat(g_hDC, g_pixelformat, &pfd)) {			//FALSEの場合
		MessageBox(g_hWnd, "SetPixelFormat関数が失敗しました。", "エラー", MB_OK | MB_ICONERROR);
		return NULL;
	}
	//OpenGLレンダリングコンテキストの作成
	if(!(g_hRC = wglCreateContext(g_hDC))) {
		MessageBox(g_hWnd, "OpenGLレンダリングコンテキスト（HGLRC）の生成に失敗しました。", "エラー", MB_OK | MB_ICONERROR);
		return NULL;
	}
	//g_hRCをレンダリングコンテキストに指定し、対象ウィンドウのDCに描画（最後にhRCをNULLにして再度wglMakeCurrentを呼び出し、指定を解除することが必要）
	wglMakeCurrent(g_hDC, g_hRC);
	//OpenGLを使用中にする
	g_GLon = TRUE;
	return g_hRC;
}

///////////////////////////////////////
//OpenGLを使用中か否かのフラグチェック
///////////////////////////////////////
bool IsGL() {
	return g_GLon;
}

////////////////////////////////////////////
//SizeChanged－WM_SIZE時のビューポートの取得
////////////////////////////////////////////
void SizeChanged(LPARAM lParam) {
/*
	//平行投影
	glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));	//ウインドウ全体に表示
	glMatrixMode(GL_PROJECTION);	//投影変換モードへ
	glLoadIdentity();				//投影変換の変換行列を単位行列で初期化
	glOrtho(-1.0, 1.0, -1.0, 1.0, 1.0, -1.0);	//各軸-1.0～1.0で囲まれる立方体の範囲を並行投影
	gluLookAt(	0, 0, 5,	//目のポイント				(GLdouble) eyex, eyey, eyez,
				0, 0, 0,	//シーンの中心を示す参照点	(GLdouble) centerx, centery, centerz,
				0, 1, 0);	//アップベクター			(GLdouble) upx, upy, upz,
	glMatrixMode(GL_MODELVIEW);		//視野変換・モデリング変換モードへ
*/
	//透視投影
	glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
	// 透視変換行列の設定
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(90.0, (double)LOWORD(lParam) / (double)HIWORD(lParam), 10.0, 100.0);
	gluLookAt(	0, 0, 10,	//目のポイント				(GLdouble) eyex, eyey, eyez,
				0, 0, 0,	//シーンの中心を示す参照点	(GLdouble) centerx, centery, centerz,
				0, 1, 0);	//アップベクター			(GLdouble) upx, upy, upz,
	// モデルビュー変換行列の設定
	glMatrixMode(GL_MODELVIEW);
}

///////////////////////////////////////////
//ReleaseRC－レンダリングコンテキストの解放
//WM_DESTROY時に実行する
///////////////////////////////////////////
void ReleaseRC() {

	//カレントレンダリングコンテキストを解放
	wglMakeCurrent(NULL, NULL);
	//レンダリングコンテキストの解放
	wglDeleteContext(g_hRC);
	//対象ウィンドウのデバイスコンテキストを開放
	ReleaseDC(g_hWnd, g_hDC);
	//OpenGLの使用を終了
	g_GLon = FALSE;
}

///////////////////
//描画メニュー処理
///////////////////
bool DrawMenu(int no) {	//引数は新しい描画メニュー番号

	ReleaseRC();	//一旦レンダリングコンテキストを開放する。
	CheckMenuItem(GetSubMenu(GetMenu(g_hWnd), 1), g_DrawMenuNo, MF_BYCOMMAND | MF_UNCHECKED);
	g_DrawMenuNo = no;
	CheckMenuItem(GetSubMenu(GetMenu(g_hWnd), 1), g_DrawMenuNo, MF_BYCOMMAND | MF_CHECKED);
	GetRC(g_hWnd);	//新たにレンダリングコンテキストを取得する。
	return TRUE;
}
