DirectX with VB.NET
Is there a set of documentation on DirectX (9 or above) that shows the objects, methods, properties, events and samlple code for the use of DirectX (9 or above) with VB.NET? The most recent SDK includes details for C++ and the "Windows DiectX Graphics documentation" file doe开发者_如何学Pythonsn't contain these details.
I think the most sane idea here is to use SlimDX (a user mantained very good wrapper). Cause remember that Managed DirectX is NO LONGER supported or updated by microsoft. (the support stopped years ago)
http://slimdx.org/
Go take a look at it. It support till DirectX11.
You might want to check this VB.NET Managed DirectX Example also The zBuffer is a really good reasource when coding for Managed DirectX and XNA!
A quick google for directx finds the DirectX developers center on MSDN. And a quick look around there finds the library page for DirectX 9.0 for managed code.
Have a look at XNA game studio , it supports all .NET languages currently. http://en.wikipedia.org/wiki/Microsoft_XNA Download it here http://www.microsoft.com/download/en/details.aspx?id=23714 It comes with examples.
I would suggest you use SharpDX. This is much like SlimDX, but faster and created nearly entirely based on header files. You should be able tu use the Library under VB even though it has "Sharp" poiting to C-Sharp in its name. Afaik it is the only solution you can also use for WinRT, and it is nearly a 1:1 adoption of DirectX - so you can use the original MSDN DirectX Documantation. It has capabilitys of DX9, DX10 and DX11.
Also have a look here, for making a decision between SlimDX and SharpDX:
SharpDX vs SlimDX for game development?
I strongly recommend to go for at least either one of them if you just want "managed DirectX" and no higher level API.
Here is an example that uses vb.net and C++ dll in visual studio 2017 Features:
- A Universal Windows Project (UWP) in VB that uses a XAML control SwapChainPanel.
- Calls a standard win32 dll The dll initializes the DirectX, creates a thread and renders the SwapChainPanel from the dll code written in C++.
- Compiled in Visual Studio 2017
In Visual Basic add a SwapChainPanel to 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>
In 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
Create a stabdard Win32 Dll project. It will export two functions. I use a .def file to define the exports. This works very well with vb. No need for other directives such as extern "C" __declspec (dllexport) BOOL __stdcall D3DInit(). Ensure it is called by the linker i.e /DEF:".\dhv.def"
LIBRARY dhv
EXPORTS
D3DInit=D3DInit
D3DRender=D3DRender
A header file Game.h (This code is based on http://www.directxtutorial.com. The Microsoft code is bloated!
#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;
};
And a Game.cpp file
#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;
}
And finally don't forget to like D3D11.lib
There you go, the VB window gets painted from the DirectX unmanaged dll at 60Hz!
Ravi
精彩评论