Exemplo n.º 1
0
        /// <summary>Resizes the specified texture to the specified width and height and returns the result.</summary>
        /// <param name="texture">The texture.</param>
        /// <param name="width">The new width.</param>
        /// <param name="height">The new height.</param>
        /// <returns>The resize texture, or the original if already of the specified size.</returns>
        /// <exception cref="System.NotSupportedException">The bits per pixel in the source texture is not supported.</exception>
        /// <exception cref="System.OverflowException">The resized texture would exceed the maximum possible size.</exception>
        public static Texture Resize(Texture texture, int width, int height)
        {
            if (width == texture.Width && height == texture.Height)
            {
                return(texture);
            }

            if (texture.BitsPerPixel != 32)
            {
                throw new NotSupportedException("The number of bits per pixel is not supported.");
            }

            TextureTransparencyType type = texture.GetTransparencyType();

            /*
             * Convert the texture into a bitmap.
             * */
            Bitmap     bitmap = new Bitmap(texture.Width, texture.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            BitmapData data   = bitmap.LockBits(new Rectangle(0, 0, texture.Width, texture.Height), ImageLockMode.WriteOnly, bitmap.PixelFormat);

            Marshal.Copy(texture.Bytes, 0, data.Scan0, texture.Bytes.Length);
            bitmap.UnlockBits(data);

            /*
             * Scale the bitmap.
             * */
            Bitmap   scaledBitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            Graphics graphics     = Graphics.FromImage(scaledBitmap);

            graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
            graphics.PixelOffsetMode   = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
            graphics.DrawImage(bitmap, new Rectangle(0, 0, width, height), new Rectangle(0, 0, texture.Width, texture.Height), GraphicsUnit.Pixel);
            graphics.Dispose();
            bitmap.Dispose();

            /*
             * Convert the bitmap into a texture.
             * */
            data = scaledBitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, scaledBitmap.PixelFormat);
            int newSize;

            try
            {
                newSize = checked (4 * width * height);
            }
            catch (OverflowException)
            {
                throw new OverflowException("The resized texture would exceed the maximum possible size.");
            }

            byte[] bytes = new byte[newSize];
            Marshal.Copy(data.Scan0, bytes, 0, bytes.Length);
            scaledBitmap.UnlockBits(data);
            scaledBitmap.Dispose();

            /*
             * Ensure opaque and partially transparent
             * textures have valid alpha components.
             * */
            if (type == TextureTransparencyType.Opaque)
            {
                for (int i = 3; i < bytes.Length; i += 4)
                {
                    bytes[i] = 255;
                }
            }
            else if (type == TextureTransparencyType.Partial)
            {
                for (int i = 3; i < bytes.Length; i += 4)
                {
                    bytes[i] = bytes[i] < 128 ? (byte)0 : (byte)255;
                }
            }

            Texture result = new Texture(width, height, 32, bytes, texture.Palette);

            return(result);
        }
Exemplo n.º 2
0
        /// <summary>Makes an object visible within the world</summary>
        /// <param name="ObjectIndex">The object's index</param>
        /// <param name="Type">Whether this is a static or dynamic object</param>
        internal static void ShowObject(int ObjectIndex, ObjectType Type)
        {
            if (ObjectManager.Objects[ObjectIndex] == null)
            {
                return;
            }
            if (ObjectManager.Objects[ObjectIndex].RendererIndex == 0)
            {
                if (ObjectCount >= Objects.Length)
                {
                    Array.Resize <Object>(ref Objects, Objects.Length << 1);
                }
                Objects[ObjectCount].ObjectIndex = ObjectIndex;
                Objects[ObjectCount].Type        = Type;
                int f = ObjectManager.Objects[ObjectIndex].Mesh.Faces.Length;
                Objects[ObjectCount].FaceListReferences = new ObjectListReference[f];
                for (int i = 0; i < f; i++)
                {
                    bool alpha = false;
                    int  k     = ObjectManager.Objects[ObjectIndex].Mesh.Faces[i].Material;
                    OpenGlTextureWrapMode wrap = OpenGlTextureWrapMode.ClampClamp;
                    if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture != null | ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture != null)
                    {
                        if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].WrapMode == null)
                        {
                            // If the object does not have a stored wrapping mode, determine it now
                            for (int v = 0; v < ObjectManager.Objects[ObjectIndex].Mesh.Vertices.Length; v++)
                            {
                                if (ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.X <0.0f |
                                                                                                              ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.X> 1.0f)
                                {
                                    wrap |= OpenGlTextureWrapMode.RepeatClamp;
                                }
                                if (ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.Y <0.0f |
                                                                                                              ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.Y> 1.0f)
                                {
                                    wrap |= OpenGlTextureWrapMode.ClampRepeat;
                                }
                            }
                        }
                        else
                        {
                            //Yuck cast, but we need the null, as otherwise requires rewriting the texture indexer
                            wrap = (OpenGlTextureWrapMode)ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].WrapMode;
                        }
                        if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture != null)
                        {
                            if (Program.CurrentHost.LoadTexture(ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture, wrap))
                            {
                                TextureTransparencyType type =
                                    ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture.Transparency;
                                if (type == TextureTransparencyType.Alpha)
                                {
                                    alpha = true;
                                }
                                else if (type == TextureTransparencyType.Partial &&
                                         Interface.CurrentOptions.TransparencyMode == TransparencyMode.Quality)
                                {
                                    alpha = true;
                                }
                            }
                        }
                        if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture != null)
                        {
                            if (Program.CurrentHost.LoadTexture(ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture, wrap))
                            {
                                TextureTransparencyType type =
                                    ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture.Transparency;
                                if (type == TextureTransparencyType.Alpha)
                                {
                                    alpha = true;
                                }
                                else if (type == TextureTransparencyType.Partial &
                                         Interface.CurrentOptions.TransparencyMode == TransparencyMode.Quality)
                                {
                                    alpha = true;
                                }
                            }
                        }
                    }
                    if (Type == ObjectType.Overlay & Camera.CurrentRestriction != CameraRestrictionMode.NotAvailable)
                    {
                        alpha = true;
                    }
                    else if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].Color.A != 255)
                    {
                        alpha = true;
                    }
                    else if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].BlendMode == MeshMaterialBlendMode.Additive)
                    {
                        alpha = true;
                    }
                    else if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].GlowAttenuationData != 0)
                    {
                        alpha = true;
                    }
                    ObjectListType listType;
                    switch (Type)
                    {
                    case ObjectType.Static:
                        listType = alpha ? ObjectListType.DynamicAlpha : ObjectListType.StaticOpaque;
                        break;

                    case ObjectType.Dynamic:
                        listType = alpha ? ObjectListType.DynamicAlpha : ObjectListType.DynamicOpaque;
                        break;

                    case ObjectType.Overlay:
                        listType = alpha ? ObjectListType.OverlayAlpha : ObjectListType.OverlayOpaque;
                        break;

                    default:
                        throw new InvalidOperationException();
                    }
                    if (listType == ObjectListType.StaticOpaque)
                    {
                        /*
                         * For the static opaque list, insert the face into
                         * the first vacant position in the matching group's list.
                         * */
                        int groupIndex = (int)ObjectManager.Objects[ObjectIndex].GroupIndex;
                        if (groupIndex >= StaticOpaque.Length)
                        {
                            if (StaticOpaque.Length == 0)
                            {
                                StaticOpaque = new ObjectGroup[16];
                            }
                            while (groupIndex >= StaticOpaque.Length)
                            {
                                Array.Resize <ObjectGroup>(ref StaticOpaque, StaticOpaque.Length << 1);
                            }
                        }
                        if (StaticOpaque[groupIndex] == null)
                        {
                            StaticOpaque[groupIndex] = new ObjectGroup();
                        }
                        ObjectList list     = StaticOpaque[groupIndex].List;
                        int        newIndex = list.FaceCount;
                        for (int j = 0; j < list.FaceCount; j++)
                        {
                            if (list.Faces[j] == null)
                            {
                                newIndex = j;
                                break;
                            }
                        }
                        if (newIndex == list.FaceCount)
                        {
                            if (list.FaceCount == list.Faces.Length)
                            {
                                Array.Resize <ObjectFace>(ref list.Faces, list.Faces.Length << 1);
                            }
                            list.FaceCount++;
                        }
                        list.Faces[newIndex] = new ObjectFace
                        {
                            ObjectListIndex = ObjectCount,
                            ObjectIndex     = ObjectIndex,
                            FaceIndex       = i,
                            Wrap            = wrap
                        };

                        // HACK: Let's store the wrapping mode.

                        StaticOpaque[groupIndex].Update            = true;
                        Objects[ObjectCount].FaceListReferences[i] = new ObjectListReference(listType, newIndex);
                        Game.InfoStaticOpaqueFaceCount++;

                        /*
                         * Check if the given object has a bounding box, and insert it to the end of the list of bounding boxes if required
                         */
                        if (ObjectManager.Objects[ObjectIndex].Mesh.BoundingBox != null)
                        {
                            int Index = list.BoundingBoxes.Length;
                            for (int j = 0; j < list.BoundingBoxes.Length; j++)
                            {
                                if (list.Faces[j] == null)
                                {
                                    Index = j;
                                    break;
                                }
                            }
                            if (Index == list.BoundingBoxes.Length)
                            {
                                Array.Resize <BoundingBox>(ref list.BoundingBoxes, list.BoundingBoxes.Length << 1);
                            }
                            list.BoundingBoxes[Index].Upper = ObjectManager.Objects[ObjectIndex].Mesh.BoundingBox[0];
                            list.BoundingBoxes[Index].Lower = ObjectManager.Objects[ObjectIndex].Mesh.BoundingBox[1];
                        }
                    }
                    else
                    {
                        /*
                         * For all other lists, insert the face at the end of the list.
                         * */
                        ObjectList list;
                        switch (listType)
                        {
                        case ObjectListType.DynamicOpaque:
                            list = DynamicOpaque;
                            break;

                        case ObjectListType.DynamicAlpha:
                            list = DynamicAlpha;
                            break;

                        case ObjectListType.OverlayOpaque:
                            list = OverlayOpaque;
                            break;

                        case ObjectListType.OverlayAlpha:
                            list = OverlayAlpha;
                            break;

                        default:
                            throw new InvalidOperationException();
                        }
                        if (list.FaceCount == list.Faces.Length)
                        {
                            Array.Resize <ObjectFace>(ref list.Faces, list.Faces.Length << 1);
                        }
                        list.Faces[list.FaceCount] = new ObjectFace
                        {
                            ObjectListIndex = ObjectCount,
                            ObjectIndex     = ObjectIndex,
                            FaceIndex       = i,
                            Wrap            = wrap
                        };

                        // HACK: Let's store the wrapping mode.

                        Objects[ObjectCount].FaceListReferences[i] = new ObjectListReference(listType, list.FaceCount);
                        list.FaceCount++;
                    }
                }
                ObjectManager.Objects[ObjectIndex].RendererIndex = ObjectCount + 1;
                ObjectCount++;
            }
        }