代码之家  ›  专栏  ›  技术社区  ›  silmeth

Linux与mingw交叉编译Direct3D

  •  4
  • silmeth  · 技术社区  · 15 年前

    如何配置mingw32来交叉编译Windows下的Direct3D应用程序?有没有可能?实际上,我已经成功地编译了本教程中的代码: http://www.directxtutorial.com/Tutorial9/B-Direct3DBasics/dx9B4.aspx -在Kubuntu上使用Code::Blocks和i586-mingw32msvc-g++。我需要补充一下 #define UNICODE #pragma ... 我使用了/usr/i586-mingw32msvc/include中的头文件和mingw包中的libs。

    但是,我无法编译本教程中的代码: http://www.directxtutorial.com/Tutorial9/B-Direct3DBasics/dx9B5.aspx

    d3dx9.h wine1.2-dev 包含wine版本的Windows相关头文件,但现在出现错误:

    #定义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();
    }
    

    我必须通过MS DirectX SDK安装吗?用密码改什么?我是DirectX和Windows相关的东西noob,但我只想交叉编译一些简单的D3D示例并检查它是否有效。

    3 回复  |  直到 15 年前
        1
  •  5
  •   silmeth    15 年前

    不幸的是,我需要下载microsoftdirectxsdk(2007年4月)(我无法用wine安装更新的)。

    然后我必须使用wine安装MinGW,还必须安装mingwutils0.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 .

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

    坏消息是:需要使用wine安装一些MinGW实用程序和整个msdxsdk。

    编辑

    还有一件事:我需要手动制作所有与WCHAR*相关的铸件,如果没有完成,mingw会发出错误的叫声。戈兹在这里很有帮助。

        2
  •  2
  •   Goz    15 年前

    如果你把字符串改成

    (const WCHAR*)L"blah blah"
    

    那么它应该编译它不理想的代码,但是在mingw下wchar和wchar似乎不兼容。我不太清楚为什么它不能编译,虽然作为windows.h定义WCHAR作为WCHAR的typedef\t。。。

        3
  •  1
  •   Prof. Falken    14 年前