[PL] Visual Studio 2010 – DXUT i problemy z kompilacją (SDK z Marca 2009)

Gdy przyjrzałem się nowemu SDK do DirectX (głównie ze względu na bibliotekę do matematyki pod Xna, zoptymalizowaną pod hardware i zgodną z Xbox DevKit) to odkryłem pomocnicza bibliotekę DXUT (DXUT.h) w natywnym DirectX. Dawno nic nie pisałem natywnie, więc się zdziwiłem i zacząłem czytać o niej w dokumentacji.

Całkiem przyjemna biblioteka, aby wiele spraw, które wcześniej wymagały mnóstwo linii kodu rozwiązać na skróty. Przykład z samego początku: stworzenie okna, urządzeń, obsługa podstawowej pętli programowej, to przez specyfikę COM oraz WinAPI to multum linii, o których najchętniej byśmy zapomnieli). DXUT to nam załatwia poprzez wywołanie paru prosto skonstruowanych funkcji:

1) Inicjalizacja:

HRESULT WINAPI DXUTInit( bool bParseCommandLine = true,
bool bShowMsgBoxOnError = true,
WCHAR* strExtraCommandLineParams = NULL,
bool bThreadSafeDXUT = false );

2) Okno:

HRESULT DXUTCreateWindow(
const WCHAR *strWindowTitle = L"Direct3D Window",
HINSTANCE hInstance = NULL,
HICON hIcon = NULL,
HMENU hMenu = NULL,
INT x = CW_USEDEFAULT,
INT y = CW_USEDEFAULT );

3) Obsługa komunikatów poprzez Callback:

VOID DXUTSetCallbackMsgProc(
LPDXUTCALLBACKMSGPROC pCallbackMsgProc,
void* pUserContext );

4) Stworzenie urządzenia DirectX:

HRESULT WINAPI DXUTCreateDevice(
bool bWindowed = true, 
int nSuggestedWidth = 0,
int nSuggestedHeight = 0 );

Dzięki temu przykładowy szkielet aplikacji, która ma coś rysować i reagować na zdarzenia może wyglądać następująco:

 INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, INT )
{
    DXUTSetCallbackD3D9DeviceAcceptable( IsDeviceAcceptable );
    DXUTSetCallbackD3D9DeviceCreated( OnCreateDevice );
    DXUTSetCallbackD3D9DeviceReset( OnResetDevice );
    DXUTSetCallbackD3D9FrameRender( OnFrameRender );
    DXUTSetCallbackD3D9DeviceLost( OnLostDevice );
    DXUTSetCallbackD3D9DeviceDestroyed( OnDestroyDevice );
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackKeyboard( KeyboardProc );
    DXUTSetCallbackFrameMove( OnFrameMove );
    DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );

    DXUTInit( true, true ); 
    DXUTCreateWindow( L"Example" );
    DXUTCreateDevice( true, 640, 480 );

    // Custom main loop
    HWND hWnd = DXUTGetHWND();
    BOOL bGotMsg;
    MSG  msg;
    msg.message = WM_NULL;
    PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );
    
    while( WM_QUIT != msg.message  )
    {
        // Use PeekMessage() so we can use idle time to render the scene
        bGotMsg = ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) != 0 );
        
        if( bGotMsg )
        {
            // Translate and dispatch the message
            if( 0 == TranslateAccelerator( hWnd, NULL, &msg ) )
            {
                TranslateMessage( &msg );
                DispatchMessage( &msg );
            }
        }
        else
        {
            // Render a frame during idle time (no messages are waiting)
            DXUTRender3DEnvironment();
        }
    }
    
    return DXUTGetExitCode();
}

Jak widać jest parę rzeczy, z którymi trzeba się zapoznać, ale mimo wszystko wygląda spójnie, zwięźle i czytelnie. W DirectX było już wiele tego typu helperów, na tym na którym ja się kiedyś zatrzymałem wszystko opierało się o klasy i trochę na modłę tego co zaproponowano w Managed DirectX w .NET Framework. Ten bardziej oparty na funkcjach niż na klasach nie narzuca nikomu pure C++ OOB i widzę, że teraz wszystkie przykłady są o niego oparte. Postanowiłem zatem też się pobawić chwilkę tą biblioteką.

Jeśli wy chcecie to od razu uprzedzam na pierwszą minę, na jaką możecie natrafić. Ta biblioteka nie jest w Include’ach i Libach. Ona jest dostępna w źródłach, więc jeśli chcecie z niej skorzystać należy ją sobie skompilować i wrzucić w rozpoznawalne dla projekty foldery.

Standardowy folder z źródłami tej biblioteki: $(SDK_DIR)\Samples\C++\DXUT

u mnie: C:\Program Files\Microsoft DirectX SDK (March 2009)\Samples\C++\DXUT

Druga mina na jaką natrafiłem wiąże się z Visual Studio 2010. Jeśli rozpoczęliście testy tego środowiska to mogliście natrafić na pewien bład, który jest omawiany tutaj. Moje Visual Studio napotkało na problem w znalezieniu plików w dodatkowych folderach dodanych do listy Include/Lib, w ten sposób pliki z najnowszego SDK nie bardzo dały się znaleźć i generowały błąd podczas kompilacji.

W tym przypadku nie znalazłem niestety innej podpowiedzi niż przekopiowanie tych plików do rozpoznawalnych folderów z defaulta (np folder z zainstalowanym VS/Include czy ~/Lib)

Według wpisu na connect.microsoft.com to jest bug, nad którym w Redmond pracują i pewnie już przy kolejnej wersji Beta będzie już historią.

Visual Studio 2005/2008 oczywiście nie powinno mieć tego problemu.