#pragma once

/*!
@page intro_graphics_page Graphics
@section intro_graphics_textureLoader_sec TextureLoader

<ol type="1">
	<li><b>プロジェクトの作成</b></li><br>
	メインメニューの「ファイル」→「新規作成」→「プロジェクト」を選んで、「Win32 コンソールアプリケーション」で 空のDLLのプロジェクトを作成します。<br>
	次にプロジェクトのプロパティを開き、「構成プロパティ」→「C/C++」→「全般」にある「追加のインクルードディレクトリ」に Mix のインクルードファイルがあるディレクトリ(※)を指定します。<br>
	<br>
	※ "Mix\Engine\Include\"<br>

	<li><b>DLL エクスポートのソースファイルの作成</b></li><br>
	プロジェクトに <b>"main.cpp"</b> を追加し、以下の関数を実装します。<br>
	<ul>
		<li><b>Mix::Plugin::INFORMATION __stdcall GetInformation ( void )</b></li><br>
		このプラグインの情報を取得する関数です。<br>

		<li><b>Int32 __stdcall Load ( Mix::Plugin::IReader* pSrc, Mix::Plugin::Graphics::ITextureKit* pDst )</b></li><br>
		テクスチャをロードする関数であり Mix::Plugin::Graphics::TEXTURE_PLUGIN_RESULT 列挙定数のいずれかを返す必要があります。<br>
		<br>
		<ul>
			<li>ソース ( pSrc )</li><br>
			テクスチャの元になるデータになります。<br>
			このソースからデータを読み取り、キットに設定、展開をします。<br>
			<br>
			<li>キット ( pDst )</li><br>
			ソースから読み取ったデータをテクスチャにする直前の構成になります。<br>
			キットは基本設定として、<b>タイプ、フォーマット、サイズ、深度、ミップレベル、フラグ</b>があります。<br>
			これらは、以下のメソッドを使用して設定します。<br>
			<br>
			Mix::Plugin::Graphics::ITextureKit::SetType<br>
			Mix::Plugin::Graphics::ITextureKit::SetFormat<br>
			Mix::Plugin::Graphics::ITextureKit::SetSize<br>
			Mix::Plugin::Graphics::ITextureKit::SetDepth<br>
			Mix::Plugin::Graphics::ITextureKit::SetMipLevels<br>
			Mix::Plugin::Graphics::ITextureKit::SetFlags<br>
			<br>
			また、タイプ、サイズ、深度、ミップレベル数、フラグによって、数、レイアウトが変化する、<b>サブリソース</b>というものがあります。<br>
			サブリソースとは、メインイメージ、ミップマップイメージなどの部分的なリソースのことをいい、<br>
			Mix::Plugin::Graphics::ITextureKit::AddSubResourceData メソッドを使用して追加します。<br>
			サブリースのレイアウトを以下に提示します。<br>
			<br>
			<ul>
				<li>Type = <b>PLANE</b> Size = <b>128x128</b> MipLevels = <b>8</b></li><br>
				プレーンテクスチャは MipLevels 分のサブリソースを必要とし、深度は無視されます。<br>
				<br>
				<ul>
					<li>MipLevel = 1 Size = 128x128</li>
					<li>MipLevel = 2 Size = 64x64</li>
					<li>MipLevel = 3 Size = 32x32</li>
					<li>MipLevel = 4 Size = 16x16</li>
					<li>MipLevel = 5 Size = 8x8</li>
					<li>MipLevel = 6 Size = 4x4</li>
					<li>MipLevel = 7 Size = 2x2</li>
					<li>MipLevel = 8 Size = 1x1</li>
				</ul>
				<br>
				<li>Type = <b>VOLUME</b> Size = <b>64x64</b> MipLevels = <b>7</b> Depth ( Slice ) = <b>4</b></li><br>
				ボリュームテクスチャは MipLevels 分のサブリソースを必要とします。<br>
				また、Slice はミップレベルが上がるにつれて半分になっていきますが、0 になることはありません。<br>
				<br>
				<ul>
					<li>MipLevel = 1 Slice = 4</li>
					<ul>
						<li>Slice = 1/4 Size = 64x64</li>
						<li>Slice = 2/4 Size = 64x64</li>
						<li>Slice = 3/4 Size = 64x64</li>
						<li>Slice = 4/4 Size = 64x64</li>
					</ul>
					<li>MipLevel = 2 Slice = 2</li>
					<ul>
						<li>Slice = 1/2 Size = 32x32</li>
						<li>Slice = 2/2 Size = 32x32</li>
					</ul>
					<li>MipLevel = 3 Slice = 1</li>
					<ul>
						<li>Slice = 1/1 Size = 16x16</li>
					</ul>
					<li>MipLevel = 4 Slice = 1</li>
					<ul>
						<li>Slice = 1/1 Size = 8x8</li>
					</ul>
					<li>MipLevel = 5 Slice = 1</li>
					<ul>
						<li>Slice = 1/1 Size = 4x4</li>
					</ul>
					<li>MipLevel = 6 Slice = 1</li>
					<ul>
						<li>Slice = 1/1 Size = 2x2</li>
					</ul>
					<li>MipLevel = 7 Slice = 1</li>
					<ul>
						<li>Slice = 1/1 Size = 1x1</li>
					</ul>
				</ul>
				<br>
				<li>Type = <b>CUBE</b> Size = <b>256x256</b> MipLevels = <b>9</b></li><br>
				キューブテクスチャは 1 〜 6 面 * MipLevels のサブリソースを必要とし、深度は無視されます。<br>
				また、面の順序は Mix::Plugin::Graphics::ITextureKit::FLAG に定義されている CUBE_??? の並びと同じになり、<br>
				サブリソースとして追加される面を Mix::Plugin::Graphics::ITextureKit::SetFlags メソッドで設定しておく必要があります。<br>
				以下のレイアウトは、6 面全てのフラグを設定したものになります。<br>
				<br>
				<ul>
					<li>POSITIVEX ( 正方向のＸ面 )</li>
					<ul>
						<li>MipLevel = 1 Size = 256x256</li>
						<li>MipLevel = 2 Size = 128x128</li>
						<li>MipLevel = 3 Size = 64x64</li>
						<li>MipLevel = 4 Size = 32x32</li>
						<li>MipLevel = 5 Size = 16x16</li>
						<li>MipLevel = 6 Size = 8x8</li>
						<li>MipLevel = 7 Size = 4x4</li>
						<li>MipLevel = 8 Size = 2x2</li>
						<li>MipLevel = 9 Size = 1x1</li>
					</ul>
					<li>NEGATIVEX ( 負方向のＸ面 )</li>
					<ul>
						<li>MipLevel = 1 Size = 256x256</li>
						<li>MipLevel = 2 Size = 128x128</li>
						<li>MipLevel = 3 Size = 64x64</li>
						<li>MipLevel = 4 Size = 32x32</li>
						<li>MipLevel = 5 Size = 16x16</li>
						<li>MipLevel = 6 Size = 8x8</li>
						<li>MipLevel = 7 Size = 4x4</li>
						<li>MipLevel = 8 Size = 2x2</li>
						<li>MipLevel = 9 Size = 1x1</li>
					</ul>
					<li>POSITIVEY ( 正方向のＹ面 )</li>
					<ul>
						<li>MipLevel = 1 Size = 256x256</li>
						<li>MipLevel = 2 Size = 128x128</li>
						<li>MipLevel = 3 Size = 64x64</li>
						<li>MipLevel = 4 Size = 32x32</li>
						<li>MipLevel = 5 Size = 16x16</li>
						<li>MipLevel = 6 Size = 8x8</li>
						<li>MipLevel = 7 Size = 4x4</li>
						<li>MipLevel = 8 Size = 2x2</li>
						<li>MipLevel = 9 Size = 1x1</li>
					</ul>
					<li>NEGATIVEY ( 負方向のＹ面 )</li>
					<ul>
						<li>MipLevel = 1 Size = 256x256</li>
						<li>MipLevel = 2 Size = 128x128</li>
						<li>MipLevel = 3 Size = 64x64</li>
						<li>MipLevel = 4 Size = 32x32</li>
						<li>MipLevel = 5 Size = 16x16</li>
						<li>MipLevel = 6 Size = 8x8</li>
						<li>MipLevel = 7 Size = 4x4</li>
						<li>MipLevel = 8 Size = 2x2</li>
						<li>MipLevel = 9 Size = 1x1</li>
					</ul>
					<li>POSITIVEZ ( 正方向のＺ面 )</li>
					<ul>
						<li>MipLevel = 1 Size = 256x256</li>
						<li>MipLevel = 2 Size = 128x128</li>
						<li>MipLevel = 3 Size = 64x64</li>
						<li>MipLevel = 4 Size = 32x32</li>
						<li>MipLevel = 5 Size = 16x16</li>
						<li>MipLevel = 6 Size = 8x8</li>
						<li>MipLevel = 7 Size = 4x4</li>
						<li>MipLevel = 8 Size = 2x2</li>
						<li>MipLevel = 9 Size = 1x1</li>
					</ul>
					<li>NEGATIVEZ ( 負方向のＺ面 )</li>
					<ul>
						<li>MipLevel = 1 Size = 256x256</li>
						<li>MipLevel = 2 Size = 128x128</li>
						<li>MipLevel = 3 Size = 64x64</li>
						<li>MipLevel = 4 Size = 32x32</li>
						<li>MipLevel = 5 Size = 16x16</li>
						<li>MipLevel = 6 Size = 8x8</li>
						<li>MipLevel = 7 Size = 4x4</li>
						<li>MipLevel = 8 Size = 2x2</li>
						<li>MipLevel = 9 Size = 1x1</li>
					</ul>
				</ul>
			</ul>
		</ul>
	</ul>

	<li><b>DLL エクスポートのモジュール定義ファイルの作成</b></li><br>
	プロジェクトに以下のモジュール文を記述したファイル <b>"main.def"</b> を追加してください。<br>

	<pre><b>EXPORTS</b>
	<b>GetInformation</b>
	<b>Load</b></pre>
	
	最後にプロジェクトのプロパティの「構成プロパティ」→「リンカ」→「入力」にある「モジュール定義ファイル」に "main.def" を指定してください。

</ol>
*/

#include "Mix/Plugin/Common.h"
#include "Mix/Plugin/IReader.h"

namespace Mix{ namespace Plugin{ namespace Graphics{

	//! @enum TEXTURE_PLUGIN_RESULT
	//! @brief テクスチャプラグインリザルト列挙定数
	enum TEXTURE_PLUGIN_RESULT
	{
		TP_NOT_SUPPORTED	= 1,	//!< サポートされていない
		TP_OK				= 0,	//!< 成功
		TP_ILLEGAL_FORMAT	= -1,	//!< 不正なフォーマット( 継続不可 )
		TP_OUT_OF_MEMORY	= -2,	//!< システムメモリが不足( 継続不可 )
		TP_FATAL_ERROR		= -3,	//!< 致命的なエラー
	};

	//! @class ITextureKit
	//! @brief テクスチャキットインターフェース
	class ITextureKit
	{
	public:
		//! @enum TYPE
		//! @brief タイプ列挙定数
		enum TYPE
		{
			PLANE	= 0,	//!< プレーンテクスチャ
			CUBE	= 1,	//!< キューブテクスチャ
			VOLUME	= 2,	//!< ボリュームテクスチャ
		};

		//! @enum FLAG
		//! @brief フラグ列挙定数
		enum FLAG
		{
			CUBE_POSITIVEX = 0x00000001,	//!< キューブの正方向のＸ面
			CUBE_NEGATIVEX = 0x00000002,	//!< キューブの負方向のＸ面
			CUBE_POSITIVEY = 0x00000004,	//!< キューブの正方向のＹ面
			CUBE_NEGATIVEY = 0x00000008,	//!< キューブの負方向のＹ面
			CUBE_POSITIVEZ = 0x00000010,	//!< キューブの正方向のＺ面
			CUBE_NEGATIVEZ = 0x00000020,	//!< キューブの負方向のＺ面
		};

		//! @enum FORMAT
		//! @brief フォーマット列挙定数
		enum FORMAT
		{
			R8G8B8A8	= 0,	//!< 各チャンネルが 8Bit の RGBA フォーマット

			BC1			= 1,	//!< BC1 フォーマット
			BC2			= 2,	//!< BC2 フォーマット
			BC3			= 3,	//!< BC3 フォーマット
		};

	protected:
		//! @brief デストラクタ
		virtual ~ITextureKit( void ) {}

	public:
		//! @brief タイプを設定します
		//! @param[in] type タイプを表す Mix::Plugin::Graphics::ITextureKit::TYPE 列挙定数
		virtual void SetType( Mix::Plugin::Graphics::ITextureKit::TYPE type ) = 0;
		//! @brief フォーマットを設定します
		//! @param[in] format フォーマットを表す Mix::Plugin::Graphics::ITextureKit::FORMAT 列挙定数
		virtual void SetFormat( Mix::Plugin::Graphics::ITextureKit::FORMAT format ) = 0;
		//! @brief サイズを設定します
		//! @param[in] width 幅
		//! @param[in] height 高さ
		virtual void SetSize( unsigned int width, unsigned int height ) = 0;
		//! @brief 深度を設定します
		//! @param[in] depth 深度
		//! @note ボリュームテクスチャのスライス数になります。
		virtual void SetDepth( unsigned int depth ) = 0;
		//! @brief ミップマップの数を設定します
		//! @param[in] mipLevels ミップマップの数
		virtual void SetMipLevels( unsigned int mipLevels ) = 0;
		//! @brief フラグを設定します
		//! @param[in] flags Mix::Plugin::Graphics::ITexture::FLAG 列挙定数の組み合わせ
		virtual void SetFlags( unsigned int flags ) = 0;

		//! @brief サブリソースを追加します
		//! @param[in] memSize メモリのサイズ( バイト単位 )
		//! @param[in] memRowPitch メモリの一線のサイズ( バイト単位 )
		//! @param[in] memSlicePitch 次のメモリまでの距離( バイト単位 )
		//! @return memSize だけ確保したメモリのポインタを返します。
		virtual void* AddSubResourceData( unsigned int memSize, unsigned int memRowPitch, unsigned int memSlicePitch = 0 ) = 0;
		//! @brief サブリソースを追加します
		//! @param[in] pMem メモリのポインタ
		//! @param[in] memSize メモリのサイズ( バイト単位 )
		//! @param[in] memRowPitch メモリの一線のサイズ( バイト単位 )
		//! @param[in] memSlicePitch 次のメモリまでの距離( バイト単位 )
		virtual void AddSubResourceData( const void* pMem, unsigned int memSize, unsigned int memRowPitch, unsigned int memSlicePitch = 0 ) = 0;
	};

}}}
