/*---------------------------------------------------------------------------* Project: NintendoWare File: gfx_ResTextureMapper.h Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision: 18106 $ *---------------------------------------------------------------------------*/ #ifndef NW_GFX_RESTEXTUREMAPPER_H_ #define NW_GFX_RESTEXTUREMAPPER_H_ #include #include #include namespace nw { namespace gfx { namespace res { class ResGraphicsFile; //! @details :private struct ResTextureSamplerData { nw::ut::ResTypeInfo typeInfo; nw::ut::Offset toOwner; nw::ut::ResS32 m_MinFilter; }; //! @details :private struct ResStandardTextureSamplerData : public ResTextureSamplerData { nw::ut::ResFloatColor m_BorderColor; nw::ut::ResF32 m_LodBias; }; //! @details :private struct ResShadowTextureSamplerData : public ResTextureSamplerData { }; //! @details :private struct ResTextureMapperData { nw::ut::ResTypeInfo typeInfo; nw::os::IAllocator* m_DynamicAllocator; nw::ut::Offset toTexture; }; //! @details :private struct ResPixelBasedTextureMapperData : public ResTextureMapperData { nw::ut::Offset toSampler; enum { ADDRESS_INDEX = 7 }; nw::ut::ResU32 m_CommandCache[14]; nw::ut::ResU32 m_CommandSizeToSend; }; //! @details :private struct ResProceduralTextureMapperData : public ResTextureMapperData { }; //-------------------------------------------------------------------------- //! @brief テクスチャサンプラの設定を管理するためのバイナリリソースクラスです。 //--------------------------------------------------------------------------- class ResTextureSampler : public nw::ut::ResCommon< ResTextureSamplerData > { public: enum { TYPE_INFO = NW_GFX_RES_TYPE_INFO(ResTextureSampler) }; enum { SIGNATURE = NW_RES_SIGNATURE32('BSTS') }; //! @brief 縮小時の補間処理です。 enum MinFilter { MINFILTER_NEAREST, //!< ニアレスト(補間なし)で、ミップマップは使用しません。 MINFILTER_LINEAR, //!< リニア(補間あり)で、ミップマップは使用しません。 MINFILTER_NEAREST_MIPMAP_NEAREST, //!< ニアレスト(補間なし)で、ミップマップもニアレスト(補間なし)です。 MINFILTER_NEAREST_MIPMAP_LINEAR, //!< ニアレスト(補間なし)で、ミップマップはリニア(補間あり)です。 MINFILTER_LINEAR_MIPMAP_NEAREST, //!< リニア(補間あり)で、ミップマップはニアレスト(補間なし)です。 MINFILTER_LINEAR_MIPMAP_LINEAR //!< リニア(補間あり)で、ミップマップもリニア(補間あり)です。 }; //! @brief 拡大時の補間処理です。 enum MagFilter { MAGFILTER_NEAREST, //!< ニアレスト(補間なし)です。 MAGFILTER_LINEAR //!< リニア(補間あり)です。 }; //! @brief テクスチャマッピングの方法です。 enum SamplerType { SAMPLERTYPE_TEXTURE_2D, //!< テクスチャ座標です。 SAMPLERTYPE_CUBE_MAP, //!< カメラキューブ座標です。 SAMPLERTYPE_SHADOW, //!< シャドウ用の投影です。 SAMPLERTYPE_PROJECTION, //!< 投影します。 SAMPLERTYPE_SHADOW_CUBE //!< シャドウキューブ用の投影です。 }; NW_RES_CTOR( ResTextureSampler ) //--------------------------------------------------------------------------- //! @fn MinFilter GetMinFilter() const //! @brief 縮小フィルタを取得します。 //--------------------------------------------------------------------------- MinFilter GetMinFilter() const { return static_cast(this->ref().m_MinFilter); } //--------------------------------------------------------------------------- //! @fn void SetMinFilter(MinFilter value) //! @brief 縮小フィルタを設定します。 //--------------------------------------------------------------------------- void SetMinFilter(MinFilter value) { this->ref().m_MinFilter = static_cast(value); ::std::pair command = GetOwnerCommand(); enum { CMD_SHIFT2 = 2, CMD_MASK2 = 0x1, CMD_NEAR = 0, CMD_LINEAR = 1, CMD_SHIFT24 = 24, CMD_MASK24 = 0x1, CMD_OTHER = 0, CMD_MIPMAP_LINER = 1, CMD_INDEX = 5 }; NW_MIN_ASSERT(command.first, (CMD_INDEX + 1) * sizeof(u32)); NW_NULL_ASSERT(command.second); const u32 table2[] = { CMD_NEAR, CMD_LINEAR, CMD_NEAR, CMD_NEAR, CMD_LINEAR, CMD_LINEAR }; u32 value2 = table2[value]; internal::SetCmdValue( &command.second[CMD_INDEX], value2, CMD_MASK2, CMD_SHIFT2 ); const u32 table24[] = { CMD_OTHER, CMD_OTHER, CMD_OTHER, CMD_MIPMAP_LINER, CMD_OTHER, CMD_MIPMAP_LINER }; u32 value24 = table24[value]; internal::SetCmdValue( &command.second[CMD_INDEX], value24, CMD_MASK24, CMD_SHIFT24 ); // 0x84 [27:24]min lod|[19:16]mipmap size を変更します。 SetTextureMipmapCommand(); } //--------------------------------------------------------------------------- //! @fn MagFilter GetMagFilter() const //! @brief 拡大フィルタを取得します。 //--------------------------------------------------------------------------- MagFilter GetMagFilter() const { ::std::pair command = GetOwnerCommand(); enum { CMD_SHIFT = 1, CMD_MASK = 0x1, CMD_INDEX = 5 }; NW_MIN_ASSERT(command.first, (CMD_INDEX + 1) * sizeof(u32)); NW_NULL_ASSERT(command.second); return static_cast(internal::GetCmdValue( command.second[CMD_INDEX], CMD_MASK, CMD_SHIFT )); } //--------------------------------------------------------------------------- //! @fn void SetMagFilter(MagFilter value) //! @brief 拡大フィルタを設定します。 //--------------------------------------------------------------------------- void SetMagFilter(MagFilter value) { ::std::pair command = GetOwnerCommand(); enum { CMD_SHIFT = 1, CMD_MASK = 0x1, CMD_INDEX = 5 }; NW_MIN_ASSERT(command.first, (CMD_INDEX + 1) * sizeof(u32)); NW_NULL_ASSERT(command.second); internal::SetCmdValue( &command.second[CMD_INDEX], value, CMD_MASK, CMD_SHIFT ); } //--------------------------------------------------------------------------- //! @brief テクスチャサンプラータイプを設定します。 //! テクスチャサンプラータイプが設定可能なのは0番目のテクスチャマッパーのみです。 //! 1、2番目に設定すると正しく動作しません。 //! //! @return テクスチャサンプラータイプです。 //--------------------------------------------------------------------------- void SetSamplerType(SamplerType value) { ::std::pair command = GetOwnerCommand(); enum { CMD_SHIFT = 28, CMD_MASK = 0x7, CMD_INDEX = 5 }; NW_MIN_ASSERT(command.first, (CMD_INDEX + 1) * sizeof(u32)); NW_NULL_ASSERT(command.second); internal::SetCmdValue( &command.second[CMD_INDEX], value, CMD_MASK, CMD_SHIFT ); } //--------------------------------------------------------------------------- //! @brief テクスチャサンプラータイプを設定します。 //! //! @return テクスチャサンプラータイプです。 //--------------------------------------------------------------------------- SamplerType GetSamplerType() const { ::std::pair command = GetOwnerCommand(); enum { CMD_SHIFT = 28, CMD_MASK = 0x7, CMD_INDEX = 5 }; NW_MIN_ASSERT(command.first, (CMD_INDEX + 1) * sizeof(u32)); NW_NULL_ASSERT(command.second); return static_cast(internal::GetCmdValue( command.second[CMD_INDEX], CMD_MASK, CMD_SHIFT )); } //--------------------------------------------------------------------------- //! @brief このテクスチャサンプラーを所有するテクスチャマッパーを取得します。 //! //! @return テクスチャマッパーへのポインタです。 //--------------------------------------------------------------------------- ResTextureMapperData* GetOwnerData() { return static_cast( ref().toOwner.to_ptr() ); } //--------------------------------------------------------------------------- //! @brief このテクスチャサンプラーを所有するテクスチャマッパーを取得します。 //! //! @return テクスチャマッパーへのポインタです。 //--------------------------------------------------------------------------- const ResTextureMapperData* GetOwnerData() const { return static_cast( ref().toOwner.to_ptr() ); } //--------------------------------------------------------------------------- //! @brief インスタンスの型情報を取得します。 //! //! @return 型情報です。 //--------------------------------------------------------------------------- nw::ut::ResTypeInfo GetTypeInfo() const { return ref().typeInfo; } protected: //! @brief このテクスチャサンプラーを所有するテクスチャマッパーのコマンドを取得します。 ::std::pair GetOwnerCommand() const; //! @brief テクスチャミップマップのコマンドを設定します。 void SetTextureMipmapCommand(); }; //-------------------------------------------------------------------------- //! @brief 標準のテクスチャサンプラの設定を表すバイナリリソースクラスです。 //--------------------------------------------------------------------------- class ResStandardTextureSampler : public ResTextureSampler { public: enum { TYPE_INFO = NW_GFX_RES_TYPE_INFO(ResStandardTextureSampler) }; enum { SIGNATURE = NW_RES_SIGNATURE32('STTS') }; NW_RES_CTOR_INHERIT( ResStandardTextureSampler, ResTextureSampler ) //--------------------------------------------------------------------------- //! @fn const nw::ut::FloatColor & GetBorderColor() const //! @brief 縁の色を取得します。 //--------------------------------------------------------------------------- const ut::FloatColor& GetBorderColor() const { return ref().m_BorderColor; } //--------------------------------------------------------------------------- //! @fn void SetBorderColor(const ut::FloatColor& value) //! @brief 縁の色を設定します。 //--------------------------------------------------------------------------- void SetBorderColor(const ut::FloatColor& value) { ref().m_BorderColor = value; u32 borderColorU32 = ref().m_BorderColor.ToPicaU32(); enum { CMD_INDEX = 2 }; ::std::pair command = GetOwnerCommand(); NW_MIN_ASSERT(command.first, (CMD_INDEX + 1) * sizeof(u32)); NW_NULL_ASSERT(command.second); command.second[CMD_INDEX] = borderColorU32; } //--------------------------------------------------------------------------- //! @fn void SetBorderColor(f32 r, f32 g, f32 b) //! @brief 縁の色を設定します。 //--------------------------------------------------------------------------- void SetBorderColor( f32 r, f32 g, f32 b ) { ref().m_BorderColor.Set(r, g, b); u32 borderColorU32 = ref().m_BorderColor.ToPicaU32(); enum { CMD_INDEX = 2 }; ::std::pair command = GetOwnerCommand(); NW_MIN_ASSERT(command.first, (CMD_INDEX + 1) * sizeof(u32)); NW_NULL_ASSERT(command.second); command.second[CMD_INDEX] = borderColorU32; } //--------------------------------------------------------------------------- //! @fn void SetBorderColor(f32 r, f32 g, f32 b, f32 a) //! @brief 縁の色を設定します。 //--------------------------------------------------------------------------- void SetBorderColor( f32 r, f32 g, f32 b, f32 a ) { ref().m_BorderColor.Set(r, g, b, a); u32 borderColorU32 = ref().m_BorderColor.ToPicaU32(); enum { CMD_INDEX = 2 }; ::std::pair command = GetOwnerCommand(); NW_MIN_ASSERT(command.first, (CMD_INDEX + 1) * sizeof(u32)); NW_NULL_ASSERT(command.second); command.second[CMD_INDEX] = borderColorU32; } enum Wrap { WRAP_CLAMP_TO_EDGE = 0, //!< テクスチャの端のピクセルを引き伸ばします。 WRAP_CLAMP_TO_BORDER = 1, //!< テクスチャの端でボーダーカラーを引き伸ばします。 WRAP_REPEAT = 2, //!< テクスチャの端で繰り返します。 WRAP_MIRRORED_REPEAT = 3 //!< テクスチャの端で反転しながら繰り返します。 }; //--------------------------------------------------------------------------- //! @fn Wrap GetWrapS() const //! @brief S方向の繰り返し方法を取得します。 //--------------------------------------------------------------------------- Wrap GetWrapS() const { ::std::pair command = GetOwnerCommand(); enum { CMD_SHIFT = 12, CMD_MASK = 0x7, CMD_INDEX = 5 }; NW_MIN_ASSERT(command.first, (CMD_INDEX + 1) * sizeof(u32)); NW_NULL_ASSERT(command.second); return static_cast(internal::GetCmdValue( command.second[CMD_INDEX], CMD_MASK, CMD_SHIFT )); } //--------------------------------------------------------------------------- //! @fn void SetWrapS(Wrap value) //! @brief S方向の繰り返し方法を設定します。 //--------------------------------------------------------------------------- void SetWrapS(Wrap value) { ::std::pair command = GetOwnerCommand(); enum { CMD_SHIFT = 12, CMD_MASK = 0x7, CMD_INDEX = 5 }; NW_MIN_ASSERT(command.first, (CMD_INDEX + 1) * sizeof(u32)); NW_NULL_ASSERT(command.second); internal::SetCmdValue( &command.second[CMD_INDEX], value, CMD_MASK, CMD_SHIFT ); } //--------------------------------------------------------------------------- //! @fn Wrap GetWrapT() const //! @brief T方向の繰り返し方法を取得します。 //--------------------------------------------------------------------------- Wrap GetWrapT() const { ::std::pair command = GetOwnerCommand(); enum { CMD_SHIFT = 8, CMD_MASK = 0x7, CMD_INDEX = 5 }; NW_MIN_ASSERT(command.first, (CMD_INDEX + 1) * sizeof(u32)); NW_NULL_ASSERT(command.second); return static_cast(internal::GetCmdValue( command.second[CMD_INDEX], CMD_MASK, CMD_SHIFT )); } //--------------------------------------------------------------------------- //! @fn void SetWrapT(Wrap value) //! @brief T方向の繰り返し方法を設定します。 //--------------------------------------------------------------------------- void SetWrapT(Wrap value) { ::std::pair command = GetOwnerCommand(); enum { CMD_SHIFT = 8, CMD_MASK = 0x7, CMD_INDEX = 5 }; NW_MIN_ASSERT(command.first, (CMD_INDEX + 1) * sizeof(u32)); NW_NULL_ASSERT(command.second); internal::SetCmdValue( &command.second[CMD_INDEX], value, CMD_MASK, CMD_SHIFT ); } //--------------------------------------------------------------------------- //! @fn u32 GetMinLod() const //! @brief 最小のLevel Of Detailsを取得します。 //--------------------------------------------------------------------------- u32 GetMinLod() const { ::std::pair command = GetOwnerCommand(); enum { CMD_SHIFT = 24, CMD_MASK = 0xf, CMD_INDEX = 6 }; NW_MIN_ASSERT(command.first, (CMD_INDEX + 1) * sizeof(u32)); NW_NULL_ASSERT(command.second); return static_cast(internal::GetCmdValue( command.second[CMD_INDEX], CMD_MASK, CMD_SHIFT )); } //--------------------------------------------------------------------------- //! @fn void SetMinLod(u32 value) //! @brief 最小のLevel Of Detailsを設定します。 //--------------------------------------------------------------------------- void SetMinLod(u32 value) { ::std::pair command = GetOwnerCommand(); enum { CMD_SHIFT = 24, CMD_MASK = 0xf, CMD_INDEX = 6 }; NW_MIN_ASSERT(command.first, (CMD_INDEX + 1) * sizeof(u32)); NW_NULL_ASSERT(command.second); NW_MINMAX_ASSERT(value, 0, 15); u32 minLod = value; if (this->ref().m_MinFilter == ResTextureSampler::MINFILTER_NEAREST || this->ref().m_MinFilter == ResTextureSampler::MINFILTER_LINEAR) { minLod = 0; } internal::SetCmdValue( &command.second[CMD_INDEX], minLod, CMD_MASK, CMD_SHIFT ); } //--------------------------------------------------------------------------- //! @fn f32 GetLodBias() const //! @brief Level Of Details のバイアスを取得します。 //--------------------------------------------------------------------------- f32 GetLodBias() const { return this->ref().m_LodBias; } //--------------------------------------------------------------------------- //! @fn void SetLodBias(f32 value) //! @brief Level Of Details のバイアスを設定します。 //--------------------------------------------------------------------------- void SetLodBias(f32 value) { this->ref().m_LodBias = value; ::std::pair command = GetOwnerCommand(); enum { CMD_SHIFT = 0, CMD_MASK = 0x1fff, CMD_INDEX = 6 }; NW_MIN_ASSERT(command.first, (CMD_INDEX + 1) * sizeof(u32)); NW_NULL_ASSERT(command.second); u32 lodBias = ut::FixedS13Fraction8::Float32ToFixed13(value); internal::SetCmdValue( &command.second[CMD_INDEX], lodBias, CMD_MASK, CMD_SHIFT ); } }; //-------------------------------------------------------------------------- //! @brief 影用テクスチャサンプラの設定を表すバイナリリソースクラスです。 //--------------------------------------------------------------------------- class ResShadowTextureSampler : public ResTextureSampler { public: enum { TYPE_INFO = NW_GFX_RES_TYPE_INFO(ResShadowTextureSampler) }; enum { SIGNATURE = NW_RES_SIGNATURE32('SHTS') }; NW_RES_CTOR_INHERIT( ResShadowTextureSampler, ResTextureSampler ) }; //-------------------------------------------------------------------------- //! @brief テクスチャとサンプラの設定を管理し、メッシュへのテクスチャ貼り付けを表すバイナリリソースクラスです。 //--------------------------------------------------------------------------- class ResTextureMapper : public nw::ut::ResCommon< ResTextureMapperData > { public: enum { TYPE_INFO = NW_GFX_RES_TYPE_INFO(ResTextureMapper) }; enum { SIGNATURE = NW_RES_SIGNATURE32('TMAP') }; NW_RES_CTOR( ResTextureMapper ) //--------------------------------------------------------------------------- //! @brief テクスチャマッパーにテクスチャを設定します。 //! テクスチャを設定した後にコマンドの生成を行います。 //! //! @param[in] resTexture テクスチャです。 //--------------------------------------------------------------------------- void SetTexture(ResTexture resTexture); //--------------------------------------------------------------------------- //! @brief テクスチャマッパーからテクスチャを取得します。 //! //! @return テクスチャです。 //--------------------------------------------------------------------------- const ResTexture GetTexture() const { return ResTexture( ref().toTexture.to_ptr() ); } //--------------------------------------------------------------------------- //! @brief リソースの初期化処理をおこないます。 //! //! @param[in] allocator アロケータです。 //! @param[in] graphicsFile グラフィックスリソースです。 //--------------------------------------------------------------------------- Result Setup(os::IAllocator* allocator, ResGraphicsFile graphicsFile); //--------------------------------------------------------------------------- //! @brief リソースの後始末をおこないます。 //--------------------------------------------------------------------------- void Cleanup(); //--------------------------------------------------------------------------- //! @brief リソースからテクスチャマッパーをクローンします。 //! //! @param[in] allocator アロケータです。 //--------------------------------------------------------------------------- ResTextureMapper CloneDynamic(os::IAllocator* allocator); //--------------------------------------------------------------------------- //! @brief クローン時に必要なメモリサイズを取得します。 //! //! @param[in] alignment 計算に用いるアライメントです。2 のべき乗である必要があります。 //--------------------------------------------------------------------------- size_t GetMemorySizeForClone(size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) const { os::MemorySizeCalculator size(alignment); GetMemorySizeForCloneInternal(&size); return size.GetSizeWithPadding(alignment); } //! @details :private void GetMemorySizeForCloneInternal(os::MemorySizeCalculator* pSize) const; //--------------------------------------------------------------------------- //! @brief ResTextureMapper のリソースを破棄します。 //--------------------------------------------------------------------------- void DestroyDynamic(); //--------------------------------------------------------------------------- //! @brief リソースの型情報を取得します。 //! //! @return 型情報です。 //--------------------------------------------------------------------------- nw::ut::ResTypeInfo GetTypeInfo() const { return ref().typeInfo; } }; typedef nw::ut::ResArrayClass::type ResTextureMapperArray; //-------------------------------------------------------------------------- //! @brief 画像データによるテクスチャをメッシュに貼り付けるためのバイナリリソースクラスです。 //--------------------------------------------------------------------------- class ResPixelBasedTextureMapper : public ResTextureMapper { public: enum { TYPE_INFO = NW_GFX_RES_TYPE_INFO(ResPixelBasedTextureMapper) }; enum { SIGNATURE = NW_RES_SIGNATURE32('PMAP') }; NW_RES_CTOR_INHERIT( ResPixelBasedTextureMapper, ResTextureMapper ) //--------------------------------------------------------------------------- //! @brief テクスチャマッパーからテクスチャサンプラーを取得します。 //! //! @return テクスチャサンプラーです。 //--------------------------------------------------------------------------- const ResTextureSampler GetSampler() const { return ResTextureSampler( ref().toSampler.to_ptr() ); } ResTextureSampler GetSampler() { return ResTextureSampler( ref().toSampler.to_ptr() ); } //--------------------------------------------------------------------------- //! @brief コマンドキャッシュを取得します。 //! //! @return コマンドキャッシュへのポインタです。 //--------------------------------------------------------------------------- u32* GetCommandCache() { return &ref().m_CommandCache[0]; } const u32* GetCommandCache() const { return &ref().m_CommandCache[0]; } //--------------------------------------------------------------------------- //! @fn void SetCommandSizeToSend(u32 value) //! @brief 送信するコマンドサイズを設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn u32 GetCommandSizeToSend() const //! @brief 送信するコマンドサイズを取得します。 //--------------------------------------------------------------------------- NW_RES_FIELD_PRIMITIVE_DECL( u32, CommandSizeToSend ) // GetCommandSizeToSend(), SetCommandSizeToSend() //--------------------------------------------------------------------------- //! @brief テクスチャ設定用のコマンドが設定されているかどうかを確認します。 //! //! @return すでに設定済みであれば true、設定されていなければ false を返します。 //--------------------------------------------------------------------------- bool IsCommandReady() const { return ref().m_CommandCache[ResPixelBasedTextureMapperData::ADDRESS_INDEX] != 0; } //--------------------------------------------------------------------------- //! @brief テクスチャ設定用のコマンドとテクスチャのバインドをリセットします。 //--------------------------------------------------------------------------- void ResetCommand() { ref().m_CommandCache[ResPixelBasedTextureMapperData::ADDRESS_INDEX] = 0; } }; typedef nw::ut::ResArrayClass::type ResPixelBasedTextureMapperArray; typedef nw::ut::ResArrayClass::type ResPixelBasedTextureMapperArrayConst; //-------------------------------------------------------------------------- //! @brief プロシージャルテクスチャのメッシュへの貼り付けを表すバイナリリソースクラスです。 //! @details :private //--------------------------------------------------------------------------- class ResProceduralTextureMapper : public ResTextureMapper { public: enum { TYPE_INFO = NW_GFX_RES_TYPE_INFO(ResProceduralTextureMapper) }; enum { SIGNATURE = NW_RES_SIGNATURE32('PRCM') }; NW_RES_CTOR_INHERIT( ResProceduralTextureMapper, ResTextureMapper ) }; } // namespace res } // namespace gfx } // namespace nw #endif // NW_GFX_RESTEXTUREMAPPER_H_