public override void Translate(ScriptCompiler compiler, AbstractNode node) { var obj = (ObjectAbstractNode)node; if (obj != null) { if (string.IsNullOrEmpty(obj.Name)) { compiler.AddError(CompileErrorCode.ObjectNameExpected, obj.File, obj.Line, "gpu program object must have names"); return; } } else { compiler.AddError(CompileErrorCode.ObjectNameExpected, obj.File, obj.Line, "gpu program object must have names"); return; } // Must have a language type if (obj.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, obj.File, obj.Line, "gpu program object require language declarations"); return; } // Get the language string language; if (!getString(obj.Values[0], out language)) { compiler.AddError(CompileErrorCode.InvalidParameters, obj.File, obj.Line); return; } if (language == "asm") { _translateGpuProgram(compiler, obj); } else if (language == "unified") { _translateUnifiedGpuProgram(compiler, obj); } else { _translateHighLevelGpuProgram(compiler, obj); } }
protected void processNode(ScriptCompiler compiler, AbstractNode node) { if (!(node is ObjectAbstractNode)) { return; } var objNode = (ObjectAbstractNode)node; // Abstract objects are completely skipped if (objNode != null && objNode.IsAbstract) { return; } // Retrieve the translator to use var translator = ScriptCompilerManager.Instance.GetTranslator(node); if (translator != null) { translator.Translate(compiler, node); } else { var msg = string.Format("token {0} is not recognized", objNode.Cls); compiler.AddError(CompileErrorCode.UnexpectedToken, node.File, node.Line, msg); } }
/// <see cref="Translator.Translate"/> public override void Translate(ScriptCompiler compiler, AbstractNode node) { var obj = (ObjectAbstractNode)node; // Must have a type as the first value if (obj.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, obj.File, obj.Line); return; } var type = string.Empty; if (!getString(obj.Values[0], out type)) { compiler.AddError(CompileErrorCode.InvalidParameters, obj.File, obj.Line); return; } var system = (ParticleSystem)obj.Parent.Context; this._Emitter = system.AddEmitter(type); foreach (var i in obj.Children) { if (i is PropertyAbstractNode) { var prop = (PropertyAbstractNode)i; var value = string.Empty; // Glob the values together foreach (var it in prop.Values) { if (it is AtomAbstractNode) { if (string.IsNullOrEmpty(value)) { value = ((AtomAbstractNode)it).Value; } else { value = value + " " + ((AtomAbstractNode)it).Value; } } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); break; } } if (!this._Emitter.SetParam(prop.Name, value)) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } else { processNode(compiler, i); } } }
/// <see cref="Translator.Translate"/> public override void Translate(ScriptCompiler compiler, AbstractNode node) { var obj = (ObjectAbstractNode)node; this._Pass = (CompositionPass)obj.Parent.Context; // Should be no parameters, just children if (obj.Values.Count != 0) { compiler.AddError(CompileErrorCode.UnexpectedToken, obj.File, obj.Line); } foreach (var i in obj.Children) { if (i is ObjectAbstractNode) { processNode(compiler, i); } else if (i is PropertyAbstractNode) { var prop = (PropertyAbstractNode)i; switch ((Keywords)prop.Id) { #region ID_CHECK case Keywords.ID_CHECK: { if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } var val = false; if (getBoolean(prop.Values[0], out val)) { this._Pass.StencilCheck = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_CHECK #region ID_COMP_FUNC case Keywords.ID_COMP_FUNC: { if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } CompareFunction func; if (getEnumeration <CompareFunction>(prop.Values[0], compiler, out func)) { this._Pass.StencilFunc = func; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_COMP_FUNC #region ID_REF_VALUE case Keywords.ID_REF_VALUE: { if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line); return; } int val; if (getInt(prop.Values[0], out val)) { this._Pass.StencilRefValue = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_REF_VALUE #region ID_MASK case Keywords.ID_MASK: { if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line); return; } int val; if (getInt(prop.Values[0], out val)) { this._Pass.StencilMask = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_MASK #region ID_FAIL_OP case Keywords.ID_FAIL_OP: { if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } StencilOperation val; if (getEnumeration <StencilOperation>(prop.Values[0], compiler, out val)) { this._Pass.StencilFailOp = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_FAIL_OP #region ID_DEPTH_FAIL_OP case Keywords.ID_DEPTH_FAIL_OP: { if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } StencilOperation val; if (getEnumeration <StencilOperation>(prop.Values[0], compiler, out val)) { this._Pass.StencilDepthFailOp = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_DEPTH_FAIL_OP #region ID_PASS_OP case Keywords.ID_PASS_OP: { if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } StencilOperation val; if (getEnumeration <StencilOperation>(prop.Values[0], compiler, out val)) { this._Pass.StencilPassOp = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_PASS_OP #region ID_TWO_SIDED case Keywords.ID_TWO_SIDED: { if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } bool val; if (getBoolean(prop.Values[0], out val)) { this._Pass.StencilTwoSidedOperation = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_TWO_SIDED default: compiler.AddError(CompileErrorCode.UnexpectedToken, prop.File, prop.Line, "token \"" + prop.Name + "\" is not recognized"); break; } } } }
/// <see cref="Translator.Translate"/> public override void Translate(ScriptCompiler compiler, AbstractNode node) { var obj = (ObjectAbstractNode)node; var target = (CompositionTargetPass)obj.Parent.Context; this._Pass = target.CreatePass(); obj.Context = this._Pass; // The name is the type of the pass if (obj.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, obj.File, obj.Line); return; } var type = string.Empty; if (!getString(obj.Values[0], out type)) { compiler.AddError(CompileErrorCode.InvalidParameters, obj.File, obj.Line); return; } this._Pass.Type = (CompositorPassType)ScriptEnumAttribute.Lookup(type, typeof(CompositorPassType)); if (this._Pass.Type == CompositorPassType.RenderCustom) { var customType = string.Empty; //This is the ugly one liner for safe access to the second parameter. if (obj.Values.Count < 2 || !getString(obj.Values[1], out customType)) { compiler.AddError(CompileErrorCode.StringExpected, obj.File, obj.Line); return; } this._Pass.CustomType = customType; } else { compiler.AddError(CompileErrorCode.InvalidParameters, obj.File, obj.Line, "pass types must be \"clear\", \"stencil\", \"render_quad\", \"render_scene\" or \"render_custom\"."); return; } foreach (var i in obj.Children) { if (i is ObjectAbstractNode) { processNode(compiler, i); } else if (i is PropertyAbstractNode) { var prop = (PropertyAbstractNode)i; switch ((Keywords)prop.Id) { #region ID_MATERIAL case Keywords.ID_MATERIAL: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line); return; } else { var val = string.Empty; if (getString(prop.Values[0], out val)) { ScriptCompilerEvent evt = new ProcessResourceNameScriptCompilerEvent(ProcessResourceNameScriptCompilerEvent.ResourceType.Material, val); compiler._fireEvent(ref evt); this._Pass.MaterialName = ((ProcessResourceNameScriptCompilerEvent)evt).Name; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_MATERIAL #region ID_INPUT case Keywords.ID_INPUT: if (prop.Values.Count < 2) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } else if (prop.Values.Count > 3) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line); return; } else { AbstractNode i0 = getNodeAt(prop.Values, 0), i1 = getNodeAt(prop.Values, 1), i2 = getNodeAt(prop.Values, 2); var id = 0; var name = string.Empty; if (getInt(i0, out id) && getString(i1, out name)) { var index = 0; if (!getInt(i2, out index)) { compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line); return; } this._Pass.SetInput(id, name, index); } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_INPUT #region ID_IDENTIFIER case Keywords.ID_IDENTIFIER: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line); return; } else { uint val; if (getUInt(prop.Values[0], out val)) { this._Pass.Identifier = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_IDENTIFIER #region ID_FIRST_RENDER_QUEUE case Keywords.ID_FIRST_RENDER_QUEUE: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line); return; } else { uint val; if (getUInt(prop.Values[0], out val)) { this._Pass.FirstRenderQueue = (RenderQueueGroupID)val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_FIRST_RENDER_QUEUE #region ID_LAST_RENDER_QUEUE case Keywords.ID_LAST_RENDER_QUEUE: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line); return; } else { uint val; if (getUInt(prop.Values[0], out val)) { this._Pass.LastRenderQueue = (RenderQueueGroupID)val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_LAST_RENDER_QUEUE #region ID_MATERIAL_SCHEME case Keywords.ID_MATERIAL_SCHEME: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line); return; } else { string val; if (getString(prop.Values[0], out val)) { this._Pass.MaterialScheme = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_MATERIAL_SCHEME #region ID_QUAD_NORMALS case Keywords.ID_QUAD_NORMALS: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line); return; } else { if (prop.Values[0] is AtomAbstractNode) { var atom = (AtomAbstractNode)prop.Values[0]; if (atom.Id == (uint)Keywords.ID_CAMERA_FAR_CORNERS_VIEW_SPACE) { this._Pass.SetQuadFarCorners(true, true); } else if (atom.Id == (uint)Keywords.ID_CAMERA_FAR_CORNERS_WORLD_SPACE) { this._Pass.SetQuadFarCorners(true, false); } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_QUAD_NORMALS default: compiler.AddError(CompileErrorCode.UnexpectedToken, prop.File, prop.Line, "token \"" + prop.Name + "\" is not recognized"); break; } } } }
protected void _translateUnifiedGpuProgram(ScriptCompiler compiler, ObjectAbstractNode obj) { var customParameters = new NameValuePairList(); AbstractNode parameters = null; foreach (var i in obj.Children) { if (i is PropertyAbstractNode) { var prop = (PropertyAbstractNode)i; if (prop.Name == "delegate") { var value = string.Empty; if (prop.Values.Count != 0 && prop.Values[0] is AtomAbstractNode) { value = ((AtomAbstractNode)prop.Values[0]).Value; } ScriptCompilerEvent evt = new ProcessResourceNameScriptCompilerEvent(ProcessResourceNameScriptCompilerEvent.ResourceType.GpuProgram, value); compiler._fireEvent(ref evt); customParameters["delegate"] = ((ProcessResourceNameScriptCompilerEvent)evt).Name; } else { var name = prop.Name; var value = string.Empty; var first = true; foreach (var it in prop.Values) { if (it is AtomAbstractNode) { if (!first) { value += " "; } else { first = false; } value += ((AtomAbstractNode)it).Value; } } customParameters.Add(name, value); } } else if (i is ObjectAbstractNode) { if (((ObjectAbstractNode)i).Id == (uint)Keywords.ID_DEFAULT_PARAMS) { parameters = i; } else { processNode(compiler, i); } } } // Allocate the program Object progObj; HighLevelGpuProgram prog = null; ScriptCompilerEvent evnt = new CreateHighLevelGpuProgramScriptCompilerEvent(obj.File, obj.Name, compiler.ResourceGroup, string.Empty, "unified", _translateIDToGpuProgramType(obj.Id)); var processed = compiler._fireEvent(ref evnt, out progObj); if (!processed) { prog = (HighLevelGpuProgram) (HighLevelGpuProgramManager.Instance.CreateProgram(obj.Name, compiler.ResourceGroup, "unified", _translateIDToGpuProgramType(obj.Id))); } else { prog = (HighLevelGpuProgram)progObj; } // Check that allocation worked if (prog == null) { compiler.AddError(CompileErrorCode.ObjectAllocationError, obj.File, obj.Line, "gpu program \"" + obj.Name + "\" could not be created"); return; } obj.Context = prog; prog.IsMorphAnimationIncluded = false; prog.PoseAnimationCount = 0; prog.IsSkeletalAnimationIncluded = false; prog.IsVertexTextureFetchRequired = false; prog.Origin = obj.File; // Set the custom parameters prog.SetParameters(customParameters); // Set up default parameters if (prog.IsSupported && parameters != null) { var ptr = prog.DefaultParameters; GpuProgramTranslator.TranslateProgramParameters(compiler, ptr, (ObjectAbstractNode)parameters); } }
public static void TranslateProgramParameters(ScriptCompiler compiler, GpuProgramParameters parameters, ObjectAbstractNode obj) { var animParametricsCount = 0; foreach (var i in obj.Children) { if (!(i is PropertyAbstractNode)) { continue; } var prop = (PropertyAbstractNode)i; switch ((Keywords)prop.Id) { #region ID_SHARED_PARAMS_REF case Keywords.ID_SHARED_PARAMS_REF: { if (prop.Values.Count != 1) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "shared_params_ref requires a single parameter"); continue; } var i0 = getNodeAt(prop.Values, 0); if (!(i0 is AtomAbstractNode)) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "shared parameter set name expected"); continue; } var atom0 = (AtomAbstractNode)i0; try { parameters.AddSharedParameters(atom0.Value); } catch (AxiomException e) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, e.Message); } } break; #endregion ID_SHARED_PARAMS_REF #region ID_PARAM_INDEXED || ID_PARAM_NAMED case Keywords.ID_PARAM_INDEXED: case Keywords.ID_PARAM_NAMED: { if (prop.Values.Count >= 3) { var named = (prop.Id == (uint)Keywords.ID_PARAM_NAMED); var i0 = getNodeAt(prop.Values, 0); var i1 = getNodeAt(prop.Values, 1); var k = getNodeAt(prop.Values, 2); if (!(i0 is AtomAbstractNode) || !(i1 is AtomAbstractNode)) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "name or index and parameter type expected"); return; } var atom0 = (AtomAbstractNode)i0; var atom1 = (AtomAbstractNode)i1; if (!named && !atom0.IsNumber) { compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line, "parameter index expected"); return; } var name = string.Empty; var index = 0; // Assign the name/index if (named) { name = atom0.Value; } else { index = (int)atom0.Number; } // Determine the type if (atom1.Value == "matrix4x4") { Matrix4 m; if (getMatrix4(prop.Values, 2, out m)) { try { if (named) { parameters.SetNamedConstant(name, m); } else { parameters.SetConstant(index, m); } } catch { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "setting matrix4x4 parameter failed"); } } else { compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line, "incorrect matrix4x4 declaration"); } } else { // Find the number of parameters var isValid = true; var type = GpuProgramParameters.ElementType.Real; var count = 0; if (atom1.Value.Contains("float")) { type = GpuProgramParameters.ElementType.Real; if (atom1.Value.Length >= 6) { count = int.Parse(atom1.Value.Substring(5)); } else { count = 1; } } else if (atom1.Value.Contains("int")) { type = GpuProgramParameters.ElementType.Int; if (atom1.Value.Length >= 4) { count = int.Parse(atom1.Value.Substring(3)); } else { count = 1; } } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "incorrect type specified; only variants of int and float allowed"); isValid = false; } if (isValid) { // First, clear out any offending auto constants if (named) { parameters.ClearNamedAutoConstant(name); } else { parameters.ClearAutoConstant(index); } var roundedCount = count % 4 != 0 ? count + 4 - (count % 4) : count; if (type == GpuProgramParameters.ElementType.Int) { var vals = new int[roundedCount]; if (getInts(prop.Values, 2, out vals, roundedCount)) { try { if (named) { parameters.SetNamedConstant(name, vals, count, 1); } else { parameters.SetConstant(index, vals, roundedCount / 4); } } catch { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "setting of constant failed"); } } else { compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line, "incorrect integer constant declaration"); } } else { var vals = new float[roundedCount]; if (getFloats(prop.Values, 2, out vals, roundedCount)) { try { if (named) { parameters.SetNamedConstant(name, vals, count, 1); } else { parameters.SetConstant(index, vals, roundedCount / 4); } } catch { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "setting of constant failed"); } } else { compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line, "incorrect float constant declaration"); } } } } } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "param_named and param_indexed properties requires at least 3 arguments"); } } break; #endregion ID_PARAM_INDEXED || ID_PARAM_NAMED #region ID_PARAM_INDEXED_AUTO || ID_PARAM_NAMED_AUTO case Keywords.ID_PARAM_INDEXED_AUTO: case Keywords.ID_PARAM_NAMED_AUTO: { var named = (prop.Id == (uint)Keywords.ID_PARAM_NAMED_AUTO); var name = string.Empty; var index = 0; if (prop.Values.Count >= 2) { var i0 = getNodeAt(prop.Values, 0); var i1 = getNodeAt(prop.Values, 1); var i2 = getNodeAt(prop.Values, 2); var i3 = getNodeAt(prop.Values, 3); if (!(i0 is AtomAbstractNode) || !(i1 is AtomAbstractNode)) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "name or index and auto constant type expected"); return; } var atom0 = (AtomAbstractNode)i0; var atom1 = (AtomAbstractNode)i1; if (!named && !atom0.IsNumber) { compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line, "parameter index expected"); return; } if (named) { name = atom0.Value; } else { index = int.Parse(atom0.Value); } // Look up the auto constant atom1.Value = atom1.Value.ToLower(); GpuProgramParameters.AutoConstantDefinition def; var defFound = GpuProgramParameters.GetAutoConstantDefinition(atom1.Value, out def); if (defFound) { switch (def.DataType) { #region None case GpuProgramParameters.AutoConstantDataType.None: // Set the auto constant try { if (named) { parameters.SetNamedAutoConstant(name, def.AutoConstantType); } else { parameters.SetAutoConstant(index, def.AutoConstantType); } } catch { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "setting of constant failed"); } break; #endregion None #region Int case GpuProgramParameters.AutoConstantDataType.Int: if (def.AutoConstantType == GpuProgramParameters.AutoConstantType.AnimationParametric) { try { if (named) { parameters.SetNamedAutoConstant(name, def.AutoConstantType, animParametricsCount++); } else { parameters.SetAutoConstant(index, def.AutoConstantType, animParametricsCount++); } } catch { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "setting of constant failed"); } } else { // Only certain texture projection auto params will assume 0 // Otherwise we will expect that 3rd parameter if (i2 == null) { if (def.AutoConstantType == GpuProgramParameters.AutoConstantType.TextureViewProjMatrix || def.AutoConstantType == GpuProgramParameters.AutoConstantType.TextureWorldViewProjMatrix || def.AutoConstantType == GpuProgramParameters.AutoConstantType.SpotLightViewProjMatrix || def.AutoConstantType == GpuProgramParameters.AutoConstantType.SpotLightWorldViewProjMatrix) { try { if (named) { parameters.SetNamedAutoConstant(name, def.AutoConstantType, 0); } else { parameters.SetAutoConstant(index, def.AutoConstantType, 0); } } catch { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "setting of constant failed"); } } else { compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line, "extra parameters required by constant definition " + atom1.Value); } } else { var success = false; var extraInfo = 0; if (i3 == null) { // Handle only one extra value if (getInt(i2, out extraInfo)) { success = true; } } else { // Handle two extra values var extraInfo1 = 0; var extraInfo2 = 0; if (getInt(i2, out extraInfo1) && getInt(i3, out extraInfo2)) { extraInfo = extraInfo1 | (extraInfo2 << 16); success = true; } } if (success) { try { if (named) { parameters.SetNamedAutoConstant(name, def.AutoConstantType, extraInfo); } else { parameters.SetAutoConstant(index, def.AutoConstantType, extraInfo); } } catch { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "setting of constant failed"); } } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "invalid auto constant extra info parameter"); } } } break; #endregion Int #region Real case GpuProgramParameters.AutoConstantDataType.Real: if (def.AutoConstantType == GpuProgramParameters.AutoConstantType.Time || def.AutoConstantType == GpuProgramParameters.AutoConstantType.FrameTime) { Real f = 1.0f; if (i2 != null) { getReal(i2, out f); } try { if (named) { parameters.SetNamedAutoConstantReal(name, def.AutoConstantType, f); } else { parameters.SetAutoConstantReal(index, def.AutoConstantType, f); } } catch { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "setting of constant failed"); } } else { if (i2 != null) { Real extraInfo = 0.0f; if (getReal(i2, out extraInfo)) { try { if (named) { parameters.SetNamedAutoConstantReal(name, def.AutoConstantType, extraInfo); } else { parameters.SetAutoConstantReal(index, def.AutoConstantType, extraInfo); } } catch { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "setting of constant failed"); } } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "incorrect float argument definition in extra parameters"); } } else { compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line, "extra parameters required by constant definition " + atom1.Value); } } break; #endregion Real } } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_PARAM_INDEXED_AUTO || ID_PARAM_NAMED_AUTO default: compiler.AddError(CompileErrorCode.UnexpectedToken, prop.File, prop.Line, "token \"" + prop.Name + "\" is not recognized"); break; } } }
/// <see cref="Translator.Translate"/> public override void Translate(ScriptCompiler compiler, AbstractNode node) { var obj = (ObjectAbstractNode)node; // Find the name if (obj != null) { if (string.IsNullOrEmpty(obj.Name)) { compiler.AddError(CompileErrorCode.ObjectNameExpected, obj.File, obj.Line); return; } } else { compiler.AddError(CompileErrorCode.ObjectNameExpected, obj.File, obj.Line); return; } // Allocate the particle system object sysObject; ScriptCompilerEvent evt = new CreateParticleSystemScriptCompilerEvent(obj.File, obj.Name, compiler.ResourceGroup); var processed = compiler._fireEvent(ref evt, out sysObject); if (!processed) { this._System = ParticleSystemManager.Instance.CreateTemplate(obj.Name, compiler.ResourceGroup); } else { this._System = (ParticleSystem)sysObject; } if (this._System == null) { compiler.AddError(CompileErrorCode.ObjectAllocationError, obj.File, obj.Line); return; } this._System.Origin = obj.File; this._System.RemoveAllEmitters(); this._System.RemoveAllAffectors(); obj.Context = this._System; foreach (var i in obj.Children) { if (i is PropertyAbstractNode) { var prop = (PropertyAbstractNode)i; switch ((Keywords)prop.Id) { case Keywords.ID_MATERIAL: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } else { if (prop.Values[0] is AtomAbstractNode) { var name = ((AtomAbstractNode)prop.Values[0]).Value; ScriptCompilerEvent locEvt = new ProcessResourceNameScriptCompilerEvent(ProcessResourceNameScriptCompilerEvent.ResourceType.Material, name); compiler._fireEvent(ref locEvt); var locEvtName = ((ProcessResourceNameScriptCompilerEvent)locEvt).Name; if (!this._System.SetParameter("material", locEvtName)) { if (this._System.Renderer != null) { if (!this._System.Renderer.SetParameter("material", locEvtName)) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "material property could not be set with material \"" + locEvtName + "\""); } } } } } break; default: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } else { string name = prop.Name, value = string.Empty; // Glob the values together foreach (var it in prop.Values) { if (it is AtomAbstractNode) { if (string.IsNullOrEmpty(value)) { value = ((AtomAbstractNode)it).Value; } else { value = value + " " + ((AtomAbstractNode)it).Value; } } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); return; } } if (!this._System.SetParameter(name, value)) { if (this._System.Renderer != null) { if (!this._System.Renderer.SetParameter(name, value)) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } } } break; } } else { processNode(compiler, i); } } }
/// <see cref="Translator.Translate"/> public override void Translate(ScriptCompiler compiler, AbstractNode node) { var obj = (ObjectAbstractNode)node; this._Pass = (CompositionPass)obj.Parent.Context; // Should be no parameters, just children if (obj.Values.Count != 0) { compiler.AddError(CompileErrorCode.UnexpectedToken, obj.File, obj.Line); } foreach (var i in obj.Children) { if (i is ObjectAbstractNode) { processNode(compiler, i); } else if (i is PropertyAbstractNode) { var prop = (PropertyAbstractNode)i; switch ((Keywords)prop.Id) { #region ID_BUFFERS case Keywords.ID_BUFFERS: { FrameBufferType buffers = 0; foreach (var k in prop.Values) { if (k is AtomAbstractNode) { switch ((Keywords)((AtomAbstractNode)k).Id) { case Keywords.ID_COLOUR: buffers |= FrameBufferType.Color; break; case Keywords.ID_DEPTH: buffers |= FrameBufferType.Depth; break; case Keywords.ID_STENCIL: buffers |= FrameBufferType.Stencil; break; default: compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); break; } } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } this._Pass.ClearBuffers = buffers; } break; #endregion ID_BUFFERS #region ID_COLOUR_VALUE case Keywords.ID_COLOUR_VALUE: { if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line); return; } var val = ColorEx.White; if (getColor(prop.Values, 0, out val)) { this._Pass.ClearColor = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_COLOUR_VALUE #region ID_DEPTH_VALUE case Keywords.ID_DEPTH_VALUE: { if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line); return; } Real val = 0; if (getReal(prop.Values[0], out val)) { this._Pass.ClearDepth = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_DEPTH_VALUE #region ID_STENCIL_VALUE case Keywords.ID_STENCIL_VALUE: { if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line); return; } var val = 0; if (getInt(prop.Values[0], out val)) { this._Pass.ClearStencil = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_STENCIL_VALUE default: compiler.AddError(CompileErrorCode.UnexpectedToken, prop.File, prop.Line, "token \"" + prop.Name + "\" is not recognized"); break; } } } }
/// <see cref="Translator.Translate"/> public override void Translate(ScriptCompiler compiler, AbstractNode node) { var obj = (ObjectAbstractNode)node; // Create the technique from the material var material = (Material)obj.Parent.Context; this._technique = material.CreateTechnique(); obj.Context = this._technique; // Get the name of the technique if (!string.IsNullOrEmpty(obj.Name)) { this._technique.Name = obj.Name; } // Set the properties for the technique foreach (var i in obj.Children) { if (i is PropertyAbstractNode) { var prop = (PropertyAbstractNode)i; switch ((Keywords)prop.Id) { #region ID_SCHEME case Keywords.ID_SCHEME: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line, "scheme only supports 1 argument"); } else { string scheme; if (getString(prop.Values[0], out scheme)) { this._technique.Scheme = scheme; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "scheme must have 1 string argument"); } } break; #endregion ID_SCHEME #region ID_LOD_INDEX case Keywords.ID_LOD_INDEX: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line, "lod_index only supports 1 argument"); } else { int val; if (getInt(prop.Values[0], out val)) { this._technique.LodIndex = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "lod_index cannot accept argument \"" + prop.Values[0].Value + "\""); } } break; #endregion ID_LOD_INDEX #region ID_SHADOW_CASTER_MATERIAL case Keywords.ID_SHADOW_CASTER_MATERIAL: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line, "shadow_caster_material only accepts 1 argument"); } else { string matName; if (getString(prop.Values[0], out matName)) { var evtMatName = string.Empty; ScriptCompilerEvent evt = new ProcessResourceNameScriptCompilerEvent(ProcessResourceNameScriptCompilerEvent.ResourceType.Material, matName); compiler._fireEvent(ref evt); evtMatName = ((ProcessResourceNameScriptCompilerEvent)evt).Name; this._technique.ShadowCasterMaterial = (Material)MaterialManager.Instance[evtMatName]; // Use the processed name } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "shadow_caster_material cannot accept argument \"" + prop.Values[0].Value + "\""); } } break; #endregion ID_SHADOW_CASTER_MATERIAL #region ID_SHADOW_RECEIVER_MATERIAL case Keywords.ID_SHADOW_RECEIVER_MATERIAL: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line, "shadow_receiver_material only accepts 1 argument"); } else { var i0 = getNodeAt(prop.Values, 0); var matName = string.Empty; if (getString(i0, out matName)) { var evtName = string.Empty; ScriptCompilerEvent evt = new ProcessResourceNameScriptCompilerEvent(ProcessResourceNameScriptCompilerEvent.ResourceType.Material, matName); compiler._fireEvent(ref evt); evtName = ((ProcessResourceNameScriptCompilerEvent)evt).Name; this._technique.ShadowReceiverMaterial = (Material)MaterialManager.Instance[evtName]; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "shadow_receiver_material_name cannot accept argument \"" + i0.Value + "\""); } } break; #endregion ID_SHADOW_RECEIVER_MATERIAL #region ID_GPU_VENDOR_RULE case Keywords.ID_GPU_VENDOR_RULE: if (prop.Values.Count < 2) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line, "gpu_vendor_rule must have 2 arguments"); } else if (prop.Values.Count > 2) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line, "gpu_vendor_rule must have 2 arguments"); } else { var i0 = getNodeAt(prop.Values, 0); var i1 = getNodeAt(prop.Values, 1); var rule = new Technique.GPUVendorRule(); if (i0 is AtomAbstractNode) { var atom0 = (AtomAbstractNode)i0; var atom0Id = (Keywords)atom0.Id; if (atom0Id == Keywords.ID_INCLUDE) { rule.Include = true; } else if (atom0Id == Keywords.ID_EXCLUDE) { rule.Include = false; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "gpu_vendor_rule cannot accept \"" + i0.Value + "\" as first argument"); } var vendor = string.Empty; if (!getString(i1, out vendor)) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "gpu_vendor_rule cannot accept \"" + i1.Value + "\" as second argument"); } rule.Vendor = RenderSystemCapabilities.VendorFromString(vendor); if (rule.Vendor != GPUVendor.Unknown) { this._technique.AddGPUVenderRule(rule); } } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "gpu_vendor_rule cannot accept \"" + i0.Value + "\" as first argument"); } } break; #endregion ID_GPU_VENDOR_RULE #region ID_GPU_DEVICE_RULE case Keywords.ID_GPU_DEVICE_RULE: if (prop.Values.Count < 2) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line, "gpu_device_rule must have at least 2 arguments"); } else if (prop.Values.Count > 3) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line, "gpu_device_rule must have at most 3 arguments"); } else { var i0 = getNodeAt(prop.Values, 0); var i1 = getNodeAt(prop.Values, 1); var rule = new Technique.GPUDeviceNameRule(); if (i0 is AtomAbstractNode) { var atom0 = (AtomAbstractNode)i0; var atom0Id = (Keywords)atom0.Id; if (atom0Id == Keywords.ID_INCLUDE) { rule.Include = true; } else if (atom0Id == Keywords.ID_EXCLUDE) { rule.Include = false; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "gpu_device_rule cannot accept \"" + i0.Value + "\" as first argument"); } if (!getString(i1, out rule.DevicePattern)) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "gpu_device_rule cannot accept \"" + i1.Value + "\" as second argument"); } if (prop.Values.Count == 3) { var i2 = getNodeAt(prop.Values, 2); if (!getBoolean(i2, out rule.CaseSensitive)) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "gpu_device_rule third argument must be \"true\", \"false\", \"yes\", \"no\", \"on\", or \"off\""); } } this._technique.AddGPUDeviceNameRule(rule); } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "gpu_device_rule cannot accept \"" + i0.Value + "\" as first argument"); } } break; #endregion ID_GPU_DEVICE_RULE default: compiler.AddError(CompileErrorCode.UnexpectedToken, prop.File, prop.Line, "token \"" + prop.Name + "\" is not recognized"); break; } //end of switch statement } // end of if ( i is PropertyAbstractNode ) else if (i is ObjectAbstractNode) { processNode(compiler, i); } } }
/// <see cref="Translator.Translate"/> public override void Translate(ScriptCompiler compiler, AbstractNode node) { var obj = (ObjectAbstractNode)node; var technique = (CompositionTechnique)obj.Parent.Context; if (obj.Id == (uint)Keywords.ID_TARGET) { this._Target = technique.CreateTargetPass(); if (!string.IsNullOrEmpty(obj.Name)) { this._Target.OutputName = obj.Name; } } else if (obj.Id == (uint)Keywords.ID_TARGET_OUTPUT) { this._Target = technique.OutputTarget; } obj.Context = this._Target; foreach (var i in obj.Children) { if (i is ObjectAbstractNode) { processNode(compiler, i); } else if (i is PropertyAbstractNode) { var prop = (PropertyAbstractNode)i; switch ((Keywords)prop.Id) { #region ID_INPUT case Keywords.ID_INPUT: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line); return; } else { if (prop.Values[0] is AtomAbstractNode) { var atom = (AtomAbstractNode)prop.Values[0]; switch ((Keywords)atom.Id) { case Keywords.ID_NONE: this._Target.InputMode = CompositorInputMode.None; break; case Keywords.ID_PREVIOUS: this._Target.InputMode = CompositorInputMode.Previous; break; default: compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); break; } } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_INPUT #region ID_ONLY_INITIAL case Keywords.ID_ONLY_INITIAL: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line); return; } else { var val = false; if (getBoolean(prop.Values[0], out val)) { this._Target.OnlyInitial = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_ONLY_INITIAL #region ID_VISIBILITY_MASK case Keywords.ID_VISIBILITY_MASK: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line); return; } else { uint val; if (getUInt(prop.Values[0], out val)) { this._Target.VisibilityMask = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_VISIBILITY_MASK #region ID_LOD_BIAS case Keywords.ID_LOD_BIAS: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line); return; } else { float val; if (getFloat(prop.Values[0], out val)) { this._Target.LodBias = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_LOD_BIAS #region ID_MATERIAL_SCHEME case Keywords.ID_MATERIAL_SCHEME: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line); return; } else { string val; if (getString(prop.Values[0], out val)) { this._Target.MaterialScheme = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_MATERIAL_SCHEME #region ID_SHADOWS_ENABLED case Keywords.ID_SHADOWS_ENABLED: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line); return; } else { bool val; if (getBoolean(prop.Values[0], out val)) { this._Target.ShadowsEnabled = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); } } break; #endregion ID_SHADOWS_ENABLED default: compiler.AddError(CompileErrorCode.UnexpectedToken, prop.File, prop.Line, "token \"" + prop.Name + "\" is not recognized"); break; } } } }
/// <see cref="Translator.Translate"/> public override void Translate(ScriptCompiler compiler, AbstractNode node) { var obj = (ObjectAbstractNode)node; if (obj != null) { if (string.IsNullOrEmpty(obj.Name)) { compiler.AddError(CompileErrorCode.ObjectNameExpected, obj.File, obj.Line); } } else { compiler.AddError(CompileErrorCode.ObjectNameExpected, node.File, node.Line); return; } // Create a material with the given name object mat; ScriptCompilerEvent evt = new CreateMaterialScriptCompilerEvent(node.File, obj.Name, compiler.ResourceGroup); var processed = compiler._fireEvent(ref evt, out mat); if (!processed) { //TODO // The original translated implementation of this code block was simply the following: // _material = (Material)MaterialManager.Instance.Create( obj.Name, compiler.ResourceGroup ); // but sometimes it generates an exception due to a duplicate resource. // In order to avoid the above mentioned exception, the implementation was changed, but // it need to be checked when ResourceManager._add will be updated to the latest version var checkForExistingMat = (Material)MaterialManager.Instance.GetByName(obj.Name); if (checkForExistingMat == null) { this._material = (Material)MaterialManager.Instance.Create(obj.Name, compiler.ResourceGroup); } else { this._material = checkForExistingMat; } } else { this._material = (Material)mat; if (this._material == null) { compiler.AddError(CompileErrorCode.ObjectAllocationError, obj.File, obj.Line, "failed to find or create material \"" + obj.Name + "\""); } } this._material.RemoveAllTechniques(); obj.Context = this._material; this._material.Origin = obj.File; foreach (var i in obj.Children) { if (i is PropertyAbstractNode) { var prop = (PropertyAbstractNode)i; switch ((Keywords)prop.Id) { #region ID_LOD_VALUES case Keywords.ID_LOD_VALUES: { var lods = new LodValueList(); foreach (var j in prop.Values) { Real v = 0; if (getReal(j, out v)) { lods.Add(v); } else { compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line, "lod_values expects only numbers as arguments"); } } this._material.SetLodLevels(lods); } break; #endregion ID_LOD_VALUES #region ID_LOD_DISTANCES case Keywords.ID_LOD_DISTANCES: { // Set strategy to distance strategy LodStrategy strategy = DistanceLodStrategy.Instance; this._material.LodStrategy = strategy; // Real in lod distances var lods = new LodValueList(); foreach (var j in prop.Values) { Real v = 0; if (getReal(j, out v)) { lods.Add(v); } else { compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line, "lod_values expects only numbers as arguments"); } } this._material.SetLodLevels(lods); } break; #endregion ID_LOD_DISTANCES #region ID_LOD_STRATEGY case Keywords.ID_LOD_STRATEGY: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line, "lod_strategy only supports 1 argument"); } else { var strategyName = string.Empty; var result = getString(prop.Values[0], out strategyName); if (result) { var strategy = LodStrategyManager.Instance.GetStrategy(strategyName); result = strategy != null; if (result) { this._material.LodStrategy = strategy; } } if (!result) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "lod_strategy argument must be a valid lod strategy"); } } break; #endregion ID_LOD_STRATEGY #region ID_RECEIVE_SHADOWS case Keywords.ID_RECEIVE_SHADOWS: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line, "receive_shadows only supports 1 argument"); } else { var val = true; if (getBoolean(prop.Values[0], out val)) { this._material.ReceiveShadows = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "receive_shadows argument must be \"true\", \"false\", \"yes\", \"no\", \"on\", or \"off\""); } } break; #endregion ID_RECEIVE_SHADOWS #region ID_TRANSPARENCY_CASTS_SHADOWS case Keywords.ID_TRANSPARENCY_CASTS_SHADOWS: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line, "transparency_casts_shadows only supports 1 argument"); } else { var val = true; if (getBoolean(prop.Values[0], out val)) { this._material.TransparencyCastsShadows = val; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "transparency_casts_shadows argument must be \"true\", \"false\", \"yes\", \"no\", \"on\", or \"off\""); } } break; #endregion ID_TRANSPARENCY_CASTS_SHADOWS #region ID_SET_TEXTURE_ALIAS case Keywords.ID_SET_TEXTURE_ALIAS: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); } else if (prop.Values.Count > 3) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line); } else { AbstractNode i0 = getNodeAt(prop.Values, 0), i1 = getNodeAt(prop.Values, 1); String name, value; if (getString(i0, out name) && getString(i1, out value)) { this._textureAliases.Add(name, value); } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "set_texture_alias must have 2 string argument"); } } break; #endregion ID_SET_TEXTURE_ALIAS default: compiler.AddError(CompileErrorCode.UnexpectedToken, prop.File, prop.Line, "token \"" + prop.Name + "\" is not recognized"); break; } //end of switch statement } else if (i is ObjectAbstractNode) { processNode(compiler, i); } } // Apply the texture aliases ScriptCompilerEvent locEvt = new PreApplyTextureAliasesScriptCompilerEvent(this._material, ref this._textureAliases); compiler._fireEvent(ref locEvt); this._material.ApplyTextureAliases(this._textureAliases); this._textureAliases.Clear(); }
/// <see cref="Translator.Translate"/> public override void Translate(ScriptCompiler compiler, AbstractNode node) { var obj = (ObjectAbstractNode)node; if (obj != null) { if (string.IsNullOrEmpty(obj.Name)) { compiler.AddError(CompileErrorCode.ObjectNameExpected, obj.File, obj.Line); return; } } else { compiler.AddError(CompileErrorCode.ObjectNameExpected, obj.File, obj.Line); return; } // Create the compositor object compObject; ScriptCompilerEvent evt = new CreateCompositorScriptCompilerEvent(obj.File, obj.Name, compiler.ResourceGroup); var processed = compiler._fireEvent(ref evt, out compObject); if (!processed) { //TODO // The original translated implementation of this code block was simply the following: // _Compositor = (Compositor)CompositorManager.Instance.Create( obj.Name, compiler.ResourceGroup ); // but sometimes it generates an excepiton due to a duplicate resource. // In order to avoid the above mentioned exception, the implementation was changed, but // it need to be checked when ResourceManager._add will be updated to the lastest version var checkForExistingComp = (Compositor)CompositorManager.Instance.GetByName(obj.Name); if (checkForExistingComp == null) { this._Compositor = (Compositor)CompositorManager.Instance.Create(obj.Name, compiler.ResourceGroup); } else { this._Compositor = checkForExistingComp; } } else { this._Compositor = (Compositor)compObject; } if (this._Compositor == null) { compiler.AddError(CompileErrorCode.ObjectAllocationError, obj.File, obj.Line); return; } // Prepare the compositor this._Compositor.RemoveAllTechniques(); this._Compositor.Origin = obj.File; obj.Context = this._Compositor; foreach (var i in obj.Children) { if (i is ObjectAbstractNode) { processNode(compiler, i); } else { compiler.AddError(CompileErrorCode.UnexpectedToken, i.File, i.Line, "token not recognized"); } } }
public override void Translate(ScriptCompiler compiler, AbstractNode node) { var obj = (ObjectAbstractNode)node; // Must have a name if (string.IsNullOrEmpty(obj.Name)) { compiler.AddError(CompileErrorCode.ObjectNameExpected, obj.File, obj.Line, "shared_params must be given a name"); return; } object paramsObj; GpuProgramParameters.GpuSharedParameters sharedParams; ScriptCompilerEvent evt = new CreateGpuSharedParametersScriptCompilerEvent(obj.File, obj.Name, compiler.ResourceGroup); bool processed = compiler._fireEvent(ref evt, out paramsObj); if (!processed) { sharedParams = GpuProgramManager.Instance.CreateSharedParameters(obj.Name); } else { sharedParams = (GpuProgramParameters.GpuSharedParameters)paramsObj; } if (sharedParams == null) { compiler.AddError(CompileErrorCode.ObjectAllocationError, obj.File, obj.Line); return; } foreach (var i in obj.Children) { if (!(i is PropertyAbstractNode)) { continue; } var prop = (PropertyAbstractNode)i; switch ((Keywords)prop.Id) { #region ID_SHARED_PARAM_NAMED case Keywords.ID_SHARED_PARAM_NAMED: { if (prop.Values.Count < 2) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "shared_param_named - expected 2 or more arguments"); continue; } var i0 = getNodeAt(prop.Values, 0); var i1 = getNodeAt(prop.Values, 1); if (!(i0 is AtomAbstractNode) || !(i1 is AtomAbstractNode)) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "name and parameter type expected"); continue; } var atom0 = (AtomAbstractNode)i0; var pName = atom0.Value; GpuProgramParameters.GpuConstantType constType; var arraySz = 1; if (!getConstantType(i1, out constType)) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "invalid parameter type"); continue; } var isFloat = GpuProgramParameters.GpuConstantDefinition.IsFloatConst(constType); var mFloats = new GpuProgramParameters.FloatConstantList(); var mInts = new GpuProgramParameters.IntConstantList(); for (var otherValsi = 2; otherValsi < prop.Values.Count; ++otherValsi) { if (!(prop.Values[otherValsi] is AtomAbstractNode)) { continue; } var atom = (AtomAbstractNode)prop.Values[otherValsi]; if (atom.Value[0] == '[' && atom.Value[atom.Value.Length - 1] == ']') { var arrayStr = atom.Value.Substring(1, atom.Value.Length - 2); if (!int.TryParse(arrayStr, out arraySz)) { compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line, "invalid array size"); continue; } } else { var floatVal = 0.0f; var intVal = 0; var parseRes = false; if (isFloat) { parseRes = float.TryParse(atom.Value, out floatVal); } else { parseRes = int.TryParse(atom.Value, out intVal); } if (!parseRes) { compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line, atom.Value + " invalid - extra parameters to shared_param_named must be numbers"); continue; } if (isFloat) { mFloats.Add(floatVal); } else { mInts.Add(intVal); } } } // each extra param // define constant entry try { sharedParams.AddConstantDefinition(pName, constType, arraySz); } catch (Exception e) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, e.Message); continue; } // initial values var elemsExpected = GpuProgramParameters.GpuConstantDefinition.GetElementSize(constType, false) * arraySz; var elemsFound = isFloat ? mFloats.Count : mInts.Count; if (elemsFound > 0) { if (elemsExpected != elemsFound) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "Wrong number of values supplied for parameter type"); continue; } if (isFloat) { sharedParams.SetNamedConstant(pName, mFloats.Data); } else { sharedParams.SetNamedConstant(pName, mInts.Data); } } } break; #endregion ID_SHARED_PARAM_NAMED default: break; } } }
protected void _translateGpuProgram(ScriptCompiler compiler, ObjectAbstractNode obj) { var customParameters = new NameValuePairList(); string syntax = string.Empty, source = string.Empty; AbstractNode parameters = null; foreach (var i in obj.Children) { if (i is PropertyAbstractNode) { var prop = (PropertyAbstractNode)i; if (prop.Id == (uint)Keywords.ID_SOURCE) { if (prop.Values.Count != 0) { if (prop.Values[0] is AtomAbstractNode) { source = ((AtomAbstractNode)prop.Values[0]).Value; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "source file expected"); } } else { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line, "source file expected"); } } else if (prop.Id == (uint)Keywords.ID_SYNTAX) { if (prop.Values.Count != 0) { if (prop.Values[0] is AtomAbstractNode) { syntax = ((AtomAbstractNode)prop.Values[0]).Value; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "syntax string expected"); } } else { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line, "syntax string expected"); } } else { string name = prop.Name, value = string.Empty; var first = true; foreach (var it in prop.Values) { if (it is AtomAbstractNode) { if (!first) { value += " "; } else { first = false; } value += ((AtomAbstractNode)it).Value; } } customParameters.Add(name, value); } } else if (i is ObjectAbstractNode) { if (((ObjectAbstractNode)i).Id == (uint)Keywords.ID_DEFAULT_PARAMS) { parameters = i; } else { processNode(compiler, i); } } } if (!GpuProgramManager.Instance.IsSyntaxSupported(syntax)) { compiler.AddError(CompileErrorCode.UnsupportedByRenderSystem, obj.File, obj.Line); //Register the unsupported program so that materials that use it know that //it exists but is unsupported var unsupportedProg = GpuProgramManager.Instance.Create(obj.Name, compiler.ResourceGroup, _translateIDToGpuProgramType(obj.Id), syntax); return; } // Allocate the program object progObj; GpuProgram prog = null; ScriptCompilerEvent evt = new CreateGpuProgramScriptCompilerEvent(obj.File, obj.Name, compiler.ResourceGroup, source, syntax, _translateIDToGpuProgramType(obj.Id)); var processed = compiler._fireEvent(ref evt, out progObj); if (!processed) { prog = (GpuProgram) GpuProgramManager.Instance.CreateProgram(obj.Name, compiler.ResourceGroup, source, _translateIDToGpuProgramType(obj.Id), syntax); } else { prog = (GpuProgram)progObj; } // Check that allocation worked if (prog == null) { compiler.AddError(CompileErrorCode.ObjectAllocationError, obj.File, obj.Line, "gpu program \"" + obj.Name + "\" could not be created"); return; } obj.Context = prog; prog.IsMorphAnimationIncluded = false; prog.PoseAnimationCount = 0; prog.IsSkeletalAnimationIncluded = false; prog.IsVertexTextureFetchRequired = false; prog.Origin = obj.File; // Set the custom parameters prog.SetParameters(customParameters); // Set up default parameters if (prog.IsSupported && parameters != null) { var ptr = prog.DefaultParameters; GpuProgramTranslator.TranslateProgramParameters(compiler, ptr, (ObjectAbstractNode)parameters); } }
/// <see cref="Translator.Translate"/> public override void Translate(ScriptCompiler compiler, AbstractNode node) { throw new NotImplementedException(); #if UNREACHABLE_CODE ObjectAbstractNode obj = (ObjectAbstractNode)node; // It has to have one value identifying the texture source name if (obj.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, node.File, node.Line, "texture_source requires a type value"); return; } // Set the value of the source //TODO: ExternalTextureSourceManager::getSingleton().setCurrentPlugIn(obj->values.front()->getValue()); // Set up the technique, pass, and texunit levels if (true /*TODO: ExternalTextureSourceManager::getSingleton().getCurrentPlugIn() != 0*/) { TextureUnitState texunit = (TextureUnitState)obj.Parent.Context; Pass pass = texunit.Parent; Technique technique = pass.Parent; Material material = technique.Parent; ushort techniqueIndex = 0, passIndex = 0, texUnitIndex = 0; for (ushort i = 0; i < material.TechniqueCount; i++) { if (material.GetTechnique(i) == technique) { techniqueIndex = i; break; } } for (ushort i = 0; i < technique.PassCount; i++) { if (technique.GetPass(i) == pass) { passIndex = i; break; } } for (ushort i = 0; i < pass.TextureUnitStageCount; i++) { if (pass.GetTextureUnitState(i) == texunit) { texUnitIndex = i; break; } } string tps = string.Format("{0} {1} {2}", techniqueIndex, passIndex, texUnitIndex); //TODO: ExternalTextureSourceManager::getSingleton().getCurrentPlugIn()->setParameter( "set_T_P_S", tps ); foreach (AbstractNode i in obj.Children) { if (i is PropertyAbstractNode) { PropertyAbstractNode prop = (PropertyAbstractNode)i; // Glob the property values all together string str = string.Empty; foreach (AbstractNode j in prop.Values) { if (j != prop.Values[0]) { str += " "; } str = str + j.Value; } //TODO: ExternalTextureSourceManager::getSingleton().getCurrentPlugIn()->setParameter(prop->name, str); } else if (i is ObjectAbstractNode) { _processNode(compiler, i); } } //TODO: ExternalTextureSourceManager::getSingleton().getCurrentPlugIn()->createDefinedTexture(material->getName(), material->getGroup()); } #endif }
/// <see cref="Translator.Translate"/> public override void Translate(ScriptCompiler compiler, AbstractNode node) { var obj = (ObjectAbstractNode)node; var compositor = (Compositor)obj.Parent.Context; this._Technique = compositor.CreateTechnique(); obj.Context = this._Technique; foreach (var i in obj.Children) { if (i is ObjectAbstractNode) { processNode(compiler, i); } else if (i is PropertyAbstractNode) { var prop = (PropertyAbstractNode)i; switch ((Keywords)prop.Id) { #region ID_TEXTURE case Keywords.ID_TEXTURE: { var atomIndex = 1; var it = getNodeAt(prop.Values, 0); if (it is AtomAbstractNode) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); return; } // Save the first atom, should be name var atom0 = (AtomAbstractNode)it; int width = 0, height = 0; float widthFactor = 1.0f, heightFactor = 1.0f; bool widthSet = false, heightSet = false, formatSet = false; var pooled = false; var hwGammaWrite = false; var fsaa = true; var scope = CompositionTechnique.TextureScope.Local; var formats = new List <PixelFormat>(); while (atomIndex < prop.Values.Count) { it = getNodeAt(prop.Values, atomIndex++); if (!(it is AtomAbstractNode)) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); return; } var atom = (AtomAbstractNode)it; switch ((Keywords)atom.Id) { case Keywords.ID_TARGET_WIDTH: width = 0; widthSet = true; break; case Keywords.ID_TARGET_HEIGHT: height = 0; heightSet = true; break; case Keywords.ID_TARGET_WIDTH_SCALED: case Keywords.ID_TARGET_HEIGHT_SCALED: { var pSetFlag = false; var pSize = 0; float pFactor = 0; if (atom.Id == (uint)Keywords.ID_TARGET_WIDTH_SCALED) { pSetFlag = widthSet; pSize = width; pFactor = widthFactor; } else { pSetFlag = heightSet; pSize = height; pFactor = heightFactor; } // advance to next to get scaling it = getNodeAt(prop.Values, atomIndex++); if (it == null || !(it is AtomAbstractNode)) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); return; } atom = (AtomAbstractNode)it; if (!atom.IsNumber) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); return; } pSize = 0; pFactor = atom.Number; pSetFlag = true; } break; case Keywords.ID_POOLED: pooled = true; break; case Keywords.ID_SCOPE_LOCAL: scope = CompositionTechnique.TextureScope.Local; break; case Keywords.ID_SCOPE_CHAIN: scope = CompositionTechnique.TextureScope.Chain; break; case Keywords.ID_SCOPE_GLOBAL: scope = CompositionTechnique.TextureScope.Global; break; case Keywords.ID_GAMMA: hwGammaWrite = true; break; case Keywords.ID_NO_FSAA: fsaa = false; break; default: if (atom.IsNumber) { if (atomIndex == 2) { width = (int)atom.Number; widthSet = true; } else if (atomIndex == 3) { height = (int)atom.Number; heightSet = true; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); return; } } else { // pixel format? var format = PixelUtil.GetFormatFromName(atom.Value, true); if (format == PixelFormat.Unknown) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line); return; } formats.Add(format); formatSet = true; } break; } } if (!widthSet || !heightSet || !formatSet) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); return; } // No errors, create var def = this._Technique.CreateTextureDefinition(atom0.Value); def.Width = width; def.Height = height; def.WidthFactor = widthFactor; def.HeightFactor = heightFactor; def.PixelFormats = formats; def.HwGammaWrite = hwGammaWrite; def.Fsaa = fsaa; def.Pooled = pooled; def.Scope = scope; } break; #endregion ID_TEXTURE #region ID_TEXTURE_REF case Keywords.ID_TEXTURE_REF: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); } else if (prop.Values.Count != 3) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "texture_ref only supports 3 argument"); } else { string texName = string.Empty, refCompName = string.Empty, refTexName = string.Empty; var it = getNodeAt(prop.Values, 0); if (!getString(it, out texName)) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "texture_ref must have 3 string arguments"); } it = getNodeAt(prop.Values, 1); if (!getString(it, out refCompName)) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "texture_ref must have 3 string arguments"); } it = getNodeAt(prop.Values, 2); if (!getString(it, out refTexName)) { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "texture_ref must have 3 string arguments"); } var refTexDef = this._Technique.CreateTextureDefinition(texName); refTexDef.ReferenceCompositorName = refCompName; refTexDef.ReferenceTextureName = refTexName; } break; #endregion ID_TEXTURE_REF #region ID_SCHEME case Keywords.ID_SCHEME: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line, "scheme only supports 1 argument"); } else { var i0 = getNodeAt(prop.Values, 0); var scheme = string.Empty; if (getString(i0, out scheme)) { this._Technique.SchemeName = scheme; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "scheme must have 1 string argument"); } } break; #endregion ID_SCHEME #region ID_COMPOSITOR_LOGIC case Keywords.ID_COMPOSITOR_LOGIC: if (prop.Values.Count == 0) { compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line); } else if (prop.Values.Count > 1) { compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line, "compositor logic only supports 1 argument"); } else { var i0 = getNodeAt(prop.Values, 0); var logicName = string.Empty; if (getString(i0, out logicName)) { this._Technique.CompositorLogicName = logicName; } else { compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line, "compositor logic must have 1 string argument"); } } break; #endregion ID_COMPOSITOR_LOGIC default: compiler.AddError(CompileErrorCode.UnexpectedToken, prop.File, prop.Line, "token \"" + prop.Name + "\" is not recognized"); break; } } } }