예제 #1
0
        /// <summary>
        /// Function to read a keyframe from a chunk.
        /// </summary>
        /// <param name="chunk">Chunk to read from.</param>
        void IKeyFrame.FromChunk(GorgonChunkReader chunk)
        {
            Value = null;
            Time  = chunk.ReadFloat();
            bool hasTexture = chunk.ReadBoolean();

            // Get the texture region we're using.
            TextureRegion = chunk.ReadRectangleF();

            if (!hasTexture)
            {
                return;
            }

            // Get our texture name.
            _textureName = chunk.ReadString();

            // Read in our texture information.
            _settings = new GorgonTexture2DSettings
            {
                ArrayCount       = chunk.ReadInt32(),
                Format           = chunk.Read <BufferFormat>(),
                Size             = chunk.ReadSize(),
                IsTextureCube    = chunk.ReadBoolean(),
                MipCount         = chunk.ReadInt32(),
                Multisampling    = new GorgonMultisampling(chunk.ReadInt32(), chunk.ReadInt32()),
                Usage            = BufferUsage.Default,
                ShaderViewFormat = BufferFormat.Unknown
            };

            // Defer load the texture.
            GetTexture();
        }
예제 #2
0
        /// <summary>
        /// Function to create 2D Gorgon image data from a single System.Drawing.Image.
        /// </summary>
        /// <param name="wic">Windows Imaging Component interface to use.</param>
        /// <param name="image">An image to convert.</param>
        /// <param name="options">Options for conversion.</param>
        /// <returns>The converted image data.</returns>
        public static GorgonImageData Create2DImageDataFromImage(GorgonWICImage wic, Image image, GorgonGDIOptions options)
        {
            if (options.Format == BufferFormat.Unknown)
            {
                options.Format = GetBufferFormat(image.PixelFormat);
            }

            if (options.Format == BufferFormat.Unknown)
            {
                throw new GorgonException(GorgonResult.FormatNotSupported,
                                          string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, image.PixelFormat));
            }

            if (options.Width < 1)
            {
                options.Width = image.Width;
            }

            if (options.Height < 1)
            {
                options.Height = image.Height;
            }

            // Specify 0 to generate a full mip chain.
            options.MipCount = options.MipCount < 1
                                                   ? GorgonImageData.GetMaxMipCount(options.Width, options.Height)
                                                   : options.MipCount.Min(GorgonImageData.GetMaxMipCount(options.Width, options.Height));

            // Create our settings.
            var settings = new GorgonTexture2DSettings
            {
                Width      = options.Width,
                Height     = options.Height,
                MipCount   = options.MipCount,
                ArrayCount = 1,
                Format     = options.Format,
                AllowUnorderedAccessViews = options.AllowUnorderedAccess,
                ShaderViewFormat          = options.ViewFormat,
                Usage = options.Usage
            };

            // Create our image data.
            var data = new GorgonImageData(settings);

            // Using the image, convert to a WIC bitmap object.
            using (Bitmap bitmap = wic.CreateWICImageFromImage(image))
            {
                for (int mipLevel = 0; mipLevel < options.MipCount; mipLevel++)
                {
                    var buffer = data.Buffers[mipLevel];
                    wic.AddWICBitmapToImageData(bitmap, options.Filter, options.Dither, buffer, options.UseClipping);
                }
            }

            return(data);
        }
예제 #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GorgonKeyTexture2D" /> struct.
 /// </summary>
 /// <param name="time">The time for the key frame.</param>
 /// <param name="value">The value to apply to the key frame.</param>
 /// <param name="region">Region on the texture to update.</param>
 public GorgonKeyTexture2D(float time, GorgonTexture2D value, RectangleF region)
 {
     Time          = time;
     _dataType     = typeof(GorgonTexture2D);
     Value         = value;
     TextureRegion = region;
     if (value != null)
     {
         _textureName = value.Name;
         _settings    = value.Settings;
     }
     else
     {
         // We didn't specify a texture, so don't defer it for later.
         _textureName = string.Empty;
         _settings    = null;
     }
 }
예제 #4
0
        /// <summary>
        /// Function to read the meta data for the image.
        /// </summary>
        /// <param name="stream">Stream containing the image data.</param>
        /// <returns>An image settings object containing information about the image.</returns>
        private static IImageSettings ReadMetaData(Stream stream)
        {
            if (!stream.CanRead)
            {
                throw new ArgumentException(@"Stream is write only.", "stream");
            }

            if (stream.Position + TvHeader.SizeInBytes >= stream.Length)
            {
                throw new EndOfStreamException();
            }

            // We only support 2D images with the tv format.
            var      settings = new GorgonTexture2DSettings();
            TvHeader header;

            // Load the header for the image.
            using (var reader = new GorgonBinaryReader(stream, true))
            {
                header = reader.ReadValue <TvHeader>();
            }

            // Ensure we've got the correct data.
            if (header.MagicValueData != MagicValue)
            {
                throw new ArgumentException(@"The image data is not a tv image.", "stream");
            }

            // Ensure the width/height are valid.
            if ((header.Width < 0) ||
                (header.Height < 0))
            {
                throw new ArgumentException(@"The image in this stream has an invalid width/height.", "stream");
            }

            settings.Width  = header.Width;
            settings.Height = header.Height;
            settings.Format = BufferFormat.R8G8B8A8_UIntNormal;

            return(settings);
        }
예제 #5
0
        /// <summary>
        /// Function to retrieve the texture if it's not assigned.
        /// </summary>
        /// <returns>TRUE if the texture was found, FALSE if not.</returns>
        internal bool GetTexture()
        {
            if (!string.IsNullOrEmpty(_textureName))
            {
                // Copy to local values because LINQ doesn't seem to work with members
                // of a struct.
                string textureName = _textureName;
                GorgonTexture2DSettings settings = _settings;

                // Our texture is deferred, so we need to find it in the graphics object tracked
                // object list.
                // In order to do that, we need to find all graphics objects first:
                var graphics = Gorgon.GetTrackedObjectsOfType <GorgonGraphics>();

                // We have no graphics, then we can't do display a texture anyway, so throw an exception.
                if (graphics.Count == 0)
                {
                    throw new GorgonException(GorgonResult.NotInitialized, Resources.GORANM_KEYFRAME_TEXTURE_NOGFX);
                }

                var textures = (from graphicsObject in graphics
                                from graphicsTexture in graphicsObject.GetTrackedObjectsOfType <GorgonTexture2D>()
                                select graphicsTexture).ToArray();

                // Then, we begin our search by looking at -all- the texture information we have:
                Value = (from graphicsTexture in textures
                         where (string.Equals(graphicsTexture.Name, textureName, StringComparison.OrdinalIgnoreCase)) &&
                         (graphicsTexture.Settings.ArrayCount == settings.ArrayCount) &&
                         (graphicsTexture.Settings.Format == settings.Format) &&
                         (graphicsTexture.Settings.Height == settings.Height) &&
                         (graphicsTexture.Settings.Width == settings.Width) &&
                         (graphicsTexture.Settings.IsTextureCube == settings.IsTextureCube) &&
                         (graphicsTexture.Settings.MipCount == settings.MipCount) &&
                         (graphicsTexture.Settings.Multisampling == settings.Multisampling)
                         select graphicsTexture).FirstOrDefault();

                // ReSharper disable ConvertIfStatementToNullCoalescingExpression
                if (Value == null)
                {
                    // That one failed, so just try and look it up by name, width, height and format.
                    Value = (from graphicsTexture in textures
                             where (string.Equals(graphicsTexture.Name, textureName, StringComparison.OrdinalIgnoreCase)) &&
                             (graphicsTexture.Settings.Format == settings.Format) &&
                             (graphicsTexture.Settings.Height == settings.Height) &&
                             (graphicsTexture.Settings.Width == settings.Width)
                             select graphicsTexture).FirstOrDefault() ?? (from graphicsTexture in textures
                                                                          where (string.Equals(graphicsTexture.Name, textureName, StringComparison.OrdinalIgnoreCase))
                                                                          select graphicsTexture).FirstOrDefault();
                }
                // ReSharper restore ConvertIfStatementToNullCoalescingExpression
            }

            // We have our texture, stop deferring.
            if (Value == null)
            {
                return(false);
            }

            _textureName = string.Empty;
            return(true);
        }
예제 #6
0
        /// <summary>
        /// Function to read in the DDS header from a stream.
        /// </summary>
        /// <param name="stream">Stream containing the data.</param>
        /// <param name="conversionFlags">Flags for conversion.</param>
        /// <returns>New image settings.</returns>
        private IImageSettings ReadHeader(GorgonDataStream stream, out TGAConversionFlags conversionFlags)
        {
            IImageSettings settings = new GorgonTexture2DSettings();

            conversionFlags = TGAConversionFlags.None;

            // Get the header for the file.
            var header = stream.Read <TGAHeader>();

            if ((header.ColorMapType != 0) || (header.ColorMapLength != 0) ||
                (header.Width <= 0) || (header.Height <= 0) ||
                ((header.Descriptor & TGADescriptor.Interleaved2Way) == TGADescriptor.Interleaved2Way) ||
                ((header.Descriptor & TGADescriptor.Interleaved4Way) == TGADescriptor.Interleaved4Way))
            {
                throw new IOException(string.Format(Resources.GORGFX_IMAGE_FILE_INCORRECT_DECODER, Codec));
            }

            settings.MipCount   = 1;
            settings.ArrayCount = 1;

            switch (header.ImageType)
            {
            case TGAImageType.TrueColor:
            case TGAImageType.TrueColorRLE:
                switch (header.BPP)
                {
                case 16:
                    settings.Format = BufferFormat.B5G5R5A1_UIntNormal;
                    break;

                case 24:
                case 32:
                    settings.Format = BufferFormat.R8G8B8A8_UIntNormal;
                    if (header.BPP == 24)
                    {
                        conversionFlags |= TGAConversionFlags.Expand;
                    }
                    break;
                }

                if (header.ImageType == TGAImageType.TrueColorRLE)
                {
                    conversionFlags |= TGAConversionFlags.RLE;
                }
                break;

            case TGAImageType.BlackAndWhite:
            case TGAImageType.BlackAndWhiteRLE:
                if (header.BPP == 8)
                {
                    settings.Format = BufferFormat.R8_UIntNormal;
                }
                else
                {
                    throw new IOException(string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, header.ImageType));
                }

                if (header.ImageType == TGAImageType.BlackAndWhiteRLE)
                {
                    conversionFlags |= TGAConversionFlags.RLE;
                }
                break;

            default:
                throw new IOException(string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, header.ImageType));
            }

            settings.Width  = header.Width;
            settings.Height = header.Height;

            if ((header.Descriptor & TGADescriptor.InvertX) == TGADescriptor.InvertX)
            {
                conversionFlags |= TGAConversionFlags.InvertX;
            }

            if ((header.Descriptor & TGADescriptor.InvertY) == TGADescriptor.InvertY)
            {
                conversionFlags |= TGAConversionFlags.InvertY;
            }

            if (header.IDLength <= 0)
            {
                return(settings);
            }

            // Skip these bytes.
            for (int i = 0; i < header.IDLength; i++)
            {
                stream.ReadByte();
            }

            return(settings);
        }
예제 #7
0
        /// <summary>
        /// Function to create 2D Gorgon image data from multiple single System.Drawing.Images.
        /// </summary>
        /// <param name="wic">Windows Imaging Component interface to use.</param>
        /// <param name="images">Images to convert.</param>
        /// <param name="options">Options for conversion.</param>
        /// <returns>The converted image data.</returns>
        public static GorgonImageData Create2DImageDataFromImages(GorgonWICImage wic, IList <Image> images, GorgonGDIOptions options)
        {
            if (options.Format == BufferFormat.Unknown)
            {
                options.Format = GetBufferFormat(images[0].PixelFormat);
            }

            if (options.Format == BufferFormat.Unknown)
            {
                throw new GorgonException(GorgonResult.FormatNotSupported,
                                          string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, images[0].PixelFormat));
            }

            if (images.Any(item => item.PixelFormat != images[0].PixelFormat))
            {
                throw new GorgonException(GorgonResult.CannotCreate,
                                          string.Format(Resources.GORGFX_IMAGE_MUST_BE_SAME_FORMAT, images[0].PixelFormat));
            }

            if (options.Width < 1)
            {
                options.Width = images[0].Width;
            }

            if (options.Height < 1)
            {
                options.Height = images[0].Height;
            }

            if (options.ArrayCount < 1)
            {
                options.ArrayCount = 1;
            }

            options.MipCount = options.MipCount < 1
                                                   ? 1
                                                   : options.MipCount.Min(GorgonImageData.GetMaxMipCount(options.Width, options.Height));

            // Create our settings.
            var settings = new GorgonTexture2DSettings
            {
                Width      = options.Width,
                Height     = options.Height,
                MipCount   = options.MipCount,
                ArrayCount = options.ArrayCount,
                Format     = options.Format,
                AllowUnorderedAccessViews = options.AllowUnorderedAccess,
                ShaderViewFormat          = options.ViewFormat,
                Usage = options.Usage
            };

            if ((options.ArrayCount * options.MipCount) > images.Count)
            {
                throw new GorgonException(GorgonResult.CannotCreate, Resources.GORGFX_IMAGE_MIPCOUNT_ARRAYCOUNT_TOO_LARGE);
            }

            // Create our image data.
            var data = new GorgonImageData(settings);

            for (int array = 0; array < data.Settings.ArrayCount; array++)
            {
                for (int mipLevel = 0; mipLevel < data.Settings.MipCount; mipLevel++)
                {
                    var image = images[array * data.Settings.MipCount + mipLevel];

                    if (image == null)
                    {
                        continue;
                    }

                    // Using the image, convert to a WIC bitmap object.
                    using (var bitmap = wic.CreateWICImageFromImage(image))
                    {
                        var buffer = data.Buffers[mipLevel, array];

                        wic.AddWICBitmapToImageData(bitmap, options.Filter, options.Dither, buffer, options.UseClipping);
                    }
                }
            }

            return(data);
        }
예제 #8
0
        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Form.Load"></see> event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            try
            {
                // Load the plug-in assembly.
                Gorgon.PlugIns.LoadPlugInAssembly(Program.PlugInPath + "Gorgon.Input.Raw.DLL");

                // Create the factory.
                _input = GorgonInputFactory.CreateInputFactory("GorgonLibrary.Input.GorgonRawPlugIn");

                // Create mouse, keyboard and joystick interfaces.
                _keyboard     = _input.CreateKeyboard(this);
                _mouse        = _input.CreatePointingDevice(this);
                _joystickList = new GorgonJoystick[_input.JoystickDevices.Count];

                // Create each joystick interface.
                for (int i = 0; i < _joystickList.Length; i++)
                {
                    _joystickList[i] = _input.CreateJoystick(this, _input.JoystickDevices[i].Name);
                }

                // Create the graphics interface.
                _graphics = new GorgonGraphics();
                _screen   = _graphics.Output.CreateSwapChain("Screen", new GorgonSwapChainSettings
                {
                    Size       = Settings.Default.Resolution,
                    Format     = BufferFormat.R8G8B8A8_UIntNormal,
                    IsWindowed = Settings.Default.IsWindowed
                });

                // For the backup image. Used to make it as large as the monitor that we're on.
                Screen currentScreen = Screen.FromHandle(Handle);

                // Relocate the window to the center of the screen.
                Location = new Point(currentScreen.Bounds.Left + (currentScreen.WorkingArea.Width / 2) - ClientSize.Width / 2,
                                     currentScreen.Bounds.Top + (currentScreen.WorkingArea.Height / 2) - ClientSize.Height / 2);


                // Create the 2D renderer.
                _2D = _graphics.Output.Create2DRenderer(_screen);

                // Create the text font.
                _font = _graphics.Fonts.CreateFont("Arial_9pt", new GorgonFontSettings
                {
                    FontFamilyName   = "Arial",
                    FontStyle        = FontStyle.Bold,
                    AntiAliasingMode = FontAntiAliasMode.AntiAlias,
                    FontHeightMode   = FontHeightMode.Points,
                    Size             = 9.0f
                });

                // Enable the mouse.
                Cursor                          = Cursors.Cross;
                _mouse.Enabled                  = true;
                _mouse.Exclusive                = false;
                _mouse.PointingDeviceDown      += MouseInput;
                _mouse.PointingDeviceMove      += MouseInput;
                _mouse.PointingDeviceWheelMove += _mouse_PointingDeviceWheelMove;

                // Enable the keyboard.
                _keyboard.Enabled   = true;
                _keyboard.Exclusive = false;
                _keyboard.KeyDown  += _keyboard_KeyDown;

                // Create text sprite.
                _messageSprite       = _2D.Renderables.CreateText("Message", _font, "Using mouse and keyboard.");
                _messageSprite.Color = Color.Black;

                // Create a back buffer.
                _backBuffer = _graphics.Output.CreateRenderTarget("BackBuffer", new GorgonRenderTarget2DSettings
                {
                    Width  = _screen.Settings.Width,
                    Height = _screen.Settings.Height,
                    Format = BufferFormat.R8G8B8A8_UIntNormal
                });
                _backBuffer.Clear(Color.White);

                var settings = new GorgonTexture2DSettings
                {
                    Width  = currentScreen.Bounds.Width,
                    Height = currentScreen.Bounds.Height,
                    Format = BufferFormat.R8G8B8A8_UIntNormal,
                    Usage  = BufferUsage.Staging
                };

                // Clear our backup image to white to match our primary screen.
                _backupImage = _graphics.Textures.CreateTexture("Backup", settings);
                using (var textureData = _backupImage.Lock(BufferLockFlags.Write))
                {
                    textureData.Data.Fill(0xFF);
                }

                // Set the mouse range and position.
                Cursor.Position = PointToScreen(new Point(Settings.Default.Resolution.Width / 2, Settings.Default.Resolution.Height / 2));
                _mouse.SetPosition(Settings.Default.Resolution.Width / 2, Settings.Default.Resolution.Height / 2);
                _mouse.SetPositionRange(0, 0, Settings.Default.Resolution.Width, Settings.Default.Resolution.Height);

                // Set gorgon events.
                _screen.AfterStateTransition += (sender, args) =>
                {
                    OnResizeEnd(EventArgs.Empty);

                    // Reposition after a state change.
                    if (!args.IsWindowed)
                    {
                        return;
                    }

                    Screen monitor = Screen.FromHandle(Handle);
                    Location = new Point(monitor.Bounds.Left + (monitor.WorkingArea.Width / 2) - args.Width / 2,
                                         monitor.Bounds.Top + (monitor.WorkingArea.Height / 2) - args.Height / 2);
                    Cursor.Position = PointToScreen(Point.Round(_mouse.Position));
                };
                Gorgon.ApplicationIdleLoopMethod = Gorgon_Idle;
            }
            catch (Exception ex)
            {
                GorgonException.Catch(ex, () => GorgonDialogs.ErrorBox(this, ex));
                Gorgon.Quit();
            }
        }