示例#1
0
        public void Render(DX11RenderContext context, DX11RenderSettings settings)
        {
            Device        device = context.Device;
            DeviceContext ctx    = context.CurrentDeviceContext;

            bool popstate = false;

            bool multistate     = this.FInState.IsConnected && this.FInState.SliceCount > 1;
            bool stateConnected = this.FInState.IsConnected;

            if (this.FInEnabled[0])
            {
                //In that case we do not care about geometry, but only apply pass for globals
                if (settings.RenderHint == eRenderHint.ApplyOnly)
                {
                    this.ApplyOnly(context, settings);
                    return;
                }

                if (settings.RenderHint == eRenderHint.Collector)
                {
                    this.Collect(context, settings);
                    return;
                }

                DX11ShaderData shaderdata = this.deviceshaderdata[context];
                if ((shaderdata.IsValid &&
                     (this.geomconnected || settings.Geometry != null) &&
                     this.spmax > 0 && this.varmanager.SetGlobalSettings(shaderdata.ShaderInstance, settings)) ||
                    this.FInApplyOnly[0])
                {
                    this.OnBeginQuery(context);

                    //Select preferred technique if available
                    if (settings.PreferredTechniques.Count == 0 && this.techniqueindex != this.FInTechnique[0].Index)
                    {
                        this.techniqueindex   = this.FInTechnique[0].Index;
                        this.techniquechanged = true;
                    }
                    else if (settings.PreferredTechniques.Count > 0)
                    {
                        int i = settings.GetPreferredTechnique(this.FShader);
                        if (i == -1)
                        {
                            i = this.FInTechnique[0].Index;
                        }
                        if (i != this.techniqueindex)
                        {
                            this.techniqueindex   = i;
                            this.techniquechanged = true;
                        }
                    }

                    //Need to build input layout
                    if (this.FGeometry.IsChanged || this.techniquechanged || shaderdata.LayoutValid.Count == 0)
                    {
                        shaderdata.Update(this.techniqueindex, 0, this.FGeometry);
                        this.FOutLayoutValid.AssignFrom(shaderdata.LayoutValid);
                        this.FOutLayoutMsg.AssignFrom(shaderdata.LayoutMsg);

                        int           errorCount = 0;
                        StringBuilder sbMsg      = new StringBuilder();
                        sbMsg.Append("Invalid layout detected for slices:");
                        for (int i = 0; i < shaderdata.LayoutValid.Count; i++)
                        {
                            if (shaderdata.LayoutValid[i] == false)
                            {
                                errorCount++;
                                sbMsg.Append(i + ",");
                            }
                        }

                        if (errorCount > 0)
                        {
                            this.FHost.Log(TLogType.Warning, sbMsg.ToString());
                        }

                        this.techniquechanged = false;
                    }

                    if (this.stateconnected && !multistate)
                    {
                        context.RenderStateStack.Push(this.FInState[0]);
                        popstate = true;
                    }

                    ShaderPipelineState pipelineState = null;
                    if (!settings.PreserveShaderStages)
                    {
                        shaderdata.ResetShaderStages(ctx);
                    }
                    else
                    {
                        pipelineState = new ShaderPipelineState(context);
                    }

                    settings.DrawCallCount = spmax; //Set number of draw calls

                    var objectsettings = this.objectSettings[context];
#pragma warning disable 0618
                    objectsettings.GeometryFromLayer = false;
#pragma warning restore 0618
                    var orderedobjectsettings = this.orderedObjectSettings[context];
                    var variableCache         = this.shaderVariableCache[context];
                    variableCache.ApplyGlobals(settings);

                    //IDX11Geometry drawgeom = null;
                    objectsettings.Geometry = null;
                    DX11Resource <IDX11Geometry> pg = null;
                    bool       doOrder       = false;
                    List <int> orderedSlices = null;
                    if (settings.LayerOrder != null && settings.LayerOrder.Enabled)
                    {
                        orderedobjectsettings.Clear();
                        for (int i = 0; i < this.spmax; i++)
                        {
                            DX11ObjectRenderSettings objSettings = new DX11ObjectRenderSettings();
                            objSettings.DrawCallIndex  = i;
                            objSettings.Geometry       = null;
                            objSettings.IterationCount = 1;
                            objSettings.IterationIndex = 0;
                            objSettings.WorldTransform = this.mworld[i % this.mworldcount];
                            objSettings.RenderStateTag = stateConnected ? this.FInState[i].Tag : null;
                            orderedobjectsettings.Add(objSettings);
                        }

                        orderedSlices = settings.LayerOrder.Reorder(settings, orderedobjectsettings);
                        doOrder       = true;
                    }

                    int drawCount = doOrder ? orderedSlices.Count : this.spmax;

                    if (this.spmax == 0)
                    {
                        drawCount = 0;
                    }

                    bool singleGeometry = this.FGeometry.SliceCount == 1 || settings.Geometry != null;
                    if (settings.Geometry != null && this.FGeometry.IsConnected == false)
                    {
#pragma warning disable 0618
                        objectsettings.GeometryFromLayer = true;
#pragma warning restore 0618

                        objectsettings.Geometry = settings.Geometry;
                        singleGeometry          = true;
                        if (!shaderdata.SetInputAssemblerFromLayer(ctx, objectsettings.Geometry, 0))
                        {
                            return;
                        }
                    }
                    else if (singleGeometry)
                    {
                        pg = this.FGeometry[0];
                        objectsettings.Geometry = pg[context];


                        if (objectsettings.Geometry == null)
                        {
                            objectsettings.Geometry = new DX11InvalidGeometry();
                        }
                        shaderdata.SetInputAssembler(ctx, objectsettings.Geometry, 0);
                    }

                    if (!multistate)
                    {
                        objectsettings.RenderStateTag = this.FInState[0] != null ? this.FInState[0].Tag : null;
                    }

                    for (int i = 0; i < drawCount; i++)
                    {
                        int idx = doOrder ? orderedSlices[i] : i;
                        if (multistate)
                        {
                            context.RenderStateStack.Push(this.FInState[idx]);
                            objectsettings.RenderStateTag = this.FInState[idx] != null ? this.FInState[idx].Tag : null;
                        }

                        if (shaderdata.IsLayoutValid(idx) || settings.Geometry != null)
                        {
                            objectsettings.IterationCount = this.FIter[idx];

                            for (int k = 0; k < objectsettings.IterationCount; k++)
                            {
                                objectsettings.IterationIndex = k;

                                if (!singleGeometry)
                                {
                                    if (settings.Geometry == null)
                                    {
                                        if (this.FGeometry[idx] != pg)
                                        {
                                            pg = this.FGeometry[idx];

                                            objectsettings.Geometry = pg[context];
                                            if (objectsettings.Geometry == null)
                                            {
                                                objectsettings.Geometry = new DX11InvalidGeometry();
                                            }

                                            shaderdata.SetInputAssembler(ctx, objectsettings.Geometry, idx);
                                        }
                                    }
                                    else
                                    {
                                        objectsettings.Geometry = settings.Geometry;
                                        shaderdata.SetInputAssembler(ctx, objectsettings.Geometry, idx);
                                    }
                                }


                                //Prepare settings
                                objectsettings.DrawCallIndex  = idx;
                                objectsettings.WorldTransform = this.mworld[idx % this.mworldcount];

                                if (settings.ValidateObject(objectsettings))
                                {
                                    variableCache.ApplySlice(objectsettings, idx);

                                    for (int ip = 0; ip < shaderdata.PassCount; ip++)
                                    {
                                        shaderdata.ApplyPass(ctx, ip);

                                        if (settings.DepthOnly)
                                        {
                                            ctx.PixelShader.Set(null);
                                        }

                                        objectsettings.Geometry.Draw();
                                    }
                                }
                            }
                        }

                        if (multistate)
                        {
                            context.RenderStateStack.Pop();
                        }
                    }

                    shaderdata.ShaderInstance.CleanUp();

                    if (pipelineState != null)
                    {
                        pipelineState.Restore(context);
                    }


                    this.OnEndQuery(context);
                }
                //this.query.End();
            }

            if (popstate)
            {
                context.RenderStateStack.Pop();
            }
            else
            {
                //Since shaders can define their own states, reapply top of the stack
                context.RenderStateStack.Apply();
            }

            if (this.FInLayer.IsConnected && this.FInEnabled[0])
            {
                this.FInLayer.RenderAll(context, settings);
            }
        }
示例#2
0
        public void Render(IPluginIO pin, DX11RenderContext context, DX11RenderSettings settings)
        {
            Device        device = context.Device;
            DeviceContext ctx    = context.CurrentDeviceContext;

            bool popstate = false;

            bool multistate = this.FInState.IsConnected && this.FInState.SliceCount > 1;

            if (this.FInEnabled[0])
            {
                //In that case we do not care about geometry, but only apply pass for globals
                if (settings.RenderHint == eRenderHint.ApplyOnly)
                {
                    DX11ShaderData sdata = this.deviceshaderdata[context];
                    this.varmanager.SetGlobalSettings(sdata.ShaderInstance, settings);
                    this.varmanager.ApplyGlobal(sdata.ShaderInstance);

                    DX11ObjectRenderSettings oset = new DX11ObjectRenderSettings();
                    oset.DrawCallIndex  = 0;
                    oset.Geometry       = null;
                    oset.IterationCount = 1;
                    oset.IterationIndex = 0;
                    oset.WorldTransform = this.mworld[0 % this.mworldcount];
                    this.varmanager.ApplyPerObject(context, sdata.ShaderInstance, oset, 0);
                    sdata.ApplyPass(ctx);


                    if (this.FInLayer.IsConnected)
                    {
                        this.FInLayer[0][context].Render(this.FInLayer.PluginIO, context, settings);
                    }

                    return;
                }

                if (settings.RenderHint == eRenderHint.Collector)
                {
                    if (this.FGeometry.PluginIO.IsConnected)
                    {
                        DX11ObjectGroup group = new DX11ObjectGroup();
                        group.ShaderName = this.Source.Name;
                        group.Semantics.AddRange(settings.CustomSemantics);

                        if (this.FGeometry.SliceCount == 1)
                        {
                            IDX11Geometry g = this.FGeometry[0][context];
                            if (g.Tag != null)
                            {
                                DX11RenderObject o = new DX11RenderObject();
                                o.ObjectType = g.PrimitiveType;
                                o.Descriptor = g.Tag;
                                o.Transforms = new Matrix[spmax];
                                for (int i = 0; i < this.spmax; i++)
                                {
                                    o.Transforms[i] = this.mworld[i % this.mworldcount];
                                }
                                group.RenderObjects.Add(o);

                                settings.SceneDescriptor.Groups.Add(group);
                            }
                        }
                        else
                        {
                            for (int i = 0; i < this.spmax; i++)
                            {
                                IDX11Geometry g = this.FGeometry[i][context];
                                if (g.Tag != null)
                                {
                                    DX11RenderObject o = new DX11RenderObject();
                                    o.ObjectType    = g.PrimitiveType;
                                    o.Descriptor    = g.Tag;
                                    o.Transforms    = new Matrix[1];
                                    o.Transforms[0] = this.mworld[i % this.mworldcount];
                                    group.RenderObjects.Add(o);
                                }
                            }

                            settings.SceneDescriptor.Groups.Add(group);
                        }
                    }
                    return;
                }

                DX11ShaderData shaderdata = this.deviceshaderdata[context];
                if ((shaderdata.IsValid &&
                     (this.geomconnected || settings.Geometry != null) &&
                     this.spmax > 0 && this.varmanager.SetGlobalSettings(shaderdata.ShaderInstance, settings)) ||
                    this.FInApplyOnly[0])
                {
                    this.OnBeginQuery(context);

                    //Select preferred technique if available
                    if (settings.PreferredTechniques.Count == 0 && this.techniqueindex != this.FInTechnique[0].Index)
                    {
                        this.techniqueindex   = this.FInTechnique[0].Index;
                        this.techniquechanged = true;
                    }
                    else if (settings.PreferredTechniques.Count > 0)
                    {
                        int i = settings.GetPreferredTechnique(this.FShader);
                        if (i == -1)
                        {
                            i = this.FInTechnique[0].Index;
                        }
                        if (i != this.techniqueindex)
                        {
                            this.techniqueindex   = i;
                            this.techniquechanged = true;
                        }
                    }

                    //Need to build input layout
                    if (this.FGeometry.IsChanged || this.techniquechanged || shaderdata.LayoutValid.Count == 0)
                    {
                        shaderdata.Update(this.techniqueindex, 0, this.FGeometry);
                        this.FOutLayoutValid.AssignFrom(shaderdata.LayoutValid);
                        this.FOutLayoutMsg.AssignFrom(shaderdata.LayoutMsg);

                        int           errorCount = 0;
                        StringBuilder sbMsg      = new StringBuilder();
                        sbMsg.Append("Invalid layout detected for slices:");
                        for (int i = 0; i < shaderdata.LayoutValid.Count; i++)
                        {
                            if (shaderdata.LayoutValid[i] == false)
                            {
                                errorCount++;
                                sbMsg.Append(i + ",");
                            }
                        }

                        if (errorCount > 0)
                        {
                            this.FHost.Log(TLogType.Warning, sbMsg.ToString());
                        }

                        this.techniquechanged = false;
                    }

                    if (this.stateconnected && !multistate)
                    {
                        context.RenderStateStack.Push(this.FInState[0]);
                        popstate = true;
                    }

                    ShaderPipelineState pipelineState = null;
                    if (!settings.PreserveShaderStages)
                    {
                        shaderdata.ResetShaderStages(ctx);
                    }
                    else
                    {
                        pipelineState = new ShaderPipelineState(context);
                    }

                    settings.DrawCallCount = spmax; //Set number of draw calls

                    this.varmanager.ApplyGlobal(shaderdata.ShaderInstance);

                    //IDX11Geometry drawgeom = null;
                    objectsettings.Geometry = null;
                    DX11Resource <IDX11Geometry> pg = null;
                    bool       doOrder       = false;
                    List <int> orderedSlices = null;
                    if (settings.LayerOrder != null && settings.LayerOrder.Enabled)
                    {
                        this.orderedObjectSettings.Clear();
                        for (int i = 0; i < this.spmax; i++)
                        {
                            DX11ObjectRenderSettings objSettings = new DX11ObjectRenderSettings();
                            objSettings.DrawCallIndex  = i;
                            objSettings.Geometry       = null;
                            objSettings.IterationCount = 1;
                            objSettings.IterationIndex = 0;
                            objSettings.WorldTransform = this.mworld[i % this.mworldcount];

                            this.orderedObjectSettings.Add(objSettings);
                        }

                        orderedSlices = settings.LayerOrder.Reorder(settings, orderedObjectSettings);
                        doOrder       = true;
                    }

                    int drawCount = doOrder ? orderedSlices.Count : this.spmax;

                    if (this.spmax == 0)
                    {
                        drawCount = 0;
                    }

                    for (int i = 0; i < drawCount; i++)
                    {
                        int idx = doOrder ? orderedSlices[i] : i;
                        if (multistate)
                        {
                            context.RenderStateStack.Push(this.FInState[idx]);
                        }

                        if (shaderdata.IsLayoutValid(idx) || settings.Geometry != null)
                        {
                            objectsettings.IterationCount = this.FIter[idx];

                            for (int k = 0; k < objectsettings.IterationCount; k++)
                            {
                                objectsettings.IterationIndex = k;
                                if (settings.Geometry == null)
                                {
                                    if (this.FGeometry[idx] != pg)
                                    {
                                        pg = this.FGeometry[idx];

                                        objectsettings.Geometry = pg[context];

                                        shaderdata.SetInputAssembler(ctx, objectsettings.Geometry, idx);
                                    }
                                }
                                else
                                {
                                    objectsettings.Geometry = settings.Geometry;
                                    shaderdata.SetInputAssembler(ctx, objectsettings.Geometry, idx);
                                }

                                //Prepare settings
                                objectsettings.DrawCallIndex  = idx;
                                objectsettings.WorldTransform = this.mworld[idx % this.mworldcount];

                                if (settings.ValidateObject(objectsettings))
                                {
                                    this.varmanager.ApplyPerObject(context, shaderdata.ShaderInstance, this.objectsettings, idx);

                                    shaderdata.ApplyPass(ctx);

                                    if (settings.DepthOnly)
                                    {
                                        ctx.PixelShader.Set(null);
                                    }

                                    if (settings.PostPassAction != null)
                                    {
                                        settings.PostPassAction(context);
                                    }


                                    objectsettings.Geometry.Draw();
                                    shaderdata.ShaderInstance.CleanUp();
                                }
                            }
                        }

                        if (multistate)
                        {
                            context.RenderStateStack.Pop();
                        }

                        if (settings.PostShaderAction != null)
                        {
                            settings.PostShaderAction(context);
                        }
                    }

                    if (pipelineState != null)
                    {
                        pipelineState.Restore(context);
                    }


                    this.OnEndQuery(context);
                }
                //this.query.End();
            }

            if (popstate)
            {
                context.RenderStateStack.Pop();
            }
            else
            {
                //Since shaders can define their own states, reapply top of the stack
                context.RenderStateStack.Apply();
            }

            if (this.FInLayer.IsConnected && this.FInEnabled[0])
            {
                this.FInLayer[0][context].Render(this.FInLayer.PluginIO, context, settings);
            }
        }