Search code examples
c#directx2ddirectx-9sharpdx

Drawing a 2D rectangle with SharpDX


How to draw a plain red 2D rectangle with SharpDX?

  • I have a SharpDX.Direct3D9.Device available from a library that sets up a Direct3D v9 device for me, so I'm hoping to be able to use that?
  • Found a tutorial on how to use Direct2D1 to draw a basic rectangle, but the code seems to be dependent on a Direct3D11 device, which I don't have - I need to be able to get the job done without Direct3D11 and without Direct3D10

    unsafe int PresentHook(IntPtr devicePtr, SharpDX.Rectangle* pSourceRect, SharpDX.Rectangle* pDestRect, IntPtr hDestWindowOverride, IntPtr pDirtyRegion)
    {
        _isUsingPresent = true;
    
        SharpDX.Direct3D9.Device device = (SharpDX.Direct3D9.Device)devicePtr;
    
        // How to draw rectangle here?
    
        if (pSourceRect == null || *pSourceRect == SharpDX.Rectangle.Empty)
            device.Present();
        else
        {
            if (hDestWindowOverride != IntPtr.Zero)
                device.Present(*pSourceRect, *pDestRect, hDestWindowOverride);
            else
                device.Present(*pSourceRect, *pDestRect);
        }
        return SharpDX.Result.Ok.Code;
    }
    

Solution

  • Could draw a sprite using something like the following:

    // Be sure to only initialise these only once (or as needed)
    // not every frame.
    
    //use relative path
    string dir = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    string filename = dir + @"\image.bmp";
    var _mytext = SharpDX.Direct3D9.Texture.FromFile(device, filename);
    var _sprite = new SharpDX.Direct3D9.Sprite(device);
    
    float posLeft = 10f;
    float posTop = 10f;
    var pos = new SharpDX.Vector3(posLeft, posTop, 0);
    var color = new SharpDX.ColorBGRA(0xffffffff);
    _sprite.Begin(SharpDX.Direct3D9.SpriteFlags.AlphaBlend);
    _sprite.Draw(_myText, color, null, null, pos);
    _sprite.End();
    

    Loading a texture this way will create a square texture, if the device capabilities support it then you can specify the dimensions when you load the texture, e.g.

    var _myText = SharpDX.Direct3D9.Texture.FromFile(device, filename, imageSize.Width, imageSize.Height, 0, Usage.None, Format.A8B8G8R8, Pool.Default, Filter.Default, Filter.Default, 0);
    

    Otherwise you can scale the X and Y appropriately within the transform:

    // Get image dimensions
    Size imageSize;
    using (var img = Image.FromFile(filename))
    {
        imageSize = img.Size;
    }
    // Calculate scale to get correct image size
    var transform = SharpDX.Matrix.AffineTransformation2D(1f, 0f, Vector2.Zero);
    // Calculate width scale
    if (imageSize.Width <= 128)
    {
        transform.M11 = (float)imageSize.Width / 128f; // scale x
    }
    else if (imageSize.Width <= 256)
    {
        transform.M11 = (float)imageSize.Width / 256f; // scale x
    }
    else if (imageSize.Width <= 512)
    {
        transform.M11 = (float)imageSize.Width / 512f; // scale x
    }
    else if (imageSize.Width <= 1024)
    {
        transform.M11 = (float)imageSize.Width / 1024f; // scale x
    }
    // Calculate height scale
    if (imageSize.Height <= 128)
    {
        transform.M22 = (float)imageSize.Height / 128f; // scale y
    }
    else if (imageSize.Height <= 256)
    {
        transform.M22 = (float)imageSize.Height / 256f; // scale y
    }
    else if (imageSize.Height <= 512)
    {
        transform.M22 = (float)imageSize.Height / 512f; // scale y
    }
    else if (imageSize.Height <= 1024)
    {
        transform.M22 = (float)imageSize.Height / 1024f; // scale y
    }
    
    _sprite.Transform = transform;