Exemple #1
0
 // This adds a patch to the texture
 public void AddPatch(TexturePatch patch)
 {
     // Add it
     patches.Add(patch);
     if (patch.LumpName == Name)
     {
         hasPatchWithSameName = true;                                    //mxd
     }
 }
Exemple #2
0
        //mxd
        private Bitmap TransformPatch(Bitmap bitmap, TexturePatch p, Bitmap patchbmp)
        {
            //mxd. Flip
            if (p.FlipX || p.FlipY)
            {
                RotateFlipType flip;
                if (p.FlipX && !p.FlipY)
                {
                    flip = RotateFlipType.RotateNoneFlipX;
                }
                else if (!p.FlipX && p.FlipY)
                {
                    flip = RotateFlipType.RotateNoneFlipY;
                }
                else
                {
                    flip = RotateFlipType.RotateNoneFlipXY;
                }
                patchbmp.RotateFlip(flip);
            }

            //mxd. Then rotate. I do it this way because RotateFlip function rotates THEN flips, and GZDoom does it the other way around.
            if (p.Rotate != 0)
            {
                RotateFlipType rotate;
                switch (p.Rotate)
                {
                case 90:  rotate = RotateFlipType.Rotate90FlipNone; break;

                case 180: rotate = RotateFlipType.Rotate180FlipNone; break;

                default:  rotate = RotateFlipType.Rotate270FlipNone; break;
                }
                patchbmp.RotateFlip(rotate);
            }

            // Adjust patch alpha, apply tint or blend
            if (p.BlendStyle != TexturePathBlendStyle.NONE || p.RenderStyle != TexturePathRenderStyle.COPY)
            {
                BitmapData bmpdata = null;

                try
                {
                    bmpdata = patchbmp.LockBits(new Rectangle(0, 0, patchbmp.Size.Width, patchbmp.Size.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                }
                catch (Exception e)
                {
                    General.ErrorLogger.Add(ErrorType.Error, "Cannot lock image \"" + p.LumpName + "\" for alpha adjustment. " + e.GetType().Name + ": " + e.Message);
                }

                if (bmpdata != null)
                {
                    PixelColor *pixels     = (PixelColor *)(bmpdata.Scan0.ToPointer());
                    int         numpixels  = bmpdata.Width * bmpdata.Height;
                    int         patchalpha = (int)Math.Round(General.Clamp(p.Alpha, 0f, 1f) * 255);             //convert alpha to [0-255] range

                    //mxd. Blend/Tint support
                    if (p.BlendStyle == TexturePathBlendStyle.BLEND)
                    {
                        for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                        {
                            cp->r = (byte)((cp->r * p.BlendColor.r) * PixelColor.BYTE_TO_FLOAT);
                            cp->g = (byte)((cp->g * p.BlendColor.g) * PixelColor.BYTE_TO_FLOAT);
                            cp->b = (byte)((cp->b * p.BlendColor.b) * PixelColor.BYTE_TO_FLOAT);
                        }
                    }
                    else if (p.BlendStyle == TexturePathBlendStyle.TINT)
                    {
                        float tintammount = p.BlendColor.a * PixelColor.BYTE_TO_FLOAT;                        // -0.1f;

                        if (tintammount > 0)
                        {
                            float br             = p.BlendColor.r * PixelColor.BYTE_TO_FLOAT * tintammount;
                            float bg             = p.BlendColor.g * PixelColor.BYTE_TO_FLOAT * tintammount;
                            float bb             = p.BlendColor.b * PixelColor.BYTE_TO_FLOAT * tintammount;
                            float invtintammount = 1.0f - tintammount;

                            for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                            {
                                cp->r = (byte)(((cp->r * PixelColor.BYTE_TO_FLOAT) * invtintammount + br) * 255.0f);
                                cp->g = (byte)(((cp->g * PixelColor.BYTE_TO_FLOAT) * invtintammount + bg) * 255.0f);
                                cp->b = (byte)(((cp->b * PixelColor.BYTE_TO_FLOAT) * invtintammount + bb) * 255.0f);
                            }
                        }
                    }

                    //mxd. Apply RenderStyle
                    if (p.RenderStyle == TexturePathRenderStyle.BLEND)
                    {
                        for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                        {
                            cp->a = (byte)((cp->a * patchalpha) * PixelColor.BYTE_TO_FLOAT);
                        }
                    }
                    //mxd. We need a copy of underlying part of texture for these styles
                    else if (p.RenderStyle != TexturePathRenderStyle.COPY)
                    {
                        // Copy portion of texture
                        int lockWidth  = (p.X + patchbmp.Size.Width > bitmap.Width) ? bitmap.Width - p.X : patchbmp.Size.Width;
                        int lockHeight = (p.Y + patchbmp.Size.Height > bitmap.Height) ? bitmap.Height - p.Y : patchbmp.Size.Height;

                        Bitmap source = new Bitmap(patchbmp.Size.Width, patchbmp.Size.Height);
                        using (Graphics sg = Graphics.FromImage(source))
                            sg.DrawImageUnscaled(bitmap, new Rectangle(-p.X, -p.Y, lockWidth, lockHeight));

                        // Lock texture
                        BitmapData texturebmpdata = null;

                        try
                        {
                            texturebmpdata = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                        }
                        catch (Exception e)
                        {
                            General.ErrorLogger.Add(ErrorType.Error, "Cannot lock texture \"" + this.Name + "\" to apply render style. " + e.GetType().Name + ": " + e.Message);
                        }

                        if (texturebmpdata != null)
                        {
                            PixelColor *texturepixels = (PixelColor *)(texturebmpdata.Scan0.ToPointer());
                            PixelColor *tcp           = texturepixels + numpixels - 1;

                            switch (p.RenderStyle)
                            {
                            case TexturePathRenderStyle.ADD:
                                for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                                {
                                    cp->r = (byte)Math.Min(255, cp->r + tcp->r);
                                    cp->g = (byte)Math.Min(255, cp->g + tcp->g);
                                    cp->b = (byte)Math.Min(255, cp->b + tcp->b);
                                    cp->a = (byte)((cp->a * patchalpha) * PixelColor.BYTE_TO_FLOAT);
                                    tcp--;
                                }
                                break;

                            case TexturePathRenderStyle.SUBTRACT:
                                for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                                {
                                    cp->r = (byte)Math.Max(0, tcp->r - cp->r);
                                    cp->g = (byte)Math.Max(0, tcp->g - cp->g);
                                    cp->b = (byte)Math.Max(0, tcp->b - cp->b);
                                    cp->a = (byte)((cp->a * patchalpha) * PixelColor.BYTE_TO_FLOAT);
                                    tcp--;
                                }
                                break;

                            case TexturePathRenderStyle.REVERSE_SUBTRACT:
                                for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                                {
                                    cp->r = (byte)Math.Max(0, cp->r - tcp->r);
                                    cp->g = (byte)Math.Max(0, cp->g - tcp->g);
                                    cp->b = (byte)Math.Max(0, cp->b - tcp->b);
                                    cp->a = (byte)((cp->a * patchalpha) * PixelColor.BYTE_TO_FLOAT);
                                    tcp--;
                                }
                                break;

                            case TexturePathRenderStyle.MODULATE:
                                for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                                {
                                    cp->r = (byte)((cp->r * tcp->r) * PixelColor.BYTE_TO_FLOAT);
                                    cp->g = (byte)((cp->g * tcp->g) * PixelColor.BYTE_TO_FLOAT);
                                    cp->b = (byte)((cp->b * tcp->b) * PixelColor.BYTE_TO_FLOAT);
                                    tcp--;
                                }
                                break;
                            }

                            source.UnlockBits(texturebmpdata);
                        }
                    }

                    patchbmp.UnlockBits(bmpdata);
                }
            }

            return(patchbmp);
        }
Exemple #3
0
 // This adds a patch to the texture
 public void AddPatch(TexturePatch patch)
 {
     // Add it
     patches.Add(patch);
 }