/*---------------------------------------------------------------------------* Project: NintendoWare File : gfx_RenderElement.h Copyright (C) 2010 Nintendo Co., Ltd. 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: 24209 $ *---------------------------------------------------------------------------*/ #ifndef NW_GFX_RENDERELEMENT_H_ #define NW_GFX_RENDERELEMENT_H_ #include #include #include #include #include namespace nw { namespace gfx { class Material; class RenderContext; //--------------------------------------------------------------------------- //! @brief レンダーキューの途中に独自処理を割り込ませるためのクラスです。 //--------------------------------------------------------------------------- class RenderCommand { private: NW_DISALLOW_COPY_AND_ASSIGN(RenderCommand); public: //! @brief コマンドを呼び出します。 virtual void Invoke(RenderContext* renderContext) = 0; protected: //! コンストラクタです。 RenderCommand() {} //! デストラクタです。 virtual ~RenderCommand() {} }; //--------------------------------------------------------------------------- //! @brief レンダーキューに積まれる描画単位となるクラスです。 //! //! @tparam TKey レンダーキーの型です。 //--------------------------------------------------------------------------- template class BasicRenderElement { public: //! @brief キーの値となる型です。 typedef TKey KeyType; //! @brief 64 ビット版の レンダーキーのビット配置の定義です。 enum Bit64RenderKeyFormat { BIT64_LAYER_SHIFT = 56, BIT64_LAYER_BIT_SIZE = 8, BIT64_LAYER_MASK = (1 << BIT64_LAYER_BIT_SIZE) - 1, BIT64_TRANSLUCENCY_KIND_SHIFT = 54, BIT64_TRANSLUCENCY_KIND_BIT_SIZE = 2, BIT64_TRANSLUCENCY_KIND_MASK = (1 << BIT64_TRANSLUCENCY_KIND_BIT_SIZE) - 1, BIT64_COMMAND_FLAG_SHIFT = 53, BIT64_COMMAND_FLAG_MASK = 0x1, BIT64_COMMAND_BIT_SIZE = 32, BIT64_COMMAND_MASK = 0xffffffff, BIT64_DEPTH_BIT_SIZE = 24, BIT64_DEPTH_MASK = (1 << BIT64_DEPTH_BIT_SIZE) - 1, BIT64_DEPTH_MAX_VALUE = BIT64_DEPTH_MASK, BIT64_MATERIAL_ID_BIT_SIZE = 29, BIT64_MATERIAL_ID_MASK = (1 << BIT64_MATERIAL_ID_BIT_SIZE) - 1, // マテリアルID用の定義です。 BIT64_MATERIAL_RESOURCE_ID_BIT_SIZE = 22, BIT64_MATERIAL_RESOURCE_ID_MASK = (1 << BIT64_MATERIAL_RESOURCE_ID_BIT_SIZE) - 1, BIT64_MATERIAL_INSTANCE_ID_BIT_SIZE = 3, BIT64_MATERIAL_INSTANCE_ID_MASK = (1 << BIT64_MATERIAL_INSTANCE_ID_BIT_SIZE) - 1, BIT64_MATERIAL_PRIORITY_BIT_SIZE = 4, BIT64_MATERIAL_PRIORITY_MASK = (1 << BIT64_MATERIAL_PRIORITY_BIT_SIZE) - 1, // 簡易マテリアルID用の定義です。深度優先のキーなどに使用します。 BIT64_SIMPLE_MATERIAL_ID_BIT_SIZE = 21, BIT64_SIMPLE_MATERIAL_ID_MASK = (1 << BIT64_SIMPLE_MATERIAL_ID_BIT_SIZE) - 1, BIT64_SIMPLE_MATERIAL_PRIORITY_BIT_SIZE = 8, BIT64_SIMPLE_MATERIAL_PRIORITY_MASK = (1 << BIT64_SIMPLE_MATERIAL_PRIORITY_BIT_SIZE) - 1 }; //! @brief 24 ビット整数の深度値量子化関数オブジェクトです。 //! //! 近いものが先に描画されるようになります。 //! struct Depth24bitQuantizer : public std::unary_function { KeyType operator()(float depth) { return static_cast( depth * static_cast(BIT64_DEPTH_MAX_VALUE)) & BIT64_DEPTH_MASK; } }; //! @brief 24 ビット整数の深度値量子化関数オブジェクトです。 //! //! 遠いものが先に描画されるようになります。 //! struct ReverseDepth24bitQuantizer : public std::unary_function { KeyType operator()(float depth) { return static_cast( (1.0f - depth) * static_cast(BIT64_DEPTH_MAX_VALUE)) & BIT64_DEPTH_MASK; } }; //! @brief 深度値量子化を行わない関数オブジェクトです。 //! //! 0を返すだけです。 //! struct ZeroQuantizer : public std::unary_function { KeyType operator()(float depth) { NW_UNUSED_VARIABLE(depth); return 0; } }; //! @brief 64 ビット版のレンダーキーを設定するためのクラスです。 template class Bit64RenderKey { private: NW_DISALLOW_COPY_AND_ASSIGN(Bit64RenderKey); public: //---------------------------------------- //! @name 作成 //@{ //! @brief コンストラクタです。 Bit64RenderKey() : m_Key(0) {} //@} //---------------------------------------- //! @name 取得/設定 //@{ //! @brief 描画要素のソート時に最優先に区分される ID を設定します。 void SetLayerId(u8 layerId) { m_Key |= static_cast(layerId & BIT64_LAYER_MASK) << BIT64_LAYER_SHIFT; } //! @brief 詳細マテリアル用の描画優先度を設定します。 void SetPriorityForDetailedMaterial(u8 priority, u32 shift) { m_Key |= static_cast(priority & BIT64_MATERIAL_PRIORITY_MASK) << (shift + BIT64_MATERIAL_RESOURCE_ID_BIT_SIZE + BIT64_MATERIAL_INSTANCE_ID_BIT_SIZE); } //! @brief 詳細マテリアル ID と描画順の種類を設定します。 void SetDetailedMaterialIdAndTranslucencyKind( const Material* material, u32 materialIdShift) { NW_NULL_ASSERT(material); ResMaterial resMaterial = material->GetOriginal(); NW_ASSERT(resMaterial.IsValid()); // HACK: もっとちゃんとしたマテリアル ID を作るようにする。 KeyType id = ((reinterpret_cast(material->GetOwnerModel()) >> 2) & BIT64_MATERIAL_INSTANCE_ID_MASK) | (static_cast(resMaterial.GetMaterialId() & BIT64_MATERIAL_RESOURCE_ID_MASK) << BIT64_MATERIAL_INSTANCE_ID_BIT_SIZE); m_Key |= (id & BIT64_MATERIAL_ID_MASK) << materialIdShift; ResMaterial shadingParametersResMaterial = material->GetShaderParameterResMaterial(); NW_ASSERT(shadingParametersResMaterial.IsValid()); ResMaterial::TranslucencyKind translucencyKind = shadingParametersResMaterial.GetTranslucencyKind(); m_Key |= static_cast(translucencyKind & BIT64_TRANSLUCENCY_KIND_MASK) << BIT64_TRANSLUCENCY_KIND_SHIFT; } //! @brief 簡易マテリアル用の描画優先度を設定します。 void SetPriorityForSimpleMaterial(u8 priority, u32 shift) { m_Key |= static_cast(priority & BIT64_SIMPLE_MATERIAL_PRIORITY_MASK) << (shift + BIT64_SIMPLE_MATERIAL_ID_BIT_SIZE); } //! @brief 簡易マテリアル ID と描画順の種類を設定します。 void SetSimpleMaterialIdAndTranslucencyKind( const Material* material, u32 materialIdShift) { NW_NULL_ASSERT(material); ResMaterial resMaterial = material->GetOriginal(); NW_ASSERT(resMaterial.IsValid()); m_Key |= static_cast(resMaterial.GetMaterialId() & BIT64_SIMPLE_MATERIAL_ID_MASK) << materialIdShift; ResMaterial resBuffer = material->GetBuffer(); ResMaterial::TranslucencyKind translucencyKind = (resBuffer.IsValid()) ? resBuffer.GetTranslucencyKind() : resMaterial.GetTranslucencyKind(); m_Key |= (static_cast(translucencyKind) & BIT64_TRANSLUCENCY_KIND_MASK) << BIT64_TRANSLUCENCY_KIND_SHIFT; } //! @brief 透明性の種類を設定します。 void SetTranslucencyKind(ResMaterial::TranslucencyKind translucencyKind) { m_Key |= (static_cast(translucencyKind) & BIT64_TRANSLUCENCY_KIND_MASK) << BIT64_TRANSLUCENCY_KIND_SHIFT; } //! @brief 深度を設定します。 void SetDepth(float depth, u32 shift) { m_Key |= TDepthQuantizer()(depth) << shift; } //! @brief コマンドを設定します。 void SetCommand(RenderCommand* command) { m_Key |= static_cast(1) << BIT64_COMMAND_FLAG_SHIFT; m_Key |= reinterpret_cast(command); } //! @brief キーを取得します。 const KeyType Key() const { return m_Key; } //@} private: KeyType m_Key; }; //---------------------------------------- //! @name 作成/破棄 //@{ //! @brief キーを設定するコンストラクタです。 explicit BasicRenderElement(const KeyType& key) : m_Key(key), m_Model(NULL) { } //! @brief メッシュ要素のコンストラクタです。 BasicRenderElement(ResMesh mesh, Model* model) : m_Key(0), m_Mesh(mesh), m_Model(model) { } //! @brief コピーコンストラクタです。 BasicRenderElement(const BasicRenderElement& element) : m_Key(element.m_Key), m_Mesh(element.m_Mesh), m_Model(element.m_Model) {} //! @brief デストラクタです。 ~BasicRenderElement() {} //@} //---------------------------------------- //! @name 取得/設定 //@{ //! @brief 要素の種類がコマンドであれば true を返します。 bool IsCommand() const { return this->GetBool(BIT64_COMMAND_FLAG_SHIFT); } //! @brief メッシュを取得します。 ResMesh GetMesh() { return m_Mesh; } //! @brief メッシュを取得します。 const ResMesh GetMesh() const { return m_Mesh; } //! @brief モデルを取得します。 Model* GetModel() { return m_Model; } //! @brief モデルを取得します。 const Model* GetModel() const { return m_Model; } //! @brief コマンドを取得します。 RenderCommand* GetCommand() { NW_ASSERT(this->IsCommand()); return reinterpret_cast( static_cast(this->m_Key) & BIT64_COMMAND_MASK); } //! @brief コマンドを取得します。 const RenderCommand* GetCommand() const { NW_ASSERT(this->IsCommand()); return reinterpret_cast( static_cast(this->m_Key) & BIT64_COMMAND_MASK); } //! @brief ソート時に比較する値を取得します。 KeyType& Key() { return this->m_Key; } //! @brief ソート時に比較する値を取得します。 const KeyType& Key() const { return this->m_Key; } //@} private: bool GetBool(int shift) const { return (this->m_Key >> shift) & 0x1; } KeyType m_Key; ResMesh m_Mesh; Model* m_Model; }; //--------------------------------------------------------------------------- //! @brief 描画ソートを行う際のキーを作成するためのクラスです。 //! //! @tparam TKey レンダーキーの型です。 //--------------------------------------------------------------------------- template class BasicRenderKeyFactory : public GfxObject { private: NW_DISALLOW_COPY_AND_ASSIGN(BasicRenderKeyFactory); public: //! @brief キーの値となる型です。 typedef TKey KeyType; //! @brief 描画単位となるクラスの定義です。 typedef BasicRenderElement RenderElementType; //! @brief レンダーキーを作成します。 virtual KeyType CreateRenderKey( const RenderElementType& renderElement, float depth, u8 layerId) = 0; //! @brief コマンド用のレンダーキーを作成します。 virtual KeyType CreateCommandRenderKey( RenderCommand* command, ResMaterial::TranslucencyKind translucencyKind, u8 priority, u8 layerId) = 0; protected: //! @brief コンストラクタです。 BasicRenderKeyFactory(os::IAllocator* allocator) : GfxObject(allocator) {} //! @brief デストラクタです。 virtual ~BasicRenderKeyFactory() {} }; //--------------------------------------------------------------------------- //! @brief マテリアルを優先するレンダーキーファクトリクラスです。 //! //! @tparam TKey レンダーキーの型です。 //! @tparam TDepthQuantizer 深度値を量子化するための関数オブジェクトの型です。 //--------------------------------------------------------------------------- template< typename TKey, typename TDepthQuantizer = typename BasicRenderElement::Depth24bitQuantizer > class PriorMaterialRenderKeyFactory : public BasicRenderKeyFactory { private: NW_DISALLOW_COPY_AND_ASSIGN(PriorMaterialRenderKeyFactory); public: //! @brief キーの値となる型です。 typedef TKey KeyType; //! @brief 描画単位となるクラスの定義です。 typedef BasicRenderElement RenderElementType; //! @brief キー作成クラスの定義です。 typedef typename BasicRenderElement::template Bit64RenderKey Bit64RenderKeyType; //---------------------------------------- //! @name 作成 //@{ //! @brief ファクトリを作成します。 //! //! @param[in] allocator アロケータです。 //! //! @return 作成したファクトリを返します。 //! static PriorMaterialRenderKeyFactory* Create(os::IAllocator* allocator) { void* factoryMemory = allocator->Alloc(1); NW_NULL_ASSERT(factoryMemory); return new(factoryMemory) PriorMaterialRenderKeyFactory(allocator); } //@} //! @brief レンダーキーを作成します。 virtual KeyType CreateRenderKey( const RenderElementType& renderElement, float depth, u8 layerId) { Bit64RenderKeyType renderKey; renderKey.SetDepth(depth, 0); const ResMesh mesh = renderElement.GetMesh(); const Model* model = renderElement.GetModel(); if (mesh.IsValid() && model) { const Material* material = model->GetMaterial(mesh.GetMaterialIndex()); renderKey.SetDetailedMaterialIdAndTranslucencyKind( material, RenderElementType::BIT64_DEPTH_BIT_SIZE); renderKey.SetPriorityForDetailedMaterial( mesh.GetRenderPriority(), RenderElementType::BIT64_DEPTH_BIT_SIZE); } renderKey.SetLayerId(layerId); return renderKey.Key(); } //! @brief コマンド用のレンダーキーを作成します。 virtual KeyType CreateCommandRenderKey( RenderCommand* command, ResMaterial::TranslucencyKind translucencyKind, u8 priority, u8 layerId) { Bit64RenderKeyType renderKey; renderKey.SetLayerId(layerId); renderKey.SetPriorityForSimpleMaterial( priority, RenderElementType::BIT64_DEPTH_BIT_SIZE); renderKey.SetTranslucencyKind(translucencyKind); renderKey.SetCommand(command); return renderKey.Key(); } private: PriorMaterialRenderKeyFactory(os::IAllocator* allocator) : BasicRenderKeyFactory(allocator) { } }; //--------------------------------------------------------------------------- //! @brief 深度を優先するレンダーキーファクトリクラスです。 //! //! @tparam TKey レンダーキーの型です。 //! @tparam TDepthQuantizer 深度値を量子化するための関数オブジェクトの型です。 //--------------------------------------------------------------------------- template< typename TKey, typename TDepthQuantizer = typename BasicRenderElement::Depth24bitQuantizer > class PriorDepthRenderKeyFactory : public BasicRenderKeyFactory { private: NW_DISALLOW_COPY_AND_ASSIGN(PriorDepthRenderKeyFactory); public: //! @brief キーの値となる型です。 typedef TKey KeyType; //! @brief 描画単位となるクラスの定義です。 typedef BasicRenderElement RenderElementType; //! @brief キー作成クラスの定義です。 typedef typename BasicRenderElement::template Bit64RenderKey Bit64RenderKeyType; //---------------------------------------- //! @name 作成 //@{ //! @brief ファクトリを作成します。 //! //! @param[in] allocator アロケータです。 //! //! @return 作成したファクトリを返します。 //! static PriorDepthRenderKeyFactory* Create(os::IAllocator* allocator) { void* factoryMemory = allocator->Alloc(1); NW_NULL_ASSERT(factoryMemory); return new(factoryMemory) PriorDepthRenderKeyFactory(allocator); } //@} //! @brief レンダーキーを作成します。 virtual KeyType CreateRenderKey( const RenderElementType& renderElement, float depth, u8 layerId) { Bit64RenderKeyType renderKey; renderKey.SetDepth(depth, RenderElementType::BIT64_SIMPLE_MATERIAL_ID_BIT_SIZE); const ResMesh mesh = renderElement.GetMesh(); const Model* model = renderElement.GetModel(); if (mesh.IsValid() && model) { const Material* material = model->GetMaterial(mesh.GetMaterialIndex()); renderKey.SetSimpleMaterialIdAndTranslucencyKind(material, 0); renderKey.SetPriorityForSimpleMaterial( mesh.GetRenderPriority(), RenderElementType::BIT64_DEPTH_BIT_SIZE); } renderKey.SetLayerId(layerId); return renderKey.Key(); } //! @brief コマンド用のレンダーキーを作成します。 virtual KeyType CreateCommandRenderKey( RenderCommand* command, ResMaterial::TranslucencyKind translucencyKind, u8 priority, u8 layerId) { Bit64RenderKeyType renderKey; renderKey.SetLayerId(layerId); renderKey.SetPriorityForSimpleMaterial( priority, RenderElementType::BIT64_DEPTH_BIT_SIZE); renderKey.SetTranslucencyKind(translucencyKind); renderKey.SetCommand(command); return renderKey.Key(); } private: PriorDepthRenderKeyFactory(os::IAllocator* allocator) : BasicRenderKeyFactory(allocator) { } }; //--------------------------------------------------------------------------- //! @brief 深度を最優先するレンダーキーファクトリクラスです。 //! //! 描画優先度よりも深度を優先します。 //! //! @tparam TKey レンダーキーの型です。 //! @tparam TDepthQuantizer 深度値を量子化するための関数オブジェクトの型です。 //--------------------------------------------------------------------------- template< typename TKey, typename TDepthQuantizer = typename BasicRenderElement::Depth24bitQuantizer > class TopPriorDepthRenderKeyFactory : public BasicRenderKeyFactory { private: NW_DISALLOW_COPY_AND_ASSIGN(TopPriorDepthRenderKeyFactory); public: //! @brief キーの値となる型です。 typedef TKey KeyType; //! @brief 描画単位となるクラスの定義です。 typedef BasicRenderElement RenderElementType; //! @brief キー作成クラスの定義です。 typedef typename BasicRenderElement::template Bit64RenderKey Bit64RenderKeyType; //---------------------------------------- //! @name 作成 //@{ //! @brief ファクトリを作成します。 //! //! @param[in] allocator アロケータです。 //! //! @return 作成したファクトリを返します。 //! static TopPriorDepthRenderKeyFactory* Create(os::IAllocator* allocator) { void* factoryMemory = allocator->Alloc(1); NW_NULL_ASSERT(factoryMemory); return new(factoryMemory) TopPriorDepthRenderKeyFactory(allocator); } //@} //! @brief レンダーキーを作成します。 virtual KeyType CreateRenderKey( const RenderElementType& renderElement, float depth, u8 layerId) { Bit64RenderKeyType renderKey; renderKey.SetDepth(depth, RenderElementType::BIT64_SIMPLE_MATERIAL_ID_BIT_SIZE + RenderElementType::BIT64_SIMPLE_MATERIAL_PRIORITY_BIT_SIZE); const ResMesh mesh = renderElement.GetMesh(); const Model* model = renderElement.GetModel(); if (mesh.IsValid() && model) { const Material* material = model->GetMaterial(mesh.GetMaterialIndex()); renderKey.SetSimpleMaterialIdAndTranslucencyKind(material, 0); renderKey.SetPriorityForSimpleMaterial(mesh.GetRenderPriority(), 0); } renderKey.SetLayerId(layerId); return renderKey.Key(); } //! @brief コマンド用のレンダーキーを作成します。 virtual KeyType CreateCommandRenderKey( RenderCommand* command, ResMaterial::TranslucencyKind translucencyKind, u8 priority, u8 layerId) { Bit64RenderKeyType renderKey; renderKey.SetLayerId(layerId); renderKey.SetPriorityForSimpleMaterial( priority, RenderElementType::BIT64_DEPTH_BIT_SIZE); renderKey.SetTranslucencyKind(translucencyKind); renderKey.SetCommand(command); return renderKey.Key(); } private: TopPriorDepthRenderKeyFactory(os::IAllocator* allocator) : BasicRenderKeyFactory(allocator) { } }; //---------------------------------------- //! @name 描画要素 //@{ //! @brief 描画ソートを行う際のキーの型です。 typedef bit64 RenderKeyType; //! @brief 標準のレンダーエレメントの定義です。 typedef BasicRenderElement RenderElement; //! @brief 標準のレンダーキーファクトリーの定義です。 typedef BasicRenderKeyFactory RenderKeyFactory; //--------------------------------------------------------------------------- //! @brief マテリアル優先のレンダーキーを作成するファクトリを生成します。 //! //! @param[in] allocator アロケータです。 //! //! @return 生成されたファクトリが返ります。 //! //! @sa nw::gfx::BasicRenderQueue::Reset //--------------------------------------------------------------------------- NW_INLINE RenderKeyFactory* CreatePriorMaterialRenderKeyFactory( os::IAllocator* allocator) { return PriorMaterialRenderKeyFactory::Create(allocator); } //--------------------------------------------------------------------------- //! @brief マテリアル優先で奥から描画されるレンダーキーを作成するファクトリを生成します。 //! //! @param[in] allocator アロケータです。 //! //! @return 生成されたファクトリが返ります。 //! //! @sa nw::gfx::BasicRenderQueue::Reset //--------------------------------------------------------------------------- NW_INLINE RenderKeyFactory* CreatePriorMaterialReverseDepthRenderKeyFactory( os::IAllocator* allocator) { return PriorMaterialRenderKeyFactory< RenderKeyType, RenderElement::ReverseDepth24bitQuantizer>::Create(allocator); } //--------------------------------------------------------------------------- //! @brief 深度情報のないマテリアル優先のレンダーキーを作成するファクトリを生成します。 //! //! @param[in] allocator アロケータです。 //! //! @return 生成されたファクトリが返ります。 //! //! @sa nw::gfx::BasicRenderQueue::Reset //--------------------------------------------------------------------------- NW_INLINE RenderKeyFactory* CreatePriorMaterialAndZeroDepthRenderKeyFactory( os::IAllocator* allocator) { return PriorMaterialRenderKeyFactory< RenderKeyType, RenderElement::ZeroQuantizer>::Create(allocator); } //--------------------------------------------------------------------------- //! @brief 深度優先のレンダーキーを作成するファクトリを生成します。 //! //! @param[in] allocator アロケータです。 //! //! @return 生成されたファクトリが返ります。 //! //! @sa nw::gfx::BasicRenderQueue::Reset //--------------------------------------------------------------------------- NW_INLINE RenderKeyFactory* CreatePriorDepthRenderKeyFactory( os::IAllocator* allocator) { return PriorDepthRenderKeyFactory::Create(allocator); } //--------------------------------------------------------------------------- //! @brief 深度優先で奥から描画されるレンダーキーを作成するファクトリを生成します。 //! //! @param[in] allocator アロケータです。 //! //! @return 生成されたファクトリが返ります。 //! //! @sa nw::gfx::BasicRenderQueue::Reset //--------------------------------------------------------------------------- NW_INLINE RenderKeyFactory* CreatePriorDepthReverseDepthRenderKeyFactory( os::IAllocator* allocator) { return PriorDepthRenderKeyFactory< RenderKeyType, RenderElement::ReverseDepth24bitQuantizer>::Create(allocator); } //--------------------------------------------------------------------------- //! @brief 深度最優先のレンダーキーを作成するファクトリを生成します。 //! //! @param[in] allocator アロケータです。 //! //! @return 生成されたファクトリが返ります。 //! //! @sa nw::gfx::BasicRenderQueue::Reset //--------------------------------------------------------------------------- NW_INLINE RenderKeyFactory* CreateTopPriorDepthRenderKeyFactory( os::IAllocator* allocator) { return TopPriorDepthRenderKeyFactory::Create(allocator); } //--------------------------------------------------------------------------- //! @brief 深度最優先で奥から描画されるレンダーキーを作成するファクトリを生成します。 //! //! @param[in] allocator アロケータです。 //! //! @return 生成されたファクトリが返ります。 //! //! @sa nw::gfx::BasicRenderQueue::Reset //--------------------------------------------------------------------------- NW_INLINE RenderKeyFactory* CreateTopPriorDepthReverseDepthRenderKeyFactory( os::IAllocator* allocator) { return TopPriorDepthRenderKeyFactory< RenderKeyType, RenderElement::ReverseDepth24bitQuantizer>::Create(allocator); } //@} } // namespace gfx } // namespace nw #endif // NW_GFX_RENDERELEMENT_H_