2010-09-28 143 views
3

如何配置mingw32以交叉編譯適用於Windows的Direct3D應用程序?有沒有可能?我實際上成功地編譯了本教程的代碼:http://www.directxtutorial.com/Tutorial9/B-Direct3DBasics/dx9B4.aspx - 在Kubuntu上使用Code :: Blocks和i586-mingw32msvc-g ++。我需要添加#define UNICODE並刪除#pragma ...部分來執行此操作,並且我還使用了mingw軟件包中來自/ usr/i586-mingw32msvc/include和libs的頭文件。在Linux上使用mingw交叉編譯Direct3D

但是我不能從本教程編譯代碼:http://www.directxtutorial.com/Tutorial9/B-Direct3DBasics/dx9B5.aspx

MinGW的沒有d3dx9.h文件。所以,我已經安裝了wine1.2-dev包與Windows相關的頭文件酒的版本,但現在我有錯誤:

隨着#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

而且沒有#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

這裏是我試圖編譯的整個代碼:

// 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(); 
} 

是否必須通過wine MS DirectX SDK進行安裝?用代碼改變一些東西?我是DirectX和Windows相關的東西,但我只是想交叉編譯一些D3D的簡單例子,並檢查它是否有效。

回答

4

好吧!我終於成功了!

不幸的是,我需要下載Microsoft DirectX SDK(2007年4月)(我無法用wine安裝更新的)。

然後,我不得不安裝MinGW使用酒,也安裝mingw-utils 0.3(我不得不獲得reimp.exe文件)。

然後,我成立了葡萄酒的寄存器通路到C:\windows;C:\windows\system;C:\MinGW\bin

然後我做了wine reimp.exe "C:\Program Files\Microsoft DirectX SDK (April 2007)/Lib/x86/d3dx9.lib"。這個命令生成了d3dx9_33.a文件,我將它更改爲d3dx9.a,並將其放入/usr/i586-mingw32msvc/lib/

我也將所有缺少的DirectX SDK頭文件複製到/usr/i586-mingw32msvc/include

然後...我編譯了程序,將它鏈接到libd3d9.a和libd3dx9.a,並編譯,鏈接並運行!

所以好消息是:可以在Linux下使用Linux版本的MinGW編譯Windows DirectX程序。

壞消息:需要安裝一些MinGW工具和使用Wine的MS DX SDK。

編輯

還有一兩件事:我需要手動進行所有WCHAR * - 相關鑄件 - MinGW的喊聲有錯誤,如果不這樣做。 Goz在這裏很有幫助。

2

如果你改變你的字符串

(const WCHAR*)L"blah blah" 

然後,它應該編譯它並不理想,但似乎wchar_t的WCHAR和不MinGW的下兼容。我不完全確定它爲什麼不編譯,雖然因爲windows.h定義WCHAR作爲wchar_t的typedef ...

+0

好的,那是有效的。仍然有缺乏libd3dx9.a文件(我需要鏈接它)。我解決了它,但是,通過使用mingw dlltool使用wine的d3dx9_36.dll和libd3dx9.def ...嘿,安裝MS DirectX SDK會更容易。 – silmeth 2010-09-28 20:26:48

+0

顯然是最容易使用Visual Studio Express ... – Goz 2010-09-28 20:35:49

+0

在Linux上很難,我真的不喜歡在酒上使用IDE ... – silmeth 2010-09-28 21:08:48

1

您也可以使用Debian或Ubuntu中的純mingw交叉編譯器,以及僅使用LoadLibrary()和GetProcAddress()的DirectX代碼。 (但DirectX上的教程不能按原樣使用。)