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 になります。


パラメータ

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


コンテキスト属性

属性 取得/設定 詳細
Filename String または CString を設定する 事前解析するファイルの完全パス名。??? What is pre-parsing???
Definition ShaderDef を返すかまたは設定する 登録/クエリを行うシェーダ定義。
Errors String または CString を返す パーサは解析エラーを出力できます。
Warnings String または 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;

}


関連項目