#pragma once

//! @file Mix/Standard.h
//! @brief スタンダードインクルードファイル

/*!
@mainpage Mainpage
ランタイムのメインページです。<br>
はじめての方は @subpage intro_page からお読みください。<br>
また、ライブラリを使用してアプリケーションを作成する際のヒントとして @subpage tips_page もご覧ください。<br>
<ul>
	<li>Mix</li><br>
	ルート<br>
	<li>Mix::Dynamics</li><br>
	物理シミュレーション<br>
	<li>Mix::IO</li><br>
	ファイルなどの入出力<br>
	<li>Mix::Geometry</li><br>
	球、平面、箱( OBB AABB )、視錐台などの簡易形状<br>
	<li>Mix::Graphics</li><br>
	DirectGraphics のラッパー<br>
	<li>Mix::HID</li><br>
	キーボード、マウス、ゲームパッドなどのヒューマンインターフェースデバイス<br>
	<li>Mix::Memory</li><br>
	メモリの操作<br>
	<li>Mix::Parallel</li><br>
	並列処理<br>
	<li>Mix::Scene</li><br>
	ダイナミクス、グラフィックスを統合した３Ｄシーンの作成<br>
	<li>Mix::Sound</li><br>
	サウンドの再生<br>
</ul>
*/

/*!
@page intro_page Introduction

@section creProj_sec Create a project

@subsection creProj_hello_subsec はじめに
Microsoft Visual Studio Community 2013 を使うことを前提としています。<br>
その他開発環境では異なる場合がございますので、ご注意ください。<br>

@subsection creProj_app_subsec アプリケーションの設定
メインメニューの「ファイル」→「新規作成」→「プロジェクト」を選択し、ダイアログを開いてください。<br>
「Win32 コンソールアプリケーション」を選択し、「Windows アプリケーション」を作成します。<br>
「ソリューションエクスプローラー」のプロジェクトを右クリックし、コンテキストメニューの「プロパティ」を選択し、<br>
「構成プロパティ」の以下の項目を設定してください。<br>

@par 「C/C++」
「全般」の「追加のインクルードディレクトリ」に "Mix\Engine\Include" を追加します。<br>

@par 「リンカ」
「全般」の「追加のライブラリディレクトリ」に "Mix\Engine\Lib\VS2013\$(PlatformTarget)\$(Configuration)" を追加します。<br>
「入力」の「追加の依存ファイル」に "Mix.lib" を追加します。<br>

@par 「ビルドイベント」
ランタイム ( "*.dll" ) はアプリケーション ( "*.exe" ) と同じディレクトリに存在している必要があるため、<br>
「ビルド後イベント」の「コマンドライン」にランタイムをコピーするコマンドを入力します。<br>
xcopy "Mix\Engine\Bin\VS2013\$(PlatformTarget)\$(Configuration)\Mix.dll" "$(TargetDir)" /D/ /C /R /Y

@subsection newProj_run_subsec エンジンの初期化から解放
最初に実行される WinMain 関数と、基本的なコードを記述します。<br>

@code
#include "Mix/Standard.h"

int APIENTRY _tWinMain( HINSTANCE, HINSTANCE, LPTSTR, int )
{
    Mix::ENGINE_CONFIG engineConfig;

    if( Mix::Initialize( engineConfig ) == True )
    {
        Mix::IEngine* pEngine = Mix::GetEnginePtr();

        while( pEngine->Update() == True )
        {
            ;
        }

        Mix::Finalize();
    }

    return 0;
}
@endcode

@par 初期化 : Mix::Initialize
Mix::ENGINE_CONFIG 構造体の設定( 今回は規定値を使用しています )を使用し、初期化処理を行います。<br>
また、これ以降 Mix の各種インターフェースが使用できるようになります。<br>

@parメインループ : Mix::IEngine::Update
ウィンドウのメッセージ処理、フレームレートの制御、各種マネージャの更新を行っています。<br>
また Mix::IEngine::Update が True を返している間は更新を継続する必要があります。<br>

@par 解放 : Mix::Finalize
Mix::IEngine::Update が False を返し、メインループを抜けた後は解放処理を行います。<br>
また、取得、作成したインターフェースは、これより前に解放してください。<br>
*/

/*!
@page tips_page Tips
<ul>
	<li>@subpage memory_page "メモリ - Memory"</li>
	<li>@subpage graphics_page "グラフィックス - Graphics"</li>
	<li>@subpage hid_page "インプット - Input"</li>
	<li>@subpage scene_page "シーン - Scene"</li>
</ul>
*/

/*!
@page memory_page Memory

@section memory_buffer メモリの割り当て
<ul>
	<li>メモリを確保</li>
	<ul>
		<li>MIX_MALLOC</li><br>
		サイズ( バイト単位 )を指定してメモリを確保します。<br>
		<li>MIX_MALLOC_T</li><br>
		型と要素の数を指定して、メモリを確保します。<br>
		<li>MIX_ALIGNED_MALLOC</li><br>
		アラインメント、サイズ( バイト単位 )を指定してメモリを確保します。<br>
		<li>MIX_ALIGNED_MALLOC_T</li><br>
		アラインメント、型、要素の数を指定してメモリを確保します。<br>
	</ul>
	<br>
	<li>メモリを再確保</li><br>
	<ul>
		<li>MIX_REALLOC</li><br>
		再確保したいバッファのメモリのポインタ、サイズ( バイト単位 )を指定してメモリを再確保します。<br>
		<li>MIX_REALLOC_T</li><br>
		再確保したいバッファのメモリのポインタ、型、要素の数を指定してメモリを再確保します。<br>
	</ul>
	<br>
	<li>メモリを解放</li>
	<ul>
		<li>MIX_FREE</li>
	</ul>
</ul>
@code
UInt8* pBuff = NULL;
UInt8* pTemp = NULL;

// 通常のメモリの確保、解放
pBuff = ( UInt8* )MIX_MALLOC( sizeof( UInt8 ) * 32 );
MIX_FREE( pBuff );

// アラインメントを指定したメモリの確保、解放
pBuff = ( UInt8* )MIX_ALIGNED_MALLOC( 16, sizeof( UInt8 ) * 32 );
MIX_FREE( pBuff );

// 型を指定したメモリの確保、解放
pBuff = MIX_MALLOC_T( UInt8, 32 );
MIX_FREE( pBuff );

// アラインメント、型を指定したメモリの確保、解放
pBuff = MIX_ALIGNED_MALLOC_T( 16, UInt8, 32 );
MIX_FREE( pBuff );

// メモリの再確保
pBuff = MIX_MALLOC_T( UInt8, 32 );
pTemp = MIX_REALLOC_T( pBuff, UInt8, 64 );
MIX_ASSERT( pTemp != NULL );
pBuff = pTemp;
MIX_FREE( pBuff );
@endcode

@section memory_class クラスのインスタンス化
<ul>
	<li>クラスのインスタンスを作成</li>
	<ul>
		<li>MIX_NEW_T</li><br>
		型、コンストラクタの引数を指定してクラスのインスタンスを作成します。<br>
		<li>MIX_ALIGNED_NEW_T</li><br>
		アラインメント、型、コンストラクタの引数を指定してクラスのインスタンスを作成します。<br>
	</ul>
	<li>クラスのインスタンスを解放</li>
	<ul>
		<li>MIX_DELETE_T</li><br>
		型を指定してクラスのインスタンスを解放します。<br>
		<li>MIX_DELETE_THIS_T</li><br>
		型を指定してクラスの自インスタンスを解放します。( delete this )<br>
	</ul>
</ul>
<ul>
	<li>クラスのインスタンス配列を作成</li>
	<ul>
		<li>MIX_NEW_ARRAY_T<br>
		型を指定してクラスのインスタンス配列を作成します。<br>
		<li>MIX_ALIGNED_NEW_ARRAY_T<br>
		アラインメント、型を指定してクラスのインスタンス配列を作成します。<br>
	</ul>
	<li>クラスのインスタンス配列を解放</li>
	<ul>
		<li>MIX_DELETE_ARRAY_T</li><br>
		型を指定してクラスのインスタンス配列を解放します。<br>
		<li>MIX_DELETE_PTR_ARRAY_T</li><br>
		型を指定してクラスのインスタンスのポインタ配列を解放します。<br>
	</ul>
</ul>
これらのマクロを使用するには、クラスに <b>MIX_DECLARE_ALLOCATOR</b> を記述する必要があります。<br>
@code
class Hoge
{
public:
	MIX_DECLARE_ALLOCATOR();

public:
	Hoge( void );
	~Hoge( void );
};

Hoge* pHoge = NULL;
Hoge* pHogeArray = NULL;
Hoge* pHogePtrArray = NULL;

// 通常のインスタンスの作成、解放
pHoge = MIX_NEW_T( Hoge );
MIX_DELETE_T( Hoge, pHoge );

// アラインメントを指定したインスタンスの作成、解放
pHoge = MIX_ALIGNED_NEW_T( 16, Hoge );
MIX_DELETE_T( Hoge, pHoge );

// 通常のインスタンス配列の作成、解放
pHogeArray = MIX_NEW_ARRAY_T( Hoge, 8 );
MIX_DELETE_ARRAY_T( Hoge, pHogeArray );

// アラインメントを指定したのインスタンス配列の作成、解放
pHogeArray = MIX_ALIGNED_NEW_ARRAY_T( 16, Hoge, 8 );
MIX_DELETE_ARRAY_T( Hoge, pHogeArray );

// インスタンスポインタ配列の作成、解放
pHogePtrArray = MIX_NEW_ARRAY_T( Hoge*, 8 );
MIX_DELETE_PTR_ARRAY_T( Hoge, pHogePtrArray );

@endcode
また、通常は使用しませんが、何かしらの理由で Windows 標準のメモリアロケータを使用したい場合は、以下のマクロを使用してください。<br>
<ul>
	<li>インスタンスの作成</li><br>
	<ul>
		<li>MIX_NEW ( new )</li>
	</ul>
	<li>インスタンスの破棄</li><br>
	<ul>
		<li>MIX_DELETE ( delete )</li>
		<li>MIX_DELETE_THIS ( delete this )</li>
		<li>MIX_DELETE_ARRAY ( delete [] )</li>
	</ul>
</ul>
*/

/*!
@page graphics_page Graphics

@section graphics_shaderModel_sec シェーダーモデル
Mix は複数のシェーダーモデルをサポートしています。<br>
また、エンジンの作成時に指定するシェーダーモデルによって使用する DirectX のバージョン、機能レベルが異なります。<br>
<table>
	<tr>
		<td></td>
		<th>DirectX のバージョン</th>
		<th>機能レベル</th>
	</tr>
	<tr>
		<th align="left">シェーダーモデル3 ※1</th>
		<td align="center">DirectX9</td>
		<td align="center"></td>
	</tr>
	<tr>
		<th align="left">シェーダーモデル4 ※2</th>
		<td align="center">DirectX11</td>
		<td align="center">10.0</td>
	</tr>
	<tr>
		<th align="left">シェーダーモデル5 ※2</th>
		<td align="center">DirectX11</td>
		<td align="center">11.0</td>
	</tr>
</table>
<b>※1 DirectX9 に機能レベルはありません</b><br>
<b>※2 Windows Vista は更新プログラム( KB971644 )が適用されていない場合は動作しません</b><br>
*/

/*! 
@page hid_page HID

@section input_keyboard キーボード
全てのキーボードに対応する場合は、NUMパッドなどの依存するキーの入力は避けてください。<br>

@section input_mouse_subsec マウス
一部のマウス(ポインティングデバイス)は入力を受け付けない可能性があります。<br>
現在入力を受けつるものとして以下のものがあります。<br>
<ul>
	<li>デスクトップでの相対座標を返すデバイス</li><br>
	マウスなど。<br>
	<li>仮想デスクトップでの絶対座標を返すデバイス</li><br>
	ペンタブレットなど。<br>
</ul>

@section input_gamepad_subsec ゲームパッド
振動機能は対応していません。<br>
*/

/*!
@page scene_page Scene

@section scene_lighting_subsec ライティング
Mix では ディレクショナルライト、半球ライトなどのシーン全体に対してライティングを行うライトのことを<b>グローバルライト</b>、<br>
ポイントライト、スポットライトなどの部分的にライティングを行うライトのことを<b>ローカルライト</b>と総称しています。<br>
<ul>
	<li>ローカルライトについて</li><br>
	ローカルライトは部分的なライティングを行うため、シーンに配置されているオブジェクトに対して効果範囲にはいっているかどうかを判定します。<br>
	またローカルライトによるライティングはコストが高く、オブジェクトに対して４本までしか適用することができないため、<br>
	必要がない場合は Mix::Scene::IEntity::SetLocalLighting メソッドで False を設定することお勧めします。<br>
</ul>

@section scene_refraction_subsec 屈折効果
ウォータータイプのマテリアルでウェーブアニメーションを<b>屈折効果</b>にしている場合に機能します。<br>
また、屈折効果は視点が水中にあるかどうかを判定してから行われるため、シーンに ウォータープール ( Mix::Scene::IWaterPool ) を追加し、<br>
Mix::Scene::IWaterPool::SetRefraction メソッドで True を設定する必要があります。<br>
<ul>
	<li>水面のメッシュについて</li>
	屈折は特殊な処理であるため、水面のメッシュ( プレーンであることが望ましい )は XZ平面 に水平になるようにしてください。<br>
	XZ平面に対して、垂直なものは屈折処理が正しく動作しませんので注意してください。<br>
	<li>オブジェクトを配置する際の注意点</li><br>
	静的なオブジェクトの場合は Mix::Scene::IEntity::SetDefaultWaterContainsResult で屈折面との位置関係をあらかじめ設定しておいてください。<br>
	そうすることによって毎フレーム、屈折面との交差判定を行うことがなくなるため、パフォーマンンスがよくなります。<br>
	また、半透明指定のマテリルが設定されているモデル、ウィジェットはなるべく配置しないようにしてください。<br>
	半透明ポリゴンは内部処理の関係で屈折面の後ろと前に２回に分けて描画する必要があるため事前処理が発生し、パフォーマンスが低下します。<br>
	また、屈折面と重なっている場合、屈折面より下、屈折面より上の半透明ポリゴンの後ろも屈折効果は行われますが、<br>
	屈折面と重なっている部分が輪切りのようになりビジュアル的によくありませんので、なるべくそのような配置は避けてください。<br>
</ul>
@section scene_optimizeWidget_subsec ウィジェットの最適化
ウィジェットには<b>プランター</b>、<b>パーティクル</b>と複数ありますが、レンダラー内部では同じものとして扱って処理しています。<br>
また毎フレーム プリミティブを生成するため、ポイントライト スポットライトによるライティング、マテリアルの設定、パーティクルの発生量にともないパーフォーマンスに大きく影響を及ぼします。<br>
<ul>
	<li>プランターについて</li><br>
	マテリアルは深度の書き込みをしない ( Mix::Scene::IDefaultMaterial::IsZWrite() == False ) ようにし、<br>
	一括描画 ( Mix::Scene::IMaterial::GetTransparencyMethod() == Mix::Scene::IMaterial::TM_LUMP )にします。<br>
	また、深度の書き込み、一括描画の設定は モデルエディター で設定することができます。<br>
	<br>
	<li>パーティクルについて</li><br>
	マテリアルの<b>ブレンド</b>が<b>加算</b>の場合は、深度の書き込みをしないようにし、一括描画にします。<br>
	それ以外の場合は通常 <b>ポリゴン単位で描画</b> にします。<br>
	またパーティクルのスプライトは発生順に並んでいるため、見た目にそれほど影響しないようでしたら、<b>一括描画</b>を推奨します。<br>
	<br>
	<li>スポットライト、ポイントライトによるライティングについて</li><br>
	基本的には行わないようにすることがもっとも最適です。<br>
	パーティクルのスプライトはブレンドの関係から奥から手前に向かって描画されるため、<br>
	ライティングの異なるものどうしが入れ子になり切り替えが多く発生した場合、<b>大幅なパフォーマンスの低下</b>につながる可能性があります。<br>
	またレンダラーにはこの状態を緩和するための<b>ライティングモード</b>という機能が備わっています。<br>
	<br>
	<ul>
		<li>Default</li><br>
		ディレクショナルライト、半球ライトによる<b>グローバルライティング</b>のみで、<br>
		スポットライト、ポイントライトによる<b>ローカルライティング</b>は行われません。<br>
		<li>Everyone</li><br>
		視界に入っている全てのウィジェットをひとまとめにし、ローカルライティングを行います。<br>
		また、ローカルライティングに使用される、スポットライト、ポイントライトの合計は４つに限定されます。<br>
		<li>Detailed</li><br>
		ウィジェット単位でローカルライティングを行います。<br>
		ローカルライトによるライティングは可能な限り正しく行われますが、パフォーマンスは最悪です。<br>
	</ul>
</ul>

@section scene_posteffect_subsec ポストエフェクト
<ul>
	<li>アンビエントオクルージョン</li><br>
	物体により光が遮断されている場所に影を落とします。<br>
	また、半透明オブジェクト ( ウィジェットも含む ) に対して実行することはできません。<br>
	<li>シャドウマッピング</li><br>
	物体の影を描写します。<br>
	また、パーティクルの影は描画することができません。<br>
	<li>ルミノシティ</li><br>
	シーンの輝度による階調補正を行います。<br>
	また、明暗順応により、階調補正が変化します。<br>
	<li>ブルーム</li><br>
	シーンの明るいと思われる部分に対し、輝き、発光しているかのような効果をだします。<br>
	<li>ライトシャフト</li><br>
	物体の隙間からさす、木漏れ日のような効果をだします。<br>
	また、ゴッドレイ、光芒とも呼ばれています。<br>
	<li>レンズフレア</li><br>
	明るい光源( 太陽など )がレンズに向けて当てられている際に反射を繰り返してできた光の写りこみを表現します。<br>
	<li>フィルミック</li><br>
	主に、輝度( ルミノシティ )により階調補正されたシーン( RGBの要素が 1.0 を超えている )の色合いを調整するためのものです。<br>
	また、必要に応じて<b>ガンマ補正</b>を行う必要がります。<br>
	<li>ガンマ補正</li><br>
	シーンの明るさを調整します。<br>
	<li>モーションブラー</li><br>
	カメラの動きによってブラーをかけます。<br>
	また、カメラが大きく動いた際につむじのような模様が出てしまう場合は、<br>
	動きを小さくするか Mix::Scene::ICamera::MOTION_BLUR_SETTINGS 構造体の スケール( scale )、減衰値( damping )を調整してください。<br>
	<li>色収差</li><br>
	光がレンズを通過した際の分散により発生した色ずれを表現します。<br>
	また、この効果は画面の周囲に現れます。<br>
	<li>被写界深度</li><br>
	焦点範囲により、シーンの手前と奥に向かって徐々にぼける効果をだします。<br>
	<li>歪曲収差</li><br>
	レンズの影響により画面が歪む効果をだします。<br>
	<li>ヴィネット</li><br>
	トイカメラで撮った様な画面の周囲が黒ずむレトロな効果をだします。<br>
	<li>アンチエイリアシング</li><br>
	ジャギーを軽減します。<br>
</ul>
*/

#include "Mix/Common.h"
#include "Mix/IEngine.h"
