2011-12-04 39 views
1

我目前正在學習DirectX,所以我是一個初學者,而且我被困在一個代碼中。我正在學習一本書,我寫了這段代碼。它應該在窗口上繪製位圖,但它給了我一個空白的屏幕。此外,當我單擊esc按鈕它會給出錯誤,但如果我按Esc之前移動或拉伸窗口,它不會給出錯誤。任何幫助讚賞。我正在使用Visual Studio 2010和C++。我有一個假設,錯誤可能在D3DXCreateSurfaceFromFile。這是代碼;Directx位圖無法加載

//Header files to include 
#include <d3d9.h> 
#include <time.h> 
#include <d3dx9.h> 

//Application title 
#define APPTITLE L"Load_Bitmap" 

//Screen Resolution 
#define WIDTH 640 
#define HEIGHT 480 

//Forward Declarations 
LRESULT WINAPI WinProc(HWND, UINT, WPARAM, LPARAM); 
ATOM MyRegisterClass(HINSTANCE); 
int GameInit(HWND); 
void GameRun(HWND); 
void GameEnd(HWND); 

//Direct3d objects 
LPDIRECT3D9 d3d = NULL; 
LPDIRECT3DDEVICE9 d3ddev = NULL; 
LPDIRECT3DSURFACE9 backbuffer = NULL; 
LPDIRECT3DSURFACE9 surface = NULL; 

//Macros to read the keyboard asynchronously 
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) 
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) 


//Window Event Callback Function 
LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
    switch(msg) 
    { 
     case WM_DESTROY: 
      GameEnd(hWnd); 
      PostQuitMessage(0); 
      return 0; 
    } 

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

//Helper function to set up the window properties 
ATOM MyRegisterClass(HINSTANCE hInstance) 
{ 
    WNDCLASSEX wc; 

    wc.cbSize = sizeof(WNDCLASSEX); 
    wc.style = CS_HREDRAW | CS_VREDRAW; 
    wc.lpfnWndProc = (WNDPROC)WinProc; 
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
    wc.hInstance = hInstance; 
    wc.hIcon = NULL; 
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 
    wc.lpszMenuName = NULL; 
    wc.lpszClassName = APPTITLE; 
    wc.hIconSm = NULL; 

    //Set up the window with the class info 
    return RegisterClassEx(&wc); 



} 

//Entry point for a windows program 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstancem, LPSTR lpCmdLine, int nCmdShow) 
{ 
    //Declare variables 
    MSG msg; 

    //Register the class 
    MyRegisterClass(hInstance); 

    //Initialize Application 
    HWND hWnd; 

    //Create new Window 
    hWnd = CreateWindow(APPTITLE, APPTITLE, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WIDTH, HEIGHT, NULL, NULL, hInstance, NULL); 

    if(!hWnd) 
     return FALSE; 

    //Display the Window 
    ShowWindow(hWnd, nCmdShow); 
    UpdateWindow(hWnd); 

    //Initialize the Game 
    if(!GameInit(hWnd)) 
     return FALSE; 

    //Main Message Loop 
    int done = 0; 
    while(!done) 
    { 
     if(PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE)) 
     { 
      //Look for quit message 
      if(msg.message == WM_QUIT) 
       done = 1; 

      //Decode and pass messages on to WndProc 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 
     else 
      //Process game loop(else prevents running after window is closed) 
      GameRun(hWnd); 
    } 

    return msg.wParam; 
} 

int GameInit(HWND hWnd) 
{ 
    HRESULT result; 

    //Initialize Direct3d 
    d3d = Direct3DCreate9(D3D_SDK_VERSION); 
    if(d3d == NULL) 
    { 
     MessageBox(hWnd, L"Error initializing Direct3d", L"Error", MB_OK); 
     return 0; 
    } 

    //Set Direct3D presentation parameters 
    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory(&d3dpp, sizeof(d3dpp)); 

    d3dpp.Windowed = TRUE; 
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 
    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; 
    d3dpp.BackBufferCount = 1; 
    d3dpp.BackBufferWidth = WIDTH; 
    d3dpp.BackBufferHeight = HEIGHT; 
    d3dpp.hDeviceWindow = hWnd; 

    //Create Direct3D device 
    d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); 

    if(d3ddev == NULL) 
    { 
     MessageBox(hWnd, L"Error creating Direct3d device", L"Error", MB_OK); 
     return 0; 
    } 

    //Set Random number seed 
    //srand(time(NULL)); 

    //Clear the backbuffer to black 
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); 

    //Create pointer to the back buffer 
    d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); 

    //Create surface 
    result = d3ddev->CreateOffscreenPlainSurface(640, 480, D3DFMT_X8R8G8B8, 
               D3DPOOL_DEFAULT, &surface, NULL); 

    if(result != D3D_OK) 
     return 1; 

    //load surface from file 
    result = D3DXLoadSurfaceFromFile(
     surface, NULL, NULL, L"c.bmp", NULL, D3DX_DEFAULT, 0, NULL); 

    //Make sure file was loaded okay 
    if(result != D3D_OK) 
     return 1; 

    d3ddev->StretchRect(surface, NULL, backbuffer, NULL, D3DTEXF_NONE); 

    //Return okay 
    return 1; 
} 

void GameRun(HWND hWnd) 
{ 

    //Make Sure the Direct3d device is valid 
    if(d3ddev == NULL) 
     return; 

    //Start Rendering 
    if(d3ddev->BeginScene()) 
    { 
     //Create pointer to the back buffer 
     d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); 

     //Draw surface to the backbuffer 
     d3ddev->StretchRect(surface, NULL, backbuffer, NULL, D3DTEXF_NONE); 
     //StopRendering 
     d3ddev->EndScene(); 
    } 

    //Display the back buffer on the screen 
    d3ddev->Present(NULL, NULL, NULL, NULL); 

    //Check for escape key(to exit program) 
    if(KEY_DOWN(VK_ESCAPE)) 
     PostMessage(hWnd, WM_DESTROY, 0, 0); 
} 

void GameEnd(HWND hWnd) 
{ 
    //free the surface 
    if(surface != NULL) 
     surface->Release(); 

    //Release the Direct3D device 
    if(d3ddev != NULL) 
     d3ddev->Release(); 

    if(d3d != NULL) 
     d3d->Release(); 
} 
+0

如果您尚未這樣做,請使用調試運行時並調整調試輸出的級別。 – user786653

+1

正如用戶上面所述,提高調試輸出水平。此外,請確保c.bmp位於應用程序的工作目錄中,該目錄通過Visual Studio不是*您的二進制文件所在的位置,而是您的項目文件所在的位置(我認爲...)。 – slugonamission

+0

好的。現在它畫了,我改變了bmp文件的位置。但是仍然有一個問題。當我按下轉義它仍然會給出錯誤 – Perex19

回答

1

當您檢查轉義鍵時,發送WM_QUIT而不是WM_DESTROY。就目前而言,消息循環將永遠不會退出,因爲它取決於發佈的WM_QUIT,並且即使在刪除曲面之後它仍會繼續調用GameRun。