/*---------------------------------------------------------------------------* Project: NintendoWare File: gfx_MaterialState.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: 26187 $ *---------------------------------------------------------------------------*/ #ifndef NW_GFX_MATERIALSTATE_H_ #define NW_GFX_MATERIALSTATE_H_ #include #include #include // このマクロを定義するとマテリアルの個々の要素の設定に関するプロファイルを行います。 // #define NW_MATERIAL_PROFILE // このマクロを定義するとマテリアルを設定します。 #define MATERIAL_SET_ENABLED namespace nw { namespace os { class IAllocator; } namespace gfx { namespace internal { // OpenGL 標準仕様の射影変換行列を生成する nn::math::Matrix34* CreateMatrixForLinearShadowMapTexture(nn::math::Matrix34* pOut, f32 coeff, f32 nearp, f32 farp); //--------------------------------------------------------------------------- //! @brief マテリアル内容を GL に設定するクラスです。 //--------------------------------------------------------------------------- class MaterialState { public: //---------------------------------------- //! @name マテリアル関連 //@{ //--------------------------------------------------------------------------- //! @brief シェーダーパラメータを設定します。 //! //! @param[in] shaderProgram シェーダープログラムです。 //! @param[in] material マテリアルです。 //--------------------------------------------------------------------------- static NW_INLINE void ActivateShaderParameter( const ShaderProgram* shaderProgram, const ResMaterial material); //--------------------------------------------------------------------------- //! @brief フラグメントライトに関するパラメータを設定します。 //! //! @param[in] sceneEnvironment シーン環境です。 //! @param[in] shaderProgram シェーダープログラムです。 //! @param[in] material マテリアルです。 //--------------------------------------------------------------------------- static NW_INLINE void ActivateFragmentLightParameters( const SceneEnvironment& sceneEnvironment, const ShaderProgram* shaderProgram, const ResMaterial material); //--------------------------------------------------------------------------- //! @brief シェーディングに関するパラメータを設定します。 //! //! @param[in] sceneEnvironment シーン環境です。 //! @param[in] shaderProgram シェーダープログラムです。 //! @param[in] material マテリアルです。 //--------------------------------------------------------------------------- static NW_INLINE void ActivateShadingParameters( const SceneEnvironment& sceneEnvironment, const ShaderProgram* shaderProgram, const ResMaterial material); //--------------------------------------------------------------------------- //! @brief ラスタライゼーションを設定します。 //! //! @param[in] rasterization ラスタライゼーションです。 //--------------------------------------------------------------------------- static NW_INLINE void ActivateRasterization(const ResRasterization rasterization); //--------------------------------------------------------------------------- //! @brief フラグメントライティングテーブルを設定します。 //! //! @param[in] fragmentLighting フラグメントライティングです。 //! @param[in] fragmentLightingTable フラグメントライティングテーブルです。 //--------------------------------------------------------------------------- static void ActivateFragmentLightingTable( const ResFragmentLighting fragmentLighting, const ResFragmentLightingTable fragmentLightingTable); //--------------------------------------------------------------------------- //! @brief テクスチャ座標の設定をおこないます。 //! //! @param[in] renderContext レンダーコンテキストです。 //! @param[in] shaderProgram シェーダープログラムです。 //! @param[in] texCoordMaterial テクスチャ座標の設定に利用するマテリアルです。 //--------------------------------------------------------------------------- static void ActivateTextureCoordinators( RenderContext* renderContext, const ShaderProgram* shaderProgram, const ResMaterial texCoordMaterial); //--------------------------------------------------------------------------- //! @brief パーティクル独自のテクスチャ座標設定をおこないます。 //! //! @param[in] renderContext レンダーコンテキストです。 //! @param[in] shaderProgram シェーダープログラムです。 //! @param[in] texCoordMaterial テクスチャ座標の設定に利用するマテリアルです。 //--------------------------------------------------------------------------- static void ActivateParticleTextureCoordinators( RenderContext* renderContext, const ShaderProgram* shaderProgram, const ResMaterial texCoordMaterial); //--------------------------------------------------------------------------- //! @brief マテリアルカラーを設定します。 //! //! @param[in] sceneEnvironment シーン環境です。 //! @param[in] shaderProgram シェーダープログラムです。 //! @param[in] materialColor マテリアルカラーです。 //! @param[in] useReflection 反射テーブルが有効どうかを表すフラグです。 //--------------------------------------------------------------------------- static NW_INLINE void ActivateMaterialColor( const SceneEnvironment& sceneEnvironment, const ShaderProgram* shaderProgram, ResMaterialColor materialColor, bool useReflection); //--------------------------------------------------------------------------- //! @brief フラグメントライティングを設定します。 //! //! @param[in] sceneEnvironment シーン環境です。 //! @param[in] fragmentLighting 設定するフラグメントライティングです。 //--------------------------------------------------------------------------- static NW_INLINE void ActivateFragmentLighting( const SceneEnvironment& sceneEnvironment, const ResFragmentLighting fragmentLighting); //--------------------------------------------------------------------------- //! @brief テクスチャマッパーの設定をおこないます。 //! //! @param[in] texMapperMaterial テクスチャマッパーを利用するマテリアルです。 //--------------------------------------------------------------------------- static NW_INLINE void ActivateTextureMappers(const ResMaterial texMapperMaterial); //--------------------------------------------------------------------------- //! @brief パーティクル独自のテクスチャマッパー設定をおこないます。 //! //! @param[in] texMapperMaterial テクスチャマッパーを利用するマテリアルです。 //--------------------------------------------------------------------------- static NW_INLINE void ActivateParticleTextureMappers(const ResMaterial texMapperMaterial); //--------------------------------------------------------------------------- //! @brief プロシージャルテクスチャマッパーの設定をおこないます。 //! //! @param[in] renderContext レンダーコンテキストです。 //! @param[in] shaderProgram シェーダープログラムです。 //! @param[in] material プロシージャルテクスチャマッパを利用するマテリアルです。 //--------------------------------------------------------------------------- static NW_INLINE void ActivateProceduralTextureMapper( RenderContext* renderContext, const ShaderProgram* shaderProgram, const ResMaterial material); //--------------------------------------------------------------------------- //! @brief テクスチャコンバイナを設定します。 //! //! @param[in] fragmentShader フラグメントシェーダーです。 //! @param[in] materialColor マテリアルカラーです。 //--------------------------------------------------------------------------- static NW_INLINE void ActivateTextureCombiners( const ResFragmentShader fragmentShader, const ResMaterialColor materialColor); //--------------------------------------------------------------------------- //! @brief アルファテストを設定します。 //! //! @param[in] alphaTest アルファテストです。 //--------------------------------------------------------------------------- static NW_INLINE void ActivateAlphaTest(const ResAlphaTest alphaTest); //--------------------------------------------------------------------------- //! @brief フラグメントオペレーションを設定します。 //! //! @param[in] fragmentOperation フラグメントオペレーションです。 //--------------------------------------------------------------------------- static NW_INLINE void ActivateFragmentOperation(const ResFragmentOperation fragmentOperation); //--------------------------------------------------------------------------- //! @brief フォグに関するパラメータを設定します。 //! //! @param[in] material マテリアルです。 //--------------------------------------------------------------------------- static NW_INLINE void ActivateFogParameters( const SceneEnvironment& sceneEnvironment, const ResMaterial material); //@} private: //! コンスタントカラーを取得します。 static NW_INLINE u32 GetConstantColorU32( ResTextureCombiner::Constant constant, const ResMaterialColor materialColor); //--------------------------------------------------------------------------- //! @brief デプスオペレーションを設定します。 //! //! @param[in] depthOperation デプスオペレーションです。 //--------------------------------------------------------------------------- static NW_INLINE void ActivateDepthOperation(const ResDepthOperation depthOperation); //--------------------------------------------------------------------------- //! @brief ステンシルオペレーションを設定します。 //! //! @param[in] stencilOperation ステンシルオペレーションです。 //--------------------------------------------------------------------------- static NW_INLINE void ActivateStencilOperation(const ResStencilOperation stencilOperation); //--------------------------------------------------------------------------- //! @brief ブレンドオペレーションを設定します。 //! //! @param[in] blendOperation ブレンドオペレーションです。 //--------------------------------------------------------------------------- static NW_INLINE void ActivateBlendOperation(const ResBlendOperation blendOperation); //--------------------------------------------------------------------------- //! @brief 計算方式別にテクスチャマトリクスを設定します。 //! //! @param[out] textureMatrix 設定されるマトリクスです。 //! @param[in] mode 計算方式の指定です。 //! @param[in] scaleS S 軸のスケール値です。 //! @param[in] scaleT T 軸のスケール値です。 //! @param[in] rotate 回転値です。 //! @param[in] translateS S 軸の移動値です。 //! @param[in] translateT T 軸の移動値です。 //--------------------------------------------------------------------------- static math::MTX44* SetupTextureMatrix( math::MTX44* textureMatrix, ResTextureCoordinator::MappingMatrixMode mode, float scaleS, float scaleT, float rotate, float translateS, float translateT); }; //---------------------------------------- NW_INLINE u32 MaterialState::GetConstantColorU32( ResTextureCombiner::Constant constant, const ResMaterialColor materialColor) { switch ( constant ) { case ResTextureCombiner::CONSTANT0: return materialColor.GetConstant0U32(); case ResTextureCombiner::CONSTANT1: return materialColor.GetConstant1U32(); case ResTextureCombiner::CONSTANT2: return materialColor.GetConstant2U32(); case ResTextureCombiner::CONSTANT3: return materialColor.GetConstant3U32(); case ResTextureCombiner::CONSTANT4: return materialColor.GetConstant4U32(); case ResTextureCombiner::CONSTANT5: return materialColor.GetConstant5U32(); case ResTextureCombiner::EMISSION: return materialColor.GetEmissionU32(); case ResTextureCombiner::AMBIENT: return materialColor.GetAmbientU32(); case ResTextureCombiner::DIFFUSE: return materialColor.GetDiffuseU32(); case ResTextureCombiner::SPECULAR0: return materialColor.GetSpecular0U32(); case ResTextureCombiner::SPECULAR1: return materialColor.GetSpecular1U32(); default: NW_FATAL_ERROR("Illegal constant name"); return materialColor.GetConstant0U32(); } } //---------------------------------------- NW_INLINE void MaterialState::ActivateFogParameters(const SceneEnvironment& sceneEnvironment, const ResMaterial material) { #if defined(NW_MATERIAL_PROFILE) NW_PROFILE("MaterialState::ActivateFogParameters"); #endif #if defined(MATERIAL_SET_ENABLED) u32 flags = material.GetFlags(); enum { FOG_MODE_FALSE = 0, FOG_MODE_FOG = 5, FOG_MODE_GAS = 7, REG_FOG_MODE = 0xe0 }; // フォグを設定します。 s32 fogMode = FOG_MODE_FALSE; if (ut::CheckFlag(flags, ResMaterialData::FLAG_FOG_ENABLED)) { if (sceneEnvironment.GetActiveFog() != NULL) { fogMode = FOG_MODE_FOG; } } { const u32 HEADER_FOG_MODE = internal::MakeCommandHeader(REG_FOG_MODE, 1, false, 0x1); u32 FOG_COMMAND[] = { fogMode, HEADER_FOG_MODE }; internal::NWUseCmdlist(&FOG_COMMAND[0]); } #endif } //---------------------------------------- NW_INLINE void MaterialState::ActivateDepthOperation(const ResDepthOperation depthOperation) { #if defined(NW_MATERIAL_PROFILE) NW_PROFILE("MaterialState::ActivateDepthOperation"); #endif GraphicsDevice::SetDepthTestEnabled( ut::CheckFlag( depthOperation.GetFlags(), ResDepthOperationData::FLAG_TEST_ENABLED)); GraphicsDevice::SetDepthMaskEnabled( ut::CheckFlag( depthOperation.GetFlags(), ResDepthOperationData::FLAG_MASK_ENABLED)); GraphicsDevice::ActivateMask(); internal::NWUseCmdlist( &depthOperation.ref().m_CommandBuffer[0] ); } //---------------------------------------- NW_INLINE void MaterialState::ActivateStencilOperation(const ResStencilOperation stencilOperation) { #if defined(NW_MATERIAL_PROFILE) NW_PROFILE("MaterialState::ActivateStencilOperation"); #endif if (!stencilOperation.IsValid()) { return; } if (stencilOperation.IsTestEnabled()) { GraphicsDevice::SetStencilTestEnabled(true); } else { GraphicsDevice::SetStencilTestEnabled(false); } internal::NWUseCmdlist( &stencilOperation.ref().m_CommandBuffer[0] ); } //---------------------------------------- NW_INLINE void MaterialState::ActivateBlendOperation(const ResBlendOperation blendOperation) { #if defined(NW_MATERIAL_PROFILE) NW_PROFILE("MaterialState::ActivateBlendOperation"); #endif ResBlendOperation::Mode mode = blendOperation.GetMode(); if (mode == ResBlendOperation::MODE_NOT_USE) { GraphicsDevice::SetBlendEnabled(false); } else { GraphicsDevice::SetBlendEnabled(true); } internal::NWUseCmdlist(blendOperation.ref().m_CommandBuffer); } //---------------------------------------- NW_INLINE void MaterialState::ActivateShaderParameter( const ShaderProgram* shaderProgram, const ResMaterial material) { #if defined(NW_MATERIAL_PROFILE) NW_PROFILE("MaterialState::ActivateShaderParameter"); #endif #if defined(MATERIAL_SET_ENABLED) ResShaderProgramDescription description = shaderProgram->GetActiveDescription(); ResShaderSymbolArray symbolArray = description.GetSymbols(); int symbolCount = description.GetSymbolsCount(); // マテリアルのシェーダパラメータの値をすべて設定した後に、設定されていないパラメータに // デフォルト値を設定します。 bool symbolHasBeenSetFlag[64] = { false }; ResShaderParameterArrayConst::const_iterator end = material.GetShaderParameters().end(); for ( ResShaderParameterArrayConst::const_iterator parameter = material.GetShaderParameters().begin(); parameter != end; ++parameter ) { int symbolIndex = (*parameter).GetSymbolIndex(); if ( 0 <= symbolIndex && symbolIndex < symbolCount) { ResShaderSymbol shaderSymbol = symbolArray[symbolIndex]; if (shaderSymbol.IsEnabled() && shaderSymbol.GetLocation() >= 0) { NW_ASSERT(shaderSymbol.GetLocation() < 96); if (shaderSymbol.IsGeometryUniform()) { shaderProgram->SetUserGeometryUniform(shaderSymbol.GetLocation(), (*parameter).GetParameter()); } else { shaderProgram->SetUserVertexUniform(shaderSymbol.GetLocation(), (*parameter).GetParameter()); } } // シェーダシンボル自体が無効な場合にも、デフォルト値の設定は必要ないのでフラグは立てておく。 symbolHasBeenSetFlag[symbolIndex] = true; } } for (int symbolIndex = 0; symbolIndex < symbolCount; ++symbolIndex) { if ( ! symbolHasBeenSetFlag[symbolIndex] ) { ResShaderSymbol shaderSymbol = symbolArray[symbolIndex]; if (shaderSymbol.IsEnabled() && shaderSymbol.GetLocation() >= 0) { NW_ASSERT(shaderSymbol.GetLocation() < 96); if (shaderSymbol.IsGeometryUniform()) { shaderProgram->SetUserGeometryUniform(shaderSymbol.GetLocation(), shaderSymbol.GetDefaultValue()); } else { shaderProgram->SetUserVertexUniform(shaderSymbol.GetLocation(), shaderSymbol.GetDefaultValue()); } } } } #endif } //---------------------------------------- NW_INLINE void MaterialState::ActivateFragmentLightParameters( const SceneEnvironment& sceneEnvironment, const ShaderProgram* shaderProgram, const ResMaterial material) { // 各種ライトの ON/OFF を設定します。 enum { REG_FRAGMENT_LIGHT_ENABLED = 0x1c6, REG_FRAGMENT_LIGHT_ENABLED2 = 0x8F }; const u32 ENABLED_HEADER = internal::MakeCommandHeader(REG_FRAGMENT_LIGHT_ENABLED, 1, false, 0x1); const u32 ENABLED_HEADER2 = internal::MakeCommandHeader(REG_FRAGMENT_LIGHT_ENABLED2, 1, false, 0x1); bool isFragmentLightEnabled = ut::CheckFlag(material.GetFlags(), ResMaterialData::FLAG_FRAGMENTLIGHT_ENABLED) && (sceneEnvironment.GetFragmentLightCount() != 0); u32 LIGHT_COUNT_COMMAND[] = { isFragmentLightEnabled ? 0 : 1, ENABLED_HEADER, isFragmentLightEnabled ? 1 : 0, ENABLED_HEADER2 }; // フラグメントライティングを行わない場合はクォータニオンの計算を省略します。 shaderProgram->SetVertexUniformBool(NW_GFX_VERTEX_UNIFORM(ISQUATE), isFragmentLightEnabled); internal::NWUseCmdlist( &LIGHT_COUNT_COMMAND[0] ); } //---------------------------------------- NW_INLINE void MaterialState::ActivateShadingParameters( const SceneEnvironment& sceneEnvironment, const ShaderProgram* shaderProgram, const ResMaterial material) { #if defined(NW_MATERIAL_PROFILE) NW_PROFILE("MaterialState::ActivateShadingParameters"); #endif #if defined(MATERIAL_SET_ENABLED) u32 flags = material.GetFlags(); #if defined(NW_GFX_VERTEX_LIGHT_ENABLED) if (shaderProgram->GetActiveDescription().GetMaxVertexLightCount() > 0) { if (sceneEnvironment.GetVertexLightCount() > 0 && ut::CheckFlag(flags, ResMaterialData::FLAG_VERTEXLIGHT_ENABLED)) { shaderProgram->SetVertexUniformBool(NW_GFX_VERTEX_UNIFORM(ISVERTL), true); } else { shaderProgram->SetVertexUniformBool(NW_GFX_VERTEX_UNIFORM(ISVERTL), false); } } #endif if (ut::CheckFlag( shaderProgram->GetActiveDescription().GetFlags(), ResShaderProgramDescription::FLAG_IS_SUPPORTING_HEMISPHERE_LIGHTING)) { if (sceneEnvironment.GetHemiSphereLight() != NULL && ut::CheckFlag(flags, ResMaterialData::FLAG_HEMISPHERELIGHT_ENABLED)) { shaderProgram->SetVertexUniformBool(NW_GFX_VERTEX_UNIFORM(ISHEMIL), true); shaderProgram->SetVertexUniformBool( NW_GFX_VERTEX_UNIFORM(ISHEMIO), ut::CheckFlag(flags, ResMaterialData::FLAG_HEMISPHERE_OCCLUSION_ENABLED)); } else { shaderProgram->SetVertexUniformBool(NW_GFX_VERTEX_UNIFORM(ISHEMIL), false); } } enum { FOG_MODE_FALSE = 0, FOG_MODE_FOG = 5, FOG_MODE_GAS = 7, REG_FOG_MODE = 0xe0 }; // フォグを設定します。 s32 fogMode = FOG_MODE_FALSE; if (ut::CheckFlag(flags, ResMaterialData::FLAG_FOG_ENABLED)) { if (sceneEnvironment.GetActiveFog() != NULL) { fogMode = FOG_MODE_FOG; } } { const u32 HEADER_FOG_MODE = internal::MakeCommandHeader(REG_FOG_MODE, 1, false, 0x1); u32 FOG_COMMAND[] = { fogMode, HEADER_FOG_MODE }; internal::NWUseCmdlist(&FOG_COMMAND[0]); } #endif } //---------------------------------------- NW_INLINE void MaterialState::ActivateRasterization(const ResRasterization rasterization) { #if defined(NW_MATERIAL_PROFILE) NW_PROFILE("MaterialState::ActivateRasterization"); #endif #if defined(MATERIAL_SET_ENABLED) NW_ASSERT(rasterization.IsValid()); GraphicsDevice::SetPolygonOffsetEnabled(ut::CheckFlag(rasterization.GetFlags(), ResRasterizationData::FLAG_POLYGON_OFFSET_ENABLED)); GraphicsDevice::SetPolygonOffsetUnit(rasterization.GetPolygonOffsetUnit()); GraphicsDevice::ActivatePolygonOffset(); // CullModeの設定 internal::NWUseCmdlist( rasterization.ref().m_CommandBuffer ); #endif } //---------------------------------------- NW_INLINE void MaterialState::ActivateMaterialColor( const SceneEnvironment& sceneEnvironment, const ShaderProgram* shaderProgram, ResMaterialColor materialColor, bool useReflection) { #if defined(NW_MATERIAL_PROFILE) NW_PROFILE("MaterialState::ActivateMaterialColor"); #endif #if defined(MATERIAL_SET_ENABLED) NW_ASSERT(materialColor.IsValid()); ResShaderProgramDescription resShaderProgram = shaderProgram->GetActiveDescription(); // 頂点シェーダーにマテリアルカラーを設定します。 internal::NWSetVertexUniform4fv(VERTEX_SHADER_UNIFORM_MATDIFF_INDEX, 1, materialColor.GetDiffuse()); internal::NWSetVertexUniform4fv(VERTEX_SHADER_UNIFORM_MATAMBI_INDEX, 1, materialColor.GetAmbient()); int lightCount = ut::Min(sceneEnvironment.GetFragmentLightCount(), MAX_PER_PIXEL_LIGHTS); internal::ActivateFragmentLightCount( lightCount ); internal::ActivateFragmentAmbientLight( materialColor, sceneEnvironment.GetAmbientLight() ); for (int i = 0; i < lightCount; ++i) { const FragmentLight* light = sceneEnvironment.GetFragmentLight(i); internal::ActivateFragmentLight(i, materialColor, light, useReflection); } #endif } //---------------------------------------- NW_INLINE void MaterialState::ActivateFragmentLighting( const SceneEnvironment& sceneEnvironment, const ResFragmentLighting fragmentLighting) { #if defined(NW_MATERIAL_PROFILE) NW_PROFILE("MaterialState::ActivateFragmentLighting"); #endif #if defined(MATERIAL_SET_ENABLED) NW_ASSERT(fragmentLighting.IsValid()); // NOTE: リソース側であらかじめコマンドを持つようにできないかを検討。 // fragmentLighting, fragmengShader(LayerConfig) のバッファを // それぞれ持っている部分が問題なので、計測してみて効果があるようなら // FragmentShaderクラス内でのメンバの引越しもあるかもしれない。 internal::ActivateFragmentLighting(fragmentLighting); bool geomFactor0 = ut::CheckFlag( fragmentLighting.GetFlags(), ResFragmentLightingData::FLAG_GEOMETRIC_FACTOR0_ENABLED); bool geomFactor1 = ut::CheckFlag( fragmentLighting.GetFlags(), ResFragmentLightingData::FLAG_GEOMETRIC_FACTOR1_ENABLED); int lightCount = sceneEnvironment.GetFragmentLightCount(); for (int i = 0; i < lightCount; ++i) { const FragmentLight* light = sceneEnvironment.GetFragmentLight(i); ResFragmentLight resLight = light->GetResFragmentLight(); s32 lightKind = resLight.GetLightKind(); bool twoSideDiffuse = ut::CheckFlag(resLight.GetFlags(), ResFragmentLightData::FLAG_TWO_SIDE_DIFFUSE_ENABLED); bool isDirectional = (lightKind == ResFragmentLight::KIND_DIRECTIONAL) || GraphicsDevice::GetFragmentLightPositionW(i); internal::ActivateFragmentLightParameters(i, isDirectional, twoSideDiffuse, geomFactor0, geomFactor1); } #endif } //---------------------------------------- NW_INLINE void MaterialState::ActivateTextureMappers(const ResMaterial texMapperMaterial) { #if defined(NW_MATERIAL_PROFILE) NW_PROFILE("MaterialState::ActivateTextureMappers"); #endif #if defined(MATERIAL_SET_ENABLED) // TODO: プロシージャルテクスチャには未対応 u32 samplerSetting = 0; for ( s32 textureUnit = 0; textureUnit < texMapperMaterial.GetTextureMappersCount(); textureUnit++) { const ResTextureMapper textureMapper = texMapperMaterial.GetTextureMappers(textureUnit); if ( ! textureMapper.IsValid() ) { continue; } samplerSetting |= 1 << textureUnit; // TODO: ShadowTextureMapperには未対応。 const ResPixelBasedTextureMapper pixTexMapper = ResStaticCast(textureMapper); // 0x81-0x8a, 0x8e[3:0] の内容はここに含まれる const u32* command = pixTexMapper.GetCommandCache(); u32 commandSize = pixTexMapper.GetCommandSizeToSend(); internal::NWUseCmdlist(command, commandSize); } const u32 HEADER = internal::MakeCommandHeader(PICA_REG_TEXTURE_FUNC, 1, false, 0x5); u32 INVALIDATE_TEXTURE_CACHE[] = { samplerSetting | 0x00010000, HEADER }; internal::NWUseCmdlist(&INVALIDATE_TEXTURE_CACHE[0]); #endif } //---------------------------------------- NW_INLINE void MaterialState::ActivateParticleTextureMappers(const ResMaterial texMapperMaterial) { #if defined(NW_MATERIAL_PROFILE) NW_PROFILE("MaterialState::ActivateParticleTextureMappers"); #endif #if defined(MATERIAL_SET_ENABLED) // TODO: プロシージャルテクスチャには未対応 const ResTextureMapper textureMapper = texMapperMaterial.GetTextureMappers(0); if ( textureMapper.IsValid() ) { // TODO: ShadowTextureMapperには未対応。 const ResPixelBasedTextureMapper pixTexMapper = ResStaticCast(textureMapper); // 0x81-0x8a, 0x8e[3:0] の内容はここに含まれる const u32* command = pixTexMapper.GetCommandCache(); u32 commandSize = pixTexMapper.GetCommandSizeToSend(); internal::NWUseCmdlist(command, commandSize); } const u32 HEADER = internal::MakeCommandHeader(PICA_REG_TEXTURE_FUNC, 1, false, 0x5); const u32 INVALIDATE_TEXTURE_CACHE[] = { 0x00010001, HEADER }; internal::NWUseCmdlist(&INVALIDATE_TEXTURE_CACHE[0]); #endif } //---------------------------------------- NW_INLINE void MaterialState::ActivateProceduralTextureMapper( RenderContext* renderContext, const ShaderProgram* shaderProgram, const ResMaterial material) { #if defined(NW_MATERIAL_PROFILE) NW_PROFILE("MaterialState::ActivateProceduralTextureMapper"); #endif NW_UNUSED_VARIABLE(renderContext); NW_UNUSED_VARIABLE(shaderProgram); NW_UNUSED_VARIABLE(material); } //---------------------------------------- NW_INLINE void MaterialState::ActivateTextureCombiners( const ResFragmentShader fragmentShader, const ResMaterialColor materialColor) { #if defined(NW_MATERIAL_PROFILE) NW_PROFILE("MaterialState::ActivateTextureCombiners"); #endif #if defined(MATERIAL_SET_ENABLED) #ifdef NW_TARGET_CTR_GL_FINAL internal::NWUseCmdlist(&(fragmentShader.ref().m_BufferCommand[0])); #endif for (uint stage = 0; stage < COMBINER_AVAILABLE_COUNT; stage++) { ResTextureCombiner textureCombiner = fragmentShader.GetTextureCombiners(stage); // 計測してみたところ、現状では処理のオーバーヘッドによる有意な差が見られなかったので、 // コンスタントカラーはマテリアルカラーから参照する形にしておく。 u32 constantU32 = GetConstantColorU32( textureCombiner.GetConstant(), materialColor); textureCombiner.SetConstantCmd( constantU32 ); internal::NWUseCmdlist( reinterpret_cast(textureCombiner.ref().m_CommandBuffer) ); } #endif } //---------------------------------------- NW_INLINE void MaterialState::ActivateAlphaTest(const ResAlphaTest alphaTest) { #if defined(NW_MATERIAL_PROFILE) NW_PROFILE("MaterialState::ActivateAlphaTest"); #endif #if defined(MATERIAL_SET_ENABLED) NW_ASSERT(alphaTest.IsValid()); internal::NWUseCmdlist( &alphaTest.ref().m_CommandBuffer[0] ); #endif } //---------------------------------------- NW_INLINE void MaterialState::ActivateFragmentOperation(const ResFragmentOperation fragmentOperation) { #if defined(MATERIAL_SET_ENABLED) ResDepthOperation resDepthOperation = fragmentOperation.GetDepthOperation(); ResStencilOperation resStencilOperation = fragmentOperation.GetStencilOperation(); ResBlendOperation resBlendOperation = fragmentOperation.GetBlendOperation(); ActivateDepthOperation(resDepthOperation); ActivateStencilOperation(resStencilOperation); ActivateBlendOperation(resBlendOperation); GraphicsDevice::SetFragmentOperationMode(fragmentOperation.GetFragmentOperationMode()); GraphicsDevice::ActivateFrameBuffer(); #endif } } // namespace internal } // namespace gfx } // namespace nw #endif // NW_GFX_MATERIALSTATE_H_