From b524dd827743131ea64f38114f2c51dac956669c Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 23 Jan 2016 02:50:13 +0100 Subject: [PATCH] Merged in GZDB r2469. --- Source/Core/Builder.csproj | 1 + Source/Core/Data/DataManager.cs | 300 ++++++++++++------ Source/Core/GZBuilder/md3/ModelReader.cs | 20 +- Source/Core/Geometry/Tools.cs | 10 +- Source/Core/Properties/Resources.Designer.cs | 23 +- Source/Core/Properties/Resources.resx | 3 + Source/Core/Resources/SkySphere.md3 | Bin 0 -> 12148 bytes Source/Core/VisualModes/VisualGeometry.cs | 2 +- Source/Core/VisualModes/VisualMode.cs | 14 +- .../VisualModes/BaseVisualGeometrySidedef.cs | 4 +- 10 files changed, 257 insertions(+), 120 deletions(-) create mode 100644 Source/Core/Resources/SkySphere.md3 diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj index baa6a41..85d29ba 100644 --- a/Source/Core/Builder.csproj +++ b/Source/Core/Builder.csproj @@ -711,6 +711,7 @@ + diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs index 3fb2439..7265245 100644 --- a/Source/Core/Data/DataManager.cs +++ b/Source/Core/Data/DataManager.cs @@ -28,12 +28,15 @@ using CodeImp.DoomBuilder.Config; using CodeImp.DoomBuilder.GZBuilder.Data; using CodeImp.DoomBuilder.GZBuilder.GZDoom; using CodeImp.DoomBuilder.GZBuilder.MD3; +using CodeImp.DoomBuilder.Geometry; using CodeImp.DoomBuilder.IO; using CodeImp.DoomBuilder.Map; +using CodeImp.DoomBuilder.Rendering; using CodeImp.DoomBuilder.Windows; using CodeImp.DoomBuilder.ZDoom; using SlimDX; using SlimDX.Direct3D9; +using Matrix = SlimDX.Matrix; #endregion @@ -496,9 +499,6 @@ namespace CodeImp.DoomBuilder.Data alltextures.AddFlat(img.Value); } - //mxd. Create skybox texture(s) - SetupSkybox(); - // Start background loading StartBackgroundLoader(); @@ -1853,9 +1853,6 @@ namespace CodeImp.DoomBuilder.Data foreach(Thing t in General.Map.Map.Things) t.UpdateCache(); - // Rebuild skybox texture - SetupSkybox(); - // Rebuild geometry if in Visual mode if (General.Editing.Mode != null && General.Editing.Mode.GetType().Name == "BaseVisualMode") { @@ -1884,8 +1881,12 @@ namespace CodeImp.DoomBuilder.Data return; } - //rebuild geometry if in Visual mode - if(General.Editing.Mode != null && General.Editing.Mode.GetType().Name == "BaseVisualMode") + // Reset skybox texture + skybox.Dispose(); + skybox = null; + + // Rebuild geometry if in Visual mode + if (General.Editing.Mode != null && General.Editing.Mode.GetType().Name == "BaseVisualMode") { General.Editing.Mode.OnReloadResources(); } @@ -2361,6 +2362,10 @@ namespace CodeImp.DoomBuilder.Data #endregion #region ================== mxd. Skybox Making + internal void UpdateSkybox() + { + if (skybox == null) SetupSkybox(); + } private void SetupSkybox() { @@ -2396,7 +2401,7 @@ namespace CodeImp.DoomBuilder.Data Bitmap img = GetTextureBitmap(skytex); if (img != null) { - skybox = MakeClassicSkyBox(img, true); + skybox = MakeClassicSkyBox(img); } } } @@ -2406,137 +2411,186 @@ namespace CodeImp.DoomBuilder.Data { ImageData tex = LoadInternalTexture("MissingSky3D.png"); tex.CreateTexture(); - skybox = MakeClassicSkyBox(new Bitmap(tex.GetBitmap()), false); + skybox = MakeClassicSkyBox(new Bitmap(tex.GetBitmap())); tex.Dispose(); } } - private static CubeTexture MakeClassicSkyBox(Bitmap img, bool dogradients) + //INFO: 1. Looks like GZDoom tries to tile a sky texture into a 1024 pixel width texture. + //INFO: 2. If sky texture width <= height, it will be tiled to fit into 512 pixel height texture vertically. + private static CubeTexture MakeClassicSkyBox(Bitmap img) { - // CubeTexture must be square with power of 2 sides - int targetwidth = General.NextPowerOf2(img.Width); - int targetheight = General.NextPowerOf2(img.Height); - - // Get averaged top and bottom colors - Color topcolor, bottomcolor; - if (dogradients) + // Get averaged top and bottom colors from the original image + int tr = 0, tg = 0, tb = 0, br = 0, bg = 0, bb = 0; + const int colorsampleheight = 28; // TODO: is this value calculated from the image's height? + for (int w = 0; w < img.Width; w++) { - int tr = 0, tg = 0, tb = 0, br = 0, bg = 0, bb = 0; - for (int i = 0; i < img.Width; i++) + for (int h = 0; h < colorsampleheight; h++) { - Color c = img.GetPixel(i, 0); + Color c = img.GetPixel(w, h); tr += c.R; tg += c.G; tb += c.B; - c = img.GetPixel(i, img.Height - 1); + c = img.GetPixel(w, img.Height - 1 - h); br += c.R; bg += c.G; bb += c.B; } - - topcolor = Color.FromArgb(255, tr / img.Width, tg / img.Width, tb / img.Width); - bottomcolor = Color.FromArgb(255, br / img.Width, bg / img.Width, bb / img.Width); - } - else - { - // This should be built-in sky texture - Color c = img.GetPixel(img.Width / 2, 0); - topcolor = Color.FromArgb(255, c); - - c = img.GetPixel(img.Width / 2, img.Height - 1); - bottomcolor = Color.FromArgb(255, c); } - // Make it Po2 - if (img.Width != targetwidth || img.Height != targetheight) img = ResizeImage(img, targetwidth, targetheight); + int pixelscount = img.Width * colorsampleheight; + Color topcolor = Color.FromArgb(255, tr / pixelscount, tg / pixelscount, tb / pixelscount); + Color bottomcolor = Color.FromArgb(255, br / pixelscount, bg / pixelscount, bb / pixelscount); - // Make it square - if (targetwidth > targetheight) + // Make tiling image + int horiztiles = (int)Math.Ceiling(1024.0f / img.Width); + int verttiles = img.Height > 256 ? 1 : 2; + + Bitmap skyimage = new Bitmap(1024, img.Height * verttiles, img.PixelFormat); + + // Draw original image + using (Graphics g = Graphics.FromImage(skyimage)) { - int c = targetwidth / targetheight; - Bitmap result = new Bitmap(targetwidth, targetwidth, img.PixelFormat); - - // Tile vertically - using (Graphics g = Graphics.FromImage(result)) + for (int w = 0; w < horiztiles; w++) { - for (int i = 0; i < c; i++) g.DrawImage(img, 0, targetheight * i); + for (int h = 0; h < verttiles; h++) + { + g.DrawImage(img, img.Width * w, img.Height * h); + } } - - img = result; - } - else if (targetwidth < targetheight) - { - int c = targetheight / targetwidth; - Bitmap result = new Bitmap(targetheight, targetheight); - - // Tile horizontally - using (Graphics g = Graphics.FromImage(result)) - { - for (int i = 0; i < c; i++) g.DrawImage(img, targetwidth * i, 0); - } - - img = result; } // Make top and bottom images - Bitmap top = new Bitmap(img.Width, img.Height); - using (Graphics g = Graphics.FromImage(top)) + const int capsimgsize = 16; + Bitmap topimg = new Bitmap(capsimgsize, capsimgsize); + using (Graphics g = Graphics.FromImage(topimg)) { using (SolidBrush b = new SolidBrush(topcolor)) - { - g.FillRectangle(b, 0, 0, img.Width, img.Height); - } + g.FillRectangle(b, 0, 0, capsimgsize, capsimgsize); } - Bitmap bottom = new Bitmap(img.Width, img.Height); - using (Graphics g = Graphics.FromImage(bottom)) + Bitmap bottomimg = new Bitmap(capsimgsize, capsimgsize); + using (Graphics g = Graphics.FromImage(bottomimg)) { using (SolidBrush b = new SolidBrush(bottomcolor)) - { - g.FillRectangle(b, 0, 0, img.Width, img.Height); - } + g.FillRectangle(b, 0, 0, capsimgsize, capsimgsize); } // Apply top/bottom gradients - if (dogradients) + using (Graphics g = Graphics.FromImage(skyimage)) { - using (Graphics g = Graphics.FromImage(img)) + Rectangle area = new Rectangle(0, 0, skyimage.Width, colorsampleheight); + using (LinearGradientBrush b = new LinearGradientBrush(area, topcolor, Color.FromArgb(0, topcolor), 90f)) { - int gradientheight = img.Height / 6; - Rectangle area = new Rectangle(0, 0, img.Width, gradientheight); - using (LinearGradientBrush b = new LinearGradientBrush(area, topcolor, Color.FromArgb(0, topcolor), 90f)) - { - g.FillRectangle(b, area); - } + g.FillRectangle(b, area); + } - area = new Rectangle(0, img.Height - gradientheight, img.Width, gradientheight); - using (LinearGradientBrush b = new LinearGradientBrush(area, Color.FromArgb(0, bottomcolor), bottomcolor, 90f)) - { - area.Y += 1; - g.FillRectangle(b, area); - } + area = new Rectangle(0, skyimage.Height - colorsampleheight, skyimage.Width, colorsampleheight); + using (LinearGradientBrush b = new LinearGradientBrush(area, Color.FromArgb(0, bottomcolor), bottomcolor, 90f)) + { + area.Y += 1; + g.FillRectangle(b, area); } } + // Load the skysphere model... + Device device = General.Map.Graphics.Device; + World3DShader effect = General.Map.Graphics.Shaders.World3D; + + BoundingBoxSizes bbs = new BoundingBoxSizes(); + Stream modeldata = General.ThisAssembly.GetManifestResourceStream("CodeImp.DoomBuilder.Resources.SkySphere.md3"); + ModelReader.MD3LoadResult result = ModelReader.ReadMD3Model(ref bbs, true, modeldata, device, 0); + if (result.Meshes.Count != 3) throw new Exception("Skybox creation failed: " + result.Errors); + + // Make skysphere textures... + Texture texside = TextureFromBitmap(device, skyimage); + Texture textop = TextureFromBitmap(device, topimg); + Texture texbottom = TextureFromBitmap(device, bottomimg); + + // Calculate model scaling (gl.skydone.cpp:RenderDome() in GZDoom) + float yscale; + if (img.Height < 128) yscale = 128 / 230.0f; + else if (img.Height < 200) yscale = img.Height / 230.0f; + else if (img.Height < 241) yscale = 1.0f + ((img.Height - 200.0f) / 200.0f) * 1.17f; + else yscale = 1.2f * 1.17f; + // Make cubemap texture - CubeTexture cubemap = new CubeTexture(General.Map.Graphics.Device, img.Width, 1, Usage.None, Format.A8R8G8B8, Pool.Managed); + const int cubemaptexsize = 1024; + CubeTexture cubemap = new CubeTexture(device, cubemaptexsize, 1, Usage.RenderTarget, Format.A8R8G8B8, Pool.Default); - // Draw faces - img.RotateFlip(RotateFlipType.Rotate180FlipX); - DrawCubemapFace(cubemap, CubeMapFace.NegativeX, img); + // Set render settings... + device.SetRenderState(RenderState.ZEnable, false); + device.SetRenderState(RenderState.CullMode, Cull.None); - img.RotateFlip(RotateFlipType.Rotate90FlipNone); - DrawCubemapFace(cubemap, CubeMapFace.NegativeY, img); + // Make custom rendertarget + Surface rendertarget = Surface.CreateRenderTarget(device, cubemaptexsize, cubemaptexsize, Format.A8R8G8B8, MultisampleType.None, 0, false); - img.RotateFlip(RotateFlipType.Rotate90FlipNone); - DrawCubemapFace(cubemap, CubeMapFace.PositiveX, img); + // Setup matrices + Vector3 offset = new Vector3(0f, 0f, -1.8f); // Sphere size is 10 mu + Matrix mworld = Matrix.Multiply(Matrix.Identity, Matrix.Translation(offset) * Matrix.Scaling(1.0f, 1.0f, yscale)); + Matrix mprojection = Matrix.PerspectiveFovLH(Angle2D.PIHALF, 1.0f, 0.5f, 100.0f); - img.RotateFlip(RotateFlipType.Rotate90FlipNone); - DrawCubemapFace(cubemap, CubeMapFace.PositiveY, img); + // Place camera at origin + effect.CameraPosition = new Vector4(); - DrawCubemapFace(cubemap, CubeMapFace.PositiveZ, top); - DrawCubemapFace(cubemap, CubeMapFace.NegativeZ, bottom); + // Set the rendertarget to our own RT surface + device.SetRenderTarget(0, rendertarget); + + // Set custom depth stencil + device.DepthStencilSurface = Surface.CreateDepthStencil(device, cubemaptexsize, cubemaptexsize, General.Map.Graphics.DepthBuffer.Description.Format, MultisampleType.None, 0, false); + + // Begin rendering + device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.DarkRed, 1.0f, 0); + device.BeginScene(); + effect.Begin(); + effect.BeginPass(1); // Fullbright pass + + // Render to the six faces of the cube map + for (int i = 0; i < 6; i++) + { + Matrix faceview = GetCubeMapViewMatrix((CubeMapFace)i); + effect.WorldViewProj = mworld * faceview * mprojection; + + // Render the skysphere meshes + for (int j = 0; j < result.Meshes.Count; j++) + { + // Set appropriate texture + switch (result.Skins[j]) + { + case "top.png": effect.Texture1 = textop; break; + case "bottom.png": effect.Texture1 = texbottom; break; + case "side.png": effect.Texture1 = texside; break; + default: throw new Exception("Unexpected skin!"); + } + + // Commit changes + effect.ApplySettings(); + + // Render mesh + result.Meshes[j].DrawSubset(0); + } + + // Copy the rendered image from our RT surface to the texture face + Surface cubeface = cubemap.GetCubeMapSurface((CubeMapFace)i, 0); + device.StretchRectangle(rendertarget, cubeface, TextureFilter.None); + + cubeface.Dispose(); + } + + // End rendering + effect.EndPass(); + effect.End(); + device.EndScene(); + + // Dispose unneeded stuff + rendertarget.Dispose(); + textop.Dispose(); + texside.Dispose(); + texbottom.Dispose(); + + // Dispose skybox meshes + foreach (Mesh m in result.Meshes) m.Dispose(); // All done... return cubemap; @@ -2757,6 +2811,62 @@ namespace CodeImp.DoomBuilder.Data return destimage; } + private static Matrix GetCubeMapViewMatrix(CubeMapFace face) + { + Vector3 lookdir, updir; + + switch (face) + { + case CubeMapFace.PositiveX: + lookdir = new Vector3(1.0f, 0.0f, 0.0f); + updir = new Vector3(0.0f, 1.0f, 0.0f); + break; + + case CubeMapFace.NegativeX: + lookdir = new Vector3(-1.0f, 0.0f, 0.0f); + updir = new Vector3(0.0f, 1.0f, 0.0f); + break; + + case CubeMapFace.PositiveY: + lookdir = new Vector3(0.0f, 1.0f, 0.0f); + updir = new Vector3(0.0f, 0.0f, -1.0f); + break; + + case CubeMapFace.NegativeY: + lookdir = new Vector3(0.0f, -1.0f, 0.0f); + updir = new Vector3(0.0f, 0.0f, 1.0f); + break; + + case CubeMapFace.PositiveZ: + lookdir = new Vector3(0.0f, 0.0f, 1.0f); + updir = new Vector3(0.0f, 1.0f, 0.0f); + break; + + case CubeMapFace.NegativeZ: + lookdir = new Vector3(0.0f, 0.0f, -1.0f); + updir = new Vector3(0.0f, 1.0f, 0.0f); + break; + + default: + throw new Exception("Unknown CubeMapFace!"); + } + + Vector3 eye = new Vector3(); + return Matrix.LookAtLH(eye, lookdir, updir); + } + + private static Texture TextureFromBitmap(Device device, Image image) + { + MemoryStream ms = new MemoryStream(); + image.Save(ms, ImageFormat.Png); + ms.Seek(0, SeekOrigin.Begin); + Texture result = Texture.FromStream(device, ms); + ms.Close(); + ms.Dispose(); + + return result; + } + #endregion } } diff --git a/Source/Core/GZBuilder/md3/ModelReader.cs b/Source/Core/GZBuilder/md3/ModelReader.cs index 69f6e19..7c5e9f7 100644 --- a/Source/Core/GZBuilder/md3/ModelReader.cs +++ b/Source/Core/GZBuilder/md3/ModelReader.cs @@ -21,9 +21,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 { internal static class ModelReader { - #region ================== Variables + #region ================== Variables - private class MD3LoadResult + internal class MD3LoadResult { public List Skins; public List Meshes; @@ -228,12 +228,12 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 mde.Model.Radius = Math.Max(Math.Max(Math.Abs(bbs.MinY), Math.Abs(bbs.MaxY)), Math.Max(Math.Abs(bbs.MinX), Math.Abs(bbs.MaxX))); } - #endregion + #endregion - #region ================== MD3 + #region ================== MD3 - private static MD3LoadResult ReadMD3Model(ref BoundingBoxSizes bbs, bool useSkins, MemoryStream s, Device device, int frame) - { + internal static MD3LoadResult ReadMD3Model(ref BoundingBoxSizes bbs, bool useSkins, Stream s, Device device, int frame) + { long start = s.Position; MD3LoadResult result = new MD3LoadResult(); @@ -419,12 +419,12 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 return ""; } - #endregion + #endregion - #region ================== MD2 + #region ================== MD2 - private static MD3LoadResult ReadMD2Model(ref BoundingBoxSizes bbs, MemoryStream s, Device device, int frame, string framename) - { + private static MD3LoadResult ReadMD2Model(ref BoundingBoxSizes bbs, Stream s, Device device, int frame, string framename) + { long start = s.Position; MD3LoadResult result = new MD3LoadResult(); diff --git a/Source/Core/Geometry/Tools.cs b/Source/Core/Geometry/Tools.cs index fafd2fa..ee845df 100644 --- a/Source/Core/Geometry/Tools.cs +++ b/Source/Core/Geometry/Tools.cs @@ -551,8 +551,14 @@ namespace CodeImp.DoomBuilder.Geometry newsector.Brightness = General.Settings.DefaultBrightness; } - //mxd. Apply overrides? - if(useOverrides) + //mxd. Better any height than none + if (newsector.CeilHeight - newsector.FloorHeight <= 0) + { + newsector.CeilHeight = newsector.FloorHeight + (General.Settings.DefaultCeilingHeight - General.Settings.DefaultFloorHeight); + } + + //mxd. Apply overrides? + if (useOverrides) { if(General.Map.Options.OverrideCeilingTexture) newsector.SetCeilTexture(General.Map.Options.DefaultCeilingTexture); if(General.Map.Options.OverrideFloorTexture) newsector.SetFloorTexture(General.Map.Options.DefaultFloorTexture); diff --git a/Source/Core/Properties/Resources.Designer.cs b/Source/Core/Properties/Resources.Designer.cs index a17717a..8bda0f3 100644 --- a/Source/Core/Properties/Resources.Designer.cs +++ b/Source/Core/Properties/Resources.Designer.cs @@ -1179,16 +1179,27 @@ namespace CodeImp.DoomBuilder.Properties { return ((System.Drawing.Bitmap)(obj)); } } - - internal static System.Drawing.Bitmap Sky - { - get - { + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Sky { + get { object obj = ResourceManager.GetObject("Sky", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } - + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. + /// + internal static byte[] SkySphere { + get { + object obj = ResourceManager.GetObject("SkySphere", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// diff --git a/Source/Core/Properties/Resources.resx b/Source/Core/Properties/Resources.resx index b333e4b..3a2f26b 100644 --- a/Source/Core/Properties/Resources.resx +++ b/Source/Core/Properties/Resources.resx @@ -547,6 +547,9 @@ ..\Resources\Sky.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\SkySphere.md3;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ..\Resources\zonebuilder.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a diff --git a/Source/Core/Resources/SkySphere.md3 b/Source/Core/Resources/SkySphere.md3 new file mode 100644 index 0000000000000000000000000000000000000000..753932b1096f08526d9b9ab77a525faeac0495b6 GIT binary patch literal 12148 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 literal 0 HcmV?d00001 diff --git a/Source/Core/VisualModes/VisualGeometry.cs b/Source/Core/VisualModes/VisualGeometry.cs index 75a920c..9924daf 100644 --- a/Source/Core/VisualModes/VisualGeometry.cs +++ b/Source/Core/VisualModes/VisualGeometry.cs @@ -84,7 +84,7 @@ namespace CodeImp.DoomBuilder.VisualModes // Internal properties public WorldVertex[] Vertices { get { return vertices; } } //mxd internal int VertexOffset { get { return vertexoffset; } set { vertexoffset = value; } } - internal int Triangles { get { return triangles; } } + public int Triangles { get { return triangles; } } //mxd public Vector3D[] BoundingBox { get { return boundingBox; } } diff --git a/Source/Core/VisualModes/VisualMode.cs b/Source/Core/VisualModes/VisualMode.cs index 4ba286b..cf27d47 100644 --- a/Source/Core/VisualModes/VisualMode.cs +++ b/Source/Core/VisualModes/VisualMode.cs @@ -158,8 +158,11 @@ namespace CodeImp.DoomBuilder.VisualModes { base.OnEngage(); - // Update projection (mxd) - General.Map.CRenderer3D.CreateProjection(); + //mxd. Sky texture may need recreating + General.Map.Data.UpdateSkybox(); + + // Update projection (mxd) + General.Map.CRenderer3D.CreateProjection(); // Update the used textures General.Map.Data.UpdateUsedTextures(); @@ -878,8 +881,11 @@ namespace CodeImp.DoomBuilder.VisualModes // Make new blockmap FillBlockMap(); - // Visibility culling (this re-creates the needed resources) - DoCulling(); + //mxd. Sky texture may need recreating + General.Map.Data.UpdateSkybox(); + + // Visibility culling (this re-creates the needed resources) + DoCulling(); } /// diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs index 0333525..343aae7 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs @@ -531,9 +531,9 @@ namespace CodeImp.DoomBuilder.BuilderModes //mxd protected void SelectNeighbours(long longtexture, bool select, bool withSameTexture, bool withSameHeight) { - if(Sidedef.Sector == null || (!withSameTexture && !withSameHeight)) return; + if (Sidedef.Sector == null || Triangles < 1 || (!withSameTexture && !withSameHeight)) return; - Rectangle rect = BuilderModesTools.GetSidedefPartSize(this); + Rectangle rect = BuilderModesTools.GetSidedefPartSize(this); if(rect.Height == 0) return; if(select && !selected)