1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: gfx_RenderQueue.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: 25569 $ 14 *---------------------------------------------------------------------------*/ 15 16 #ifndef NW_GFX_RENDERQUEUE_H_ 17 #define NW_GFX_RENDERQUEUE_H_ 18 19 #include <nw/gfx/gfx_RenderElement.h> 20 21 #include <nw/ut/ut_MoveArray.h> 22 #include <nw/ut/ut_Preprocessor.h> 23 #include <nw/ut/ut_TypeTraits.h> 24 #include <nw/gfx/gfx_Camera.h> 25 #include <nw/gfx/gfx_Model.h> 26 #include <nw/gfx/gfx_SkeletalModel.h> 27 #include <nw/gfx/gfx_SceneHelper.h> 28 29 namespace nw 30 { 31 namespace gfx 32 { 33 34 //--------------------------------------------------------------------------- 35 //! @brief 描画要素を格納するキュークラスです。 36 //! 37 //! @tparam TElement 描画単位となるクラスです。 38 //! @tparam TElementList 描画単位のクラスを格納するためのコンテナです。 39 //! @tparam TElementKeyFactory 描画単位をソートするためのキーを作成するクラスです。 40 //--------------------------------------------------------------------------- 41 template< 42 typename TElement, 43 typename TElementList, 44 typename TElementKeyFactory = BasicRenderKeyFactory<typename TElement::KeyType> 45 > 46 class BasicRenderQueue : public GfxObject 47 { 48 private: 49 NW_DISALLOW_COPY_AND_ASSIGN(BasicRenderQueue); 50 NW_STATIC_ASSERT(!ut::IsArray<TElement>::value); 51 52 public: 53 NW_UT_RUNTIME_TYPEINFO; 54 55 static const u8 PRIORITY_END = 0xff; //!< プライオリティの最後(最大値)を表す定義です。 56 57 typedef TElement ElementType; 58 typedef TElementList ElementListType; 59 typedef TElementKeyFactory ElementKeyFactoryType; 60 typedef typename TElement::KeyType ElementKeyType; 61 62 typedef typename TElementList::reference reference; 63 typedef typename TElementList::difference_type difference_type; 64 typedef typename TElementList::value_type value_type; 65 typedef typename TElementList::iterator iterator; 66 typedef typename TElementList::const_iterator const_iterator; 67 68 #if defined(_MSC_VER) && _MSC_VER <= 1201 69 typedef std::reverse_iterator<iterator, TElement> reverse_iterator; 70 typedef std::reverse_iterator<const_iterator, TElement> const_reverse_iterator; 71 #else 72 typedef std::reverse_iterator<iterator> reverse_iterator; 73 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 74 #endif 75 76 //--------------------------------------------------------------------------- 77 //! @brief 描画レイヤーが1(半透明用)のときのみ深度計算を行うための関数オブジェクトです。 78 //--------------------------------------------------------------------------- 79 struct IsCalculatingOnlyLayer1Functor 80 { IsCalculatingOnlyLayer1FunctorIsCalculatingOnlyLayer1Functor81 IsCalculatingOnlyLayer1Functor(Model* model, ResMesh mesh) 82 { 83 isCalculating = 84 model->GetRenderLayerId(mesh) == ResMaterial::TRANSLUCENCY_KIND_LAYER1; 85 } 86 IsCalculatingOnlyLayer1FunctorIsCalculatingOnlyLayer1Functor87 IsCalculatingOnlyLayer1Functor(ResMaterial::TranslucencyKind renderLayer) 88 { 89 isCalculating = renderLayer == ResMaterial::TRANSLUCENCY_KIND_LAYER1; 90 } 91 operatorIsCalculatingOnlyLayer1Functor92 bool operator ()() const 93 { 94 return isCalculating; 95 } 96 97 bool isCalculating; 98 }; 99 100 //--------------------------------------------------------------------------- 101 //! @brief 常に深度計算を行うための関数オブジェクトです。 102 //--------------------------------------------------------------------------- 103 struct AlwaysCalculatingFunctor 104 { AlwaysCalculatingFunctorAlwaysCalculatingFunctor105 AlwaysCalculatingFunctor(Model* model, ResMesh mesh) 106 { NW_UNUSED_VARIABLE(model); NW_UNUSED_VARIABLE(mesh); } 107 AlwaysCalculatingFunctorAlwaysCalculatingFunctor108 AlwaysCalculatingFunctor(ResMaterial::TranslucencyKind renderLayer) 109 { NW_UNUSED_VARIABLE(renderLayer); } 110 operatorAlwaysCalculatingFunctor111 bool operator ()() const 112 { 113 return true; 114 } 115 }; 116 117 //--------------------------------------------------------------------------- 118 //! @brief クリップ座標系での深度を計算する関数オブジェクトです。 119 //--------------------------------------------------------------------------- 120 struct CalculateDepthFunctor 121 { 122 typedef Model ModelType; 123 CalculateDepthFunctorCalculateDepthFunctor124 CalculateDepthFunctor(ModelType* model) 125 : model(model) 126 { 127 NW_NULL_ASSERT(model); 128 this->resModel = model->GetResModel(); 129 NW_ASSERT(resModel.IsValid()); 130 } 131 132 template<typename IsCalculating> operatorCalculateDepthFunctor133 float operator ()(ResMesh mesh, const Camera& camera, IsCalculating isCalculating) const 134 { 135 if (isCalculating()) 136 { 137 ResShape shape = resModel.GetShapes(mesh.GetShapeIndex()); 138 NW_ASSERT(shape.IsValid()); 139 140 return SceneHelper::CalculateDepth( 141 shape.GetCenterPosition(), model->WorldMatrix(), camera); 142 } 143 else 144 { 145 return 0.0f; 146 } 147 } 148 149 ModelType* model; 150 ResModel resModel; 151 }; 152 153 //--------------------------------------------------------------------------- 154 //! @brief スケルタルモデル用のクリップ座標系での深度を計算する関数オブジェクトです。 155 //--------------------------------------------------------------------------- 156 struct CalculateDepthOfSkeletalModelFunctor 157 { 158 typedef SkeletalModel ModelType; 159 CalculateDepthOfSkeletalModelFunctorCalculateDepthOfSkeletalModelFunctor160 CalculateDepthOfSkeletalModelFunctor(ModelType* model) 161 : model(model) 162 { 163 NW_NULL_ASSERT(model); 164 this->resModel = model->GetResModel(); 165 NW_ASSERT(resModel.IsValid()); 166 } 167 168 template<typename IsCalculating> operatorCalculateDepthOfSkeletalModelFunctor169 float operator ()(ResMesh mesh, const Camera& camera, IsCalculating isCalculating) const 170 { 171 if (isCalculating()) 172 { 173 float depth; 174 ResShape shape = resModel.GetShapes(mesh.GetShapeIndex()); 175 NW_ASSERT(shape.IsValid()); 176 177 // プリミティブが1つの場合はボーンのマトリクスを使用する 178 if (shape.GetPrimitiveSetsCount() == 1) 179 { 180 ResPrimitiveSet primitiveSet = shape.GetPrimitiveSets(0); 181 s32 boneIndex = primitiveSet.GetBoneIndexTable(0); 182 Skeleton::MatrixPose& pose = this->model->GetSkeleton()->WorldMatrixPose(); 183 depth = SceneHelper::CalculateDepth( 184 shape.GetCenterPosition(), *pose.GetMatrix(boneIndex), camera); 185 } 186 else 187 { 188 depth = SceneHelper::CalculateDepth( 189 shape.GetCenterPosition(), model->WorldMatrix(), camera); 190 } 191 192 return depth; 193 } 194 else 195 { 196 return 0.0f; 197 } 198 } 199 200 ModelType* model; 201 ResModel resModel; 202 }; 203 204 //--------------------------------------------------------------------------- 205 //! @brief モデルをレンダーキューに追加するための関数オブジェクトです。 206 //--------------------------------------------------------------------------- 207 template<typename ModelType, typename CalculateDepth, typename IsCalculating> 208 struct BasicEnqueueModelFunctor : public std::unary_function<ResMesh, void> 209 { BasicEnqueueModelFunctorBasicEnqueueModelFunctor210 BasicEnqueueModelFunctor( 211 BasicRenderQueue* renderQueue, 212 ModelType* model, 213 u8 layerId, 214 const Camera& camera) 215 : calculateDepth(model), 216 renderQueue(renderQueue), 217 camera(camera), 218 layerId(layerId) {} 219 operatorBasicEnqueueModelFunctor220 result_type operator()(argument_type mesh) 221 { 222 NW_ASSERT(mesh.IsValid()); 223 if (calculateDepth.model->IsMeshVisible(mesh)) 224 { 225 float depth = calculateDepth(mesh, camera, IsCalculating(calculateDepth.model, mesh)); 226 renderQueue->EnqueueMesh(mesh, calculateDepth.model, depth, layerId); 227 } 228 } 229 230 CalculateDepth calculateDepth; 231 BasicRenderQueue* renderQueue; 232 const Camera& camera; 233 u8 layerId; 234 }; 235 236 //! @brief モデルをレンダーキューに追加するための関数オブジェクトです。 237 typedef BasicEnqueueModelFunctor<Model, CalculateDepthFunctor, AlwaysCalculatingFunctor> 238 EnqueueModelFunctor; 239 240 //! @brief スケルタルモデルをレンダーキューに追加するための関数オブジェクトです。 241 typedef BasicEnqueueModelFunctor<SkeletalModel, CalculateDepthOfSkeletalModelFunctor, AlwaysCalculatingFunctor> 242 EnqueueSkeletalModelFunctor; 243 244 //! @brief モデルをレンダーキューに追加するための関数オブジェクトです。 245 //! 描画レイヤーが1(半透明用)のときのみ深度計算を行います。 246 typedef BasicEnqueueModelFunctor<Model, CalculateDepthFunctor, IsCalculatingOnlyLayer1Functor> 247 FastEnqueueModelFunctor; 248 249 //! @brief スケルタルモデルをレンダーキューに追加するための関数オブジェクトです。 250 //! 描画レイヤーが1(半透明用)のときのみ深度計算を行います。 251 typedef BasicEnqueueModelFunctor<SkeletalModel, CalculateDepthOfSkeletalModelFunctor, IsCalculatingOnlyLayer1Functor> 252 FastEnqueueSkeletalModelFunctor; 253 254 //--------------------------------------------------------------------------- 255 //! @brief モデルをレンダーキューに追加するための関数オブジェクトです。 256 //! 257 //! 半透明系のメッシュの深度をモデル単位にしてキーを作成します。 258 //--------------------------------------------------------------------------- 259 template<typename ModelType, typename CalculateDepth, typename IsCalculating> 260 struct BasicEnqueueModelTranslucentModelBaseFunctor : public std::unary_function<ResMesh, void> 261 { BasicEnqueueModelTranslucentModelBaseFunctorBasicEnqueueModelTranslucentModelBaseFunctor262 BasicEnqueueModelTranslucentModelBaseFunctor( 263 BasicRenderQueue* renderQueue, 264 ModelType* model, 265 u8 layerId, 266 const Camera& camera) 267 : calculateDepth(model), 268 renderQueue(renderQueue), 269 camera(camera), 270 layerId(layerId) 271 { 272 NW_NULL_ASSERT(renderQueue); 273 274 modelDepth = SceneHelper::CalculateDepth(model->WorldMatrix(), camera); 275 } 276 operatorBasicEnqueueModelTranslucentModelBaseFunctor277 result_type operator()(argument_type mesh) 278 { 279 NW_ASSERT(mesh.IsValid()); 280 if (calculateDepth.model->IsMeshVisible(mesh)) 281 { 282 ResMaterial::TranslucencyKind translucencyKind = 283 calculateDepth.model->GetRenderLayerId(mesh); 284 285 float depth = (translucencyKind == ResMaterial::TRANSLUCENCY_KIND_OPAQUE) 286 ? calculateDepth(mesh, camera, IsCalculating(translucencyKind)) 287 : modelDepth; 288 289 renderQueue->EnqueueElement( 290 ElementType(mesh, calculateDepth.model), translucencyKind, depth, layerId); 291 } 292 } 293 294 CalculateDepth calculateDepth; 295 BasicRenderQueue* renderQueue; 296 const Camera& camera; 297 float modelDepth; 298 u8 layerId; 299 }; 300 301 //! @brief モデルをレンダーキューに追加するための関数オブジェクトです。 302 typedef BasicEnqueueModelTranslucentModelBaseFunctor<Model, CalculateDepthFunctor, AlwaysCalculatingFunctor> 303 EnqueueModelTranslucentModelBaseFunctor; 304 305 //! @brief スケルタルモデルをレンダーキューに追加するための関数オブジェクトです。 306 typedef BasicEnqueueModelTranslucentModelBaseFunctor<SkeletalModel, CalculateDepthOfSkeletalModelFunctor, AlwaysCalculatingFunctor> 307 EnqueueSkeletalModelTranslucentModelBaseFunctor; 308 309 //! @brief モデルをレンダーキューに追加するための関数オブジェクトです。 310 //! 描画レイヤーが1(半透明用)のときのみ深度計算を行います。 311 typedef BasicEnqueueModelTranslucentModelBaseFunctor<Model, CalculateDepthFunctor, IsCalculatingOnlyLayer1Functor> 312 FastEnqueueModelTranslucentModelBaseFunctor; 313 314 //! @brief スケルタルモデルをレンダーキューに追加するための関数オブジェクトです。 315 //! 描画レイヤーが1(半透明用)のときのみ深度計算を行います。 316 typedef BasicEnqueueModelTranslucentModelBaseFunctor<SkeletalModel, CalculateDepthOfSkeletalModelFunctor, IsCalculatingOnlyLayer1Functor> 317 FastEnqueueSkeletalModelTranslucentModelBaseFunctor; 318 319 //---------------------------------------- 320 //! @name デバッグユーティリティ 321 //@{ 322 323 //! @brief レンダーキューの状態をログ出力にレポートするための関数オブジェクトです。 324 struct ReportFunctor : public std::unary_function<void, reference> 325 { ReportFunctorReportFunctor326 ReportFunctor() : count(0) {} 327 328 //! @brief ログ出力にレポートします。 operatorReportFunctor329 void operator() (reference element) 330 { 331 #ifdef NW_RELEASE 332 NW_UNUSED_VARIABLE(element); 333 #else 334 if (element.IsCommand()) 335 { 336 NW_DEV_LOG("%3d : Command(%x)\n", 337 count, 338 reinterpret_cast<u32>(element.GetCommand())); 339 } 340 else 341 { 342 const ResMesh mesh = element.GetMesh(); 343 const ResModel model = element.GetModel()->GetResModel(); 344 const ResMaterial material = 345 element.GetModel()->GetMaterial(mesh.GetMaterialIndex())->GetOriginal(); 346 NW_DEV_LOG("%3d : Model(%s), Mesh(%s), Material(%s)\n", 347 count, 348 model.GetName(), 349 mesh.GetName(), 350 material.GetName()); 351 } 352 353 ++count; 354 #endif 355 } 356 357 int count; 358 }; 359 360 //@} 361 362 //---------------------------------------- 363 //! @name 作成 364 //@{ 365 366 //! @brief BasicRenderQueue を作成するためのクラスです。 367 //! 368 //! IsFixedSizeMemory の初期値は true です。false に変更すると、各種最大数の設定は無視されます。 369 class Builder 370 { 371 public: 372 //! @brief コンストラクタです。 Builder()373 Builder() : m_IsFixedSizeMemory(true), m_MaxRenderElements(64) {} 374 375 //! @brief デストラクタです。 ~Builder()376 ~Builder() {} 377 378 //! @brief 生成時以外にもメモリを確保するかどうかのフラグを設定します。 379 //! 380 //! true を指定すると、生成時のみ固定サイズのメモリ確保を行います。 381 //! 382 //! false を指定すると、生成時以外にも必要に応じて動的にメモリ確保が行われます。 IsFixedSizeMemory(bool isFixedSizeMemory)383 Builder& IsFixedSizeMemory(bool isFixedSizeMemory) 384 { 385 m_IsFixedSizeMemory = isFixedSizeMemory; 386 return *this; 387 } 388 389 //! @brief キューに積む描画要素の最大数を設定します。 MaxRenderElements(int max)390 Builder& MaxRenderElements(int max) { m_MaxRenderElements = max; return *this; } 391 392 //! @brief レンダーキューを生成します。 393 //! 394 //! @param[in] allocator アロケータです。 395 //! 396 //! @return 生成したレンダーキューを返します。 397 //! Create(os::IAllocator * allocator)398 BasicRenderQueue* Create(os::IAllocator* allocator) 399 { 400 void* queueMemory = allocator->Alloc<BasicRenderQueue>(1); 401 NW_NULL_ASSERT(queueMemory); 402 BasicRenderQueue* queue; 403 if (m_IsFixedSizeMemory) 404 { 405 queue = new(queueMemory) BasicRenderQueue(allocator, m_MaxRenderElements); 406 } 407 else 408 { 409 queue = new(queueMemory) BasicRenderQueue(allocator); 410 } 411 return queue; 412 } 413 414 private: 415 bool m_IsFixedSizeMemory; 416 int m_MaxRenderElements; 417 }; 418 419 //@} 420 421 //---------------------------------------- 422 //! @name キュー操作 423 //@{ 424 425 //! @brief キューに描画要素を追加します。 426 //! 427 //! @param[in] element 追加する描画要素です。 428 //! @param[in] translucencyKind 透明性の種類です。 429 //! @param[in] depth スクリーン座標系におけるメッシュの深度です。(0.0 ~ 1.0) 430 //! @param[in] layerId 描画要素のソート時に最優先に区分される ID です。レイヤーやビューポートの描画を制御するのに用います。 431 //! EnqueueElement(const ElementType & element,ResMaterial::TranslucencyKind translucencyKind,float depth,u8 layerId)432 ElementType* EnqueueElement( 433 const ElementType& element, 434 ResMaterial::TranslucencyKind translucencyKind, 435 float depth, 436 u8 layerId) 437 { 438 this->m_List.push_back(element); 439 ElementType* back = &m_List.back(); 440 NW_NULL_ASSERT(back); 441 442 if (this->m_KeyCachingState == UNUSE_CACHED_KEY || 443 translucencyKind == ResMaterial::TRANSLUCENCY_KIND_LAYER1) 444 { 445 RenderKeyFactory* keyFactory = this->GetKeyFactory(translucencyKind); 446 back->Key() = keyFactory->CreateRenderKey(*back, depth, layerId); 447 } 448 else 449 { 450 if (ut::CheckFlag<u32, u32>(back->GetMesh().GetFlags(), ResMesh::FLAG_VALID_RENDER_KEY_CACHE)) 451 { 452 // キャッシュしたキーを利用します。 453 back->Key() = back->GetMesh().GetRenderKeyCache(); 454 } 455 else 456 { 457 // キーを作成して、キャッシュします。 458 RenderKeyFactory* keyFactory = this->GetKeyFactory(translucencyKind); 459 back->Key() = keyFactory->CreateRenderKey(*back, depth, layerId); 460 461 back->GetMesh().SetRenderKeyCache(back->Key()); 462 back->GetMesh().SetFlags(ut::EnableFlag<u32, u32>( 463 back->GetMesh().GetFlags(), ResMesh::FLAG_VALID_RENDER_KEY_CACHE)); 464 } 465 } 466 467 return back; 468 } 469 470 //! @brief キューにメッシュ要素を追加します。 471 //! 472 //! @param[in] mesh メッシュです。 473 //! @param[in] model メッシュの所有者となるモデルです。 474 //! @param[in] depth スクリーン座標系におけるメッシュの深度です。(0.0 ~ 1.0) 475 //! @param[in] layerId 描画要素のソート時に最優先に区分される ID です。レイヤーやビューポートの描画を制御するのに用います。 476 //! EnqueueMesh(ResMesh mesh,Model * model,float depth,u8 layerId)477 ElementType* EnqueueMesh( 478 ResMesh mesh, 479 Model* model, 480 float depth, 481 u8 layerId) 482 { 483 NW_ASSERT(mesh.IsValid()); 484 NW_NULL_ASSERT(model); 485 486 return EnqueueElement( 487 ElementType(mesh, model), model->GetRenderLayerId(mesh), depth, layerId); 488 } 489 490 //! @brief キューにモデルに含まれるメッシュ要素を追加します。 491 //! 492 //! @param[in] model メッシュの所有者となるモデルです。 493 //! @param[in] layerId 描画要素のソート時に最優先に区分される ID です。レイヤーやビューポートの描画を制御するのに用います。 494 //! @param[in] camera メッシュの深度を計算するのに用いるカメラです。 495 //! EnqueueModel(Model * model,u8 layerId,const Camera & camera)496 void EnqueueModel( 497 Model* model, 498 u8 layerId, 499 const Camera& camera) 500 { 501 NW_NULL_ASSERT(model); 502 gfx::ResMeshArray meshs = model->GetResMeshes(); 503 std::for_each( 504 meshs.begin(), 505 meshs.end(), 506 EnqueueModelFunctor(this, model, layerId, camera)); 507 } 508 509 //! @brief キューにスケルタルモデルに含まれるメッシュ要素を追加します。 510 //! 511 //! @param[in] model メッシュの所有者となるモデルです。 512 //! @param[in] layerId 描画要素のソート時に最優先に区分される ID です。レイヤーやビューポートの描画を制御するのに用います。 513 //! @param[in] camera メッシュの深度を計算するのに用いるカメラです。 514 //! EnqueueSkeletalModel(SkeletalModel * model,u8 layerId,const Camera & camera)515 void EnqueueSkeletalModel( 516 SkeletalModel* model, 517 u8 layerId, 518 const Camera& camera) 519 { 520 NW_NULL_ASSERT(model); 521 gfx::ResMeshArray meshs = model->GetResMeshes(); 522 std::for_each( 523 meshs.begin(), 524 meshs.end(), 525 EnqueueSkeletalModelFunctor(this, model, layerId, camera)); 526 } 527 528 //! @brief キューにコマンド要素を追加します。 529 //! 530 //! ここで設定するコマンドは描画時に呼び出されるので、 531 //! コマンドのインスタンスは描画時まで保持されるようにしてください。 532 //! ローカル変数等を使用して、描画前にデストラクトされると 533 //! 不正な関数呼び出しが行われてしまいます。 534 //! 535 //! @param[in] command 描画時に呼び出されるコマンドです。 536 //! @param[in] translucencyKind 透明性の種類です。 537 //! @param[in] priority メッシュの描画優先度です。 538 //! @param[in] layerId 描画要素のソート時に最優先に区分される ID です。レイヤーやビューポートの描画を制御するのに用います。 539 //! EnqueueCommand(RenderCommand * command,ResMaterial::TranslucencyKind translucencyKind,u8 priority,u8 layerId)540 ElementType* EnqueueCommand( 541 RenderCommand* command, 542 ResMaterial::TranslucencyKind translucencyKind, 543 u8 priority, 544 u8 layerId) 545 { 546 RenderKeyFactory* keyFactory = this->GetKeyFactory(translucencyKind); 547 548 this->m_List.push_back( 549 ElementType(keyFactory->CreateCommandRenderKey( 550 command, translucencyKind, priority, layerId))); 551 552 return &this->m_List.back(); 553 } 554 555 //! @brief キューの全ての要素を削除します。 556 //! 557 //! @param[in] cacheEnabled true を指定するとキャッシュ機能を有効にします。 558 //! 559 void Reset(bool cacheEnabled = false) 560 { 561 this->m_List.clear(); 562 this->m_KeyCachingState = (cacheEnabled) ? USE_CACHED_KEY : UNUSE_CACHED_KEY; 563 } 564 565 //! @brief キューの全ての要素を削除して、キーファクトリの設定を行います。 566 //! 567 //! 各キーファクトリに NULL を設定すると、ファクトリの変更を行いません。 568 //! 569 //! @param[in] opacityKeyFactory 不透明メッシュのキーファクトリです。 570 //! @param[in] translucentKeyFactory 半透明メッシュのキーファクトリです。 571 //! @param[in] additiveKeyFactory 加算合成メッシュのキーファクトリです。 572 //! @param[in] subtractionKeyFactory 減算合成メッシュのキーファクトリです。 573 //! @param[in] cacheEnabled true を指定するとキャッシュ機能を有効にします。 574 //! 575 //! @sa nw::gfx::CreatePriorMaterialRenderKeyFactory 576 //! @sa nw::gfx::CreatePriorMaterialReverseDepthRenderKeyFactory 577 //! @sa nw::gfx::CreatePriorMaterialAndZeroDepthRenderKeyFactory 578 //! @sa nw::gfx::CreatePriorDepthRenderKeyFactory 579 //! @sa nw::gfx::CreatePriorDepthReverseDepthRenderKeyFactory 580 //! @sa nw::gfx::CreateTopPriorDepthRenderKeyFactory 581 //! @sa nw::gfx::CreateTopPriorDepthReverseDepthRenderKeyFactory 582 //! 583 void Reset( 584 ElementKeyFactoryType* opacityKeyFactory, 585 ElementKeyFactoryType* translucentKeyFactory, 586 ElementKeyFactoryType* additiveKeyFactory, 587 ElementKeyFactoryType* subtractionKeyFactory, 588 bool cacheEnabled = false) 589 { 590 this->Reset(cacheEnabled); 591 592 if (opacityKeyFactory != NULL) 593 { 594 this->m_OpacityKeyFactory = opacityKeyFactory; 595 } 596 if (translucentKeyFactory != NULL) 597 { 598 this->m_TranslucentKeyFactory = translucentKeyFactory; 599 } 600 if (additiveKeyFactory != NULL) 601 { 602 this->m_AdditiveKeyFactory = additiveKeyFactory; 603 } 604 if (subtractionKeyFactory != NULL) 605 { 606 this->m_SubtractionKeyFactory = subtractionKeyFactory; 607 } 608 } 609 610 //@} 611 612 //---------------------------------------- 613 //! @name 取得/設定 614 //@{ 615 616 //! @brief 要素数を取得します。 Size()617 int Size() const 618 { 619 return m_List.size(); 620 } 621 622 //! @brief 要素が1つもない場合は true を返します。 Empty()623 bool Empty() const 624 { 625 return m_List.empty(); 626 } 627 628 //! @brief 先頭の要素を参照します。 Peek()629 ElementType& Peek() 630 { 631 return m_List.front(); 632 } 633 634 //! @brief 先頭の要素を参照します。 Peek()635 const ElementType& Peek() const 636 { 637 return m_List.front(); 638 } 639 640 //! @brief 先頭のイテレータを取得します。 Begin()641 iterator Begin() 642 { 643 return m_List.begin(); 644 } 645 646 //! @brief 先頭のイテレータを取得します。 Begin()647 const_iterator Begin() const 648 { 649 return m_List.begin(); 650 } 651 652 //! @brief 末尾のイテレータを取得します。 End()653 iterator End() 654 { 655 return m_List.end(); 656 } 657 658 //! @brief 末尾のイテレータを取得します。 End()659 const_iterator End() const 660 { 661 return m_List.end(); 662 } 663 664 //! @brief 先頭のリバースイテレータを取得します。 ReverseBegin()665 reverse_iterator ReverseBegin() 666 { 667 return m_List.rbegin(); 668 } 669 670 //! @brief 先頭のリバースイテレータを取得します。 ReverseBegin()671 const_reverse_iterator ReverseBegin() const 672 { 673 return m_List.rbegin(); 674 } 675 676 //! @brief 末尾のリバースイテレータを取得します。 ReverseEnd()677 reverse_iterator ReverseEnd() 678 { 679 return m_List.rend(); 680 } 681 682 //! @brief 末尾のリバースイテレータを取得します。 ReverseEnd()683 const_reverse_iterator ReverseEnd() const 684 { 685 return m_List.rend(); 686 } 687 688 //@} 689 690 //---------------------------------------- 691 //! @name ユーティリティ 692 //@{ 693 694 //! @brief クリップ座標系での深度を計算します。(非推奨) 695 //! 696 //! 廃止予定なので、SceneHelper::CalculateDepth をご利用ください。 697 //! 698 //! @sa SceneHelper::CalculateDepth 699 //! NW_DEPRECATED_FUNCTION(float CalculateDepth (const math::VEC3 & localPosition,const math::MTX34 & worldMatrix,const Camera & camera))700 NW_DEPRECATED_FUNCTION(float CalculateDepth( 701 const math::VEC3& localPosition, 702 const math::MTX34& worldMatrix, 703 const Camera& camera)) 704 { 705 return SceneHelper::CalculateDepth(localPosition, worldMatrix, camera); 706 } 707 708 //! @brief クリップ座標系での深度を計算します。(非推奨) 709 //! 710 //! 廃止予定なので、SceneHelper::CalculateDepth をご利用ください。 711 //! 712 //! @sa SceneHelper::CalculateDepth 713 //! NW_DEPRECATED_FUNCTION(float CalculateDepth (const math::MTX34 & worldMatrix,const Camera & camera))714 NW_DEPRECATED_FUNCTION(float CalculateDepth( 715 const math::MTX34& worldMatrix, 716 const Camera& camera)) 717 { 718 return SceneHelper::CalculateDepth(worldMatrix, camera); 719 } 720 721 //@} 722 723 private: BasicRenderQueue(os::IAllocator * allocator)724 explicit BasicRenderQueue(os::IAllocator* allocator) 725 : GfxObject(allocator), 726 m_List(allocator), 727 m_OpacityKeyFactory(NULL), 728 m_TranslucentKeyFactory(NULL), 729 m_AdditiveKeyFactory(NULL), 730 m_SubtractionKeyFactory(NULL), 731 m_KeyCachingState(UNUSE_CACHED_KEY) {} 732 BasicRenderQueue(os::IAllocator * allocator,int maxRenderElements)733 BasicRenderQueue(os::IAllocator* allocator, int maxRenderElements) 734 : GfxObject(allocator), 735 m_List(maxRenderElements, allocator), 736 m_OpacityKeyFactory(NULL), 737 m_TranslucentKeyFactory(NULL), 738 m_AdditiveKeyFactory(NULL), 739 m_SubtractionKeyFactory(NULL), 740 m_KeyCachingState(UNUSE_CACHED_KEY) {} 741 ~BasicRenderQueue()742 virtual ~BasicRenderQueue() {} 743 GetKeyFactory(ResMaterial::TranslucencyKind translucencyKind)744 ElementKeyFactoryType* GetKeyFactory(ResMaterial::TranslucencyKind translucencyKind) 745 { 746 ElementKeyFactoryType* keyFactory = NULL; 747 switch (translucencyKind) 748 { 749 case ResMaterial::TRANSLUCENCY_KIND_LAYER0: 750 keyFactory = this->m_OpacityKeyFactory; 751 break; 752 case ResMaterial::TRANSLUCENCY_KIND_LAYER1: 753 keyFactory = this->m_TranslucentKeyFactory; 754 break; 755 case ResMaterial::TRANSLUCENCY_KIND_LAYER2: 756 keyFactory = this->m_SubtractionKeyFactory; 757 break; 758 case ResMaterial::TRANSLUCENCY_KIND_LAYER3: 759 keyFactory = this->m_AdditiveKeyFactory; 760 break; 761 default: NW_FAILSAFE_IF(false) { keyFactory = this->m_OpacityKeyFactory; } break; 762 } 763 NW_NULL_ASSERT(keyFactory); 764 return keyFactory; 765 } 766 767 TElementList m_List; 768 ElementKeyFactoryType* m_OpacityKeyFactory; 769 ElementKeyFactoryType* m_TranslucentKeyFactory; 770 ElementKeyFactoryType* m_AdditiveKeyFactory; 771 ElementKeyFactoryType* m_SubtractionKeyFactory; 772 773 enum KeyCachingState 774 { 775 UNUSE_CACHED_KEY, 776 USE_CACHED_KEY 777 }; 778 779 KeyCachingState m_KeyCachingState; 780 }; 781 782 //! @brief 標準のレンダーキューの定義です。 783 typedef BasicRenderQueue< 784 BasicRenderElement<RenderKeyType>, 785 ut::MoveArray<BasicRenderElement<RenderKeyType> > > 786 RenderQueue; 787 788 //--------------------------------------------------------------------------- 789 //! @brief ソート比較用関数オブジェクトです。 790 //--------------------------------------------------------------------------- 791 struct RenderElementCompare 792 : public std::binary_function<RenderElement, RenderElement, bool> 793 { operatorRenderElementCompare794 bool operator() ( 795 const RenderElement& lhs, 796 const RenderElement& rhs) 797 { 798 return lhs.Key() < rhs.Key(); 799 } 800 }; 801 802 } // namespace gfx 803 } // namespace nw 804 805 #endif // NW_GFX_RENDERQUEUE_H_ 806