# 独自ローダーの設定

## 概要

Effekseerでは基本的な読込はサポートしておりますが、実際開発の場で使用できるような読込になっていません。そのため、ローダークラスを追加し、ファイルの読込方法を拡張します。

## エフェクトファイルの読込

エフェクトファイルを読み込むには「::Effekseer::EffectLoader」クラスを継承し、「::Effekseer::Manager::SetEffectLoader」にて設定します。 実際に、通常のファイルシステムから読み込むためのクラスを記述してみます。Load関数でメモリを確保し、Unload関数でメモリを破棄します。

    class EffectLoader : public ::Effekseer::EffectLoader {
    public:
    	EffectLoader() {}
    	virtual ~EffectLoader() {}
    	bool Load( const EFK_CHAR* path, void*& data, int32_t& size );
    	void Unload( void* data, int32_t size );
    };

    bool EffectLoader::Load( const EFK_CHAR* path, void*& data, int32_t& size ) {
    	data = NULL;
    	size = 0;

    	FILE* fp = _wfopen( (const wchar_t*)path, L"rb" );
    	if( fp == NULL ) return false;

    	fseek( fp, 0, SEEK_END );
    	size = (int32_t)ftell( fp );
    	data = new uint8_t[size];
    	fseek( fp, 0, SEEK_SET );
    	fread( data, 1, size, fp );
    	fclose( fp );

    	return true;
    }

    void EffectLoader::Unload( void* data, int32_t size ) {
    	if( data != NULL ) delete [] data;
    }

    // 設定する。
    manager->SetEffectLoader( new EffectLoader() );

## テクスチャファイルの読込

テクスチャファイルを読み込むには「::Effekseer::TextureLoader」クラスを継承し、「::Effekseer::Manager::SetTextureLoader」にて設定します。 実際に、DirectX9にて通常のファイルシステムから読み込むためのクラスを記述してみます。Load関数でテクスチャを読み込み、Unload関数でテクスチャを破棄します。

現在(バージョン0.54)、OpenGL版の場合、テクスチャはミップマップを持つ必要があります。

    class TextureLoader : public ::Effekseer::TextureLoader {
    private:
    	::EffekseerRenderer::Renderer*	m_renderer;

    public:
    	TextureLoader( ::EffekseerRenderer::Renderer* renderer ) { m_renderer = renderer; }
    	virtual ~TextureLoader() {}
    	void* Load( const EFK_CHAR* path );
    	void Unload( void* data );
    };

    void* TextureLoader::Load( const EFK_CHAR* path ) {
    	FILE* fp_texture = _wfopen( (const wchar_t *)path, L"rb" );

    	if( fp_texture != NULL ) {
    		IDirect3DTexture9* texture = NULL;

    		fseek( fp_texture, 0, SEEK_END );
    		size_t size_texture = ftell( fp_texture );
    		char* data_texture = new char[size_texture];
    		fseek( fp_texture, 0, SEEK_SET );
    		fread( data_texture, 1, size_texture, fp_texture );
    		fclose( fp_texture );

    		D3DXCreateTextureFromFileInMemory( m_renderer->GetDevice(), data_texture, size_texture, &texture );

    		delete [] data_texture;

    		return (void*)texture;
    	}

    	return NULL;
    }

    void TextureLoader::Unload( void* data ) {
    	if( data != NULL ) {
    		IDirect3DTexture9* texture = (IDirect3DTexture9*)data;
    		texture->Release();
    	}
    }

    // 設定する。
    manager->SetTextureLoader( new TextureLoader() );

## 相対パスの問題

テクスチャファイルの場合、渡されるパスはツールで保存した時のテクスチャへの相対パスとなっています。多くの場合、エフェクトファイルを読み込んだ時、エフェクトファイルからの相対パスの位置のテクスチャを読み込む必要があります。その方法として、一例を記述します。TextureLoaderクラスにファイルパスを持たせれるようにし、「::Effekseer::Create::Effect::Create」を実行する前にパスを書き換えます。

    class TextureLoader : public ::Effekseer::TextureLoader {
    private:
    	::EffekseerRenderer::Renderer*	m_renderer;

    public:
    	TextureLoader( ::EffekseerRenderer::Renderer* renderer ) { m_renderer = renderer; }
    	virtual ~TextureLoader() {}
    	void* Load( const EFK_CHAR* path );
    	void Unload( void* data );

    	// 読み込み時のルート
    	std::wstring RootPath;
    };

    void* TextureLoader::Load( const EFK_CHAR* path ) {

    	wchar_t dst[260];

    	// ファイルパスを結合する関数
    	Combine( RootPath.c_str(), (const wchar_t *)path, dst, 260 );

    	FILE* fp_texture = _wfopen( (const wchar_t *)dst, L"rb" );

    	if( fp_texture != NULL ) {
    		IDirect3DTexture9* texture = NULL;

    		fseek( fp_texture, 0, SEEK_END );
    		size_t size_texture = ftell( fp_texture );
    		char* data_texture = new char[size_texture];
    		fseek( fp_texture, 0, SEEK_SET );
    		fread( data_texture, 1, size_texture, fp_texture );
    		fclose( fp_texture );

    		D3DXCreateTextureFromFileInMemory( m_renderer->GetDevice(), data_texture, size_texture, &texture );

    		delete [] data_texture;

    		return (void*)texture;
    	}

    	return NULL;
    }

    void TextureLoader::Unload( void* data ) {
    	if( data != NULL ) {
    		IDirect3DTexture9* texture = (IDirect3DTexture9*)data;
    		texture->Release();
    	}
    }

    // 設定する。
    manager->SetTextureLoader( new TextureLoader() );

    // 読み込む。
    // Createを実行指定する前に指定する。
    ((TextureLoader*)manager->GetTextureLoader())->RootPath = std::wstring( Path );
    ::Effekseer::Effect* effect = ::Effekseer::Effect::Create( manager, Path );