Managed DirectX, конвертация из MDX в SlimDX (2/3)

Опубликовано Июн 22, 2010 в .NET, DirectX | Нет комментариев

Начинаем миграцию Managed DirectX в SlimDX framework, на примере MDX приложения Патрика Мурриса Terrain Viewer.

В виде комментариев показан Managed DirectX код, и рядом с ним новый код, работающий с SlimDX.

Миграция MDX проекта в SlimDX

Подключение библиотек SlimDX

Загружаем и устанавливаем « SlimDX SDK (February 2010).msi «.
Добавляем в проекте Reference на .NET библиотеку C:\Program Files\SlimDX SDK (February 2010)\Bin\x86\SlimDX.dll. Если вы добавили ссылку в диалоговом окне Add Reference не через закладку «.NET» а через «Browse», то установите свойства ссылки Copy Local -> true и Specific Version -> true.

    //using Microsoft.DirectX.Direct3D;
    //using Microsoft.DirectX;
    //using Microsoft.DirectX.DirectInput;
    
    using SlimDX;
    using SlimDX.Direct3D9;
    using Key = SlimDX.DirectInput.Key;
    using KeyboardState = SlimDX.DirectInput.KeyboardState;
    using Keyboard = SlimDX.DirectInput.Keyboard;
    using DirectInput = SlimDX.DirectInput.DirectInput;

Почему не использовать просто using SlimDX.DirectInput;? Можно, но тогда появится конфликт для класса Device, который есть в обоих namespace.

Использование классов SlimDX.Direct3D9

    //private Microsoft.DirectX.Direct3D.Device _device;
    //private Microsoft.DirectX.DirectInput.Device _keyboard;
    //private Microsoft.DirectX.Direct3D.Font _font;

    private Device _device;
    private Direct3D _direct3d;
    private FilterCaps _textureFilterCaps;
    private DirectInput _directInput;
    private Keyboard _keyb;
    private SlimDX.Direct3D9.Font _font;

Создание SlimDX.Direct3D9.Device

Приведён только код, требующий конвертации.

    // Create device
    PresentParameters presentParams = new PresentParameters();

    //presentParams.AutoDepthStencilFormat = DepthFormat.D16;
    //device = new Device(0, DeviceType.Hardware, this, CreateFlags.HardwareVertexProcessing, presentParams);

    presentParams.AutoDepthStencilFormat = Format.D16;
    _direct3d = new Direct3D();
    _device = new Device(_direct3d, 0, DeviceType.Hardware, this.Handle, CreateFlags.HardwareVertexProcessing, presentParams);

События Device

    //device.DeviceReset += new EventHandler(OnDeviceReset);
    //device.DeviceResizing += new CancelEventHandler(OnDeviceResizing);

Аналогов пока не нашёл 🙂

Установка параметров рендера Device

Простые типы:

    // Rendering setup
    //device.RenderState.ZBufferEnable = true;
    //device.RenderState.Ambient = ambientColor;
    //device.RenderState.FogStart = mapWidth == 0 ? 60 : (float)mapWidth / 8;

    device.SetRenderState(RenderState.ZEnable, true); // bool
    device.SetRenderState(RenderState.Ambient, ambientColor.ToArgb()); // int (Color4)
    device.SetRenderState(RenderState.FogStart, mapWidth == 0 ? 60 : (float)mapWidth / 8); // int

и т.д.

Типизированные параметры:

    //device.RenderState.FillMode = FillMode.Solid;
    //device.RenderState.CullMode = Cull.CounterClockwise;
    //device.RenderState.SourceBlend = Blend.SourceAlpha;
    //device.RenderState.FogTableMode = FogMode.Linear;

    device.SetRenderState(RenderState.FillMode, FillMode.Solid);
    device.SetRenderState(RenderState.CullMode, Cull.Counterclockwise);
    device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
    device.SetRenderState(RenderState.FogTableMode, FogMode.Linear);

Остальные параметры Device

    // Texture filtering
    //device.SamplerState[0].MinFilter = TextureFilter.Anisotropic;
    //device.SamplerState[0].MagFilter = TextureFilter.Linear;
    //device.SamplerState[0].AddressU = TextureAddress.Clamp;
    //device.SamplerState[0].AddressV = TextureAddress.Clamp;

    device.SetSamplerState(0, SamplerState.MinFilter, TextureFilter.Anisotropic);
    device.SetSamplerState(0, SamplerState.MagFilter, TextureFilter.Linear);
    device.SetSamplerState(0, SamplerState.AddressU, TextureAddress.Clamp);
    device.SetSamplerState(0, SamplerState.AddressV, TextureAddress.Clamp);

    // Texture stage states.
    //device.TextureState[0].ColorArgument2 = TextureArgument.Diffuse;
    //device.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor;
    //device.TextureState[0].ColorOperation = TextureOperation.Modulate;
    //device.TextureState[0].AlphaOperation = TextureOperation.SelectArg1;

    device.SetTextureStageState(0, TextureStage.ColorArg2, TextureArgument.Diffuse);
    device.SetTextureStageState(0, TextureStage.AlphaArg1, TextureArgument.Texture);
    device.SetTextureStageState(0, TextureStage.ColorOperation, TextureOperation.Modulate);
    device.SetTextureStageState(0, TextureStage.AlphaOperation, TextureOperation.SelectArg1);

device.DeviceCaps

Все проверки вида:

    // Check for hardware vertex processing and pure device.
    //if (device.DeviceCaps.TextureFilterCaps.SupportsMinifyAnisotropic) ...
    //if (device.DeviceCaps.TextureFilterCaps.SupportsMinifyLinear) ...
    //if (device.DeviceCaps.TextureFilterCaps.SupportsMagnifyAnisotropic) ...
    //if (device.DeviceCaps.TextureFilterCaps.SupportsMagnifyLinear) ...

Меняются на такую конструкцию:

    Capabilities deviceCaps = _direct3d.GetDeviceCaps(0, DeviceType.Hardware);
    FilterCaps textureFilterCaps = deviceCaps.TextureFilterCaps;

    if ((textureFilterCaps & FilterCaps.MinAnisotropic) != 0) ...
    if ((textureFilterCaps & FilterCaps.MinLinear) != 0) ...
    if ((textureFilterCaps & FilterCaps.MagAnisotropic) != 0) ...
    if ((textureFilterCaps & FilterCaps.MagLinear) != 0) ...

Простые типы

    Color -> SlimDX.Color4

    //material.SpecularSharpness = 30.0f;  // thin highlight (smaller = larger)

    material.Power = 30.0f;  // thin highlight (smaller = larger)

Вектора

    //Vector3 ray = Vector3.Empty;

    Vector3 ray = Vector3.Zero;

Вектора. Vector3.Unproject(…)

    Vector3 p1 = new Vector3(x, y, minZ);
    ...

    //p1.Unproject(device.Viewport, device.Transform.Projection, device.Transform.View, device.Transform.World);

Эта строка меняется на конструкцию:

    float minZ = device.Viewport.MinZ;
    float maxZ = device.Viewport.MaxZ;
    int width = device.Viewport.Width;
    int height = device.Viewport.Height;
    int vX = device.Viewport.X;
    int vY = device.Viewport.Y;

    Matrix worldViewProjection = device.GetTransform(TransformState.Projection) * device.GetTransform(TransformState.View) * device.GetTransform(TransformState.World);

    p1 = Vector3.Unproject(p1, vX, vY, width, height, minZ, maxZ, worldViewProjection);

Вектора. Vector3.Scale(float)

    //ray.Scale((float)u);

    ray = Vector3.Multiply(ray, (float)u);

Вектора. Матричные преобразования

    Vector3 pos = new Vector3();
    Matrix lightTrans = Matrix.Identity;
    ...

    //pos.TransformCoordinate(lightTrans);

    pos = Vector3.TransformCoordinate(pos, lightTrans);

Оставить комментарий