diff --git a/OpenRa.Gl/GraphicsDevice.cs b/OpenRa.Gl/GraphicsDevice.cs index d76ce2cfd8..78c9359d91 100644 --- a/OpenRa.Gl/GraphicsDevice.cs +++ b/OpenRa.Gl/GraphicsDevice.cs @@ -16,6 +16,7 @@ namespace OpenRa.GlRenderer Graphics g; public IntPtr dc; public IntPtr rc; + public IntPtr cgContext; public static void CheckGlError() { @@ -46,6 +47,18 @@ namespace OpenRa.GlRenderer if (rc == IntPtr.Zero) throw new InvalidOperationException("can't create wglcontext"); Wgl.wglMakeCurrent(dc, rc); + + cgContext = Cg.cgCreateContext(); + //Cg.cgSetErrorCallback(CgErrorCallback); + CgGl.cgGLRegisterStates(cgContext); + } + + void CgErrorCallback() + { + var err = Cg.cgGetError(); + var str = Cg.cgGetErrorString(err); + throw new InvalidOperationException( + string.Format("CG Error: {0}: {1}", err, str)); } public void EnableScissor(int left, int top, int width, int height) @@ -168,13 +181,40 @@ namespace OpenRa.GlRenderer public class Shader { - public Shader(GraphicsDevice dev, Stream s) { } + IntPtr effect; + IntPtr highTechnique; + IntPtr lowTechnique; + + public Shader(GraphicsDevice dev, Stream s) + { + var code = new StreamReader(s).ReadToEnd(); + effect = Cg.cgCreateEffect(dev.cgContext, code, null); + + if (effect == IntPtr.Zero) + { + var err = Cg.cgGetErrorString(Cg.cgGetError()); + var results = Cg.cgGetLastListing(dev.cgContext); + throw new InvalidOperationException( + string.Format("Cg compile failed ({0}):\n{1}", err, results)); + } + + lowTechnique = Cg.cgGetNamedTechnique(effect, "low_quality"); + highTechnique = Cg.cgGetNamedTechnique(effect, "high_quality"); + + if (lowTechnique != IntPtr.Zero && 0 == Cg.cgValidateTechnique(lowTechnique)) + lowTechnique = IntPtr.Zero; + if (highTechnique != IntPtr.Zero && 0 == Cg.cgValidateTechnique(highTechnique)) + highTechnique = IntPtr.Zero; + + if (highTechnique == IntPtr.Zero && lowTechnique == IntPtr.Zero) + throw new InvalidOperationException("No valid techniques"); + } + public ShaderQuality Quality { get; set; } public void Render(Action a) { } public void SetValue(string param, Texture texture) { } public void SetValue(string param, T t) where T : struct { } public void Commit() { } - } public class Texture @@ -210,6 +250,11 @@ namespace OpenRa.GlRenderer [Flags] public enum VertexFormat { Position, Texture2 } - public enum ShaderQuality { Low, Medium, High } - public enum PrimitiveType { PointList, LineList, TriangleList } + public enum ShaderQuality { Low, High } + public enum PrimitiveType + { + PointList = Gl.GL_POINTS, + LineList = Gl.GL_LINES, + TriangleList = Gl.GL_TRIANGLES + } } diff --git a/line.fx b/line.fx index 2815387772..f4a7451379 100644 --- a/line.fx +++ b/line.fx @@ -2,14 +2,13 @@ // Author: C. Forbes //-------------------------------------------------------- -shared float2 Scroll; +float2 Scroll; -shared float2 r1, r2; // matrix elements +float2 r1, r2; // matrix elements struct VertexIn { float4 Position: POSITION; - float2 RG: TEXCOORD0; - float2 BA: TEXCOORD1; + float4 Color: TEXCOORD0; }; struct VertexOut { @@ -17,37 +16,28 @@ struct VertexOut { float4 Color: COLOR0; }; -struct FragmentIn { - float4 Color: COLOR0; -}; - VertexOut Simple_vp(VertexIn v) { VertexOut o; float2 p = (v.Position.xy - Scroll.xy) * r1 + r2; o.Position = float4(p.x,p.y,0,1); - o.Color.rg = v.RG.xy; - o.Color.ba = v.BA.xy; -// o.Color.a = 1.0f; + o.Color = v.Color; return o; } -const float2 texelOffset = float2( 0, 1.0f/32.0f ); - -float4 Simple_fp(FragmentIn f) : COLOR0 { +float4 Simple_fp(VertexOut f) : COLOR0 { return f.Color; } technique high_quality { pass p0 { - AlphaBlendEnable = true; - ZWriteEnable = false; - ZEnable = false; - CullMode = None; - FillMode = Wireframe; - VertexShader = compile vs_2_0 Simple_vp(); - PixelShader = compile ps_2_0 Simple_fp(); + BlendEnable = true; + DepthTestEnable = false; + //CullMode = None; + //FillMode = Wireframe; + VertexProgram = compile arbvp1 Simple_vp(); + FragmentProgram = compile arbfp1 Simple_fp(); - SrcBlend = SrcAlpha; - DestBlend = InvSrcAlpha; + //SrcBlend = SrcAlpha; + //DestBlend = InvSrcAlpha; } } diff --git a/world-shp.fx b/world-shp.fx index c11e8b88df..5aee4721c5 100644 --- a/world-shp.fx +++ b/world-shp.fx @@ -2,36 +2,26 @@ // Author: C. Forbes //-------------------------------------------------------- -shared texture DiffuseTexture, Palette; -shared float2 Scroll; +float2 Scroll; +float2 r1, r2; // matrix elements -shared float2 r1, r2; // matrix elements - -sampler s_DiffuseTexture = sampler_state { - Texture = ; - MinFilter = None; - MagFilter = None; - MipFilter = None; - - AddressU = Wrap; - AddressV = Wrap; - AddressW = Wrap; +sampler2D DiffuseTexture = sampler_state { + MinFilter = Nearest; + MagFilter = Nearest; + WrapS = Repeat; + WrapT = Repeat; }; -sampler s_PaletteTexture = sampler_state { - Texture = ; - MinFilter = None; - MagFilter = None; - MipFilter = None; - - AddressU = Clamp; - AddressV = Clamp; +sampler2D Palette = sampler_state { + MinFilter = Nearest; + MagFilter = Nearest; + WrapS = Repeat; + WrapT = Repeat; }; struct VertexIn { float4 Position: POSITION; - float2 Tex0: TEXCOORD0; - float2 Tex1: TEXCOORD1; + float4 Tex0: TEXCOORD0; }; struct VertexOut { @@ -40,11 +30,6 @@ struct VertexOut { float4 ChannelMask: TEXCOORD1; }; -struct FragmentIn { - float3 Tex0: TEXCOORD0; - float4 ChannelMask: TEXCOORD1; -}; - float4 DecodeChannelMask( float x ) { if (x > 0) @@ -55,45 +40,27 @@ float4 DecodeChannelMask( float x ) VertexOut Simple_vp(VertexIn v) { VertexOut o; - float2 p = (v.Position.xy - Scroll.xy) * r1 + r2; o.Position = float4(p.x,p.y,0,1); - o.Tex0 = float3(v.Tex0.x, v.Tex0.y, v.Tex1.x); - o.ChannelMask = DecodeChannelMask( v.Tex1.y ); + o.Tex0 = float3(v.Tex0.x, v.Tex0.y, v.Tex0.z); + o.ChannelMask = DecodeChannelMask( v.Tex0.w ); return o; } const float2 texelOffset = float2( 0, 1.0f/32.0f ); -float4 Palette_fp(FragmentIn f) : COLOR0 { - float4 x = tex2D(s_DiffuseTexture, f.Tex0.xy); +float4 Palette_fp(VertexOut f) : COLOR0 { + float4 x = tex2D(DiffuseTexture, f.Tex0.xy); float2 p = float2( dot(x, f.ChannelMask), f.Tex0.z ); - return tex2D(s_PaletteTexture, p + texelOffset); + return tex2D(Palette, p + texelOffset); } technique low_quality { pass p0 { - AlphaBlendEnable = false; - ZWriteEnable = false; - ZEnable = false; - CullMode = None; - FillMode = Solid; - VertexShader = compile vs_2_0 Simple_vp(); - PixelShader = compile ps_2_0 Palette_fp(); - } -} - -technique high_quality { - pass p0 { - AlphaBlendEnable = true; - ZWriteEnable = false; - ZEnable = false; - CullMode = None; - FillMode = Solid; - VertexShader = compile vs_2_0 Simple_vp(); - PixelShader = compile ps_2_0 Palette_fp(); - - SrcBlend = SrcAlpha; - DestBlend = InvSrcAlpha; + BlendEnable = false; + DepthTestEnable = false; + CullFaceEnable = false; + VertexProgram = compile arbvp1 Simple_vp(); + FragmentProgram = compile arbfp1 Palette_fp(); } }