
#define __SHADER_CPP__

//--------------------
// 組み込みファイル名
//--------------------
#ifdef _DEBUG
#include <stdio.h>
#include <assert.h>
#endif

#include "shader.h"

////////////////////////////////////////////////////////////////////////////////
#ifdef _DEBUG
void __debug_printf(char *fmt, ...)
{
	va_list ap;
	#define _PRINT_CHAR_MAX 128
	char buf[_PRINT_CHAR_MAX];
	va_start(ap,fmt);
	vsprintf(buf,fmt,ap);
	va_end(ap);
	OutputDebugString(buf);
}
#define _Trace		__debug_printf
#define _Assert(f,s) 					\
	if (!(f)) {							\
		if((s)){						\
			_Trace(s);					\
		}								\
		_Trace("Assertion failed.\n");	\
		DebugBreak();					\
	}
#else
#define _Trace			1 ? (void)0 : __debug_printf
#define	_Assert(f,s)	((void)0)
#endif

////////////////////////////////////////////////////////////////////////////////
static LPDIRECT3DDEVICE9 g_pD3DDev = NULL;

////////////////////////////////////////////////////////////////////////////////

//----------------
// コンストラクタ
//----------------
CShader::CShader()
{
	m_pVertexShader		= NULL;
	m_pPixelShader		= NULL;

	m_pVertexConstTbl	= NULL;
	m_pPixelConstTbl	= NULL;
}

//--------------
// デストラクタ
//--------------
CShader::~CShader()
{
	if(m_pVertexShader != NULL){
		IDirect3DVertexShader9_Release(m_pVertexShader);
		if(m_pVertexConstTbl != NULL){
			m_pVertexConstTbl->Release();
		}
	}
	if(m_pPixelShader != NULL){
		IDirect3DPixelShader9_Release(m_pPixelShader);
		if(m_pPixelConstTbl != NULL){
			m_pPixelConstTbl->Release();
		}
	}
}

//------------------
// メモリを確保する
//------------------
CShader *CShader::allocate(void)
{
	return(new CShader());
}

//------------------
// メモリを解放する
//------------------
void CShader::dispose(CShader *&shd)
{
	if(shd != NULL){
		delete shd;
		shd = NULL;
	}
}

//------------------------------
// 頂点シェーダをコンパイルする
//------------------------------
int CShader::compileVertexShader(const char *pFileName, const char *pProfile)
{
	HRESULT result;
	LPD3DXBUFFER pBinShader;
	result = D3DXCompileShaderFromFile(pFileName, NULL, NULL, "main", pProfile, 0, &pBinShader, NULL, &m_pVertexConstTbl);
	if( FAILED(result) ){ 
		_Assert(0,"Vertex Shader Compile Failed\n");
		return(-1);
	}
	result = g_pD3DDev->CreateVertexShader( (DWORD*)pBinShader->GetBufferPointer(), &m_pVertexShader );
	if( FAILED(result) ){ 
		_Assert(0,"Vertex Shader Creation Failed\n");
		return(-2);
	}
	pBinShader->Release();
	return(0);
}

//----------------------------------
// ピクセルシェーダをコンパイルする
//----------------------------------
int CShader::compilePixelShader(const char *pFileName, const char *pProfile)
{
	HRESULT result;
	LPD3DXBUFFER pBinShader;
	result = D3DXCompileShaderFromFile(pFileName, NULL, NULL, "main", pProfile, 0, &pBinShader, NULL, &m_pPixelConstTbl);
	if( FAILED(result) ){ 
		_Assert(0,"Pixel Shader Compile Failed\n");
		return(-1);
	}
	result = g_pD3DDev->CreatePixelShader( (DWORD*)pBinShader->GetBufferPointer(), &m_pPixelShader );
	if( FAILED(result) ){ 
		_Assert(0,"Pixel Shader Creation Failed\n");
		return(-2);
	}
	pBinShader->Release();
	return(0);
}

//----------------------
// シェーダをビルドする
//----------------------
int CShader::buildShader(LPDIRECT3DDEVICE9 pD3DDev, const char *pVertexFileName, const char *pVertexProfile, const char *pPixelFileName, const char *pPixelProfile)
{
	g_pD3DDev = pD3DDev;

	int result = 0;
	if(pVertexFileName != NULL){
		// 頂点シェーダをコンパイルする
		result = compileVertexShader(pVertexFileName, pVertexProfile);
		if(result < 0) return(-1);
	}
	if(pPixelFileName != NULL){
		// ピクセルシェーダをコンパイルする
		result = compilePixelShader(pPixelFileName, pPixelProfile);
		if(result < 0) return(-1);
	}
	return(result);
}
