diff --git a/OpenRA.Renderer.Cg/GraphicsDevice.cs b/OpenRA.Renderer.Cg/GraphicsDevice.cs index 3088ece268..ff7673de06 100755 --- a/OpenRA.Renderer.Cg/GraphicsDevice.cs +++ b/OpenRA.Renderer.Cg/GraphicsDevice.cs @@ -14,6 +14,7 @@ using System.IO; using System.Linq; using System.Runtime.InteropServices; using OpenRA.FileFormats.Graphics; +using OpenRA.Renderer.SdlCommon; using Tao.Cg; using Tao.OpenGl; using Tao.Sdl; @@ -40,48 +41,11 @@ namespace OpenRA.Renderer.Cg public Size WindowSize { get { return windowSize; } } - public enum GlError - { - GL_NO_ERROR = Gl.GL_NO_ERROR, - GL_INVALID_ENUM = Gl.GL_INVALID_ENUM, - GL_INVALID_VALUE = Gl.GL_INVALID_VALUE, - GL_STACK_OVERFLOW = Gl.GL_STACK_OVERFLOW, - GL_STACK_UNDERFLOW = Gl.GL_STACK_UNDERFLOW, - GL_OUT_OF_MEMORY = Gl.GL_OUT_OF_MEMORY, - GL_TABLE_TOO_LARGE = Gl.GL_TABLE_TOO_LARGE, - GL_INVALID_OPERATION = Gl.GL_INVALID_OPERATION, - } - - internal static void CheckGlError() - { - var n = Gl.glGetError(); - if( n != Gl.GL_NO_ERROR ) - { - var error = "GL Error: {0}\n{1}".F((GlError)n, new System.Diagnostics.StackTrace()); - WriteGraphicsLog(error); - throw new InvalidOperationException("OpenGL Error: See graphics.log for details."); - } - } - - static void WriteGraphicsLog(string message) - { - Log.AddChannel("graphics", "graphics.log"); - Log.Write("graphics", message); - Log.Write("graphics", ""); - Log.Write("graphics", "OpenGL Information:"); - Log.Write("graphics", "Vendor: {0}", Gl.glGetString(Gl.GL_VENDOR)); - Log.Write("graphics", "Renderer: {0}", Gl.glGetString(Gl.GL_RENDERER)); - Log.Write("graphics", "GL Version: {0}", Gl.glGetString(Gl.GL_VERSION)); - Log.Write("graphics", "Shader Version: {0}", Gl.glGetString(Gl.GL_SHADING_LANGUAGE_VERSION)); - Log.Write("graphics", "Available extensions:"); - Log.Write("graphics", Gl.glGetString(Gl.GL_EXTENSIONS)); - } - static Tao.Cg.Cg.CGerrorCallbackFuncDelegate CgErrorCallback = () => { var err = Tao.Cg.Cg.cgGetError(); var msg = "CG Error: {0}: {1}".F(err, Tao.Cg.Cg.cgGetErrorString(err)); - WriteGraphicsLog(msg); + ErrorHandler.WriteGraphicsLog(msg); throw new InvalidOperationException("CG Error. See graphics.log for details"); }; @@ -134,7 +98,7 @@ namespace OpenRA.Renderer.Cg Sdl.SDL_EnableUNICODE( 1 ); Sdl.SDL_EnableKeyRepeat( Sdl.SDL_DEFAULT_REPEAT_DELAY, Sdl.SDL_DEFAULT_REPEAT_INTERVAL ); - CheckGlError(); + ErrorHandler.CheckGlError(); // Test for required extensions var required = new string[] @@ -152,7 +116,8 @@ namespace OpenRA.Renderer.Cg if (missingExtensions.Any()) { - WriteGraphicsLog("Unsupported GPU: Missing extensions: {0}".F(string.Join(",", missingExtensions))); + ErrorHandler.WriteGraphicsLog("Unsupported GPU: Missing extensions: {0}" + .F(string.Join(",", missingExtensions))); throw new InvalidProgramException("Unsupported GPU. See graphics.log for details."); } @@ -168,9 +133,9 @@ namespace OpenRA.Renderer.Cg fragmentProfile = CgGl.cgGLGetLatestProfile( CgGl.CG_GL_FRAGMENT ); Gl.glEnableClientState( Gl.GL_VERTEX_ARRAY ); - CheckGlError(); + ErrorHandler.CheckGlError(); Gl.glEnableClientState( Gl.GL_TEXTURE_COORD_ARRAY ); - CheckGlError(); + ErrorHandler.CheckGlError(); Sdl.SDL_SetModState( 0 ); // i have had enough. } @@ -180,23 +145,23 @@ namespace OpenRA.Renderer.Cg if( width < 0 ) width = 0; if( height < 0 ) height = 0; Gl.glScissor( left, windowSize.Height - ( top + height ), width, height ); - CheckGlError(); + ErrorHandler.CheckGlError(); Gl.glEnable( Gl.GL_SCISSOR_TEST ); - CheckGlError(); + ErrorHandler.CheckGlError(); } public void DisableScissor() { Gl.glDisable( Gl.GL_SCISSOR_TEST ); - CheckGlError(); + ErrorHandler.CheckGlError(); } public void Clear( Color c ) { Gl.glClearColor( 0, 0, 0, 0 ); - CheckGlError(); + ErrorHandler.CheckGlError(); Gl.glClear( Gl.GL_COLOR_BUFFER_BIT ); - CheckGlError(); + ErrorHandler.CheckGlError(); } MouseButton lastButtonBits = (MouseButton)0; @@ -340,13 +305,13 @@ namespace OpenRA.Renderer.Cg pendingMotion = null; } - CheckGlError(); + ErrorHandler.CheckGlError(); } public void DrawPrimitives( PrimitiveType pt, int firstVertex, int numVertices ) { Gl.glDrawArrays( ModeFromPrimitiveType( pt ), firstVertex, numVertices ); - CheckGlError(); + ErrorHandler.CheckGlError(); } static int ModeFromPrimitiveType( PrimitiveType pt ) @@ -361,9 +326,9 @@ namespace OpenRA.Renderer.Cg throw new NotImplementedException(); } - public IVertexBuffer CreateVertexBuffer( int size ) { return new VertexBuffer( this, size ); } - public ITexture CreateTexture() { return new Texture( this ); } - public ITexture CreateTexture( Bitmap bitmap ) { return new Texture( this, bitmap ); } + 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; } } diff --git a/OpenRA.Renderer.Cg/OpenRA.Renderer.Cg.csproj b/OpenRA.Renderer.Cg/OpenRA.Renderer.Cg.csproj index e39b1125e8..c1fa8ef141 100644 --- a/OpenRA.Renderer.Cg/OpenRA.Renderer.Cg.csproj +++ b/OpenRA.Renderer.Cg/OpenRA.Renderer.Cg.csproj @@ -58,8 +58,6 @@ - - diff --git a/OpenRA.Renderer.Cg/Shader.cs b/OpenRA.Renderer.Cg/Shader.cs index 0cd7d0bdfc..ab56fb4882 100644 --- a/OpenRA.Renderer.Cg/Shader.cs +++ b/OpenRA.Renderer.Cg/Shader.cs @@ -12,6 +12,7 @@ using System; using System.IO; using OpenRA.FileFormats; using OpenRA.FileFormats.Graphics; +using OpenRA.Renderer.SdlCommon; namespace OpenRA.Renderer.Cg { diff --git a/OpenRA.Renderer.Cg/Texture.cs b/OpenRA.Renderer.Cg/Texture.cs deleted file mode 100644 index a8cd5a339f..0000000000 --- a/OpenRA.Renderer.Cg/Texture.cs +++ /dev/null @@ -1,119 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation. For more information, - * see COPYING. - */ -#endregion - -using System; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using OpenRA.FileFormats; -using OpenRA.FileFormats.Graphics; -using Tao.OpenGl; - -namespace OpenRA.Renderer.Cg -{ - public class Texture : ITexture - { - internal int texture; - - public Texture(GraphicsDevice dev) - { - Gl.glGenTextures(1, out texture); - GraphicsDevice.CheckGlError(); - } - - public Texture(GraphicsDevice dev, Bitmap bitmap) - { - Gl.glGenTextures(1, out texture); - GraphicsDevice.CheckGlError(); - SetData(bitmap); - } - - void FinalizeInner() { Gl.glDeleteTextures( 1, ref texture ); } - ~Texture() { Game.RunAfterTick( FinalizeInner ); } - - void PrepareTexture() - { - Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture); - GraphicsDevice.CheckGlError(); - Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_BASE_LEVEL, 0); - GraphicsDevice.CheckGlError(); - Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAX_LEVEL, 0); - GraphicsDevice.CheckGlError(); - } - - public void SetData(byte[] colors, int width, int height) - { - if (!IsPowerOf2(width) || !IsPowerOf2(height)) - throw new InvalidDataException("Non-power-of-two array {0}x{1}".F(width, height)); - - unsafe - { - fixed (byte* ptr = &colors[0]) - { - IntPtr intPtr = new IntPtr((void*)ptr); - - PrepareTexture(); - Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, width, height, - 0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, intPtr); - GraphicsDevice.CheckGlError(); - } - } - } - - // An array of RGBA - public void SetData(uint[,] colors) - { - int width = colors.GetUpperBound(1) + 1; - int height = colors.GetUpperBound(0) + 1; - - if (!IsPowerOf2(width) || !IsPowerOf2(height)) - throw new InvalidDataException("Non-power-of-two array {0}x{1}".F(width,height)); - - unsafe - { - fixed (uint* ptr = &colors[0,0]) - { - IntPtr intPtr = new IntPtr((void *) ptr); - - PrepareTexture(); - Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, width, height, - 0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, intPtr); - GraphicsDevice.CheckGlError(); - } - } - } - - public void SetData(Bitmap bitmap) - { - if (!IsPowerOf2(bitmap.Width) || !IsPowerOf2(bitmap.Height)) - { - //throw new InvalidOperationException( "non-power-of-2-texture" ); - bitmap = new Bitmap(bitmap, new Size(Exts.NextPowerOf2(bitmap.Width), Exts.NextPowerOf2(bitmap.Height))); - } - - var bits = bitmap.LockBits( - new Rectangle(0, 0, bitmap.Width, bitmap.Height), - ImageLockMode.ReadOnly, - PixelFormat.Format32bppArgb); - - PrepareTexture(); - Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, bits.Width, bits.Height, - 0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, bits.Scan0); // todo: weird strides - GraphicsDevice.CheckGlError(); - - bitmap.UnlockBits(bits); - } - - bool IsPowerOf2(int v) - { - return (v & (v - 1)) == 0; - } - } -} diff --git a/OpenRA.Renderer.Cg/VertexBuffer.cs b/OpenRA.Renderer.Cg/VertexBuffer.cs deleted file mode 100644 index 8fbc5a3d8f..0000000000 --- a/OpenRA.Renderer.Cg/VertexBuffer.cs +++ /dev/null @@ -1,59 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation. For more information, - * see COPYING. - */ -#endregion - -using System; -using System.Drawing; -using System.Runtime.InteropServices; -using OpenRA.FileFormats.Graphics; -using Tao.OpenGl; - -namespace OpenRA.Renderer.Cg -{ - public class VertexBuffer : IVertexBuffer - where T : struct - { - int buffer; - - public VertexBuffer(GraphicsDevice dev, int size) - { - Gl.glGenBuffers(1, out buffer); - GraphicsDevice.CheckGlError(); - Bind(); - Gl.glBufferData(Gl.GL_ARRAY_BUFFER, - new IntPtr(Marshal.SizeOf(typeof(T)) * size), - new T[ size ], - Gl.GL_DYNAMIC_DRAW); - GraphicsDevice.CheckGlError(); - } - - void FinalizeInner() { Gl.glDeleteBuffers( 1, ref buffer ); } - ~VertexBuffer() { Game.RunAfterTick( FinalizeInner ); } - - public void SetData(T[] data, int length) - { - Bind(); - Gl.glBufferSubData(Gl.GL_ARRAY_BUFFER, - IntPtr.Zero, - new IntPtr(Marshal.SizeOf(typeof(T)) * length), - data); - GraphicsDevice.CheckGlError(); - } - - public void Bind() - { - Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, buffer); - GraphicsDevice.CheckGlError(); - Gl.glVertexPointer(3, Gl.GL_FLOAT, Marshal.SizeOf(typeof(T)), IntPtr.Zero); - GraphicsDevice.CheckGlError(); - Gl.glTexCoordPointer(4, Gl.GL_FLOAT, Marshal.SizeOf(typeof(T)), new IntPtr(12)); - GraphicsDevice.CheckGlError(); - } - } -} diff --git a/OpenRA.Renderer.Gl/Texture.cs b/OpenRA.Renderer.Gl/Texture.cs deleted file mode 100644 index 1568074d99..0000000000 --- a/OpenRA.Renderer.Gl/Texture.cs +++ /dev/null @@ -1,146 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation. For more information, - * see COPYING. - */ -#endregion - -using System; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using OpenRA.FileFormats; -using OpenRA.FileFormats.Graphics; -using Tao.OpenGl; - -namespace OpenRA.Renderer.Glsl -{ - public class Texture : ITexture - { - internal int texture; - internal int memory; - GraphicsDevice dev; - - public Texture(GraphicsDevice dev) - { - this.dev = dev; - - Gl.glGenTextures(1, out texture); - GraphicsDevice.CheckGlError(); - } - - public Texture(GraphicsDevice dev, Bitmap bitmap) - { - this.dev = dev; - - Gl.glGenTextures(1, out texture); - GraphicsDevice.CheckGlError(); - SetData(bitmap); - } - - void FinalizeInner() { UpdateMemoryUsage(0); Gl.glDeleteTextures(1, ref texture); } - ~Texture() { Game.RunAfterTick(FinalizeInner); } - - void PrepareTexture() - { - GraphicsDevice.CheckGlError(); - Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture); - GraphicsDevice.CheckGlError(); - Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST); - GraphicsDevice.CheckGlError(); - Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST); - GraphicsDevice.CheckGlError(); - - Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_BASE_LEVEL, 0); - GraphicsDevice.CheckGlError(); - Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAX_LEVEL, 0); - GraphicsDevice.CheckGlError(); - } - - void UpdateMemoryUsage( int newSize ) - { - if (newSize == memory) - return; - - dev.GpuMemoryUsed -= memory; - memory = newSize; - dev.GpuMemoryUsed += memory; - - Log.Write("debug", "GPU Memory: {0:F2} MiB", dev.GpuMemoryUsed / 1024 / 1024f); - } - - public void SetData(byte[] colors, int width, int height) - { - if (!IsPowerOf2(width) || !IsPowerOf2(height)) - throw new InvalidDataException("Non-power-of-two array {0}x{1}".F(width, height)); - - unsafe - { - fixed (byte* ptr = &colors[0]) - { - IntPtr intPtr = new IntPtr((void*)ptr); - PrepareTexture(); - Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, width, height, - 0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, intPtr); - GraphicsDevice.CheckGlError(); - } - } - - UpdateMemoryUsage(colors.Length); - } - - // An array of RGBA - public void SetData(uint[,] colors) - { - int width = colors.GetUpperBound(1) + 1; - int height = colors.GetUpperBound(0) + 1; - - if (!IsPowerOf2(width) || !IsPowerOf2(height)) - throw new InvalidDataException("Non-power-of-two array {0}x{1}".F(width,height)); - - unsafe - { - fixed (uint* ptr = &colors[0,0]) - { - IntPtr intPtr = new IntPtr((void *) ptr); - PrepareTexture(); - Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, width, height, - 0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, intPtr); - GraphicsDevice.CheckGlError(); - } - } - - UpdateMemoryUsage(width * height * sizeof(uint)); - } - - public void SetData(Bitmap bitmap) - { - if (!IsPowerOf2(bitmap.Width) || !IsPowerOf2(bitmap.Height)) - { - //throw new InvalidOperationException( "non-power-of-2-texture" ); - bitmap = new Bitmap(bitmap, new Size(Exts.NextPowerOf2(bitmap.Width), Exts.NextPowerOf2(bitmap.Height))); - } - - var bits = bitmap.LockBits( - new Rectangle(0, 0, bitmap.Width, bitmap.Height), - ImageLockMode.ReadOnly, - PixelFormat.Format32bppArgb); - - PrepareTexture(); - Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, bits.Width, bits.Height, - 0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, bits.Scan0); // todo: weird strides - GraphicsDevice.CheckGlError(); - bitmap.UnlockBits(bits); - - UpdateMemoryUsage(bitmap.Width * bitmap.Height * sizeof(uint)); - } - - bool IsPowerOf2(int v) - { - return (v & (v - 1)) == 0; - } - } -} diff --git a/OpenRA.Renderer.Gl/VertexBuffer.cs b/OpenRA.Renderer.Gl/VertexBuffer.cs deleted file mode 100644 index 0aa49dcae2..0000000000 --- a/OpenRA.Renderer.Gl/VertexBuffer.cs +++ /dev/null @@ -1,58 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation. For more information, - * see COPYING. - */ -#endregion - -using System; -using System.Runtime.InteropServices; -using OpenRA.FileFormats.Graphics; -using Tao.OpenGl; - -namespace OpenRA.Renderer.Glsl -{ - public class VertexBuffer : IVertexBuffer - where T : struct - { - int buffer; - - public VertexBuffer(GraphicsDevice dev, int size) - { - Gl.glGenBuffers(1, out buffer); - GraphicsDevice.CheckGlError(); - Bind(); - Gl.glBufferData(Gl.GL_ARRAY_BUFFER, - new IntPtr(Marshal.SizeOf(typeof(T)) * size), - new T[ size ], - Gl.GL_DYNAMIC_DRAW); - GraphicsDevice.CheckGlError(); - } - - public void SetData(T[] data, int length) - { - Bind(); - Gl.glBufferSubData(Gl.GL_ARRAY_BUFFER, - IntPtr.Zero, - new IntPtr(Marshal.SizeOf(typeof(T)) * length), - data); - GraphicsDevice.CheckGlError(); - } - - public void Bind() - { - Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, buffer); - GraphicsDevice.CheckGlError(); - Gl.glVertexPointer(3, Gl.GL_FLOAT, Marshal.SizeOf(typeof(T)), IntPtr.Zero); - GraphicsDevice.CheckGlError(); - Gl.glTexCoordPointer(4, Gl.GL_FLOAT, Marshal.SizeOf(typeof(T)), new IntPtr(12)); - GraphicsDevice.CheckGlError(); - } - - void FinalizeInner() { Gl.glDeleteBuffers( 1, ref buffer ); } - ~VertexBuffer() { Game.RunAfterTick( FinalizeInner ); } - } -}