【问题标题】:DirectX with VB.NETDirectX 与 VB.NET
【发布时间】:2017-03-30 14:24:56
【问题描述】:

是否有一组关于 DirectX(9 或更高版本)的文档,其中显示了在 VB.NET 中使用 DirectX(9 或更高版本)的对象、方法、属性、事件和示例代码? 最新的 SDK 包含 C++ 的详细信息,“Windows DiectX 图形文档”文件不包含这些详细信息。

【问题讨论】:

  • 请注意,Microsoft 不再支持托管 DirectX。他们希望我们改用 XNA。有关 XNA 信息,请参阅 Filip 答案。
  • 另一方面,XNA 只支持 DirectX 9。对于 10 和 11,SlimDX 是唯一的方法。

标签: directx


【解决方案1】:

我认为这里最明智的想法是使用 SlimDX(用户维护的非常好的包装器)。请记住,Microsoft 不再支持或更新托管 DirectX。 (多年前停止支持)

http://slimdx.org/

去看看吧。它支持到 DirectX11。

【讨论】:

    【解决方案2】:

    在为托管 DirectX 和 XNA 编码时,您可能想检查一下 VB.NET Managed DirectX ExampleThe zBuffer 是一个非常好的资源!

    【讨论】:

      【解决方案3】:

      直接在 Google 上搜索一下即可在 MSDN 上找到 DirectX developers center。 快速浏览一下,可以找到DirectX 9.0 for managed code 的库页面。

      【讨论】:

        【解决方案4】:

        看看 XNA 游戏工作室,它目前支持所有 .NET 语言。 http://en.wikipedia.org/wiki/Microsoft_XNA 在这里下载 http://www.microsoft.com/download/en/details.aspx?id=23714 它带有示例。

        【讨论】:

        • 请记住,Directx9 是比 Direct 9+x 更好的起点
        【解决方案5】:

        我建议您使用 SharpDX。这很像 SlimDX,但速度更快,并且几乎完全基于头文件创建。您应该能够在 VB 下使用该库,即使它的名称中有“Sharp”指向 C-Sharp。 Afaik 它是您也可以用于 WinRT 的唯一解决方案,它几乎是 1:1 采用 DirectX - 因此您可以使用原始的 MSDN DirectX 文档。它具有DX9、DX10和DX11的能力。

        还可以在这里查看,以便在 SlimDX 和 SharpDX 之间做出决定:

        SharpDX vs SlimDX for game development?

        如果您只想要“托管 DirectX”而不需要更高级别的 API,我强烈建议您至少选择其中之一。

        【讨论】:

          【解决方案6】:

          这是一个在 Visual Studio 2017 中使用 vb.net 和 C++ dll 的示例 特点:

          • VB 中使用 XAML 控件的通用 Windows 项目 (UWP) 交换链面板。
          • 调用标准的win32 dll dll初始化 DirectX,创建一个线程并从 dll 呈现 SwapChainPanel 用 C++ 编写的代码。
          • 在 Visual Studio 2017 中编译

          在 Visual Basic 中,将 SwapChainPanel 添加到 MainPage.xaml

          <SwapChainPanel x:Name="swapChainPanel1">
                  <TextBlock x:Name="txt1" Text="Hello from XAML!"
                         HorizontalAlignment="Right"
                         VerticalAlignment="Top"
                         FontSize="30" />
                  <Button Content="Button" HorizontalAlignment="Left" Height="30" Margin="812,484,0,0" VerticalAlignment="Top" Width="97" Click="Button_Click"/>
                  <Button Content="Button" HorizontalAlignment="Left" Height="79" Margin="851,561,0,0" VerticalAlignment="Top" Width="126" Click="Button_Click_1"/>
          
          </SwapChainPanel>
          

          在 MainPage.xaml.vb 中

          Imports System.Runtime.InteropServices      ' Required for dll calling. Our C dll is "dhv.dll"
          
          
              <DllImport("dhv.dll", CallingConvention:=CallingConvention.StdCall)>
              Private Shared Function D3DInit(ByVal swapChainNative As IntPtr) As UInteger
              End Function
          
              <DllImport("dhv.dll", CallingConvention:=CallingConvention.StdCall)>
              Private Shared Function D3DRender() As UInteger
              End Function
          
          
          
           Dim SwapChainNative As IntPtr
          
          
              Private Sub Tst(ByRef s As SwapChainPanel)              ' this is the Vb implementation of QueryInterface on SwapChainPanel cast as IUnknown. See the DirectX documentation
                  Dim inspectableIface As IntPtr
                  Dim uuid As New Guid("F92F19D2-3ADE-45A6-A20C-F6F1EA90554B")    ' GUID of ISwapChainPanelNative decalred in <windows.ui.xaml.media.dxinterop.h>
          
                  inspectableIface = System.Runtime.InteropServices.Marshal.GetIUnknownForObject(s)
                  System.Runtime.InteropServices.Marshal.QueryInterface(inspectableIface, uuid, SwapChainNative)
              End Sub
          
              Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
                  Dim r As UInt32
                  Tst(Me.swapChainPanel1)
                  r = D3DInit(SwapChainNative)
                  Me.txt1.Text = r 
              End Sub
          
              Private Sub Button_Click_1(sender As Object, e As RoutedEventArgs)
                  D3DRender()
              End Sub
          

          创建一个标准的 Win32 Dll 项目。它将导出两个函数。我使用 .def 文件来定义导出。这适用于 vb。不需要其他指令,例如 extern "C" __declspec (dllexport) BOOL __stdcall D3DInit()。确保它被链接器调用,即 /DEF:".\dhv.def"

          LIBRARY   dhv
          EXPORTS  
              D3DInit=D3DInit
              D3DRender=D3DRender
          

          头文件Game.h(此代码基于http://www.directxtutorial.com。微软代码臃肿!

          #pragma once
          
          using namespace Microsoft::WRL;
          using namespace DirectX;
          
          class CGame
          {
          
          
          public:
              ComPtr<ID3D11Device1> dev;              // the device interface
              ComPtr<ID3D11DeviceContext1> devcon;    // the device context interface
              ComPtr<IDXGISwapChain1> swapchain;      // the swap chain interface
              ComPtr<ID3D11RenderTargetView> rendertarget;    
          
              ComPtr<ID3D11Texture2D> Backbuffer;
          
              UINT32 Initialize();
              void Update();
              UINT32 Render();
              void InitGraphics();
          
          private:
              float ScreenColour;
              UINT ScreenColourI;
          
              UINT Width, Height;
              UINT32 * TextureData;
          
          };
          

          还有一个 Game.cpp 文件

          #include "stdafx.h"
          #include <wrl/client.h>
          #include <d3d11_1.h>
          #include <DirectXMath.h>
          #include <windows.ui.xaml.media.dxinterop.h>
          #include "Game.h"
          
          DWORD WINAPI renderThread(LPVOID lpParameter);
          
          CGame* pGame;
          ComPtr<ISwapChainPanelNative> pSwapChainNative;
          
          UINT32 __stdcall D3DInit(PULONG ptrSwapChainNative)
          {
              UINT r;
              pGame = new CGame;
              pSwapChainNative = reinterpret_cast<ISwapChainPanelNative*> (ptrSwapChainNative);
              r = pGame->Initialize();
          
              return r;
          }
          UINT32 __stdcall D3DRender(void)
          {
          
              CreateThread(NULL, NULL, renderThread, NULL, 0, NULL);
              return 0;
          }
          
          
          DWORD WINAPI renderThread(LPVOID lpParameter)
          {
          
              for (int i = 0; i < 500; i++)
              {
                  //pGame->Update();
                  pGame->Render();
              }
              return 1;
          }
          
          
          // this function initializes and prepares Direct3D for use
          UINT32 CGame::Initialize()
          {
              HRESULT hr;
              // Define temporary pointers to a device and a device context
              ComPtr<ID3D11Device> dev11;
              ComPtr<ID3D11DeviceContext> devcon11;
          
              // Create the device and device context objects
              D3D11CreateDevice(
                  nullptr,
                  D3D_DRIVER_TYPE_HARDWARE,
                  nullptr,
                  0,
                  nullptr,
                  0,
                  D3D11_SDK_VERSION,
                  &dev11,
                  nullptr,
                  &devcon11);
          
              // Convert the pointers from the DirectX 11 versions to the DirectX 11.1 versions
              dev11.As(&dev);
              devcon11.As(&devcon);
          
          
              // First, convert our ID3D11Device1 into an IDXGIDevice1
              ComPtr<IDXGIDevice1> dxgiDevice;
              dev.As(&dxgiDevice);
          
              // Second, use the IDXGIDevice1 interface to get access to the adapter
              ComPtr<IDXGIAdapter> dxgiAdapter;
              dxgiDevice->GetAdapter(&dxgiAdapter);
          
              // Third, use the IDXGIAdapter interface to get access to the factory
              ComPtr<IDXGIFactory2> dxgiFactory;
              dxgiAdapter->GetParent(__uuidof(IDXGIFactory2), &dxgiFactory);
          
          
              /*
              // set up the swap chain description
              DXGI_SWAP_CHAIN_DESC1 scd = {0};
              scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;    // how the swap chain should be used
              scd.BufferCount = 2;                                  // a front buffer and a back buffer
              scd.Format = DXGI_FORMAT_B8G8R8A8_UNORM;              // the most common swap chain format
              scd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;    // the recommended flip mode
              scd.SampleDesc.Count = 1;                             // disable anti-aliasing
          
          
          
              CoreWindow^ Window = CoreWindow::GetForCurrentThread();    // get the window pointer
          
              hr = dxgiFactory->CreateSwapChainForCoreWindow(
              dev.Get(),                                  // address of the device
              reinterpret_cast<IUnknown*>(Window),        // address of the window
              &scd,                                       // address of the swap chain description
              nullptr,                                    // advanced
              &swapchain);
              */
          
              DXGI_SWAP_CHAIN_DESC1 scd = { 0 };
              scd.Width = 1000;           //BUG setting it arbitarily. Needs cleanup. by Ravi
              scd.Height = 800;
              scd.Format = DXGI_FORMAT_B8G8R8A8_UNORM;           // this is the most common swapchain format
              scd.Stereo = false;
              scd.SampleDesc.Count = 1;                          // don't use multi-sampling
              scd.SampleDesc.Quality = 0;
              scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
              scd.BufferCount = 2;
              scd.Scaling = DXGI_SCALING_STRETCH;
              scd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // we recommend using this swap effect for all applications
              scd.Flags = 0;
          
          
              hr = dxgiFactory->CreateSwapChainForComposition(
                  dev.Get(),
                  &scd,
                  nullptr,                                    // allow on any display 
                  &swapchain);
          
          
              if (FAILED(hr))
              {
                  return  204;
              }
          
              pSwapChainNative->SetSwapChain(swapchain.Get());
          
          
              // get a pointer directly to the back buffer
              swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), &Backbuffer);
          
          
              // create a render target pointing to the back buffer
              dev->CreateRenderTargetView(Backbuffer.Get(), nullptr, &rendertarget);
          
          
              // Width and Height
              swapchain->GetDesc1(&scd);
              Width = scd.Width;
              Height = scd.Height;
          
          
              TextureData = new UINT32[Width * Height];
          
          
              // initialize graphics and the pipeline
              InitGraphics();
          
          
              return 0;
          }
          
          // this function performs updates to the state of the game
          void CGame::Update()
          {
          }
          
          // this function renders a single frame of 3D graphics
          UINT32 CGame::Render()
          {
              UINT n, i;
              UINT  * psrc;
          /*
              // set our new render target object as the active render target
              devcon->OMSetRenderTargets(1, rendertarget.GetAddressOf(), nullptr);
          
              ScreenColour += 0.005f;
              if (ScreenColour >0.9f)
                  ScreenColour = 0.0f;
          
              // clear the back buffer to a deep blue
              float color[4] = {ScreenColour, ScreenColour, ScreenColour, 1.0f};
              devcon->ClearRenderTargetView(rendertarget.Get(), color);
          */
              psrc = TextureData;
              i = ScreenColourI & 255;
          
              for (n=0; n<Width*Height; n++)
              {
                  *psrc++ = (i<<16) | (i<<8) | i ;
                  i++;
                  i &= 255;
              }
          
          
              ScreenColourI += 1;
          
              devcon->UpdateSubresource (Backbuffer.Get(), 0, NULL, TextureData, Width*4, 0);
          
              // switch the back buffer and the front buffer
              swapchain->Present(1, 0);
          
              return 0;
          
          }
          
          // this function loads and initializes all graphics data
          void CGame::InitGraphics()
          {
              ScreenColour = 0.0f;
              ScreenColourI = 0;
          }
          

          最后别忘了点赞 D3D11.lib

          你去吧,VB 窗口是从 DirectX 非托管 dll 以 60Hz 绘制的!

          拉维

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-06-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多