2010-09-28 5 views
3

Comment configurer mingw32 pour effectuer une compilation croisée des applications Direct3D pour Windows? Y a-t-il une possibilité? J'ai effectivement réussi à compiler du code à partir de ce tutoriel: http://www.directxtutorial.com/Tutorial9/B-Direct3DBasics/dx9B4.aspx - en utilisant Code :: Blocs sur Kubuntu avec i586-mingw32msvc-g ++. Je devais ajouter #define UNICODE et supprimer les parties #pragma ... pour ce faire, et j'ai utilisé des fichiers d'en-tête de/usr/i586-mingw32msvc/include et libs aussi de mingw package.Compilation croisée Direct3D sous Linux avec MINGW

Cependant je ne peux pas compiler le code de ce tutoriel: http://www.directxtutorial.com/Tutorial9/B-Direct3DBasics/dx9B5.aspx

Mingw n'a pas le fichier d3dx9.h. J'ai donc installé le paquet wine1.2-dev avec les versions de vin de fichiers d'en-tête liés à Windows, mais maintenant j'ai des erreurs:

Avec #define UNICODE:

-------------- Build: Debug in d3d --------------- 

i586-mingw32msvc-g++ -Wall -g -I/usr/include/wine/windows -c /home/silmeth/programowanie/codeblocks/d3d/main.cpp -o obj/Debug/main.o 
/home/silmeth/programowanie/codeblocks/d3d/main.cpp: In function ‘int WinMain(HINSTANCE__*, HINSTANCE__*, CHAR*, int)’: 
/home/silmeth/programowanie/codeblocks/d3d/main.cpp:50: error: invalid conversion from ‘const wchar_t*’ to ‘const WCHAR*’ 
/home/silmeth/programowanie/codeblocks/d3d/main.cpp:56: error: invalid conversion from ‘const wchar_t*’ to ‘const WCHAR*’ 
/home/silmeth/programowanie/codeblocks/d3d/main.cpp:56: error: initializing argument 2 of ‘HWND__* CreateWindowExW(DWORD, const WCHAR*, const WCHAR*, DWORD, INT, INT, INT, INT, HWND__*, HMENU__*, HINSTANCE__*, void*)’ 
/home/silmeth/programowanie/codeblocks/d3d/main.cpp:56: error: invalid conversion from ‘const wchar_t*’ to ‘const WCHAR*’ 
/home/silmeth/programowanie/codeblocks/d3d/main.cpp:56: error: initializing argument 3 of ‘HWND__* CreateWindowExW(DWORD, const WCHAR*, const WCHAR*, DWORD, INT, INT, INT, INT, HWND__*, HMENU__*, HINSTANCE__*, void*)’ 
/home/silmeth/programowanie/codeblocks/d3d/main.cpp: In function ‘void render_frame()’: 
/home/silmeth/programowanie/codeblocks/d3d/main.cpp:158: warning: taking address of temporary 
/home/silmeth/programowanie/codeblocks/d3d/main.cpp:159: warning: taking address of temporary 
/home/silmeth/programowanie/codeblocks/d3d/main.cpp:160: warning: taking address of temporary 
Process terminated with status 1 (0 minutes, 0 seconds) 
5 errors, 3 warnings

Et sans #define:


-------------- Build: Debug in d3d --------------- 

i586-mingw32msvc-g++ -Wall -g -I/usr/include/wine/windows -c /home/silmeth/programowanie/codeblocks/d3d/main.cpp -o obj/Debug/main.o 
/home/silmeth/programowanie/codeblocks/d3d/main.cpp: In function ‘int WinMain(HINSTANCE__*, HINSTANCE__*, CHAR*, int)’: 
/home/silmeth/programowanie/codeblocks/d3d/main.cpp:50: error: cannot convert ‘const wchar_t [12]’ to ‘const CHAR*’ in assignment 
/home/silmeth/programowanie/codeblocks/d3d/main.cpp:56: error: cannot convert ‘const wchar_t*’ to ‘const CHAR*’ for argument ‘2’ to ‘HWND__* CreateWindowExA(DWORD, const CHAR*, const CHAR*, DWORD, INT, INT, INT, INT, HWND__*, HMENU__*, HINSTANCE__*, void*)’ 
/home/silmeth/programowanie/codeblocks/d3d/main.cpp: In function ‘void render_frame()’: 
/home/silmeth/programowanie/codeblocks/d3d/main.cpp:158: warning: taking address of temporary 
/home/silmeth/programowanie/codeblocks/d3d/main.cpp:159: warning: taking address of temporary 
/home/silmeth/programowanie/codeblocks/d3d/main.cpp:160: warning: taking address of temporary 
Process terminated with status 1 (0 minutes, 0 seconds) 
2 errors, 3 warnings

ici est l'ensemble du code que j'essaie de compiler:

// include the basic windows header files and the Direct3D header file 
#define UNICODE //tried to comment and uncomment this 
#include <windows.h> 
#include <windowsx.h> 
#include <d3d9.h> 
#include <d3dx9.h> 

// define the screen resolution 
#define SCREEN_WIDTH 800 
#define SCREEN_HEIGHT 600 

// include the Direct3D Library files 
//#pragma comment (lib, "d3d9.lib") 
//#pragma comment (lib, "d3dx9.lib") 

// global declarations 
LPDIRECT3D9 d3d; // the pointer to our Direct3D interface 
LPDIRECT3DDEVICE9 d3ddev; // the pointer to the device class 
LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL; // the pointer to the vertex buffer 

// function prototypes 
void initD3D(HWND hWnd); // sets up and initializes Direct3D 
void render_frame(void); // renders a single frame 
void cleanD3D(void); // closes Direct3D and releases memory 
void init_graphics(void); // 3D declarations 

struct CUSTOMVERTEX {FLOAT X, Y, Z; DWORD COLOR;}; 
#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE) 

// the WindowProc function prototype 
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); 


// the entry point for any Windows program 
int WINAPI WinMain(HINSTANCE hInstance, 
        HINSTANCE hPrevInstance, 
        LPSTR lpCmdLine, 
        int nCmdShow) 
{ 
    HWND hWnd; 
    WNDCLASSEX wc; 

    ZeroMemory(&wc, sizeof(WNDCLASSEX)); 

    wc.cbSize = sizeof(WNDCLASSEX); 
    wc.style = CS_HREDRAW | CS_VREDRAW; 
    wc.lpfnWndProc = WindowProc; 
    wc.hInstance = hInstance; 
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
    wc.lpszClassName = L"WindowClass"; 

    RegisterClassEx(&wc); 

    hWnd = CreateWindowEx(NULL, L"WindowClass", L"Our Direct3D Program", 
          WS_OVERLAPPEDWINDOW, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 
          NULL, NULL, hInstance, NULL); 

    ShowWindow(hWnd, nCmdShow); 

    // set up and initialize Direct3D 
    initD3D(hWnd); 

    // enter the main loop: 

    MSG msg; 

    while(TRUE) 
    { 
     while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
     { 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 

     if(msg.message == WM_QUIT) 
      break; 

     render_frame(); 
    } 

    // clean up DirectX and COM 
    cleanD3D(); 

    return msg.wParam; 
} 


// this is the main message handler for the program 
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch(message) 
    { 
     case WM_DESTROY: 
      { 
       PostQuitMessage(0); 
       return 0; 
      } break; 
    } 

    return DefWindowProc (hWnd, message, wParam, lParam); 
} 


// this function initializes and prepares Direct3D for use 
void initD3D(HWND hWnd) 
{ 
    d3d = Direct3DCreate9(D3D_SDK_VERSION); 

    D3DPRESENT_PARAMETERS d3dpp; 

    ZeroMemory(&d3dpp, sizeof(d3dpp)); 
    d3dpp.Windowed = TRUE; 
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 
    d3dpp.hDeviceWindow = hWnd; 
    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; 
    d3dpp.BackBufferWidth = SCREEN_WIDTH; 
    d3dpp.BackBufferHeight = SCREEN_HEIGHT; 

    // create a device class using this information and the info from the d3dpp stuct 
    d3d->CreateDevice(D3DADAPTER_DEFAULT, 
         D3DDEVTYPE_HAL, 
         hWnd, 
         D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
         &d3dpp, 
         &d3ddev); 

    init_graphics(); // call the function to initialize the triangle 

    d3ddev->SetRenderState(D3DRS_LIGHTING, FALSE); // turn off the 3D lighting 
} 


// this is the function used to render a single frame 
void render_frame(void) 
{ 
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); 

    d3ddev->BeginScene(); 

    // select which vertex format we are using 
    d3ddev->SetFVF(CUSTOMFVF); 

    // SET UP THE PIPELINE 

    D3DXMATRIX matRotateY; // a matrix to store the rotation information 

    static float index = 0.0f; index+=0.05f; // an ever-increasing float value 

    // build a matrix to rotate the model based on the increasing float value 
    D3DXMatrixRotationY(&matRotateY, index); 

    // tell Direct3D about our matrix 
    d3ddev->SetTransform(D3DTS_WORLD, &matRotateY); 

    D3DXMATRIX matView; // the view transform matrix 

    D3DXMatrixLookAtLH(&matView, 
         &D3DXVECTOR3 (0.0f, 0.0f, 10.0f), // the camera position 
         &D3DXVECTOR3 (0.0f, 0.0f, 0.0f), // the look-at position 
         &D3DXVECTOR3 (0.0f, 1.0f, 0.0f)); // the up direction 

    d3ddev->SetTransform(D3DTS_VIEW, &matView); // set the view transform to matView 

    D3DXMATRIX matProjection;  // the projection transform matrix 

    D3DXMatrixPerspectiveFovLH(&matProjection, 
           D3DXToRadian(45), // the horizontal field of view 
           (FLOAT)SCREEN_WIDTH/(FLOAT)SCREEN_HEIGHT, // aspect ratio 
           1.0f, // the near view-plane 
           100.0f); // the far view-plane 

    d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection); // set the projection 

    // select the vertex buffer to display 
    d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); 

    // copy the vertex buffer to the back buffer 
    d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1); 

    d3ddev->EndScene(); 

    d3ddev->Present(NULL, NULL, NULL, NULL); 
} 


// this is the function that cleans up Direct3D and COM 
void cleanD3D(void) 
{ 
    v_buffer->Release(); // close and release the vertex buffer 
    d3ddev->Release(); // close and release the 3D device 
    d3d->Release(); // close and release Direct3D 
} 


// this is the function that puts the 3D models into video RAM 
void init_graphics(void) 
{ 
    // create the vertices using the CUSTOMVERTEX struct 
    CUSTOMVERTEX vertices[] = 
    { 
     { 3.0f, -3.0f, 0.0f, D3DCOLOR_XRGB(0, 0, 255), }, 
     { 0.0f, 3.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 0), }, 
     { -3.0f, -3.0f, 0.0f, D3DCOLOR_XRGB(255, 0, 0), }, 
    }; 

    // create a vertex buffer interface called v_buffer 
    d3ddev->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX), 
           0, 
           CUSTOMFVF, 
           D3DPOOL_MANAGED, 
           &v_buffer, 
           NULL); 

    VOID* pVoid; // a void pointer 

    // lock v_buffer and load the vertices into it 
    v_buffer->Lock(0, 0, (void**)&pVoid, 0); 
    memcpy(pVoid, vertices, sizeof(vertices)); 
    v_buffer->Unlock(); 
} 

Dois-je installer à travers le vin MS DirectX SDK? Changer quelque chose avec le code? Je suis des choses liées à DirectX et Windows, mais je veux juste compiler quelques exemples simples de D3D et vérifier si cela fonctionne.

Répondre

4

Ok! J'ai finalement réussi!

Malheureusement, j'avais besoin de télécharger Microsoft DirectX SDK (Avril 2007) (Je ne pouvais pas installer les plus récents avec du vin).

Ensuite, j'ai dû installer MinGW en utilisant le vin et également installer mingw-utils 0.3 (je devais obtenir le fichier reimp.exe).

Je mis en place PATH dans le registre du vin à C:\windows;C:\windows\system;C:\MinGW\bin

Alors je fait wine reimp.exe "C:\Program Files\Microsoft DirectX SDK (April 2007)/Lib/x86/d3dx9.lib". Cette commande a généré le fichier d3dx9_33.a, je l'ai changé en d3dx9.a et l'ai mis en /usr/i586-mingw32msvc/lib/.

J'ai également copié tous les fichiers d'en-tête manquant de DirectX SDK à /usr/i586-mingw32msvc/include.

Et puis ... J'ai compilé le programme, le liant à libd3d9.a et libd3dx9.a, et il compilé, lié, et ça marche! La bonne nouvelle est la suivante: on peut compiler des programmes Windows DirectX sous Linux en utilisant la version Linux de MinGW. Les mauvaises nouvelles: il faut installer quelques utilitaires MinGW et MS DX SDK ensemble en utilisant le vin.

EDIT

Et une chose: je devais faire toutes les pièces moulées WCHAR * manuellement concernant la PI - cris MinGW avec des erreurs si elle ne se fait pas. Goz était utile ici.

2

Si vous changez vos chaînes

(const WCHAR*)L"blah blah" 

Ensuite, il devrait compiler son pas l'idéal, mais il semble que wchar_t et WCHAR ne sont pas compatibles sous MinGW. Je ne suis pas entièrement sûr pourquoi il ne compile pas bien que windows.h définit WCHAR comme un typedef de wchar_t ...

+0

Ok, ça marche. Il manque encore le fichier libd3dx9.a (j'ai besoin de le lier). Je l'ai résolu, cependant, en utilisant mingw dlltool en utilisant d3dx9_36.dll de vin et libd3dx9.def ... Heh, il serait plus facile d'installer MS DirectX SDK. – silmeth

+0

Propably serait plus facile à utiliser Visual Studio express ... – Goz

+0

Très difficile sur Linux, je n'aime vraiment pas utiliser IDE sur le vin ... – silmeth

1

Vous pouvez également utiliser le compilateur croisé plain mingw, par exemple Debian ou Ubuntu, et le code pour DirectX uniquement en utilisant LoadLibrary() et GetProcAddress(). (Mais les tutoriels sur DirectX ne peuvent pas être utilisés tels quels.)

Questions connexes