diff --git a/Resources/Shaders.fxcproj b/Resources/Shaders.fxcproj new file mode 100644 index 00000000..d9f7ab6f --- /dev/null +++ b/Resources/Shaders.fxcproj @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Resources/base2d.dae b/Resources/base2d.dae new file mode 100644 index 00000000..4954cc8b --- /dev/null +++ b/Resources/base2d.dae @@ -0,0 +1,30 @@ + + + + + Pascal + NVIDIA FX Composer 2.0 + + + + 2007-10-19T17:06:49 + FXComposer, NVIDIA + 2007-10-19T17:07:14 + + + </asset> + <library_effects> + <effect id="Effect" name="base2d"> + <profile_COMMON> + <technique sid="__fxc2_default"> + <constant/> + </technique> + </profile_COMMON> + <extra type="import"> + <technique profile="NVIDIA_FXCOMPOSER"> + <import url="../Source/Resources/base2d.fx" compiler_options="" profile="fx"/> + </technique> + </extra> + </effect> + </library_effects> +</COLLADA> diff --git a/Source/Builder.csproj b/Source/Builder.csproj index d235538f..6b50f93d 100644 --- a/Source/Builder.csproj +++ b/Source/Builder.csproj @@ -153,16 +153,18 @@ <DesignTime>True</DesignTime> <DependentUpon>Resources.resx</DependentUpon> </Compile> + <Compile Include="Rendering\Base2DShader.cs" /> <Compile Include="Rendering\D3DGraphics.cs" /> <Compile Include="Data\ImageData.cs" /> + <Compile Include="Rendering\D3DShader.cs" /> <Compile Include="Rendering\FlatVertex.cs" /> <Compile Include="Rendering\ID3DResource.cs" /> <Compile Include="Rendering\PixelColor.cs" /> <Compile Include="Rendering\Plotter.cs" /> - <Compile Include="Rendering\PTVertex.cs" /> <Compile Include="Rendering\Renderer.cs" /> <Compile Include="Rendering\Renderer2D.cs" /> <Compile Include="Rendering\Renderer3D.cs" /> + <Compile Include="Rendering\ShaderManager.cs" /> </ItemGroup> <ItemGroup> <Reference Include="SlimDX, Version=1.0.2847.35002, Culture=neutral, processorArchitecture=x86" /> @@ -225,6 +227,7 @@ <DependentUpon>ResourceListEditor.cs</DependentUpon> </EmbeddedResource> <EmbeddedResource Include="Resources\Actions.cfg" /> + <EmbeddedResource Include="Resources\base2d.fx" /> <None Include="Resources\Splash2.png" /> </ItemGroup> </Project> \ No newline at end of file diff --git a/Source/Rendering/Base2DShader.cs b/Source/Rendering/Base2DShader.cs new file mode 100644 index 00000000..5c8b356a --- /dev/null +++ b/Source/Rendering/Base2DShader.cs @@ -0,0 +1,112 @@ + +#region ================== Copyright (c) 2007 Pascal vd Heiden + +/* + * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + * This program is released under GNU General Public License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#endregion + +#region ================== Namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using System.Windows.Forms; +using System.IO; +using System.Reflection; +using System.Drawing; +using System.ComponentModel; +using CodeImp.DoomBuilder.Map; +using SlimDX.Direct3D; +using SlimDX.Direct3D9; +using SlimDX; +using CodeImp.DoomBuilder.Geometry; +using System.Drawing.Imaging; + +#endregion + +namespace CodeImp.DoomBuilder.Rendering +{ + internal class Base2DShader : D3DShader + { + #region ================== Variables + + // Property handlers + private EffectHandle texture1; + private EffectHandle settings; + + #endregion + + #region ================== Properties + + public Texture Texture1 { set { if(manager.Enabled) effect.SetValue(texture1, value); } } + + #endregion + + #region ================== Constructor / Disposer + + // Constructor + public Base2DShader(ShaderManager manager) : base(manager) + { + // Load effect from file + effect = LoadEffect("base2d.fx"); + + // Get the property handlers from effect + if(effect != null) + { + texture1 = effect.GetParameter(null, "texture1"); + settings = effect.GetParameter(null, "settings"); + } + + // Initialize world vertex declaration + VertexElement[] elements = new VertexElement[] + { + new VertexElement(0, 0, DeclarationType.Float4, DeclarationMethod.Default, DeclarationUsage.PositionTransformed, 0), + new VertexElement(0, 16, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0), + VertexElement.VertexDeclarationEnd + }; + vertexdecl = new VertexDeclaration(General.Map.Graphics.Device, elements); + + // We have no destructor + GC.SuppressFinalize(this); + } + + // Diposer + public override void Dispose() + { + // Not already disposed? + if(!isdisposed) + { + // Clean up + texture1.Dispose(); + settings.Dispose(); + + // Done + base.Dispose(); + } + } + + #endregion + + #region ================== Methods + + // This sets the settings + public void SetSettings(float texelx, float texely, float blendfactor) + { + Vector4 values = new Vector4(texelx, texely, blendfactor, 0f); + if(manager.Enabled) effect.SetValue(settings, values); + } + + #endregion + } +} diff --git a/Source/Rendering/D3DGraphics.cs b/Source/Rendering/D3DGraphics.cs index e1786871..a79c1673 100644 --- a/Source/Rendering/D3DGraphics.cs +++ b/Source/Rendering/D3DGraphics.cs @@ -58,6 +58,7 @@ namespace CodeImp.DoomBuilder.Rendering private Renderer3D renderer3d; private Viewport viewport; private List<ID3DResource> resources; + private ShaderManager shaders; // Disposing private bool isdisposed = false; @@ -72,7 +73,8 @@ namespace CodeImp.DoomBuilder.Rendering public Renderer3D Renderer3D { get { return renderer3d; } } public RenderTargetControl RenderTarget { get { return rendertarget; } } public Viewport Viewport { get { return viewport; } } - + public ShaderManager Shaders { get { return shaders; } } + #endregion #region ================== Constructor / Disposer @@ -139,7 +141,6 @@ namespace CodeImp.DoomBuilder.Rendering device.SetRenderState(RenderState.ZWriteEnable, false); device.SetRenderState(RenderState.Clipping, true); device.SetRenderState(RenderState.CullMode, Cull.None); - device.VertexFormat = PTVertex.Format; // Sampler settings device.SetSamplerState(0, SamplerState.MagFilter, TextureFilter.Linear); @@ -154,7 +155,6 @@ namespace CodeImp.DoomBuilder.Rendering // First texture stage device.SetTextureStageState(0, TextureStage.ColorOperation, TextureOperation.SelectArg1); device.SetTextureStageState(0, TextureStage.ColorArg1, TextureArgument.Texture); - device.SetTextureStageState(0, TextureStage.ColorArg2, TextureArgument.TFactor); device.SetTextureStageState(0, TextureStage.ResultArg, TextureArgument.Current); device.SetTextureStageState(0, TextureStage.TexCoordIndex, 0); @@ -164,7 +164,6 @@ namespace CodeImp.DoomBuilder.Rendering // First alpha stage device.SetTextureStageState(0, TextureStage.AlphaOperation, TextureOperation.SelectArg1); device.SetTextureStageState(0, TextureStage.AlphaArg1, TextureArgument.Texture); - device.SetTextureStageState(0, TextureStage.AlphaArg2, TextureArgument.TFactor); // No more further stages device.SetTextureStageState(1, TextureStage.AlphaOperation, TextureOperation.Disable); @@ -178,6 +177,10 @@ namespace CodeImp.DoomBuilder.Rendering // Get the viewport viewport = device.Viewport; + + // Setup shaders + if(shaders != null) shaders.Dispose(); + shaders = new ShaderManager(); } #endregion @@ -302,7 +305,7 @@ namespace CodeImp.DoomBuilder.Rendering // Unload all Direct3D resources foreach(ID3DResource res in resources) res.UnloadResource(); - + // Make present parameters displaypp = CreatePresentParameters(adapter); diff --git a/Source/Rendering/D3DShader.cs b/Source/Rendering/D3DShader.cs new file mode 100644 index 00000000..783cd72d --- /dev/null +++ b/Source/Rendering/D3DShader.cs @@ -0,0 +1,176 @@ + +#region ================== Copyright (c) 2007 Pascal vd Heiden + +/* + * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + * This program is released under GNU General Public License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#endregion + +#region ================== Namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using System.Windows.Forms; +using System.IO; +using System.Reflection; +using System.Drawing; +using System.ComponentModel; +using CodeImp.DoomBuilder.Map; +using SlimDX.Direct3D; +using SlimDX.Direct3D9; +using SlimDX; +using CodeImp.DoomBuilder.Geometry; +using System.Drawing.Imaging; + +#endregion + +namespace CodeImp.DoomBuilder.Rendering +{ + internal abstract class D3DShader : IDisposable + { + #region ================== Constants + + #endregion + + #region ================== Variables + + // The manager + protected ShaderManager manager; + + // The effect + protected Effect effect; + + // The vertex declaration + protected VertexDeclaration vertexdecl; + + // Disposing + protected bool isdisposed = false; + + #endregion + + #region ================== Properties + + // Disposing + public bool IsDisposed { get { return isdisposed; } } + + #endregion + + #region ================== Constructor / Disposer + + // Constructor + public D3DShader(ShaderManager manager) + { + // Initialize + this.manager = manager; + + // We have no destructor + GC.SuppressFinalize(this); + } + + // Diposer + public virtual void Dispose() + { + // Not already disposed? + if(!isdisposed) + { + // Clean up + manager = null; + if(effect != null) effect.Dispose(); + vertexdecl.Dispose(); + + // Done + isdisposed = true; + } + } + + #endregion + + #region ================== Methods + + // This loads an effect + protected Effect LoadEffect(string fxfile) + { + Effect fx; + string errors; + Stream fxdata; + byte[] alldata; + + // Return null when not using shaders + if(!manager.Enabled) return null; + + //try + { + // Load the resource + fxdata = General.ThisAssembly.GetManifestResourceStream("CodeImp.DoomBuilder.Resources." + fxfile); + alldata = new byte[(int)fxdata.Length]; + fxdata.Read(alldata, 0, (int)fxdata.Length); + + // Load effect from file + fx = Effect.FromMemory(General.Map.Graphics.Device, alldata, null, null, null, ShaderFlags.None, null, out errors); + if((errors != null) && (errors != "")) + { + throw new Exception("Errors in effect file " + Path.GetFileName(fxfile) + ": " + errors); + } + } + /* + catch(Exception e) + { + throw new Exception(e.GetType().Name + " while loading effect " + fxfile + ": " + e.Message); + } + */ + + // Set the technique to use + fx.Technique = manager.ShaderTechnique; + + // Return result + return fx; + } + + // This applies the shader + public void Begin() + { + // Set vertex declaration + General.Map.Graphics.Device.VertexDeclaration = vertexdecl; + + // Set effect + if(manager.Enabled) effect.Begin(FX.DoNotSaveState); + } + + // This begins a pass + public void BeginPass(int index) + { + if(manager.Enabled) effect.BeginPass(index); + } + + // This ends a pass + public void EndPass() + { + if(manager.Enabled) effect.EndPass(); + } + + // This ends te shader + public void End() + { + if(manager.Enabled) effect.End(); + } + + // This applies properties during a pass + public void ApplySettings() + { + if(manager.Enabled) effect.CommitChanges(); + } + + #endregion + } +} diff --git a/Source/Rendering/FlatVertex.cs b/Source/Rendering/FlatVertex.cs index 4a15369f..e8e0395c 100644 --- a/Source/Rendering/FlatVertex.cs +++ b/Source/Rendering/FlatVertex.cs @@ -11,8 +11,7 @@ namespace CodeImp.DoomBuilder.Rendering public struct FlatVertex { // Vertex format - public static readonly VertexFormat Format = VertexFormat.PositionRhw | VertexFormat.Texture1; - public static readonly int Stride = 6 * 4; + public static readonly int Stride = 7 * 4; // Members public float x; diff --git a/Source/Rendering/PTVertex.cs b/Source/Rendering/PTVertex.cs deleted file mode 100644 index 0a9c893e..00000000 --- a/Source/Rendering/PTVertex.cs +++ /dev/null @@ -1,50 +0,0 @@ - -#region ================== Copyright (c) 2007 Pascal vd Heiden - -/* - * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com - * This program is released under GNU General Public License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#endregion - -#region ================== Namespaces - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Globalization; -using System.Text; -using System.Windows.Forms; -using System.IO; -using System.Reflection; -using System.Drawing; -using SlimDX.Direct3D9; -using System.ComponentModel; - -#endregion - -namespace CodeImp.DoomBuilder.Rendering -{ - // PTVertex - public struct PTVertex - { - // Vertex format - public static readonly VertexFormat Format = VertexFormat.Position | VertexFormat.Diffuse | VertexFormat.Texture1; - public static readonly int Stride = 6 * 4; - - // Members - public float x; - public float y; - public float z; - public int c; - public float u; - public float v; - } -} diff --git a/Source/Rendering/Renderer2D.cs b/Source/Rendering/Renderer2D.cs index 325cf6a2..10197ee3 100644 --- a/Source/Rendering/Renderer2D.cs +++ b/Source/Rendering/Renderer2D.cs @@ -104,8 +104,6 @@ namespace CodeImp.DoomBuilder.Rendering // Start drawing if(graphics.StartRendering()) { - graphics.Device.VertexFormat = FlatVertex.Format; - // Left top verts[0].x = -0.5f; verts[0].y = -0.5f; @@ -134,11 +132,19 @@ namespace CodeImp.DoomBuilder.Rendering verts[3].u = 1f; verts[3].v = 1f; - // Draw + // Set renderstates AND shader settings graphics.Device.SetTexture(0, tex); graphics.Device.SetRenderState(RenderState.CullMode, Cull.None); + graphics.Shaders.Base2D.Texture1 = tex; + graphics.Shaders.Base2D.SetSettings(1f / pwidth, 1f / pheight, 0.3f); + + // Draw + graphics.Shaders.Base2D.Begin(); + graphics.Shaders.Base2D.BeginPass(0); try { graphics.Device.DrawUserPrimitives<FlatVertex>(PrimitiveType.TriangleStrip, 0, 2, verts); } catch(Exception) { } + graphics.Shaders.Base2D.EndPass(); + graphics.Shaders.Base2D.End(); // Done graphics.FinishRendering(); diff --git a/Source/Rendering/ShaderManager.cs b/Source/Rendering/ShaderManager.cs new file mode 100644 index 00000000..0c9fded0 --- /dev/null +++ b/Source/Rendering/ShaderManager.cs @@ -0,0 +1,104 @@ + +#region ================== Copyright (c) 2007 Pascal vd Heiden + +/* + * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + * This program is released under GNU General Public License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#endregion + +#region ================== Namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using System.Windows.Forms; +using System.IO; +using System.Reflection; +using System.Drawing; +using System.ComponentModel; +using CodeImp.DoomBuilder.Map; +using SlimDX.Direct3D; +using SlimDX.Direct3D9; +using SlimDX; +using CodeImp.DoomBuilder.Geometry; +using System.Drawing.Imaging; + +#endregion + +namespace CodeImp.DoomBuilder.Rendering +{ + internal class ShaderManager : IDisposable + { + #region ================== Constants + + #endregion + + #region ================== Variables + + // Settings + private string shadertechnique; + private bool useshaders; + + // Shaders + private Base2DShader base2dshader; + + // Disposing + private bool isdisposed = false; + + #endregion + + #region ================== Properties + + public bool Enabled { get { return useshaders; } } + public string ShaderTechnique { get { return shadertechnique; } } + public Base2DShader Base2D { get { return base2dshader; } } + public bool IsDisposed { get { return isdisposed; } } + + #endregion + + #region ================== Constructor / Disposer + + // Constructor + public ShaderManager() + { + Capabilities caps; + + // Check if we can use shaders + caps = General.Map.Graphics.Device.GetDeviceCaps(); + useshaders = (caps.PixelShaderVersion.Major >= 2); + shadertechnique = "SM20"; + + // Initialize effects + base2dshader = new Base2DShader(this); + + // We have no destructor + GC.SuppressFinalize(this); + } + + // Diposer + public void Dispose() + { + // Not already disposed? + if(!isdisposed) + { + // Clean up + base2dshader.Dispose(); + + // Done + isdisposed = true; + } + } + + #endregion + } +} diff --git a/Source/Resources/base2d.fx b/Source/Resources/base2d.fx new file mode 100644 index 00000000..7be57874 --- /dev/null +++ b/Source/Resources/base2d.fx @@ -0,0 +1,69 @@ +// Base 2D rendering shader +// Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + +// Pixel input data +struct PixelData +{ + float4 pos : POSITION; + float2 uv : TEXCOORD0; +}; + +// Settings +// x = texel width +// y = texel height +// z = blend factor +float4 settings; + +// Texture1 input +texture texture1 +< + string UIName = "Texture1"; + string ResourceType = "2D"; +>; + +// Texture sampler settings +sampler2D texture1samp = sampler_state +{ + Texture = <texture1>; + MagFilter = Linear; + MinFilter = Linear; + MipFilter = Linear; + AddressU = Wrap; + AddressV = Wrap; +}; + +// This blends the max of 2 pixels +float4 addcolor(float4 c1, float4 c2) +{ + return float4(max(c1.r, c2.r), + max(c1.g, c2.g), + max(c1.b, c2.b), + max(c1.a, c2.a)); +} + +// Pixel shader +float4 ps20_main(PixelData pd) : COLOR +{ + float4 c = tex2D(texture1samp, pd.uv); + float4 neightbourblend = + tex2D(texture1samp, float2(pd.uv.x + settings.x, pd.uv.y)) * settings.z + + tex2D(texture1samp, float2(pd.uv.x - settings.x, pd.uv.y)) * settings.z + + tex2D(texture1samp, float2(pd.uv.x, pd.uv.y + settings.y)) * settings.z + + tex2D(texture1samp, float2(pd.uv.x, pd.uv.y - settings.y)) * settings.z; + return lerp(neightbourblend, c, c.a); +} + +// Technique for shader model 2.0 +technique SM20 +{ + pass p0 + { + VertexShader = null; + PixelShader = compile ps_2_0 ps20_main(); + CullMode = None; + ZEnable = false; + AlphaBlendEnable = true; + SrcBlend = SrcAlpha; + DestBlend = InvSrcAlpha; + } +}