Рисование 2D-прямоугольника с помощью SharpDX

Как нарисовать простой красный 2D-прямоугольник с помощью SharpDX?

  • У меня есть SharpDX.Direct3D9.Device, доступный из библиотеки, который настраивает для меня устройство Direct3D v9, поэтому я надеюсь, что смогу его использовать?
  • Нашел руководство по использованию Direct2D1 для рисования базового прямоугольник, но код, похоже, зависит от устройства Direct3D11, которого у меня нет — мне нужно иметь возможность выполнять работу без Direct3D11 и без 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;
    }
    

person Cel    schedule 28.06.2015    source источник
comment
Вам не нужен графический процессор Direct3D11, чтобы использовать его. В Direct3D есть нечто, называемое уровнями функций, что означает, что он будет запускать D3D11, но только с функциями, доступными для вашего графического процессора. Так что, если вы не используете Windows XP, вы сможете запустить ее. Если хотите, откройте Run... и введите dxdiag. Затем найдите DirectX version. Если это DirectX 11 или более поздняя версия, то все в порядке.   -  person LHLaurini    schedule 28.06.2015
comment
@LHLaurini дело в том, что у меня есть SharpDX.Direct3D9.Device, который я могу использовать из библиотеки, как я могу его использовать? (у меня нет SharpDX.Direct3D11.Device)   -  person Cel    schedule 29.06.2015
comment
Извините, я умею использовать DirectX с нативным кодом. Я не очень разбираюсь в управляемой стороне. Так что кто-то другой должен будет ответить вам на это. Вы пытались запустить этот код DX11? Извините, я очень тупой, когда дело доходит до C#.   -  person LHLaurini    schedule 29.06.2015


Ответы (1)


Можно нарисовать спрайт, используя что-то вроде следующего:

// 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();

Загрузка текстуры таким образом создаст квадратную текстуру, если возможности устройства поддерживают это, вы можете указать размеры при загрузке текстуры, например.

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

В противном случае вы можете соответствующим образом масштабировать X и Y внутри преобразования:

// 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;
person Justin Stenning    schedule 03.07.2015
comment
большое спасибо! этот код работает в основном, за исключением странной проблемы, заключающейся в том, что он растягивает изображение, чтобы оно было выше (чтобы оно было такой же высоты, как и ширина, даже если исходное изображение не является квадратом) - см. github.com/spazzarama/Direct3DHook/issues/27 - person Cel; 03.07.2015
comment
Обновлено, чтобы включить масштабирование (при условии, что изображение не больше 1024 по любому измерению) - person Justin Stenning; 05.07.2015
comment
Другой вариант размера — указать его при загрузке текстуры (при условии, что возможности устройства поддерживают текстуры, отличные от квадратных/pow2): var _myText = SharpDX.Direct3D9.Texture.FromFile(device, filename, imageSize.Width, imageSize.Height, 0, Использование.Нет, Формат.A8B8G8R8, Пул.По умолчанию, Фильтр.По умолчанию, Фильтр.По умолчанию, 0); - person Justin Stenning; 05.07.2015
comment
попробовал второй вариант на одном устройстве и все сработало идеально. еще раз спасибо! - person Cel; 05.07.2015