Beispiel #1
0
 public bool Equals(ref ViewTransform rhs)
 {
     return((Scale == rhs.Scale) &&
            (Position == rhs.Position) &&
            (Projection == rhs.Projection) &&
            (ModelView == rhs.ModelView));
 }
Beispiel #2
0
        private void ApplyViewTransformToMaterial(Material m, ref ViewTransform viewTransform)
        {
            var em = m as IEffectMaterial;

            if (em == null)
            {
                return;
            }

            var e = em.Effect;

            if (e == null)
            {
                return;
            }

#if SDL2
            if (em.Parameters.ViewportScale != null && em.Parameters.ViewportPosition != null)
            {
                // Only WorldSpace has these parameters -flibit
                em.Parameters.ViewportScale.SetValue(viewTransform.Scale);
                em.Parameters.ViewportPosition.SetValue(viewTransform.Position);
            }
#else
            em.Parameters.ViewportScale.SetValue(viewTransform.Scale);
            em.Parameters.ViewportPosition.SetValue(viewTransform.Position);
#endif

            em.Parameters.ProjectionMatrix.SetValue(viewTransform.Projection);
            em.Parameters.ModelViewMatrix.SetValue(viewTransform.ModelView);
        }
        /// <summary>
        /// Synchronously renders a complete frame to the specified render target.
        /// Automatically sets up the device's viewport and the view transform of your materials and restores them afterwards.
        /// </summary>
        public bool SynchronousDrawToRenderTarget(RenderTarget2D renderTarget, DefaultMaterialSet materials, Action <Frame> drawBehavior)
        {
            if (renderTarget.IsDisposed)
            {
                return(false);
            }
            if (!SynchronousDrawsEnabled)
            {
                throw new InvalidOperationException("Synchronous draws not available inside of Game.Draw");
            }

            WaitForActiveDraw();

            var oldDrawIsActive = Interlocked.Exchange(ref _SynchronousDrawIsActive, 1);

            if (oldDrawIsActive != 0)
            {
                throw new InvalidOperationException("A synchronous draw is already in progress");
            }

            _SynchronousDrawFinishedSignal.Reset();

            WaitForActiveDraw();

            try {
                using (var frame = Manager.CreateFrame()) {
                    materials.PushViewTransform(ViewTransform.CreateOrthographic(renderTarget.Width, renderTarget.Height));

                    ClearBatch.AddNew(frame, int.MinValue, materials.Clear, clearColor: Color.Transparent);

                    drawBehavior(frame);

                    PrepareNextFrame(frame, false);

                    var oldRenderTargets = Device.GetRenderTargets();
                    var oldViewport      = Device.Viewport;
                    try {
                        Device.SetRenderTarget(renderTarget);
                        RenderManager.ResetDeviceState(Device);
                        Device.Viewport = new Viewport(0, 0, renderTarget.Width, renderTarget.Height);

                        RenderFrameToDraw(frame, false);
                    } finally {
                        Device.SetRenderTargets(oldRenderTargets);
                        materials.PopViewTransform();
                        Device.Viewport = oldViewport;
                    }
                }

                return(true);
            } finally {
                _SynchronousDrawFinishedSignal.Set();
                Interlocked.Exchange(ref _SynchronousDrawIsActive, 0);
            }
        }
        private void PendingDrawSetupHandler(DeviceManager dm, object _pd)
        {
            var pd = (PendingDraw)_pd;

            if (!AutoRenderTarget.IsRenderTargetValid(pd.RenderTarget))
            {
                throw new ObjectDisposedException("Render target for pending draw was disposed between prepare and issue");
            }

            var vt = pd.ViewTransform ??
                     ViewTransform.CreateOrthographic(pd.RenderTarget.Width, pd.RenderTarget.Height);

            pd.Materials.PushViewTransform(in vt);
            dm.Device.Clear(Color.Transparent);
        }
Beispiel #5
0
        /// <summary>
        /// Manually sets the view transform of all material(s) owned by this material set without changing the ViewTransform field.
        /// </summary>
        /// <param name="viewTransform">The view transform to apply.</param>
        public void ApplyViewTransform(ref ViewTransform viewTransform)
        {
            if (
                CurrentlyAppliedViewTransform.HasValue &&
                CurrentlyAppliedViewTransform.Value.Equals(ref viewTransform)
                )
            {
                // Already applied. Don't apply again.
                return;
            }
            else
            {
                CurrentlyAppliedViewTransform = viewTransform;
            }

            ForEachMaterial(_ApplyViewTransformDelegate, ref viewTransform);
        }
Beispiel #6
0
        public void ApplyViewTransformToMaterial(Material m, ref ViewTransform viewTransform)
        {
            if (m.Effect == null)
            {
                return;
            }

            var ub = GetUniformBinding <ViewTransform>(m, "Viewport");

            if (ub == null)
            {
                return;
            }

            ub.Value.Current = viewTransform;

            // FIXME: WHY IS THIS NECESSARY?
            // m.Flush();
        }
        private bool DoSynchronousDrawToRenderTarget(
            RenderTarget2D renderTarget,
            DefaultMaterialSet materials,
            Delegate drawBehavior, object userData,
            ref ViewTransform?viewTransform,
            string description
            )
        {
            var oldLazyState = materials.LazyViewTransformChanges;

            try {
                materials.LazyViewTransformChanges = false;
                materials.ApplyViewTransform(materials.ViewTransform, true);
                using (var frame = Manager.CreateFrame(this)) {
                    frame.ChangeRenderTargets = false;
                    frame.Label = description;
                    if (viewTransform.HasValue)
                    {
                        materials.PushViewTransform(in viewTransform);
                    }
                    else
                    {
                        materials.PushViewTransform(ViewTransform.CreateOrthographic(renderTarget.Width, renderTarget.Height));
                    }

                    try {
                        // FIXME: Should queued draws run here? They are probably meant to run in the next real frame

                        var singleBehavior = drawBehavior as Action <Frame>;
                        var multiBehavior  = drawBehavior as PendingDrawHandler;
                        if (singleBehavior != null)
                        {
                            singleBehavior(frame);
                        }
                        else if (multiBehavior != null)
                        {
                            multiBehavior(frame, materials, userData);
                        }
                        else
                        {
                            throw new ArgumentException("Draw behavior was not of a compatible type");
                        }

                        RunBeforePrepareHandlers();
                        PrepareNextFrame(frame, false);

                        Manager.DeviceManager.SetRenderTarget(renderTarget);
                        RenderManager.ResetDeviceState(Device);
                        Device.Clear(Color.Transparent);

                        RenderFrameToDraw(frame, false);
                        // We don't have to push/pop anymore because the stacks are cleared at the end of a frame.

                        return(true);
                    } finally {
                        materials.PopViewTransform();
                    }
                }
            } finally {
                materials.LazyViewTransformChanges = oldLazyState;
            }
        }
Beispiel #8
0
 /// <summary>
 /// Immediately changes the view transform of the material set, without waiting for a clear.
 /// </summary>
 public void PushViewTransform(ref ViewTransform viewTransform)
 {
     ViewTransformStack.Push(viewTransform);
     ApplyViewTransform(ref viewTransform);
 }
Beispiel #9
0
        public DefaultMaterialSet(IServiceProvider serviceProvider)
        {
            _ApplyViewTransformDelegate = ApplyViewTransformToMaterial;
            _ApplyTimeDelegate          = ApplyTimeToMaterial;

            TimeProvider = (ITimeProvider)serviceProvider.GetService(typeof(ITimeProvider))
                           ?? new DotNetTimeProvider();

#if SDL2 // `Content/SquaredRender/` folder -flibit
            BuiltInShaders = new ContentManager(serviceProvider, "Content/SquaredRender");
#else
            BuiltInShaders = new ResourceContentManager(serviceProvider, Shaders.ResourceManager);
#endif

            Clear = new Material(
                null, null,
                new Action <DeviceManager>[] { (dm) => ApplyShaderVariables() }
                );


            var bitmapShader   = BuiltInShaders.Load <Effect>("SquaredBitmapShader");
            var geometryShader = BuiltInShaders.Load <Effect>("SquaredGeometryShader");

            ScreenSpaceBitmap = new Material(
                bitmapShader,
                "ScreenSpaceBitmapTechnique"
                );

            WorldSpaceBitmap = new Material(
                bitmapShader,
                "WorldSpaceBitmapTechnique"
                );

            ScreenSpaceShadowedBitmap = new Material(
                bitmapShader,
                "ScreenSpaceShadowedBitmapTechnique"
                );
            ScreenSpaceShadowedBitmap.Parameters.ShadowColor.SetValue(new Vector4(0, 0, 0, 1));
            ScreenSpaceShadowedBitmap.Parameters.ShadowOffset.SetValue(new Vector2(2, 2));

            WorldSpaceShadowedBitmap = new Material(
                bitmapShader,
                "WorldSpaceShadowedBitmapTechnique"
                );
            WorldSpaceShadowedBitmap.Parameters.ShadowColor.SetValue(new Vector4(0, 0, 0, 1));
            WorldSpaceShadowedBitmap.Parameters.ShadowOffset.SetValue(new Vector2(2, 2));

            ScreenSpaceBitmapWithDiscard = new Material(
                bitmapShader,
                "ScreenSpaceBitmapWithDiscardTechnique"
                );

            WorldSpaceBitmapWithDiscard = new Material(
                bitmapShader,
                "WorldSpaceBitmapWithDiscardTechnique"
                );

            ScreenSpaceGeometry = new Material(
                geometryShader,
                "ScreenSpaceUntextured"
                );

            WorldSpaceGeometry = new Material(
                geometryShader,
                "WorldSpaceUntextured"
                );

            var lightmapShader = BuiltInShaders.Load <Effect>("Lightmap");

            ScreenSpaceLightmappedBitmap = new Material(
                lightmapShader,
                "ScreenSpaceLightmappedBitmap"
                );

            WorldSpaceLightmappedBitmap = new Material(
                lightmapShader,
                "WorldSpaceLightmappedBitmap"
                );

            var blurShader = BuiltInShaders.Load <Effect>("GaussianBlur");

            ScreenSpaceHorizontalGaussianBlur5Tap = new Material(
                blurShader,
                "ScreenSpaceHorizontalGaussianBlur5Tap"
                );

            ScreenSpaceVerticalGaussianBlur5Tap = new Material(
                blurShader,
                "ScreenSpaceVerticalGaussianBlur5Tap"
                );

            WorldSpaceHorizontalGaussianBlur5Tap = new Material(
                blurShader,
                "WorldSpaceHorizontalGaussianBlur5Tap"
                );

            WorldSpaceVerticalGaussianBlur5Tap = new Material(
                blurShader,
                "WorldSpaceVerticalGaussianBlur5Tap"
                );

            var gds = serviceProvider.GetService(typeof(IGraphicsDeviceService)) as IGraphicsDeviceService;
            if (gds != null)
            {
                ViewTransformStack.Push(ViewTransform.CreateOrthographic(
                                            gds.GraphicsDevice.PresentationParameters.BackBufferWidth,
                                            gds.GraphicsDevice.PresentationParameters.BackBufferHeight
                                            ));
            }
            else
            {
                ViewTransformStack.Push(ViewTransform.Default);
            }

            PreallocateBindings();
        }
Beispiel #10
0
        public DefaultMaterialSet(IServiceProvider serviceProvider)
        {
            _ApplyViewTransformDelegate = ApplyViewTransformToMaterial;

#if SDL2
            BuiltInShaders = new ContentManager(serviceProvider, "Content/SquaredRender");
#elif !PSM
            BuiltInShaders = new ResourceContentManager(serviceProvider, Shaders.ResourceManager);
#else
            BuiltInShaders = new Squared.Render.PSM.PSMShaderManager(serviceProvider);
#endif

            Clear = new DelegateMaterial(
                new NullMaterial(),
                new Action <DeviceManager>[] { (dm) => ApplyShaderVariables() },
                null
                );


#if PSM
            ScreenSpaceBitmap   = new EffectMaterial(BuiltInShaders.Load <Effect>("ScreenSpaceBitmap"));
            WorldSpaceBitmap    = new EffectMaterial(BuiltInShaders.Load <Effect>("WorldSpaceBitmap"));
            ScreenSpaceGeometry = new EffectMaterial(BuiltInShaders.Load <Effect>("ScreenSpaceGeometry"));
            WorldSpaceGeometry  = new EffectMaterial(BuiltInShaders.Load <Effect>("WorldSpaceGeometry"));
#elif SDL2
            ScreenSpaceBitmap = new EffectMaterial(
                BuiltInShaders.Load <Effect>("ScreenSpaceBitmapTechnique"),
                "ScreenSpaceBitmapTechnique"
                );

            WorldSpaceBitmap = new EffectMaterial(
                BuiltInShaders.Load <Effect>("WorldSpaceBitmapTechnique"),
                "WorldSpaceBitmapTechnique"
                );

            ScreenSpaceGeometry = new EffectMaterial(
                BuiltInShaders.Load <Effect>("ScreenSpaceUntextured"),
                "ScreenSpaceUntextured"
                );

            WorldSpaceGeometry = new EffectMaterial(
                BuiltInShaders.Load <Effect>("WorldSpaceUntextured"),
                "WorldSpaceUntextured"
                );
#else
            var bitmapShader   = BuiltInShaders.Load <Effect>("SquaredBitmapShader");
            var geometryShader = BuiltInShaders.Load <Effect>("SquaredGeometryShader");

            ScreenSpaceBitmap = new EffectMaterial(
                bitmapShader,
                "ScreenSpaceBitmapTechnique"
                );

            WorldSpaceBitmap = new EffectMaterial(
                bitmapShader,
                "WorldSpaceBitmapTechnique"
                );

            ScreenSpaceBitmapWithDiscard = new EffectMaterial(
                bitmapShader,
                "ScreenSpaceBitmapWithDiscardTechnique"
                );

            WorldSpaceBitmapWithDiscard = new EffectMaterial(
                bitmapShader,
                "WorldSpaceBitmapWithDiscardTechnique"
                );

            ScreenSpaceGeometry = new EffectMaterial(
                geometryShader,
                "ScreenSpaceUntextured"
                );

            WorldSpaceGeometry = new EffectMaterial(
                geometryShader,
                "WorldSpaceUntextured"
                );
#endif

#if SDL2
            ScreenSpaceLightmappedBitmap = new EffectMaterial(
                BuiltInShaders.Load <Effect>("ScreenSpaceLightmappedBitmap"),
                "ScreenSpaceLightmappedBitmap"
                );

            WorldSpaceLightmappedBitmap = new EffectMaterial(
                BuiltInShaders.Load <Effect>("WorldSpaceLightmappedBitmap"),
                "WorldSpaceLightmappedBitmap"
                );
#elif !PSM
            var lightmapShader = BuiltInShaders.Load <Effect>("Lightmap");

            ScreenSpaceLightmappedBitmap = new EffectMaterial(
                lightmapShader,
                "ScreenSpaceLightmappedBitmap"
                );

            WorldSpaceLightmappedBitmap = new EffectMaterial(
                lightmapShader,
                "WorldSpaceLightmappedBitmap"
                );

            var blurShader = BuiltInShaders.Load <Effect>("GaussianBlur");

            ScreenSpaceHorizontalGaussianBlur5Tap = new EffectMaterial(
                blurShader,
                "ScreenSpaceHorizontalGaussianBlur5Tap"
                );

            ScreenSpaceVerticalGaussianBlur5Tap = new EffectMaterial(
                blurShader,
                "ScreenSpaceVerticalGaussianBlur5Tap"
                );

            WorldSpaceHorizontalGaussianBlur5Tap = new EffectMaterial(
                blurShader,
                "WorldSpaceHorizontalGaussianBlur5Tap"
                );

            WorldSpaceVerticalGaussianBlur5Tap = new EffectMaterial(
                blurShader,
                "WorldSpaceVerticalGaussianBlur5Tap"
                );
#endif

            var gds = serviceProvider.GetService(typeof(IGraphicsDeviceService)) as IGraphicsDeviceService;
            if (gds != null)
            {
                ViewTransformStack.Push(ViewTransform.CreateOrthographic(
                                            gds.GraphicsDevice.PresentationParameters.BackBufferWidth,
                                            gds.GraphicsDevice.PresentationParameters.BackBufferHeight
                                            ));
            }
            else
            {
                ViewTransformStack.Push(ViewTransform.Default);
            }
        }