1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: gfx_Material.h 4 5 Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Revision: 28677 $ 14 *---------------------------------------------------------------------------*/ 15 16 #ifndef NW_GFX_MATERIAL_H_ 17 #define NW_GFX_MATERIAL_H_ 18 19 #include <nw/gfx/gfx_SceneObject.h> 20 #include <nw/ut/ut_RuntimeTypeInfo.h> 21 #include <nw/ut/ut_MoveArray.h> 22 #include <nw/gfx/gfx_ShaderProgram.h> 23 24 namespace nw 25 { 26 namespace gfx 27 { 28 29 class Model; 30 class AnimGroup; 31 32 //--------------------------------------------------------------------------- 33 //! @brief マテリアルを表すクラスです。 34 //! 35 //! マテリアルに対して、アニメーション後に生成時の状態に戻したい場合、Bufferを使用する必要があります。 36 //--------------------------------------------------------------------------- 37 class Material : public SceneObject 38 { 39 private: 40 NW_DISALLOW_COPY_AND_ASSIGN(Material); 41 42 public: 43 NW_UT_RUNTIME_TYPEINFO; 44 45 //---------------------------------------- 46 //! @name 作成 47 //@{ 48 49 //! @brief リソースからマテリアルを生成します。 50 //! 51 //! @param[in] resource リソースです。 52 //! @param[in] bufferCount 生成するマテリアルバッファの数です。 53 //! @param[in] parent マテリアルの親となるモデルクラスです。 54 //! @param[in] allocator アロケータです。 55 //! 56 //! @return 生成されたマテリアルです。 57 //! 58 static Material* Create( 59 ResMaterial resource, 60 s32 bufferCount, 61 Model* parent, 62 os::IAllocator* allocator); 63 64 //! @brief 生成時に必要なメモリサイズを取得します。 65 //! 66 //! @param[in] resource リソースです。 67 //! @param[in] bufferCount 生成するマテリアルバッファの数です。 68 //! @param[in] parent マテリアルの親となるモデルクラスです。 69 //! @param[in] alignment 計算に用いるアライメントです。2 のべき乗である必要があります。 70 static size_t GetMemorySize( 71 ResMaterial resource, 72 s32 bufferCount, 73 bit32 bufferOption, 74 size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 75 { 76 os::MemorySizeCalculator size(alignment); 77 78 GetMemorySizeInternal(&size, resource, bufferCount, bufferOption); 79 80 return size.GetSizeWithPadding(alignment); 81 } 82 83 84 //! @details :private 85 static void GetMemorySizeInternal( 86 os::MemorySizeCalculator* pSize, 87 ResMaterial resource, 88 s32 bufferCount, 89 bit32 bufferOption); 90 91 //@} 92 93 //---------------------------------------- 94 //! @name 取得/設定 95 //@{ 96 97 //! @brief オリジナルリソースを取得します。 GetOriginal()98 ResMaterial GetOriginal() 99 { 100 return ResStaticCast<ResMaterial>(this->GetResSceneObject()); 101 } 102 103 //! @brief オリジナルリソースを取得します。 GetOriginal()104 const ResMaterial GetOriginal() const 105 { 106 return ResStaticCast<ResMaterial>(this->GetResSceneObject()); 107 } 108 109 //! @brief 所有者となるモデルを取得します。 110 //! 111 //! @return マテリアルの所有者のモデルです。 112 //! GetOwnerModel()113 Model* GetOwnerModel() 114 { 115 return this->m_Owner; 116 } 117 118 //! @brief 所有者となるモデルを取得します。 119 //! 120 //! @return マテリアルの所有者のモデルです。 121 //! GetOwnerModel()122 const Model* GetOwnerModel() const 123 { 124 return this->m_Owner; 125 } 126 127 //! @brief リソースを設定します。 128 //! 129 //! @param[in] description シェーダプログラムの詳細設定です。 130 //! SetDescription(ResShaderProgramDescription description)131 void SetDescription(ResShaderProgramDescription description) { m_ProgramDescription = description; } 132 133 //! @brief リソースを取得します。 134 //! 135 //! @return シェーダプログラムの詳細設定です。 136 //! GetDescription()137 const ResShaderProgramDescription GetDescription() const { return m_ProgramDescription; } 138 139 //@} 140 141 //---------------------------------------- 142 //! @name バッファオプション関連 143 //@{ 144 145 //! @brief バッファの数を取得します。 GetBufferCount()146 int GetBufferCount() const 147 { 148 return this->m_Buffers.size(); 149 } 150 151 //! @brief バッファを取得します。 GetBuffer()152 ResMaterial GetBuffer() 153 { 154 bool hasBuffer = (0 < m_BufferCount); 155 156 if (hasBuffer) 157 { 158 return this->m_Buffers[0]; 159 } 160 else 161 { 162 return ResMaterial(NULL); 163 } 164 } 165 166 //! バッファを取得します。 GetBuffer()167 const ResMaterial GetBuffer() const 168 { 169 bool hasBuffer = (0 < m_BufferCount); 170 171 if (hasBuffer) 172 { 173 return this->m_Buffers[0]; 174 } 175 else 176 { 177 return ResMaterial(NULL); 178 } 179 } 180 181 //! 有効なシェーダーパラメータが取得できるマテリアルを取得します。 GetShaderParameterResMaterial()182 ResMaterial& GetShaderParameterResMaterial() { return m_ShaderParameterResMaterial; } 183 184 //! 有効なシェーダーパラメータが取得できるマテリアルを取得します。 GetShaderParameterResMaterial()185 const ResMaterial& GetShaderParameterResMaterial() const { return m_ShaderParameterResMaterial; } 186 187 //! 有効なシェーディングパラメータが取得できるマテリアルを取得します。 GetShadingParameterResMaterial()188 ResMaterial& GetShadingParameterResMaterial() { return m_ShadingParameterResMaterial; } 189 190 //! 有効なシェーディングパラメータが取得できるマテリアルを取得します。 GetShadingParameterResMaterial()191 const ResMaterial& GetShadingParameterResMaterial() const { return m_ShadingParameterResMaterial; } 192 193 //! 有効なマテリアルカラーが取得できるマテリアルを取得します。 GetMaterialColorResMaterial()194 ResMaterial& GetMaterialColorResMaterial() { return m_MaterialColorResMaterial; } 195 196 //! 有効なマテリアルカラーが取得できるマテリアルを取得します。 GetMaterialColorResMaterial()197 const ResMaterial& GetMaterialColorResMaterial() const { return m_MaterialColorResMaterial; } 198 199 //! 有効なラスタライゼーションが取得できるマテリアルを取得します。 GetRasterizationResMaterial()200 ResMaterial& GetRasterizationResMaterial() { return m_RasterizationResMaterial; } 201 202 //! 有効なラスタライゼーションが取得できるマテリアルを取得します。 GetRasterizationResMaterial()203 const ResMaterial& GetRasterizationResMaterial() const { return m_RasterizationResMaterial; } 204 205 //! 有効なテクスチャコーディネータが取得できるマテリアルを取得します。 GetTextureCoordinatorResMaterial()206 ResMaterial& GetTextureCoordinatorResMaterial() { return m_TextureCoordinatorResMaterial; } 207 208 //! 有効なテクスチャコーディネータが取得できるマテリアルを取得します。 GetTextureCoordinatorResMaterial()209 const ResMaterial& GetTextureCoordinatorResMaterial() const { return m_TextureCoordinatorResMaterial; } 210 211 //! 有効なテクスチャマッパーが取得できるマテリアルを取得します。 GetTextureMapperResMaterial()212 ResMaterial& GetTextureMapperResMaterial() { return m_TextureMapperResMaterial; } 213 214 //! 有効なテクスチャマッパーが取得できるマテリアルを取得します。 GetTextureMapperResMaterial()215 const ResMaterial& GetTextureMapperResMaterial() const { return m_TextureMapperResMaterial; } 216 217 //! 有効なフラグメントライティングが取得できるマテリアルを取得します。 GetFragmentLightingResMaterial()218 ResMaterial& GetFragmentLightingResMaterial() { return m_FragmentLightingResMaterial; } 219 220 //! 有効なフラグメントライティングが取得できるマテリアルを取得します。 GetFragmentLightingResMaterial()221 const ResMaterial& GetFragmentLightingResMaterial() const { return m_FragmentLightingResMaterial; } 222 223 //! 有効なフラグメントライティングテーブルが取得できるマテリアルを取得します。 GetFragmentLightingTableResMaterial()224 ResMaterial& GetFragmentLightingTableResMaterial() { return m_FragmentLightingTableResMaterial; } 225 226 //! 有効なフラグメントライティングテーブルが取得できるマテリアルを取得します。 GetFragmentLightingTableResMaterial()227 const ResMaterial& GetFragmentLightingTableResMaterial() const { return m_FragmentLightingTableResMaterial; } 228 229 //! 有効なテクスチャコンバイナが取得できるマテリアルを取得します。 GetTextureCombinerResMaterial()230 ResMaterial& GetTextureCombinerResMaterial() { return m_TextureCombinerResMaterial; } 231 232 //! 有効なテクスチャコンバイナが取得できるマテリアルを取得します。 GetTextureCombinerResMaterial()233 const ResMaterial& GetTextureCombinerResMaterial() const { return m_TextureCombinerResMaterial; } 234 235 //! 有効なアルファテストが取得できるマテリアルを取得します。 GetAlphaTestResMaterial()236 ResMaterial& GetAlphaTestResMaterial() { return m_AlphaTestResMaterial; } 237 238 //! 有効なアルファテストが取得できるマテリアルを取得します。 GetAlphaTestResMaterial()239 const ResMaterial& GetAlphaTestResMaterial() const { return m_AlphaTestResMaterial; } 240 241 //! 有効なフラグメントオペレーションが取得できるマテリアルを取得します。 GetFragmentOperationResMaterial()242 ResMaterial& GetFragmentOperationResMaterial() { return m_FragmentOperationResMaterial; } 243 244 //! 有効なフラグメントオペレーションが取得できるマテリアルを取得します。 GetFragmentOperationResMaterial()245 const ResMaterial& GetFragmentOperationResMaterial() const { return m_FragmentOperationResMaterial; } 246 247 //! 有効なシェーディングパラメータが取得できるマテリアルを取得します。 GetSceneEnvironmentResMaterial()248 ResMaterial& GetSceneEnvironmentResMaterial() { return m_SceneEnvironmentResMaterial; } 249 250 //! 有効なシーン環境の設定が取得できるマテリアルを取得します。 GetSceneEnvironmentResMaterial()251 const ResMaterial& GetSceneEnvironmentResMaterial() const { return m_SceneEnvironmentResMaterial; } 252 253 //@} 254 255 protected: 256 //---------------------------------------- 257 //! @name コンストラクタ/デストラクタ 258 //@{ 259 260 //! コンストラクタです。 261 Material( 262 os::IAllocator* allocator, 263 ResMaterial resMaterial, 264 s32 bufferCount, 265 Model* parent); 266 267 //! デストラクタです。 268 virtual ~Material(); 269 270 //@} 271 272 struct ResMaterialDestroyer : public std::unary_function<ResMaterial, void> 273 { m_AllocatorResMaterialDestroyer274 ResMaterialDestroyer(os::IAllocator* allocator = 0) : m_Allocator(allocator) 275 {} operatorResMaterialDestroyer276 result_type operator()(argument_type data) 277 { 278 DestroyResMaterial(m_Allocator, data); 279 } 280 281 os::IAllocator* m_Allocator; 282 }; 283 284 private: 285 286 //! @brief メンバのメモリ確保と初期化を行います。 287 Result Initialize(os::IAllocator* allocator); 288 289 //--------------------------------------------------------------------------- 290 //! @brief バッファを作成します。 291 //! 292 //! @param[in] allocator アロケータです。 293 //--------------------------------------------------------------------------- 294 Result CreateBuffers(os::IAllocator* allocator); 295 296 //--------------------------------------------------------------------------- 297 //! @brief ResMaterialをコピーします。 298 //! 299 //! @param[in] allocator アロケータです。 300 //! @param[in] bufferOption 生成オプションです。 301 //! 302 //! @return コピーしたマテリアルとコピー結果を表すフラグを返します。 303 //--------------------------------------------------------------------------- 304 ::std::pair<ResMaterial, Result> CopyResMaterial( 305 os::IAllocator* allocator, 306 bit32 bufferOption); 307 308 //--------------------------------------------------------------------------- 309 //! @brief ResMaterial のリソースを破棄します。 310 //! 311 //! @param[in] allocator リソース用のメモリを解放するアロケータです。 312 //! @param[in] resMaterial 解放するリソースです。 313 //--------------------------------------------------------------------------- 314 static void DestroyResMaterial(os::IAllocator* allocator, ResMaterial resMaterial); 315 316 //--------------------------------------------------------------------------- 317 //! @brief ResFragmentShader のリソースを破棄します。 318 //! 319 //! @param[in] allocator リソース用のメモリを解放するアロケータです。 320 //! @param[in] resFragmentShader 解放するリソースです。 321 //--------------------------------------------------------------------------- 322 static void DestroyResFragmentShader( 323 os::IAllocator* allocator, 324 ResFragmentShader resFragmentShader); 325 326 //--------------------------------------------------------------------------- 327 //! @brief ResShaderParameter のリソースを破棄します。 328 //! 329 //! @param[in] allocator リソース用のメモリを解放するアロケータです。 330 //! @param[in] resShaderParameter 解放するリソースです。 331 //--------------------------------------------------------------------------- 332 static void DestroyResShaderParameter( 333 os::IAllocator* allocator, 334 ResShaderParameter resShaderParameter); 335 336 //--------------------------------------------------------------------------- 337 //! @brief リソースからフラグメントライティングテーブルをコピーします。 338 //! 339 //! @param[in] allocator アロケータです。 340 //! @param[in] resFragmentLightingTable オリジナルのデータです。 341 //--------------------------------------------------------------------------- 342 ::std::pair<ResFragmentLightingTable, Result> CopyResFragmentLightingTable( 343 os::IAllocator* allocator, 344 ResFragmentLightingTable resFragmentLightingTable); 345 346 //--------------------------------------------------------------------------- 347 //! @brief リソースからライティング参照テーブルをコピーします。 348 //! 349 //! @param[in] allocator アロケータです。 350 //! @param[in] resLightingLookupTable オリジナルのデータです。 351 //--------------------------------------------------------------------------- 352 ::std::pair<ResLightingLookupTable, Result> CopyResLightingLookupTable( 353 os::IAllocator* allocator, 354 ResLightingLookupTable resLightingLookupTable); 355 356 //! @brief アニメーション対象のリソースを取得します。 357 //! 358 //! @param objectType 対応するタイプです。 359 //! @return バッファがあればバッファを、無ければオリジナルを返します。 360 //! GetActiveResource(u32 objectType)361 ResMaterial GetActiveResource(u32 objectType) 362 { 363 return (CanUseBuffer(objectType)) ? GetBuffer() : GetOriginal(); 364 } 365 366 //! @brief アニメーションに登録するモデルデータのポインタを取得します。 367 void* GetAnimTargetObject(const anim::ResAnimGroupMember& anim, const ResMaterial resMaterial); 368 369 // アニメーションのオブジェクトタイプに対応するバッファーが存在するかどうかを取得します。 370 bool CanUseBuffer(u32 objectType) const; 371 372 typedef ut::MoveArray<ResMaterial> ResMaterialArray; 373 374 ResMaterialArray m_Buffers; 375 Model* m_Owner; 376 ResShaderProgramDescription m_ProgramDescription; 377 s32 m_BufferCount; 378 379 ResMaterial m_ShaderParameterResMaterial; 380 ResMaterial m_ShadingParameterResMaterial; 381 ResMaterial m_MaterialColorResMaterial; 382 ResMaterial m_RasterizationResMaterial; 383 ResMaterial m_TextureCoordinatorResMaterial; 384 ResMaterial m_TextureMapperResMaterial; 385 ResMaterial m_FragmentLightingResMaterial; 386 ResMaterial m_FragmentLightingTableResMaterial; 387 ResMaterial m_TextureCombinerResMaterial; 388 ResMaterial m_AlphaTestResMaterial; 389 ResMaterial m_FragmentOperationResMaterial; 390 ResMaterial m_SceneEnvironmentResMaterial; 391 392 // TODO: CanUseBufferを非公開にするために暫定で対処しています。 393 friend class Model; 394 }; 395 396 //! @brief マテリアルの Array の定義です。 397 typedef ut::MoveArray<Material*> MaterialArray; 398 399 } // namespace gfx 400 } // namespace nw 401 402 #endif // NW_GFX_MATERIAL_H_ 403