Open vchelaru opened 1 year ago
C# example:
private SpriteBatch _spriteBatch = null!; private TimeSpan _effectDuration = TimeSpan.FromSeconds(4); private void CustomInitialize() { _spriteBatch = new SpriteBatch(FlatRedBallServices.GraphicsDevice); } public void Draw(Camera camera) { // flip y axis because SpriteBatch drawing coordinates start from the top-left corner // where positive x is right (same as FRB) and positive y is down (opposite of FRB) var drawPosition = SpriteInstance.Position.ToVector2() * new Vector2(1, -1); var shader = DefaultSprite; SetCommonShaderParameters(shader, camera, drawPosition, _effectDuration, SpriteInstance.TextureScale, SpriteInstance.Texture); var spriteColor = new Color(SpriteInstance.Red, SpriteInstance.Green, SpriteInstance.Blue, SpriteInstance.Alpha); var origin = new Vector2(SpriteInstance.ScaleX, SpriteInstance.ScaleY) / SpriteInstance.TextureScale; SpriteEffects shouldFlip = (SpriteInstance.FlipHorizontal, SpriteInstance.FlipVertical) switch { (false, false) => SpriteEffects.None, (true , false) => SpriteEffects.FlipHorizontally, (false, true ) => SpriteEffects.FlipVertically, (true , true ) => SpriteEffects.FlipHorizontally | SpriteEffects.FlipVertically, }; _spriteBatch.Begin(effect: shader); _spriteBatch.Draw(SpriteInstance.Texture, drawPosition, null, spriteColor, SpriteInstance.RotationZ, origin, SpriteInstance.TextureScale, shouldFlip, Position.Z); _spriteBatch.End(); } private void CustomDestroy() { _spriteBatch.Dispose(); } private static Matrix GetViewProjection(Camera camera) { // flip y axis because SpriteBatch drawing coordinates start from the top-left corner // where positive x is right (same as FRB) and positive y is down (opposite of FRB) var adjustedView = camera.View with { M42 = -camera.View.M42 }; var adjustedProj = camera.Projection with { M22 = -camera.Projection.M22 }; return adjustedView * adjustedProj; } private static void SetCommonShaderParameters(Effect shader, Camera camera, Vector2 drawPosition, TimeSpan effectDuration, float textureScale, Texture2D texture) { double normalizedTime = TimeManager.CurrentScreenTime % effectDuration.TotalSeconds / effectDuration.TotalSeconds; // ======= required parameters ======= shader.Parameters["ViewProjection"].SetValue(GetViewProjection(camera)); // ======= optional parameters ======= shader.Parameters?["WorldPosition"]?.SetValue(drawPosition); shader.Parameters?["Time"]?.SetValue((float)TimeManager.CurrentScreenTime); shader.Parameters?["NormalizedTime"]?.SetValue((float)normalizedTime); shader.Parameters?["TextureSize"]?.SetValue(textureScale * new Vector2(texture.Width, texture.Height)); }
#if OPENGL #define VS_SHADERMODEL vs_3_0 #define PS_SHADERMODEL ps_3_0 #else #define VS_SHADERMODEL vs_4_0 #define PS_SHADERMODEL ps_4_0 #endif //============================================================================== // GraphicsDevice Parameters //============================================================================== SamplerState SamplerState0 : register(s0); //============================================================================== // External Parameters //============================================================================== float4x4 ViewProjection; float Time; float NormalizedTime; float2 WorldPosition; float2 TextureSize; //============================================================================== // Shader Stage Parameters //============================================================================== struct AssemblerToVertex { float4 Position : POSITION0; float4 Color : COLOR0; float4 TexCoord : TEXCOORD0; }; struct VertexToPixel { float4 Position : SV_Position0; float4 Color : COLOR0; float4 TexCoord : TEXCOORD0; }; //============================================================================== // Vertex Shaders //============================================================================== VertexToPixel VsMain(const in AssemblerToVertex input) { VertexToPixel output; output.Position = mul(input.Position, ViewProjection); output.Color = input.Color; output.TexCoord = input.TexCoord; return output; } //============================================================================== // Pixel Shaders //============================================================================== float4 PsMain(VertexToPixel input) : SV_TARGET { float4 diffuse = tex2D(SamplerState0, input.TexCoord.xy); float4 finalColor = diffuse * input.Color; return finalColor; } //============================================================================== // Techniques //============================================================================== technique Tech0 { pass Pass0 { VertexShader = compile VS_SHADERMODEL VsMain(); PixelShader = compile PS_SHADERMODEL PsMain(); } }
This is going to be accompanied with changes to the engine and Glue to make adding global shaders easier. This may also expand to support layer-specific shaders/swap chains.
Adding a checklist of things to fix:
C# example: