Parse


詳細

シェーダ定義を関連付けられたファイルからの情報とともに登録します。 これは関連付けられたファイルを解析する 2 番目のパスです。最初に ParseInfo コールバックが解析し、十分な情報をコンパイルしてシェーダ定義を登録し、Preset Manager を設定します。

このコールバックは、このパーサの言語を使用して実装されるシェーダがインスタンス化されるときに発生します。


適用対象

カスタム シェーダ


構文

public class <plugin-item_name>
{
        public bool Parse( Context in_context )
        {
                ...
        }
}
CStatus <plugin-item_name>_Parse( CRef& in_context ) 
{ 
        ... 
}
function <plugin-item_name>_Parse( in_context ) 
{ 
        ... 
}
def <plugin-item_name>_Parse( in_context ):
        ...
Function <plugin-item_name>_Parse( in_context )
        ...
End Function
sub <plugin-item_name>_Parse 
{ 
        my $in_context = shift; 
}

<plugin-item_name> は、PluginRegistrar.RegisterShaderLanguageParser の呼び出しで指定されているパーサ名です。この名前に含まれるスペースはアンダースコアに置き換えられます。 たとえば、My Parser という名前のパーサをプラグインに登録する場合、コールバック関数の名前の先頭は My_Parser になります。


パラメータ

パラメータ Language タイプ 詳細
in_context スクリプティングおよび C# コンテキスト Context.GetAttribute("Definition")は ShaderDef を返します。
C++ CRef& Context::GetAttribute("Definition")は ShaderDef へのリファレンスを返します。

コンテキスト属性

Attribute 取得/設定 詳細
Filename 文字列 または CString を設定する 事前解析するファイルの完全パス名。??? What is pre-parsing???
Definition ShaderDef を返すかまたは設定する 登録/クエリを行うシェーダ定義。
Errors 文字列 または CString を戻す パーサは解析エラーを出力できます。
Warnings 文字列 または CString を戻す パーサは解析に関する警告を出力できます。

SICALLBACK UtShaderLanguageParser_Parse( CRef& in_ctxt  )
{
        XSI::Application app;
        XSI::Factory fact = app.GetFactory();

        /*      For this example, we use a very simple format to define the shader.
                First line represents the prog id.
                Following lines have this format:
                        Type space Input space Texturable space PortName
                        color|float|boolean|integer|vector2|vector3|vector4 in|out on|off $PortName
                Until a line with a single dot is found.
                Then, 2 strings separated by a space give the MR function name and library.                     */
        XSI::Context ctxt(in_ctxt);
        XSI::CString strFilename = ctxt.GetAttribute( L"FileName" );
        XSI::ShaderDef shaderDef = ctxt.GetAttribute( L"Definition" );

        // We'll just check if our user attribute is there
        {
                XSI::CValue valDune;
                valDune = shaderDef.GetAttributes().GetAttribute( L"{F2EF07FE-1B57-4245-BF08-F5556212BFDF}" );
                assert( !valDune.IsEmpty() );
        }

        std::ifstream in( strFilename.GetAsciiString() );
        if(!in) 
        {
                ctxt.PutAttribute( L"Errors", L"Cannot open file: " + strFilename + L"\n" );
                return CStatus::Fail;
        }

        char buf[255];

        // Skip First Line
        in.getline( buf, 255 );

        XSI::ShaderParamDefOptions optTexturableInput = fact.CreateShaderParamDefOptions();
        optTexturableInput.SetTexturable(true);

        // Port Defs 
        XSI::ShaderStructParamDef currentStructDef;
        while( in.getline( buf, 255 ).eof()==false )
        {
                if( strlen( buf ) > 0 )
                {
                        CSIString str(buf);
                        std::vector<CSIString> tokens;
                        str.Split( L" ", tokens );

                        // Strip the enum tokens
                        XSI::CValue valEnumValues;
                        {
                                CSIString strEnumValues;
                                std::vector<CSIString>::iterator itEraseStart = tokens.end();
                                bool bStartedEnum=false;
                                for( std::vector<CSIString>::iterator it=tokens.begin(); it!=tokens.end(); ++it )
                                {
                                        // Skip the enum token
                                        if( *it == L"enum" )
                                        {
                                                
                                                itEraseStart = it;
                                                bStartedEnum = true;
                                        }
                                        // Gather the enum tokens and remove them from the token list
                                        else if( bStartedEnum )
                                        {
                                                
                                                std::vector<CSIString> enumTokens;
                                                it->Split( L"=", enumTokens );
                                                if( enumTokens.size() == 2 )
                                                {
                                                        //Replace '_' by ' '
                                                        for( ULONG i=0; i<enumTokens[0].Length(); ++i )
                                                        {
                                                                if( ((LPCWSTR)enumTokens[0])[i] == L'_' )
                                                                {
                                                                        enumTokens[0].SetAt( i, L' ' );
                                                                }
                                                        }

                                                        strEnumValues += enumTokens[0];
                                                        strEnumValues += L",";
                                                        strEnumValues += enumTokens[1];
                                                        strEnumValues += L";";
                                                }
                                        }
                                }
                        
                                if( bStartedEnum )
                                {
                                        if( itEraseStart!=tokens.end() )
                                                tokens.erase( itEraseStart, tokens.end() );

                                        if( !strEnumValues.IsEmpty() )
                                        {
                                                valEnumValues = (LPCWSTR)strEnumValues;
                                        }
                                }
                        }
                        

                        if( tokens.size()==1  )
                        {
                                if( str==L"." )
                                        break;
                                else if( str==L"endstruct")
                                        currentStructDef=CRef();
                        }
                        else if( tokens.size()==4 )
                        {
                                XSI::CString strParamName = (LPCWSTR)tokens[3];
                                
                                CSIString strType = tokens[0];

                                bool bIsInput= tokens[1]==L"in";
                                bool bTexturable= tokens[2]==L"on";
                                bool bIsArray =false;

                                if( strType.Right(2) == L"[]" )
                                {
                                        bIsArray = true;
                                        strType.TruncateRight(2);
                                }
                                
                                XSI::siShaderParameterType eType = siScalarParameterType;
                                if( strType == L"color"  )
                                        eType = siColorParameterType;
                                if( strType == L"float" )
                                        eType = siScalarParameterType;
                                else if( strType == L"vector2" )
                                        eType = siVector2ParameterType;
                                else if( strType == L"vector3" )
                                        eType = siVectorParameterType;
                                else if( strType == L"vector4" )
                                        eType = siVector4ParameterType;
                                else if( strType == L"boolean" )
                                        eType = siBooleanParameterType;
                                else if( strType == L"integer" )
                                        eType = siIntegerParameterType;
                                else if( strType == L"reference" )
                                        eType = siReferenceParameterType;
                                else if ( strType == L"matrix4")
                                        eType = siMatrixParameterType;
                                else if ( strType == L"matrix3")
                                        eType = siMatrix3ParameterType;
                                else if ( strType == L"string")
                                        eType = siStringParameterType;
                                else if ( strType == L"quaternion")
                                        eType = siQuaternionParameterType;
                                else if ( strType == L"fcurve")
                                        eType = siProfileCurveParameterType;
                                else if ( strType == L"gradient")
                                        eType = siGradientParameterType;
                                else if ( strType == L"texture")
                                        eType = siTextureParameterType;
                                else if ( strType == L"tspace")
                                        eType = siTextureSpaceParameterType;
                                else if ( strType == L"struct" && !currentStructDef.IsValid() )
                                        eType = siStructParameterType;

                                // Now add the port.
                                XSI::ShaderParamDef paramDef;

                                bTexturable &= bIsInput;

                                XSI::ShaderParamDefContainer pdefContainer;
                                if( currentStructDef.IsValid() )
                                        pdefContainer = currentStructDef.GetSubParamDefs();
                                else if( bIsInput )
                                        pdefContainer = shaderDef.GetInputParamDefs();
                                else
                                        pdefContainer = shaderDef.GetOutputParamDefs();


                                if( !bIsArray )
                                {
                                        paramDef = pdefContainer.AddParamDef( strParamName, eType, bTexturable ? optTexturableInput :CRef() );

                                        if( eType == siStructParameterType )
                                        {
                                                currentStructDef = paramDef;
                                        }
                                }
                                else
                                {
                                        paramDef = pdefContainer.AddArrayParamDef( strParamName, eType, bTexturable ? optTexturableInput :CRef() );

                                        XSI::ShaderArrayParamDef arrayDef = paramDef;
                                        
                                        XSI::ShaderParamDef itemDef = arrayDef.GetArrayItemDef();
                                        
                                        if( eType == siStructParameterType )
                                        {
                                                currentStructDef = itemDef;
                                        }
                                }

                                // Set the enum values
                                if( !valEnumValues.IsEmpty() )
                                        paramDef.GetAttributes().SetAttribute( L"PPGPortEnumValues", valEnumValues );
                                
                                // Set tspace filter
                                if( strType==L"tspace" )
                                {
                                        paramDef.GetAttributes().SetAttribute( siPropertyFilterAttribute, (LONG)siUVPropertyFilter );
                                }
                        }
                }
        }

        if( in.getline( buf, 255 ).eof()==true )
        {
                CSIString str(buf);
                std::vector<CSIString> tokens;
                str.Split( L" ", tokens );
                
                // Fill MR MetaShaderDef
                if( tokens.size()==2 || tokens.size()==3 )
                {
                        // Texture type can connect to anything.
                        shaderDef.AddType( L"texture" );

                        XSI::MetaShaderRendererDef rendererDef = shaderDef.AddRendererDef( L"Mental Ray");
                        rendererDef.PutSymbolName( (LPCWSTR)tokens[0] );
                        rendererDef.PutCodePath( (LPCWSTR)tokens[1] );

                        CValue valVersion;

                        if( tokens.size()==2 )
                        {
                                valVersion=(LONG)1;
                        }
                        else
                        {
                                valVersion = (LPCWSTR)tokens[2];
                                valVersion.ChangeType( XSI::CValue::siInt8 );
                        }

                        XSI::AttributeMap rendererOptions = rendererDef.GetRendererOptions();
                        rendererOptions.SetAttribute( L"version", valVersion );

                        // Hardcoded options by shader types.
                        if( tokens[0] == L"sib_uvwgen" )
                        {
                                rendererOptions.SetAttribute( L"derivative1", L"on" );
                                rendererOptions.SetAttribute( L"derivative2", L"on" );
                        }
                }
                else
                {
                        ctxt.PutAttribute( L"Errors", L"Cannot find the DLL Code Section.\n" );
                        in.close();
                        return CStatus::Fail;
                }
        }
        else
        {
                ctxt.PutAttribute( L"Errors", L"Cannot find the DLL Code Section.\n" );
                in.close();
                return CStatus::Fail;
        }
        
        in.close();
        return CStatus::OK;
}

関連項目