
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

	FILE	: Clipping.cpp

+ ------ Explanation of file --------------------------------------------------------------------------

	○×つくろーどっとコムより引用、改変
	http://marupeke296.com/DXG_No54_StencilClipping.html

+ _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

#include "Common.h"

#include "Clipping.h"

// マスク作成開始
void Clipping::beginMask(bool isExcept)
{
	int init, write;
	// 逆マスク
	if(isExcept){
		init = MASK_FILL;		// 初期は全て描画不可
		write = MASK_TRANS;		// マスク部分の描画を許可
	}
	// 通常マスク
	else{
		init = MASK_TRANS;		// 初期は全て描画可能
		write = MASK_FILL;		// マスク部分の描画を制限
	}

	// 描画されたものをマスクに置き換える
	GetDevice()->Clear(0, NULL, D3DCLEAR_STENCIL, 0, 1.0f, init);			// ステンシルの初期化
	GetDevice()->GetRenderState(D3DRS_ZENABLE, &m_zTest);					// Zテスト保存
	GetDevice()->GetRenderState(D3DRS_ZFUNC,   &m_zFunc);					// Z比較関数保存
	GetDevice()->SetRenderState(D3DRS_ZENABLE,	true);						// Zテスト有効
	GetDevice()->SetRenderState(D3DRS_ZFUNC,	D3DCMP_NEVER);					// ただし描画許可しない
	GetDevice()->SetRenderState(D3DRS_STENCILENABLE,true);					// ステンシル有効
	GetDevice()->SetRenderState(D3DRS_STENCILFUNC,  D3DCMP_ALWAYS);			// 全書き込み許可
	GetDevice()->SetRenderState(D3DRS_STENCILPASS,	D3DSTENCILOP_REPLACE);	// 書き込み情報をREFに置き換える
	GetDevice()->SetRenderState(D3DRS_STENCILZFAIL,	D3DSTENCILOP_REPLACE);	// Zテスト全失敗、ステンシルは許可
	GetDevice()->SetRenderState(D3DRS_STENCILREF,	write);					// 置き換える数値
	GetDevice()->SetRenderState(D3DRS_STENCILMASK,	MASK_NON);				// AND除外値、全許可
}
// マスク作成終了
void Clipping::endMask(void)
{
	// Zバッファ復活
	GetDevice()->SetRenderState(D3DRS_STENCILENABLE,false);	// ステンシル無効
	GetDevice()->SetRenderState(D3DRS_ZENABLE,		m_zTest);	// Zテストを元に戻す
	GetDevice()->SetRenderState(D3DRS_ZFUNC,		m_zFunc);	// Z比較関数も戻す
}
// クリッピング描画開始
void Clipping::beginClip(void)
{
	// マスク部分以外を描画許可
	GetDevice()->SetRenderState(D3DRS_STENCILENABLE,true);
	GetDevice()->SetRenderState(D3DRS_STENCILFUNC,	D3DCMP_NOTEQUAL);		// REFでなければ書き込み許可
	GetDevice()->SetRenderState(D3DRS_STENCILPASS,	D3DSTENCILOP_KEEP);	// ステンシルは更新しない
	GetDevice()->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);	// Zテストも更新しない
	GetDevice()->SetRenderState(D3DRS_STENCILREF,	MASK_FILL);			// 書き込み許可されない値
	GetDevice()->SetRenderState(D3DRS_STENCILMASK,	MASK_NON);				// AND除外値、全許可
}
// クリッピング描画終了
void Clipping::endClip(void)
{
	// ステンシルを無効化しバッファをクリア
	GetDevice()->SetRenderState(D3DRS_STENCILENABLE, false);				// ステンシル無効
	GetDevice()->Clear(0, NULL, D3DCLEAR_STENCIL, 0, 1.0f, MASK_TRANS);	// 透過でクリア
}

