2010-02-23 38 views
1

[編輯] 注意:這些項目是我已複製和重命名的項目。不知道這是否與它有任何關係。加載圖像僅在可執行文件打開時才起作用

我正在使用directx sdk,只是玩弄它。我試圖通過加載外部文件將圖像粘貼到屏幕上。出於某種原因,當我構建它並在調試中運行時,它不起作用。但是,如果我去調試文件夾並打開exe文件。有用。我不知道爲什麼。這裏是我的代碼

#include <windows.h> 
#include <d3d9.h> 
#include <d3dx9.h> 
#include <time.h> 
#include <iostream> 
using namespace std; 

#pragma comment(lib,"d3d9.lib") 
#pragma comment(lib, "d3dx9.lib") 

const string APPTITLE = "Game Loop"; 
const int SCREENW = 1024; 
const int SCREENH = 768; 

bool gameover = false; 

LPDIRECT3D9 d3d    = NULL; 
LPDIRECT3DDEVICE9 d3ddev = NULL; 
LPDIRECT3DSURFACE9 surface = NULL; 
LPDIRECT3DSURFACE9 backbuffer = NULL; 

#define KEY_DOWN(vk_code)((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) 

bool Game_Init(HWND window) 
{ 
    MessageBox(window, "Game_Init", "BREAKPOINT",0); 
    //Initialize 

    d3d = Direct3DCreate9(D3D_SDK_VERSION); 
    if(d3d == NULL) 
    { 
     MessageBox(window, "Error Initializing", "ERROR",MB_OK); 
     return 0; 
    } 

    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory(&d3dpp, sizeof(d3dpp)); 
    d3dpp.Windowed = TRUE; 
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 
    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; 
    d3dpp.BackBufferCount = 1; 
    d3dpp.BackBufferWidth = SCREENW; 
    d3dpp.BackBufferHeight = SCREENH; 
    d3dpp.hDeviceWindow = window; 
    d3dpp.Windowed = TRUE; 

    d3d->CreateDevice(
     D3DADAPTER_DEFAULT, 
     D3DDEVTYPE_HAL, 
     window, 
     D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
     &d3dpp, 
     &d3ddev 
     ); 

    if(d3ddev == NULL) 
    { 
     MessageBox(window, "Error Creating Device", "ERROR",MB_OK); 
     return 0; 
    } 

    srand(time(NULL)); 

    d3ddev->Clear(0,NULL,D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,255,0), 1.0f,0); 

    d3ddev->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO, &backbuffer); 
    HRESULT result = d3ddev->CreateOffscreenPlainSurface(
     SCREENW,SCREENH, 
     D3DFMT_X8R8G8B8, 
     D3DPOOL_DEFAULT, 
     &surface, 
     NULL); 
    if(!SUCCEEDED(result)) return false; 

    result = D3DXLoadSurfaceFromFile(
     surface, 
     NULL,NULL, 
     "legotron.bmp", 
     NULL, 
     D3DX_DEFAULT, 
     0, 
     NULL); 

    if(!SUCCEEDED(result)) 
    { 
     MessageBox(window, "Error Loading Image", "ERROR",MB_OK); 
     return false; 
    } 

    return true; 
} 

void Game_Run(HWND hwnd) 
{ 
    if(!d3ddev) return; 

    d3ddev->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO, &backbuffer); 

    if(d3ddev->BeginScene()) 
    { 

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

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

    if(KEY_DOWN(VK_ESCAPE)) 
     PostMessage(hwnd, WM_DESTROY,0,0); 
} 

void Game_End(HWND hwnd) 
{ 
    if(surface) surface->Release(); 
    if(d3ddev)d3ddev->Release(); 
    if(d3d)d3d->Release(); 
} 

LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM WParam, LPARAM lparam) 
{ 
    switch(message) 
    { 
     case WM_DESTROY: 
      gameover = true; 
      PostQuitMessage(0); 
      return 0; 
     break; 
    } 

    return DefWindowProc(hWnd, message, WParam, lparam); 
} 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
        LPSTR lpCmdLine, int nCmdShow) 
{ 
     //set the new windows properties 

    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.c_str(); 
    wc.hIconSm  = NULL; 

    RegisterClassEx(&wc); 

    HWND window = CreateWindow(
     APPTITLE.c_str(), 
     APPTITLE.c_str(), 
     WS_OVERLAPPED, 
     CW_USEDEFAULT, CW_USEDEFAULT, 
     SCREENW,SCREENH, 
     NULL, 
     NULL, 
     hInstance, 
     NULL); 

    if(window == 0) return 0; 

    //display the window 
    ShowWindow(window, nCmdShow); 
    UpdateWindow(window); 

    //initialize the game 
    if(!Game_Init(window)) return 0; 

    MSG message; 

    //main message loop 
    while(!gameover) 
    { 
     if(PeekMessage(&message,NULL, 0, 0,PM_REMOVE)) 
     { 
      TranslateMessage(&message); 
      DispatchMessage(&message); 
     } 
     Game_Run(window); 
    } 

    Game_End(window); 

    return message.wParam; 
} 

我有它,它關閉應用程序,如果圖像加載失敗。

result = D3DXLoadSurfaceFromFile(
      surface, 
      NULL,NULL, 
      "legotron.bmp", 
      NULL, 
      D3DX_DEFAULT, 
      0, 
      NULL); 

     if(!SUCCEEDED(result)) 
     { 
      MessageBox(window, "Error Loading Image", "ERROR",MB_OK); 
      return false; 
     } 

如果我刪除了返回false行,窗口保持打開狀態(但沒有圖像)。顯然它失敗了。該圖像與.exe文件(在調試文件夾內)位於同一文件夾中,因爲它應該如此。因爲我曾經竭盡全力告訴它去別的地方去。當我親自打開調試文件夾中的.exe文件時,它仍然有效。但是當我構建它並嘗試運行時,它在IDE中不起作用。

[編輯]

我建立從零開始應用程序並運行它。仍然沒有工作。

+0

您的IDE可能有一個您不知道的默認文件位置。您是否嘗試將該文件調用爲「。\\ legotron.bmp」? – 2010-02-23 17:42:07

回答

1

當前文件夾不一定是您的.exe文件所在的文件夾。檢查項目選項的調試頁面,並確保工作文件夾是你所期望的。

當您在調試中運行程序時,您從該調試文件夾運行相同的.exe文件,但Visual Studio設置它運行的環境 - 包含工作文件夾。你知道該程序運行,因此很可能環境存在問題。

作爲發佈版本但不調試的程序偶爾會發生,通常意味着存在內存損壞。當被稱爲一種方式但不是另一種方式的同一構建工作的程序更爲罕見,但可能發生。這些東西是調試的噩夢。

雖然我懷疑這是問題。

+0

這個項目是一個複製的項目。這可能與它有關。我該如何檢查。我是新來的MSVS環境。 – numerical25 2010-02-23 20:39:22

+1

右鍵單擊「解決方案資源管理器」窗格中的項目。在上下文菜單中選擇「屬性」。在出現的對話框中,您應該在左側的樹形視圖中看到「調試」。選擇它,你會看到右邊的各種選項(包括「工作目錄」)。點擊它,你可以輸入一個文件夾名稱,或者使用顯示的小箭頭從「」和看似多餘的「」中選擇。檢查「配置」(對話框的左上角),以確保處理調試版本。它的工作原理是 – Steve314 2010-02-23 23:24:48

+0

。我將目錄更改爲調試目錄,它工作。我不知道爲什麼它不是默認設置 – numerical25 2010-02-23 23:41:20

0

您是否檢查過當前的工作目錄?這是一段時間,但我認爲這個功能是http://msdn.microsoft.com/en-us/library/aa364934%28VS.85%29.aspx。將其作爲調試輸出調用添加,以查看它作爲調試項目運行時的執行位置。該bmp將需要在該文件夾,IIRC。

+0

這可能是一個原因。我正在使用的這個項目是一個複製的項目。這可能與它有任何關係。 – numerical25 2010-02-23 20:36:27

+0

我懷疑問題在於該程序的CWD中沒有該圖像。所以如果你調試程序認爲CWD是什麼,那麼檢查該文件夾是否存在圖像。在那裏複製,然後再試一次。 – Amy 2010-02-23 20:56:28

+0

什麼是CWD? – numerical25 2010-02-23 22:31:52

相關問題