diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs index c8bbb4a13e52e168cb92cd7f7fa1f0618d066bd8..9668e58c2a7fdd3558eeadddf2e1be6da788b233 100755 --- a/Source/Core/Data/DataManager.cs +++ b/Source/Core/Data/DataManager.cs @@ -3424,7 +3424,7 @@ namespace CodeImp.DoomBuilder.Data // Make custom rendertarget const int cubemaptexsize = 1024; - Texture rendertarget = new Texture(cubemaptexsize, cubemaptexsize, 1, Format.A8R8G8B8); + Texture rendertarget = new Texture(cubemaptexsize, cubemaptexsize); // Start rendering General.Map.Graphics.StartRendering(true, new Color4(), rendertarget, true); @@ -3452,7 +3452,7 @@ namespace CodeImp.DoomBuilder.Data yscale *= 1.65f; // Make cubemap texture - CubeTexture cubemap = new CubeTexture(cubemaptexsize, 1, Format.A8R8G8B8); + CubeTexture cubemap = new CubeTexture(cubemaptexsize); // Set render settings... General.Map.Graphics.SetRenderState(RenderState.ZEnable, false); @@ -3652,7 +3652,7 @@ namespace CodeImp.DoomBuilder.Data // sides[] must contain 6 square Po2 images in this order: North, East, South, West, Top, Bottom private static CubeTexture MakeSkyBox(Bitmap[] sides, int targetsize, bool fliptop) { - CubeTexture cubemap = new CubeTexture(targetsize, 1, Format.A8R8G8B8); + CubeTexture cubemap = new CubeTexture(targetsize); // Draw faces sides[3].RotateFlip(RotateFlipType.Rotate90FlipNone); @@ -3752,15 +3752,10 @@ namespace CodeImp.DoomBuilder.Data private static Texture TextureFromBitmap(Image image) { - using(MemoryStream ms = new MemoryStream()) - { - image.Save(ms, ImageFormat.Png); - ms.Seek(0, SeekOrigin.Begin); - - // Classic skies textures can be NPo2 (and D3D Texture is resized to Po2 by default), - // so we need to explicitly specify the size - return Texture.FromStream(ms, (int) ms.Length, image.Size.Width, image.Size.Height, 0, Format.Unknown); - } + using (var bitmap = new Bitmap(image)) + { + return new Texture(bitmap); + } } #endregion diff --git a/Source/Core/Data/ImageData.cs b/Source/Core/Data/ImageData.cs index d7e3a0d9bd561a5bc004726b466275351c665dd2..3be3ccc42674c9091d6c80fabd54eb78c6c1ce48 100755 --- a/Source/Core/Data/ImageData.cs +++ b/Source/Core/Data/ImageData.cs @@ -464,22 +464,10 @@ namespace CodeImp.DoomBuilder.Data // Only do this when texture is not created yet if(((texture == null) || (texture.Disposed)) && this.IsImageLoaded && !loadfailed) { - Image img = bitmap; + Bitmap img = bitmap; if(loadfailed) img = Properties.Resources.Failed; - - // Write to memory stream and read from memory - MemoryStream memstream = new MemoryStream((img.Size.Width * img.Size.Height * 4) + 4096); - img.Save(memstream, ImageFormat.Bmp); - memstream.Seek(0, SeekOrigin.Begin); - if(dynamictexture) - { - texture = Texture.FromStream(memstream, (int)memstream.Length, img.Size.Width, img.Size.Height, mipmaplevels, Format.A8R8G8B8); - } - else - { - texture = Texture.FromStream(memstream, (int)memstream.Length, img.Size.Width, img.Size.Height, mipmaplevels, Format.Unknown); - } - memstream.Dispose(); + + texture = new Texture(img); if(dynamictexture) { diff --git a/Source/Core/GZBuilder/md3/ModelReader.cs b/Source/Core/GZBuilder/md3/ModelReader.cs index da21e52995c5ed879d217f47522d37bbe7c1db67..8d5555114b59f17bda4073f392fff6dccac9a740 100755 --- a/Source/Core/GZBuilder/md3/ModelReader.cs +++ b/Source/Core/GZBuilder/md3/ModelReader.cs @@ -1160,16 +1160,11 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 // Calculate model radius mde.Model.Radius = Math.Max(Math.Max(Math.Abs(minY), Math.Abs(maxY)), Math.Max(Math.Abs(minX), Math.Abs(maxX))); - // Create texture - MemoryStream memstream = new MemoryStream((4096 * 4) + 4096); - using(Bitmap bmp = CreateVoxelTexture(palette)) bmp.Save(memstream, ImageFormat.Bmp); - memstream.Seek(0, SeekOrigin.Begin); - - Texture texture = Texture.FromStream(memstream, (int)memstream.Length, 64, 64, 0, Format.Unknown); - memstream.Dispose(); - - // Add texture - mde.Model.Textures.Add(texture); + // Create texture new Texture(bmp.Width) + using(Bitmap bmp = CreateVoxelTexture(palette)) + { + mde.Model.Textures.Add(new Texture(bmp)); + } // Create mesh Mesh mesh = new Mesh(vertexElements, verts.ToArray(), indices.ToArray()); @@ -1666,23 +1661,13 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 Texture texture = null; //create texture - if(Path.GetExtension(path) == ".pcx") //pcx format requires special handling... - { - FileImageReader fir = new FileImageReader(); - Bitmap bitmap = fir.ReadAsBitmap(ms); - - ms.Close(); + FileImageReader fir = new FileImageReader(); + Bitmap bitmap = fir.ReadAsBitmap(ms); + ms.Close(); - if(bitmap != null) - { - texture.SetPixels(bitmap); - } - } - else + if(bitmap != null) { - texture = Texture.FromStream(ms); - - ms.Close(); + texture = new Texture(bitmap); } return texture; diff --git a/Source/Core/Rendering/D3DDevice.cs b/Source/Core/Rendering/D3DDevice.cs index d42083fcadee859871d5e9bfa99f9e93b3282220..c08ed154588a6b7ea74b8c4bf45540fee2ada6ed 100755 --- a/Source/Core/Rendering/D3DDevice.cs +++ b/Source/Core/Rendering/D3DDevice.cs @@ -264,7 +264,6 @@ namespace CodeImp.DoomBuilder.Rendering public enum TransformState { World, View, Projection } public enum SamplerState { AddressU, AddressV, AddressW } public enum TextureAddress { Wrap, Clamp } - public enum Format { Unknown, A8R8G8B8 } public enum ShaderFlags { None, Debug } public enum PrimitiveType { LineList, TriangleList, TriangleStrip } public enum TextureFilter { None, Point, Linear, Anisotropic } diff --git a/Source/Core/Rendering/Renderer2D.cs b/Source/Core/Rendering/Renderer2D.cs index 89446a7d482fe0667161b524156a1dd3f2d0777c..88996af398bdf552df1c040af2e854b045307d4a 100755 --- a/Source/Core/Rendering/Renderer2D.cs +++ b/Source/Core/Rendering/Renderer2D.cs @@ -361,11 +361,11 @@ namespace CodeImp.DoomBuilder.Rendering windowsize.Height = graphics.RenderTarget.ClientSize.Height; // Create rendertargets textures - plottertex = new Texture(windowsize.Width, windowsize.Height, 1, Format.A8R8G8B8); - thingstex = new Texture(windowsize.Width, windowsize.Height, 1, Format.A8R8G8B8); - backtex = new Texture(windowsize.Width, windowsize.Height, 1, Format.A8R8G8B8); - overlaytex = new Texture(windowsize.Width, windowsize.Height, 1, Format.A8R8G8B8); - surfacetex = new Texture(windowsize.Width, windowsize.Height, 1, Format.A8R8G8B8); + plottertex = new Texture(windowsize.Width, windowsize.Height); + thingstex = new Texture(windowsize.Width, windowsize.Height); + backtex = new Texture(windowsize.Width, windowsize.Height); + overlaytex = new Texture(windowsize.Width, windowsize.Height); + surfacetex = new Texture(windowsize.Width, windowsize.Height); // Get the real surface sizes structsize.Width = plottertex.Width; diff --git a/Source/Core/Rendering/TextLabel.cs b/Source/Core/Rendering/TextLabel.cs index 63eaafac6c978c6821b1f88e520eefa8306cfb51..d49b2654d24e31f63db2c82afd167cfebfe7a099 100755 --- a/Source/Core/Rendering/TextLabel.cs +++ b/Source/Core/Rendering/TextLabel.cs @@ -326,16 +326,11 @@ namespace CodeImp.DoomBuilder.Rendering texture = null; } - // Create label image - Bitmap img = CreateLabelImage(text, font, color, backcolor, drawbg, textrect, bgrect, texturesize, textorigin); - //texturesize = img.Size; - - // Create texture - MemoryStream memstream = new MemoryStream((img.Size.Width * img.Size.Height * 4) + 4096); - img.Save(memstream, ImageFormat.Bmp); - memstream.Seek(0, SeekOrigin.Begin); - - texture = Texture.FromStream(memstream, (int)memstream.Length, img.Size.Width, img.Size.Height, 1, Format.Unknown); + // Create label image + using (Bitmap img = CreateLabelImage(text, font, color, backcolor, drawbg, textrect, bgrect, texturesize, textorigin)) + { + texture = new Texture(img); + } } //mxd. Create the buffer diff --git a/Source/Core/Rendering/Texture.cs b/Source/Core/Rendering/Texture.cs index 0be8ca321a937fea3945854311cfc571d336e6c7..b8928b3041f9f5e076af6a2b4343ceee8b64b590 100644 --- a/Source/Core/Rendering/Texture.cs +++ b/Source/Core/Rendering/Texture.cs @@ -32,19 +32,59 @@ namespace CodeImp.DoomBuilder.Rendering } } - IntPtr Handle; + protected IntPtr Handle; [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] - static extern IntPtr Texture_New(); + protected static extern IntPtr Texture_New(); [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] - static extern void Texture_Delete(IntPtr handle); + protected static extern void Texture_Delete(IntPtr handle); + + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + protected static extern void Texture_Set2DImage(IntPtr handle, int width, int height); + + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + protected static extern void Texture_SetPixels(IntPtr handle, IntPtr data); + + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + protected static extern IntPtr Texture_Lock(IntPtr handle); + + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + protected static extern void Texture_Unlock(IntPtr handle); + + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + protected static extern void Texture_SetCubeImage(IntPtr handle, int size); + + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + protected static extern void Texture_SetCubePixels(IntPtr handle, CubeMapFace face, IntPtr data); } public class Texture : BaseTexture { - public Texture(int width, int height, int levels, Format format) + public Texture(int width, int height) { + Width = width; + Height = height; + Texture_Set2DImage(Handle, Width, Height); + } + + public Texture(System.Drawing.Bitmap bitmap) + { + Width = bitmap.Width; + Height = bitmap.Height; + Texture_Set2DImage(Handle, Width, Height); + SetPixels(bitmap); + } + + public Texture(System.Drawing.Image image) + { + using (var bitmap = new System.Drawing.Bitmap(image)) + { + Width = bitmap.Width; + Height = bitmap.Height; + Texture_Set2DImage(Handle, Width, Height); + SetPixels(bitmap); + } } public int Width { get; private set; } @@ -54,48 +94,50 @@ namespace CodeImp.DoomBuilder.Rendering public void SetPixels(System.Drawing.Bitmap bitmap) { - /* - BitmapData bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); + System.Drawing.Imaging.BitmapData bmpdata = bitmap.LockBits( + new System.Drawing.Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), + System.Drawing.Imaging.ImageLockMode.ReadOnly, + System.Drawing.Imaging.PixelFormat.Format32bppArgb); - DataRectangle textureLock = texture.LockRectangle(0, LockFlags.None); - textureLock.Data.WriteRange(bmlock.Scan0, bmlock.Height * bmlock.Stride); - texture.UnlockRectangle(0); + Texture_SetPixels(Handle, bmpdata.Scan0); bitmap.UnlockBits(bmpdata); - */ } internal Plotter LockPlotter(int visibleWidth, int visibleHeight) { - //return new Plotter((PixelColor*)plotlocked.Data.DataPointer.ToPointer(), plotlocked.Pitch / sizeof(PixelColor), Height, visibleWidth, visibleHeight); - return null; + unsafe + { + IntPtr data = Texture_Lock(Handle); + return new Plotter((PixelColor*)data.ToPointer(), Width, Height, Math.Min(Width, visibleWidth), Math.Min(Height, visibleHeight)); + } } public void UnlockPlotter() { - } - - public static Texture FromStream(System.IO.Stream stream) - { - return null; - } - - public static Texture FromStream(System.IO.Stream stream, int length, int width, int height, int levels, Format format) - { - return null; + Texture_Unlock(Handle); } } public class CubeTexture : BaseTexture { - public CubeTexture(int size, int levels, Format format) + public CubeTexture(int size) { + Texture_SetCubeImage(Handle, size); } public void SetPixels(CubeMapFace face, System.Drawing.Bitmap bitmap) { + System.Drawing.Imaging.BitmapData bmpdata = bitmap.LockBits( + new System.Drawing.Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), + System.Drawing.Imaging.ImageLockMode.ReadOnly, + System.Drawing.Imaging.PixelFormat.Format32bppArgb); + + Texture_SetCubePixels(Handle, face, bmpdata.Scan0); + + bitmap.UnlockBits(bmpdata); } } - public enum CubeMapFace { PositiveX, PositiveY, PositiveZ, NegativeX, NegativeY, NegativeZ } + public enum CubeMapFace : int { PositiveX, PositiveY, PositiveZ, NegativeX, NegativeY, NegativeZ } } diff --git a/Source/Native/IndexBuffer.cpp b/Source/Native/IndexBuffer.cpp index 578f76ec651bfd7986de3aa4f40106ef47237ffd..29ec49bdf601f8511a41b43c62b09828a7227fc7 100644 --- a/Source/Native/IndexBuffer.cpp +++ b/Source/Native/IndexBuffer.cpp @@ -1,12 +1,14 @@ #include "IndexBuffer.h" -IndexBuffer::IndexBuffer(int sizeInBytes) +IndexBuffer::IndexBuffer(int sizeInBytes) : mData(sizeInBytes) { } void IndexBuffer::SetBufferData(const void* data, int64_t size) { + if (size > 0 && size < (int64_t)mData.size()) + memcpy(mData.data(), data, size); } ///////////////////////////////////////////////////////////////////////////// diff --git a/Source/Native/IndexBuffer.h b/Source/Native/IndexBuffer.h index 25f844b782ba681b19415e8b9f86bcce33bae64a..a4367b8f95a62c68e0bedd4868d3d6e4bed6d152 100644 --- a/Source/Native/IndexBuffer.h +++ b/Source/Native/IndexBuffer.h @@ -1,6 +1,7 @@ #pragma once #include <cstdint> +#include <vector> class IndexBuffer { @@ -8,4 +9,7 @@ public: IndexBuffer(int sizeInBytes); void SetBufferData(const void* data, int64_t size); + +private: + std::vector<uint8_t> mData; }; diff --git a/Source/Native/Texture.cpp b/Source/Native/Texture.cpp index 2a2339720cf5ccc8d890fb8bc7dc88b19ebfe610..b4a6841feaa9f1e46a1dac8f674d151739b3f5c5 100644 --- a/Source/Native/Texture.cpp +++ b/Source/Native/Texture.cpp @@ -5,6 +5,44 @@ Texture::Texture() { } +void Texture::Set2DImage(int width, int height) +{ + mCubeTexture = false; + mWidth = width; + mHeight = height; +} + +void Texture::SetCubeImage(int size) +{ + mCubeTexture = true; + mWidth = size; + mHeight = size; +} + +void Texture::SetPixels(const void* data) +{ + mPixels[0].resize(mWidth * (size_t)mHeight); + memcpy(mPixels[0].data(), data, sizeof(uint32_t) * mWidth * mHeight); +} + +void Texture::SetCubePixels(CubeMapFace face, const void* data) +{ + mPixels[(int)face].resize(mWidth * (size_t)mHeight); + memcpy(mPixels[(int)face].data(), data, sizeof(uint32_t) * mWidth * mHeight); +} + +void* Texture::Lock() +{ + mPixels[0].resize(mWidth * (size_t)mHeight); + return mPixels[0].data(); +} + +void Texture::Unlock() +{ +} + +///////////////////////////////////////////////////////////////////////////// + Texture* Texture_New() { return new Texture(); @@ -14,3 +52,33 @@ void Texture_Delete(Texture* tex) { delete tex; } + +void Texture_Set2DImage(Texture* handle, int width, int height) +{ + handle->Set2DImage(width, height); +} + +void Texture_SetPixels(Texture* handle, const void* data) +{ + handle->SetPixels(data); +} + +void* Texture_Lock(Texture* handle) +{ + return handle->Lock(); +} + +void Texture_Unlock(Texture* handle) +{ + handle->Unlock(); +} + +void Texture_SetCubeImage(Texture* handle, int size) +{ + handle->SetCubeImage(size); +} + +void Texture_SetCubePixels(Texture* handle, CubeMapFace face, const void *data) +{ + handle->SetCubePixels(face, data); +} diff --git a/Source/Native/Texture.h b/Source/Native/Texture.h index 3896b0eb6184417f995cfe8f7dce66aaeacd139e..f0654a3159f7235b3488ebfa771b1198785b0226 100644 --- a/Source/Native/Texture.h +++ b/Source/Native/Texture.h @@ -1,9 +1,36 @@ #pragma once #include <cstdint> +#include <vector> +#include <map> + +enum class CubeMapFace : int +{ + PositiveX, + PositiveY, + PositiveZ, + NegativeX, + NegativeY, + NegativeZ +}; class Texture { public: Texture(); + + void Set2DImage(int width, int height); + void SetCubeImage(int size); + + void SetPixels(const void* data); + void SetCubePixels(CubeMapFace face, const void* data); + + void* Lock(); + void Unlock(); + +private: + int mWidth = 0; + int mHeight = 0; + bool mCubeTexture = false; + std::map<int, std::vector<uint32_t>> mPixels; }; diff --git a/Source/Native/VertexBuffer.cpp b/Source/Native/VertexBuffer.cpp index a13b3665b114229c672d20eb65e9b31ef452bfe8..97c09bd9f73489afc7ea11fc32d364666ba5760c 100644 --- a/Source/Native/VertexBuffer.cpp +++ b/Source/Native/VertexBuffer.cpp @@ -1,16 +1,20 @@ #include "VertexBuffer.h" -VertexBuffer::VertexBuffer(int sizeInBytes) +VertexBuffer::VertexBuffer(int sizeInBytes) : mData(sizeInBytes) { } void VertexBuffer::SetBufferData(const void* data, int64_t size) { + if (size > 0 && size < (int64_t)mData.size()) + memcpy(mData.data(), data, size); } void VertexBuffer::SetBufferSubdata(int64_t destOffset, const void* data, int64_t size) { + if (destOffset >= 0 && size > 0 && size < (int64_t)mData.size() - destOffset) + memcpy(mData.data() + destOffset, data, size); } ///////////////////////////////////////////////////////////////////////////// diff --git a/Source/Native/VertexBuffer.h b/Source/Native/VertexBuffer.h index 88cd17cda9452dbf1bf9a48b7782fb3e1a24b2a6..bf9caba571892ec0f819ffbbd9c1e1add298b30c 100644 --- a/Source/Native/VertexBuffer.h +++ b/Source/Native/VertexBuffer.h @@ -1,6 +1,7 @@ #pragma once #include <cstdint> +#include <vector> class VertexBuffer { @@ -9,4 +10,7 @@ public: void SetBufferData(const void* data, int64_t size); void SetBufferSubdata(int64_t destOffset, const void* data, int64_t size); + +private: + std::vector<uint8_t> mData; }; diff --git a/Source/Native/exports.def b/Source/Native/exports.def index 743769a9833c326e64633ae7fc5418ca47ef8804..0a6d2afba93d37e2c6e11b9e7cc983f1108192f9 100644 --- a/Source/Native/exports.def +++ b/Source/Native/exports.def @@ -14,3 +14,9 @@ EXPORTS IndexBuffer_SetBufferData Texture_New Texture_Delete + Texture_Set2DImage + Texture_SetPixels + Texture_Lock + Texture_Unlock + Texture_SetCubeImage + Texture_SetCubePixels