diff --git a/OpenRA.FileFormats/Graphics/IGraphicsDevice.cs b/OpenRA.FileFormats/Graphics/IGraphicsDevice.cs index 36b228b58f..12231dadca 100755 --- a/OpenRA.FileFormats/Graphics/IGraphicsDevice.cs +++ b/OpenRA.FileFormats/Graphics/IGraphicsDevice.cs @@ -40,7 +40,6 @@ namespace OpenRA.FileFormats.Graphics IShader CreateShader( string name ); Size WindowSize { get; } - int GpuMemoryUsed { get; } void Clear(); void Present(); @@ -61,9 +60,9 @@ namespace OpenRA.FileFormats.Graphics public interface IShader { - void SetValue( string name, float x, float y ); - void SetValue( string param, ITexture texture ); - void Render( Action a ); + void SetVec(string name, float x, float y); + void SetTexture(string param, ITexture texture); + void Render(Action a); } public interface ITexture diff --git a/OpenRA.Game/Graphics/LineRenderer.cs b/OpenRA.Game/Graphics/LineRenderer.cs index a3ede4fa10..63baa7cde5 100644 --- a/OpenRA.Game/Graphics/LineRenderer.cs +++ b/OpenRA.Game/Graphics/LineRenderer.cs @@ -77,5 +77,12 @@ namespace OpenRA.Graphics for (float y = r.Top; y < r.Bottom; y++) DrawLine(new float2(r.Left, y), new float2(r.Right, y), color, color); } + + public void SetShaderParams(ITexture palette, Size screen, float zoom, float2 scroll) + { + shader.SetVec("Scroll", (int)scroll.X, (int)scroll.Y); + shader.SetVec("r1", zoom*2f/screen.Width, -zoom*2f/screen.Height); + shader.SetVec("r2", -1, 1); + } } } diff --git a/OpenRA.Game/Graphics/Renderer.cs b/OpenRA.Game/Graphics/Renderer.cs index e354698882..8be5040802 100644 --- a/OpenRA.Game/Graphics/Renderer.cs +++ b/OpenRA.Game/Graphics/Renderer.cs @@ -26,11 +26,6 @@ namespace OpenRA.Graphics internal static int SheetSize; internal static int TempBufferSize; internal static int TempBufferCount; - internal IShader WorldSpriteShader { get; private set; } - internal IShader WorldLineShader { get; private set; } - internal IShader LineShader { get; private set; } - internal IShader RgbaSpriteShader { get; private set; } - internal IShader SpriteShader { get; private set; } public SpriteRenderer WorldSpriteRenderer { get; private set; } public LineRenderer WorldLineRenderer { get; private set; } @@ -50,17 +45,11 @@ namespace OpenRA.Graphics TempBufferCount = Game.Settings.Graphics.NumTempBuffers; SheetSize = Game.Settings.Graphics.SheetSize; - WorldSpriteShader = device.CreateShader("shp"); - WorldLineShader = device.CreateShader("line"); - LineShader = device.CreateShader("line"); - RgbaSpriteShader = device.CreateShader("rgba"); - SpriteShader = device.CreateShader("shp"); - - WorldSpriteRenderer = new SpriteRenderer(this, WorldSpriteShader); - WorldLineRenderer = new LineRenderer(this, WorldLineShader); - LineRenderer = new LineRenderer(this, LineShader); - RgbaSpriteRenderer = new SpriteRenderer(this, RgbaSpriteShader); - SpriteRenderer = new SpriteRenderer(this, SpriteShader); + WorldSpriteRenderer = new SpriteRenderer(this, device.CreateShader("shp")); + WorldLineRenderer = new LineRenderer(this, device.CreateShader("line")); + LineRenderer = new LineRenderer(this, device.CreateShader("line")); + RgbaSpriteRenderer = new SpriteRenderer(this, device.CreateShader("rgba")); + SpriteRenderer = new SpriteRenderer(this, device.CreateShader("shp")); for (int i = 0; i < TempBufferCount; i++) tempBuffers.Enqueue(device.CreateVertexBuffer(TempBufferSize)); @@ -76,23 +65,11 @@ namespace OpenRA.Graphics public void BeginFrame(float2 scroll, float zoom) { device.Clear(); - float2 r1 = new float2(2f/Resolution.Width, -2f/Resolution.Height); - float2 r2 = new float2(-1, 1); - var zr1 = zoom*r1; - - SetShaderParams(WorldSpriteShader, zr1, r2, scroll); - SetShaderParams(WorldLineShader, zr1, r2, scroll); - SetShaderParams(LineShader, r1, r2, float2.Zero); - SetShaderParams(RgbaSpriteShader, r1, r2, float2.Zero); - SetShaderParams(SpriteShader, r1, r2, float2.Zero); - } - - void SetShaderParams(IShader s, float2 r1, float2 r2, float2 scroll) - { - s.SetValue("Palette", PaletteTexture); - s.SetValue("Scroll", (int)scroll.X, (int)scroll.Y); - s.SetValue("r1", r1.X, r1.Y); - s.SetValue("r2", r2.X, r2.Y); + WorldSpriteRenderer.SetShaderParams(PaletteTexture, Resolution, zoom, scroll); + WorldLineRenderer.SetShaderParams(PaletteTexture, Resolution, zoom, scroll); + SpriteRenderer.SetShaderParams(PaletteTexture, Resolution, 1f, float2.Zero); + LineRenderer.SetShaderParams(PaletteTexture, Resolution, 1f, float2.Zero); + RgbaSpriteRenderer.SetShaderParams(PaletteTexture, Resolution, 1f, float2.Zero); } public void EndFrame(IInputHandler inputHandler) diff --git a/OpenRA.Game/Graphics/SpriteRenderer.cs b/OpenRA.Game/Graphics/SpriteRenderer.cs index b1bba04e3a..5140c2a99a 100644 --- a/OpenRA.Game/Graphics/SpriteRenderer.cs +++ b/OpenRA.Game/Graphics/SpriteRenderer.cs @@ -8,6 +8,7 @@ */ #endregion +using System.Drawing; using OpenRA.FileFormats.Graphics; namespace OpenRA.Graphics @@ -27,14 +28,11 @@ namespace OpenRA.Graphics this.shader = shader; } - public SpriteRenderer(Renderer renderer) - : this(renderer, renderer.SpriteShader) { } - public void Flush() { if (nv > 0) { - shader.SetValue( "DiffuseTexture", currentSheet.Texture ); + shader.SetTexture("DiffuseTexture", currentSheet.Texture); shader.Render(() => { var vb = renderer.GetTempVertexBuffer(); @@ -72,7 +70,6 @@ namespace OpenRA.Graphics nv += 4; } - // For RGBASpriteRenderer, which doesn't use palettes public void DrawSprite(Sprite s, float2 location) { @@ -83,5 +80,19 @@ namespace OpenRA.Graphics { DrawSprite(s, location, 0, size); } + + public void DrawVertexBuffer(IVertexBuffer buffer, int start, int length, PrimitiveType type, Sheet sheet) + { + shader.SetTexture("DiffuseTexture", sheet.Texture); + shader.Render(() => renderer.DrawBatch(buffer, start, length, type)); + } + + public void SetShaderParams(ITexture palette, Size screen, float zoom, float2 scroll) + { + shader.SetTexture("Palette", palette); + shader.SetVec("Scroll", (int)scroll.X, (int)scroll.Y); + shader.SetVec("r1", zoom*2f/screen.Width, -zoom*2f/screen.Height); + shader.SetVec("r2", -1, 1); + } } } diff --git a/OpenRA.Game/Graphics/TerrainRenderer.cs b/OpenRA.Game/Graphics/TerrainRenderer.cs index 317820217a..7ead56a88b 100644 --- a/OpenRA.Game/Graphics/TerrainRenderer.cs +++ b/OpenRA.Game/Graphics/TerrainRenderer.cs @@ -84,11 +84,9 @@ namespace OpenRA.Graphics if( lastRow < firstRow ) lastRow = firstRow; - Game.Renderer.WorldSpriteShader.SetValue( "DiffuseTexture", terrainSheet.Texture ); - Game.Renderer.WorldSpriteShader.Render(() => - Game.Renderer.DrawBatch(vertexBuffer, - verticesPerRow * firstRow, verticesPerRow * (lastRow - firstRow), - PrimitiveType.QuadList)); + Game.Renderer.WorldSpriteRenderer.DrawVertexBuffer( + vertexBuffer, verticesPerRow * firstRow, verticesPerRow * (lastRow - firstRow), + PrimitiveType.QuadList, terrainSheet); foreach (var r in world.WorldActor.TraitsImplementing()) r.Render( wr ); diff --git a/OpenRA.Renderer.Cg/GraphicsDevice.cs b/OpenRA.Renderer.Cg/GraphicsDevice.cs index b0e6153679..0ac9a1dff2 100755 --- a/OpenRA.Renderer.Cg/GraphicsDevice.cs +++ b/OpenRA.Renderer.Cg/GraphicsDevice.cs @@ -24,21 +24,23 @@ namespace OpenRA.Renderer.Cg { public IGraphicsDevice Create(Size size, WindowMode windowMode) { + Console.WriteLine("Using Cg renderer"); return new GraphicsDevice(size, windowMode); } } - public class GraphicsDevice : IGraphicsDevice + public class GraphicsDevice : SdlGraphics { - Size windowSize; + static string[] RequiredExtensions = + { + "GL_ARB_vertex_program", + "GL_ARB_fragment_program", + "GL_ARB_vertex_buffer_object" + }; + internal IntPtr cgContext; internal int vertexProfile, fragmentProfile; - IntPtr surf; - SdlInput input; - - public Size WindowSize { get { return windowSize; } } - static Tao.Cg.Cg.CGerrorCallbackFuncDelegate CgErrorCallback = () => { var err = Tao.Cg.Cg.cgGetError(); @@ -48,19 +50,8 @@ namespace OpenRA.Renderer.Cg }; public GraphicsDevice(Size size, WindowMode window) + : base(size, window, RequiredExtensions) { - Console.WriteLine("Using Cg renderer"); - windowSize = size; - - var extensions = new [] - { - "GL_ARB_vertex_program", - "GL_ARB_fragment_program", - "GL_ARB_vertex_buffer_object", - }; - - surf = SdlGraphics.InitializeSdlGl(ref windowSize, window, extensions); - cgContext = Tao.Cg.Cg.cgCreateContext(); Tao.Cg.Cg.cgSetErrorCallback(CgErrorCallback); @@ -69,54 +60,8 @@ namespace OpenRA.Renderer.Cg Tao.Cg.CgGl.cgGLSetManageTextureParameters(cgContext, true); vertexProfile = CgGl.cgGLGetLatestProfile(CgGl.CG_GL_VERTEX); fragmentProfile = CgGl.cgGLGetLatestProfile(CgGl.CG_GL_FRAGMENT); - - Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY); - ErrorHandler.CheckGlError(); - Gl.glEnableClientState(Gl.GL_TEXTURE_COORD_ARRAY); - ErrorHandler.CheckGlError(); - - Sdl.SDL_SetModState(0); // i have had enough. - - input = new SdlInput(surf); } - public void EnableScissor(int left, int top, int width, int height) - { - if (width < 0) width = 0; - if (height < 0) height = 0; - - Gl.glScissor(left, windowSize.Height - ( top + height ), width, height); - ErrorHandler.CheckGlError(); - Gl.glEnable(Gl.GL_SCISSOR_TEST); - ErrorHandler.CheckGlError(); - } - - public void DisableScissor() - { - Gl.glDisable(Gl.GL_SCISSOR_TEST); - ErrorHandler.CheckGlError(); - } - - public void Clear() { SdlGraphics.Clear(); } - public void Present() { Sdl.SDL_GL_SwapBuffers(); } - public void PumpInput(IInputHandler inputHandler) { input.PumpInput(inputHandler); } - - public void DrawPrimitives(PrimitiveType pt, int firstVertex, int numVertices) - { - SdlGraphics.DrawPrimitives(pt, firstVertex, numVertices); - } - - public void SetLineWidth(float width) - { - Gl.glLineWidth(width); - ErrorHandler.CheckGlError(); - } - - public IVertexBuffer CreateVertexBuffer(int size) { return new VertexBuffer(size); } - public ITexture CreateTexture() { return new Texture(); } - public ITexture CreateTexture(Bitmap bitmap) { return new Texture(bitmap); } - public IShader CreateShader(string name) { return new Shader(this, name); } - - public int GpuMemoryUsed { get { return 0; } } + public override IShader CreateShader(string name) { return new Shader(this, name); } } } diff --git a/OpenRA.Renderer.Cg/Shader.cs b/OpenRA.Renderer.Cg/Shader.cs index 22173a144e..59aac51084 100644 --- a/OpenRA.Renderer.Cg/Shader.cs +++ b/OpenRA.Renderer.Cg/Shader.cs @@ -67,7 +67,7 @@ namespace OpenRA.Renderer.Cg Tao.Cg.CgGl.cgGLDisableProfile(dev.vertexProfile); } - public void SetValue(string name, ITexture t) + public void SetTexture(string name, ITexture t) { var texture = (Texture)t; var param = Tao.Cg.Cg.cgGetNamedEffectParameter(effect, name); @@ -75,7 +75,7 @@ namespace OpenRA.Renderer.Cg Tao.Cg.CgGl.cgGLSetupSampler(param, texture.texture); } - public void SetValue(string name, float x, float y) + public void SetVec(string name, float x, float y) { var param = Tao.Cg.Cg.cgGetNamedEffectParameter(effect, name); if (param != IntPtr.Zero) diff --git a/OpenRA.Renderer.Gl/GraphicsDevice.cs b/OpenRA.Renderer.Gl/GraphicsDevice.cs index 5728ddc123..b9a091bac8 100755 --- a/OpenRA.Renderer.Gl/GraphicsDevice.cs +++ b/OpenRA.Renderer.Gl/GraphicsDevice.cs @@ -23,79 +23,23 @@ namespace OpenRA.Renderer.Glsl { public IGraphicsDevice Create(Size size, WindowMode windowMode) { + Console.WriteLine("Using Gl renderer"); return new GraphicsDevice(size, windowMode); } } - public class GraphicsDevice : IGraphicsDevice + public class GraphicsDevice : SdlGraphics { - Size windowSize; - IntPtr surf; - SdlInput input; - - public Size WindowSize { get { return windowSize; } } + static string[] RequiredExtensions = + { + "GL_ARB_vertex_shader", + "GL_ARB_fragment_shader", + "GL_ARB_vertex_buffer_object" + }; public GraphicsDevice(Size size, WindowMode window) - { - Console.WriteLine("Using Gl renderer"); - windowSize = size; + : base(size, window, RequiredExtensions) {} - var extensions = new [] - { - "GL_ARB_vertex_shader", - "GL_ARB_fragment_shader", - "GL_ARB_vertex_buffer_object", - }; - - surf = SdlGraphics.InitializeSdlGl(ref windowSize, window, extensions); - - Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY); - ErrorHandler.CheckGlError(); - Gl.glEnableClientState(Gl.GL_TEXTURE_COORD_ARRAY); - ErrorHandler.CheckGlError(); - - Sdl.SDL_SetModState(0); - - input = new SdlInput(surf); - } - - public void EnableScissor(int left, int top, int width, int height) - { - if (width < 0) width = 0; - if (height < 0) height = 0; - - Gl.glScissor(left, windowSize.Height - ( top + height ), width, height); - ErrorHandler.CheckGlError(); - Gl.glEnable(Gl.GL_SCISSOR_TEST); - ErrorHandler.CheckGlError(); - } - - public void DisableScissor() - { - Gl.glDisable(Gl.GL_SCISSOR_TEST); - ErrorHandler.CheckGlError(); - } - - public void Clear() { SdlGraphics.Clear(); } - public void Present() { Sdl.SDL_GL_SwapBuffers(); } - public void PumpInput(IInputHandler inputHandler) { input.PumpInput(inputHandler); } - - public void DrawPrimitives(PrimitiveType pt, int firstVertex, int numVertices) - { - SdlGraphics.DrawPrimitives(pt, firstVertex, numVertices); - } - - public void SetLineWidth( float width ) - { - Gl.glLineWidth(width); - ErrorHandler.CheckGlError(); - } - - public IVertexBuffer CreateVertexBuffer( int size ) { return new VertexBuffer( size ); } - public ITexture CreateTexture() { return new Texture(); } - public ITexture CreateTexture( Bitmap bitmap ) { return new Texture( bitmap ); } - public IShader CreateShader( string name ) { return new Shader( this, name ); } - - public int GpuMemoryUsed { get; internal set; } + public override IShader CreateShader(string name) { return new Shader( this, name ); } } } diff --git a/OpenRA.Renderer.Gl/Shader.cs b/OpenRA.Renderer.Gl/Shader.cs index 8f39d77aac..f4731d0074 100644 --- a/OpenRA.Renderer.Gl/Shader.cs +++ b/OpenRA.Renderer.Gl/Shader.cs @@ -132,15 +132,16 @@ namespace OpenRA.Renderer.Glsl ErrorHandler.CheckGlError(); } - public void SetValue(string name, ITexture t) + public void SetTexture(string name, ITexture t) { - if( t == null ) return; + if (t == null) + return; int texUnit; - if( samplers.TryGetValue( name, out texUnit ) ) + if (samplers.TryGetValue(name, out texUnit)) textures[texUnit] = t; } - public void SetValue(string name, float x, float y) + public void SetVec(string name, float x, float y) { Gl.glUseProgramObjectARB(program); ErrorHandler.CheckGlError(); diff --git a/OpenRA.Renderer.Null/NullGraphicsDevice.cs b/OpenRA.Renderer.Null/NullGraphicsDevice.cs index 63d86b9657..742ac7f6b9 100644 --- a/OpenRA.Renderer.Null/NullGraphicsDevice.cs +++ b/OpenRA.Renderer.Null/NullGraphicsDevice.cs @@ -54,14 +54,12 @@ namespace OpenRA.Renderer.Null public ITexture CreateTexture() { return new NullTexture(); } public ITexture CreateTexture(Bitmap bitmap) { return new NullTexture(); } public IShader CreateShader(string name) { return new NullShader(); } - - public int GpuMemoryUsed { get { return 0; } } } public class NullShader : IShader { - public void SetValue(string name, float x, float y) { } - public void SetValue(string param, ITexture texture) { } + public void SetVec(string name, float x, float y) { } + public void SetTexture(string param, ITexture texture) { } public void Commit() { } public void Render(Action a) { } } diff --git a/OpenRA.Renderer.SdlCommon/SdlGraphics.cs b/OpenRA.Renderer.SdlCommon/SdlGraphics.cs index fdccf07e2d..e274c54a78 100644 --- a/OpenRA.Renderer.SdlCommon/SdlGraphics.cs +++ b/OpenRA.Renderer.SdlCommon/SdlGraphics.cs @@ -18,9 +18,30 @@ using Tao.Sdl; namespace OpenRA.Renderer.SdlCommon { - public static class SdlGraphics + public abstract class SdlGraphics : IGraphicsDevice { - public static IntPtr InitializeSdlGl( ref Size size, WindowMode window, string[] requiredExtensions ) + Size windowSize; + IntPtr surf; + SdlInput input; + + public Size WindowSize { get { return windowSize; } } + + public SdlGraphics(Size size, WindowMode window, string[] extensions) + { + windowSize = size; + surf = InitializeSdlGl(ref windowSize, window, extensions); + + Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY); + ErrorHandler.CheckGlError(); + Gl.glEnableClientState(Gl.GL_TEXTURE_COORD_ARRAY); + ErrorHandler.CheckGlError(); + + Sdl.SDL_SetModState(0); + + input = new SdlInput(surf); + } + + IntPtr InitializeSdlGl(ref Size size, WindowMode window, string[] requiredExtensions) { Sdl.SDL_Init( Sdl.SDL_INIT_NOPARACHUTE | Sdl.SDL_INIT_VIDEO ); Sdl.SDL_GL_SetAttribute( Sdl.SDL_GL_DOUBLEBUFFER, 1 ); @@ -30,7 +51,7 @@ namespace OpenRA.Renderer.SdlCommon Sdl.SDL_GL_SetAttribute( Sdl.SDL_GL_ALPHA_SIZE, 0 ); int windowFlags = 0; - switch( window ) + switch (window) { case WindowMode.Fullscreen: windowFlags |= Sdl.SDL_FULLSCREEN; @@ -59,14 +80,14 @@ namespace OpenRA.Renderer.SdlCommon Console.WriteLine("Using resolution: {0}x{1}", size.Width, size.Height); - var surf = Sdl.SDL_SetVideoMode( size.Width, size.Height, 0, Sdl.SDL_OPENGL | windowFlags ); + var surf = Sdl.SDL_SetVideoMode(size.Width, size.Height, 0, Sdl.SDL_OPENGL | windowFlags); if (surf == IntPtr.Zero) Console.WriteLine("Failed to set video mode."); - Sdl.SDL_WM_SetCaption( "OpenRA", "OpenRA" ); - Sdl.SDL_ShowCursor( 0 ); - Sdl.SDL_EnableUNICODE( 1 ); - Sdl.SDL_EnableKeyRepeat( Sdl.SDL_DEFAULT_REPEAT_DELAY, Sdl.SDL_DEFAULT_REPEAT_INTERVAL ); + Sdl.SDL_WM_SetCaption("OpenRA", "OpenRA"); + Sdl.SDL_ShowCursor(0); + Sdl.SDL_EnableUNICODE(1); + Sdl.SDL_EnableKeyRepeat(Sdl.SDL_DEFAULT_REPEAT_DELAY, Sdl.SDL_DEFAULT_REPEAT_INTERVAL); ErrorHandler.CheckGlError(); @@ -86,7 +107,7 @@ namespace OpenRA.Renderer.SdlCommon return surf; } - static int ModeFromPrimitiveType(PrimitiveType pt) + int ModeFromPrimitiveType(PrimitiveType pt) { switch(pt) { @@ -98,19 +119,49 @@ namespace OpenRA.Renderer.SdlCommon throw new NotImplementedException(); } - public static void DrawPrimitives(PrimitiveType pt, int firstVertex, int numVertices) + public void DrawPrimitives(PrimitiveType pt, int firstVertex, int numVertices) { Gl.glDrawArrays(ModeFromPrimitiveType(pt), firstVertex, numVertices); ErrorHandler.CheckGlError(); } - public static void Clear() + public void Clear() { Gl.glClearColor(0, 0, 0, 0); ErrorHandler.CheckGlError(); Gl.glClear(Gl.GL_COLOR_BUFFER_BIT); ErrorHandler.CheckGlError(); } + + public void EnableScissor(int left, int top, int width, int height) + { + if (width < 0) width = 0; + if (height < 0) height = 0; + + Gl.glScissor(left, windowSize.Height - (top + height), width, height); + ErrorHandler.CheckGlError(); + Gl.glEnable(Gl.GL_SCISSOR_TEST); + ErrorHandler.CheckGlError(); + } + + public void DisableScissor() + { + Gl.glDisable(Gl.GL_SCISSOR_TEST); + ErrorHandler.CheckGlError(); + } + + public void SetLineWidth(float width) + { + Gl.glLineWidth(width); + ErrorHandler.CheckGlError(); + } + + public void Present() { Sdl.SDL_GL_SwapBuffers(); } + public void PumpInput(IInputHandler inputHandler) { input.PumpInput(inputHandler); } + public IVertexBuffer CreateVertexBuffer(int size) { return new VertexBuffer(size); } + public ITexture CreateTexture() { return new Texture(); } + public ITexture CreateTexture(Bitmap bitmap) { return new Texture(bitmap); } + public abstract IShader CreateShader(string name); } }