diff --git a/OpenRA.FileFormats/Graphics/IGraphicsDevice.cs b/OpenRA.FileFormats/Graphics/IGraphicsDevice.cs index b8cf0787e4..8e44f22817 100755 --- a/OpenRA.FileFormats/Graphics/IGraphicsDevice.cs +++ b/OpenRA.FileFormats/Graphics/IGraphicsDevice.cs @@ -80,6 +80,8 @@ namespace OpenRA.FileFormats.Graphics void SetData(Bitmap bitmap); void SetData(uint[,] colors); void SetData(byte[] colors, int width, int height); + byte[] GetData(); + Size Size { get; } } public interface IFrameBuffer diff --git a/OpenRA.Renderer.Cg/Shader.cs b/OpenRA.Renderer.Cg/Shader.cs index 9ef2c1d3c3..7be1a3b3b7 100644 --- a/OpenRA.Renderer.Cg/Shader.cs +++ b/OpenRA.Renderer.Cg/Shader.cs @@ -72,7 +72,7 @@ namespace OpenRA.Renderer.Cg var texture = (Texture)t; var param = Tao.Cg.Cg.cgGetNamedEffectParameter(effect, name); if (param != IntPtr.Zero && texture != null) - Tao.Cg.CgGl.cgGLSetupSampler(param, texture.texture); + Tao.Cg.CgGl.cgGLSetupSampler(param, texture.ID); } public void SetVec(string name, float x) diff --git a/OpenRA.Renderer.Gl/Shader.cs b/OpenRA.Renderer.Gl/Shader.cs index 1bc9427f1d..ea6db304d7 100644 --- a/OpenRA.Renderer.Gl/Shader.cs +++ b/OpenRA.Renderer.Gl/Shader.cs @@ -115,8 +115,8 @@ namespace OpenRA.Renderer.Glsl foreach (var kv in textures) { - Gl.glActiveTextureARB( Gl.GL_TEXTURE0_ARB + kv.Key ); - Gl.glBindTexture( Gl.GL_TEXTURE_2D, ((Texture)kv.Value).texture ); + Gl.glActiveTextureARB(Gl.GL_TEXTURE0_ARB + kv.Key); + Gl.glBindTexture(Gl.GL_TEXTURE_2D, ((Texture)kv.Value).ID); } /* configure blend state */ diff --git a/OpenRA.Renderer.Null/NullGraphicsDevice.cs b/OpenRA.Renderer.Null/NullGraphicsDevice.cs index 359915d371..e1fbfab9a1 100644 --- a/OpenRA.Renderer.Null/NullGraphicsDevice.cs +++ b/OpenRA.Renderer.Null/NullGraphicsDevice.cs @@ -79,6 +79,8 @@ namespace OpenRA.Renderer.Null public void SetData(Bitmap bitmap) { } public void SetData(uint[,] colors) { } public void SetData(byte[] colors, int width, int height) { } + public byte[] GetData() { return new byte[0]; } + public Size Size { get { return new Size(0, 0); } } } public class NullFrameBuffer : IFrameBuffer diff --git a/OpenRA.Renderer.SdlCommon/Texture.cs b/OpenRA.Renderer.SdlCommon/Texture.cs index 8aadc8e740..915d0edf33 100644 --- a/OpenRA.Renderer.SdlCommon/Texture.cs +++ b/OpenRA.Renderer.SdlCommon/Texture.cs @@ -20,7 +20,11 @@ namespace OpenRA.Renderer.SdlCommon { public class Texture : ITexture { - public int texture; /* temp: can be internal again once shaders are in shared code */ + int texture; + public int ID { get { return texture; } } + + Size size; + public Size Size { get { return size; } } public Texture() { @@ -59,6 +63,7 @@ namespace OpenRA.Renderer.SdlCommon if (!Exts.IsPowerOf2(width) || !Exts.IsPowerOf2(height)) throw new InvalidDataException("Non-power-of-two array {0}x{1}".F(width, height)); + size = new Size(width, height); unsafe { fixed (byte* ptr = &colors[0]) @@ -81,6 +86,7 @@ namespace OpenRA.Renderer.SdlCommon if (!Exts.IsPowerOf2(width) || !Exts.IsPowerOf2(height)) throw new InvalidDataException("Non-power-of-two array {0}x{1}".F(width,height)); + size = new Size(width, height); unsafe { fixed (uint* ptr = &colors[0,0]) @@ -99,6 +105,7 @@ namespace OpenRA.Renderer.SdlCommon if (!Exts.IsPowerOf2(bitmap.Width) || !Exts.IsPowerOf2(bitmap.Height)) bitmap = new Bitmap(bitmap, bitmap.Size.NextPowerOf2()); + size = new Size(bitmap.Width, bitmap.Height); var bits = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); @@ -109,5 +116,34 @@ namespace OpenRA.Renderer.SdlCommon ErrorHandler.CheckGlError(); bitmap.UnlockBits(bits); } + + public byte[] GetData() + { + var data = new byte[4*size.Width * size.Height]; + + ErrorHandler.CheckGlError(); + Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture); + unsafe + { + fixed (byte *ptr = &data[0]) + { + IntPtr intPtr = new IntPtr((void*)ptr); + Gl.glGetTexImage(Gl.GL_TEXTURE_2D, 0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, intPtr); + } + } + return data; + } + + public void SetEmpty(int width, int height) + { + if (!Exts.IsPowerOf2(width) || !Exts.IsPowerOf2(height)) + throw new InvalidDataException("Non-power-of-two array {0}x{1}".F(width, height)); + + size = new Size(width, height); + PrepareTexture(); + Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, width, height, + 0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, null); + ErrorHandler.CheckGlError(); + } } }