2012-07-04 32 views
0

我有一個VC++ DirectX應用程序,可以使用W,A,S,D鍵和鼠標移動相機來渲染3D立方體。在左上角,一個文本顯示當前的攝像機座標;然而,在10-15秒後,分配的RAM和CPU增加到1.6Gb和差不多50%的總數。只有啓用文本時(即使移動仍然是「基於FLOPS」 ,所以無論如何它有點「生鏽」,有或沒有文字印刷)。D3D文本使用了太多的RAM ..?

我想文本一遍又一遍地被渲染導致RAM填滿,因爲它不會「釋放」以前寫的一個..?這個是我的代碼(有點長,我包括了一切'cuz也許是別的 - 但是,我不建議你運行它,因爲它可以,在最壞的情況下,凍結所有的RAM!):

#include <windows.h> // form header 
#include <windowsx.h> // form header 2 
#include <d3d9.h> // Direct3D9 header 
#include <d3dx9.h> // DirectX9 header 
#include <conio.h> 
#include <dinput.h> // DirectInput header 
#include <math.h> 
#include <string> 
using namespace std; 

const double PI = 3.1415926; 

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

// include the DirectInput8 Library file 
#pragma comment (lib, "dinput8.lib") 
#pragma comment (lib, "dxguid.lib") 

// define the screen resolution 
#define SCREEN_WIDTH 1024 
#define SCREEN_HEIGHT 768 

// 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 
LPDIRECT3DINDEXBUFFER9 i_buffer; // the pointer to an index buffer 
LPDIRECT3DTEXTURE9 texture; // declare a texture 
LPDIRECT3DTEXTURE9 bump; 

LPDIRECTINPUT8 din; // the pointer to our DirectInput interface 
LPDIRECTINPUTDEVICE8 dinkeyboard; // the pointer to the keyboard device 
LPDIRECTINPUTDEVICE8 dinmouse; // the pointer to the mouse device 
BYTE keystate[256]; // the storage for the key-information 
DIMOUSESTATE mousestate; // the storage for the mouse-information 
ID3DXFont *dxfont; 

VOID* pVoid; // a void pointer 


// 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 
void init_light(void); // sets up the light and the material 
void initDInput(HINSTANCE hInstance, HWND hWnd); // sets up and initializes DirectInput 
void detect_input(void); // gets the current input state 
void cleanDInput(void); // closes DirectInput and releases memory 
void PrintText(char* str, int size, int x, int y, DWORD color); 

inline DWORD F2DW(FLOAT f) { return *((DWORD*)&f); } 

struct CUSTOMVERTEX {FLOAT X, Y, Z; D3DVECTOR NORMAL; FLOAT U,V;}; 
#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1) 

// 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.hbrBackground = (HBRUSH)COLOR_WINDOW; 
    wc.lpszClassName = L"WindowClass"; 
    RegisterClassEx(&wc); 

    hWnd = CreateWindowEx(NULL, 
          L"WindowClass", 
          L"Our First Direct3D Program", 
          WS_OVERLAPPEDWINDOW, // non-fullscreen values 
          0, 0, // the starting x and y positions should be 0 
          SCREEN_WIDTH, SCREEN_HEIGHT, // set window to new resolution 
          NULL, 
          NULL, 
          hInstance, 
          NULL); 

    ShowWindow(hWnd, nCmdShow); 

    // set up and initialize Direct3D 
    initD3D(hWnd); 
    initDInput(hInstance, hWnd); // initialize DirectInput 

    // 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; 

     detect_input(); // update the input data before rendering 
     render_frame(); 

     if(keystate[DIK_ESCAPE] & 0x80) 
      PostMessage(hWnd, WM_DESTROY, 0, 0); 
    } 

    // clean up DirectX and COM 
    cleanD3D(); 
    cleanDInput(); // release DirectInput 

    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); // create the Direct3D interface 

    D3DPRESENT_PARAMETERS d3dpp; // create a struct to hold various device information 

    ZeroMemory(&d3dpp, sizeof(d3dpp)); // clear out the struct for use 
    d3dpp.Windowed = TRUE; // program fullscreen, not windowed 
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames 
    d3dpp.hDeviceWindow = hWnd; // set the window to be used by Direct3D 
    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; // set the back buffer format to 32-bit 
    d3dpp.BackBufferWidth = SCREEN_WIDTH; // set the width of the buffer 
    d3dpp.BackBufferHeight = SCREEN_HEIGHT; // set the height of the buffer 
    d3dpp.EnableAutoDepthStencil = TRUE; 
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 

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

    d3ddev->SetRenderState(D3DRS_LIGHTING, TRUE); // turn off the 3D lighting 
    d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE); // turn on the z-buffer 
    d3ddev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50)); // ambient light 

    init_graphics(); // call the function to initialize the triangle 
    init_light(); // call the function to initialize the light and material 

    d3ddev->SetRenderState(D3DRS_LIGHTING, TRUE); // turn on the 3D lighting 
    d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE); // turn on the z-buffer 
    d3ddev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50)); // ambient light 
    d3ddev->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE); // handle the normal lenght 
    d3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); // turn color blending on 

    // set filters and samples 
    d3ddev->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, 8); 
    d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC); 
    d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); 
    d3ddev->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); 

    //d3ddev->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); // set the blending operation 
    //d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); // set the source blending 
    //d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); // set the destination blending 

    D3DXCreateTextureFromFile(d3ddev, // the Direct3D device 
          L"brick.bmp", // the filename of the texture 
          &texture); // the address of the texture storage 

    D3DXCreateTextureFromFile(d3ddev, 
          L"bump.bmp", 
          &bump); 

    //d3ddev->SetRenderState(D3DRS_TEXTUREFACTOR, D3DCOLOR_XRGB(200, 200, 200)); 
//d3ddev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3); 
//d3ddev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); 
//d3ddev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); 
//d3ddev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); 
//d3ddev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); 

//d3ddev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); 
//d3ddev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); 
//d3ddev->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE); 
//d3ddev->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); 
//d3ddev->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); 

d3ddev->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); 
d3ddev->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); 





//D3DXAssembleShaderFromFile("shader1.fx", 0 , NULL, &pCode, NULL); 

} 

// Hypotenuse function 
float hypo(float x,float y) 
{ 
float hypo=sqrt(x*x+y*y); 
return hypo; 
} 

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

    d3ddev->BeginScene(); // begins the 3D scene  

    d3ddev->SetFVF(CUSTOMFVF); // tells Direct3D what FVF code we are using currently 

     // set the texture 
    d3ddev->SetTexture(1, bump); 
    d3ddev->SetTexture(0, texture); 

    /////// 


    D3DXMATRIX matTranslateA; // a matrix to store the translation for triangle A 
    D3DXMATRIX matTranslateB; // a matrix to store the translation for triangle B 
    D3DXMATRIX matRotate; // a matrix to store the rotation for each triangle 
    D3DXMATRIX matRotate2; 
    D3DXMATRIX matScale; 
    static float index = 0.0f; // left movement (A) 
    static float index2 = 10.0f; // upward movement (PRIOR) 
    static float index3 = 18.0f; // backward movement (S) -- 1.0f 
    static float index4 = 0.0f; // left lookAt 
    static float index5 = 10.0f; // upward lookAt 
    static float index6 = 18.0f; // backward lookAt 

    // camera variables 
    static float radius = 30.00f; 
    static float theta = (3.0f * D3DX_PI)/2.0f; 
    static float phi = D3DX_PI/2; 
    float Cx, Cy, Cz; 
    static int field = 45; 
    float slide = 0.001f; 
    static float dist1 = fabs(index-index4); 
    static float dist2 = fabs(index2-index5); 
    static float dist3 = fabs(index3-index6); 

    // player movements 


    // mouse movements 
    field -= 0.01 * mousestate.lZ; 
    theta += slide * mousestate.lX; 
    phi -= slide * mousestate.lY; 

    if(phi >= (D3DX_PI/9) * 8) 
    {   
     phi = (D3DX_PI/9) * 8; 
    } 
    if(phi <= (D3DX_PI/9)) 
    {   
     phi = (D3DX_PI/9); 
    } 

    Cx = radius * cosf(theta) * sinf(phi); 
    Cy = radius * cosf(phi); 
    Cz = radius * sinf(theta) * sinf(phi); 

    float mov = radius*0.012; 
    float mov1 = Cz*0.012; 
    float mov2 = -Cx*0.012; 

    // previous index. values 
    float indexb = index; 
    float index3b = index3; 

    //if (GetAsyncKeyState(VK_SHIFT)) // --- 0.06f/0.03f 
    //{ 
     if (keystate[DIK_A] & 0x80) 
     { 
      index=index-mov1; 
      index3=index3+mov2; 
     } 
     if (keystate[DIK_D] & 0x80) 
     { 
      index=index+mov1; 
      index3=index3-mov2; 
     } 
     if (keystate[DIK_PRIOR] & 0x80) // up + 
     { 
      index2+=0.22f; 
     } 
     if (keystate[DIK_NEXT] & 0x80) // down - 
     { 
      index2-=0.22f; 
     } 
     if (keystate[DIK_W] & 0x80) // prior 
     { 
      index3=index3+mov1; 
      index=index+mov2; 
     } 
     if (keystate[DIK_S] & 0x80) // next 
     { 
      index3=index3-mov1; 
      index=index-mov2; 
     } 
     if (keystate[DIK_SPACE] & 0x80) // next 
     { 
      // JUMP!!!!!!!!!!!! 
     } 

     if (hypo(index-indexb,index3-index3b)>mov) 
     { 
      index=indexb+0.7071*(index-indexb); 
      index3=index3b+0.7071*(index3-index3b); 
     } 


     // print a text 
     char msg1[64], msg2[64], msg3[64]; 
     sprintf (msg1, "X axis: %f", index); 
     sprintf (msg2, "Z axis: %f", index3); 
     PrintText(msg1, 20, 30, 30, D3DCOLOR_XRGB(255,255,255)); 
     PrintText(msg2, 20, 30, 60, D3DCOLOR_XRGB(255,255,255)); 


    //} 
    /*else 

    if (GetAsyncKeyState(VK_LEFT)) 
    { 
     index+=0.06f; 
     index4+=0.06f; 
    } 
    if (GetAsyncKeyState(VK_RIGHT)) 
    { 
     index-=0.06f; 
     index4-=0.06f; 
    } 
    if (GetAsyncKeyState(VK_PRIOR)) 
    { 
     index2-=0.06f; 
     index5-=0.06f; 
    } 
    if (GetAsyncKeyState(VK_NEXT)) 
    { 
     index2+=0.06f; 
     index5+=0.06f; 
    } 
    if (GetAsyncKeyState(VK_UP)) 
    { 
     index3-=0.03f; 
     index6-=0.06f; 
    } 
    if (GetAsyncKeyState(VK_DOWN)) 
    { 
     index3+=0.03f; 
     index6+=0.06f; 
    }*/ 


    // build MULTIPLE matrices to translate the model and one to rotate 
    D3DXMatrixTranslation(&matTranslateA, 0.0f, 0.0f, 0.0f); 
    //D3DXMatrixTranslation(&matTranslateB, 0.0f, 0.0f, -3.0f); 
    D3DXMatrixRotationY(&matRotate, 0.0f); // the front side --- index 
    D3DXMatrixRotationX(&matRotate2, 0.0f); // index2 
    D3DXMatrixScaling(&matScale, 1.0f, 1.0f, 1.0f); // index3 

    /////// 


    D3DXMATRIX matView; // the view transform matrix 

    D3DXMatrixLookAtLH(&matView, 
         &D3DXVECTOR3 (index, index2, index3), // the camera position --- (0.0f, 10.0f, 18.0f) 
         &D3DXVECTOR3 (index-Cx, index2-Cy, index3+Cz), // the look-at position --- (0.0f, 0.0f, 0.0f) 
         &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(field), // 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 

    // tell Direct3D about each world transform, and then draw another triangle 

    d3ddev->SetTransform(D3DTS_WORLD, &(matTranslateA * matRotate * matRotate2 * matScale)); 

    /////// 

    /// select the vertex and index buffers to use 
    d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); 
    d3ddev->SetIndices(i_buffer); 

    // draw the cube 
    d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 24, 0, 12); 


    d3ddev->EndScene(); // ends the 3D scene 

    d3ddev->Present(NULL, NULL, NULL, NULL); // displays the created frame on the screen 
} 

// this is the function that cleans up Direct3D and COM 
void cleanD3D(void) 
{ 
    v_buffer->Release(); // close and release the vertex buffer 
    //i_buffer->Release(); // close and release the index buffer 
    texture->Release(); // close and release the texture 
    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, 3.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }, // side 1 
     { 3.0f, -3.0f, 3.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f }, 
     { -3.0f, 3.0f, 3.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, 
     { 3.0f, 3.0f, 3.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f }, 

     { 3.0f, -3.0f, -3.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f }, // side 2 
     { -3.0f, -3.0f, -3.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f }, 
     { 3.0f, 3.0f, -3.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f }, 
     { -3.0f, 3.0f, -3.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f }, 

     { -3.0f, 3.0f, -3.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f }, // side 3 
     { -3.0f, 3.0f, 3.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f }, 
     { 3.0f, 3.0f, -3.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }, 
     { 3.0f, 3.0f, 3.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f }, 

     { -3.0f, -3.0f, -3.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f }, // side 4 
     { 3.0f, -3.0f, -3.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f }, 
     { -3.0f, -3.0f, 3.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f }, 
     { 3.0f, -3.0f, 3.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f }, 

     { 3.0f, -3.0f, 3.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f }, // side 5 
     { 3.0f, -3.0f, -3.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f }, 
     { 3.0f, 3.0f, 3.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }, 
     { 3.0f, 3.0f, -3.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f }, 

     { -3.0f, -3.0f, -3.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f }, // side 6 
     { -3.0f, -3.0f, 3.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f }, 
     { -3.0f, 3.0f, -3.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f }, 
     { -3.0f, 3.0f, 3.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f }, 
    }; 

    // create a vertex buffer interface called v_buffer 
    d3ddev->CreateVertexBuffer(24*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(); 

    // create the indices using an int array 
    short indices[] = 
    { 
     0, 1, 2, // side 1 
     2, 1, 3, 
     4, 5, 6, // side 2 
     6, 5, 7, 
     8, 9, 10, // side 3 
     10, 9, 11, 
     12, 13, 14, // side 4 
     14, 13, 15, 
     16, 17, 18, // side 5 
     18, 17, 19, 
     20, 21, 22, // side 6 
     22, 21, 23, 
    }; 

    // create an index buffer interface called i_buffer 
    d3ddev->CreateIndexBuffer(36*sizeof(short), 
           0, 
           D3DFMT_INDEX16, 
           D3DPOOL_MANAGED, 
           &i_buffer, 
           NULL); 

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

// this is the function that sets up the lights and materials 
void init_light(void) 
{ 
    D3DLIGHT9 light; // create the light struct 
    D3DMATERIAL9 material; // create the material struct 

    ZeroMemory(&light, sizeof(light)); // clear out the light struct for use 
    light.Type = D3DLIGHT_POINT; // make the light type 'point light' 
    light.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); // set the light's color 
    //light.Specular = D3DXCOLOR(5.5f, 5.5f, 5.5f, 1.0f); 
    light.Position = D3DXVECTOR3(10.0f, 10.0f, 5.0f); 
    light.Range = 100.0f; 
    //light.Direction = D3DXVECTOR3(-1.0f, -0.3f, -1.0f); 

    light.Attenuation0 = 0.0f; // constant attenuation 
    light.Attenuation1 = 0.0f; // inverse attenuation 
    light.Attenuation2 = 0.01f; // square inverse attenuation 

    d3ddev->SetLight(0, &light); // send the light struct properties to light #0 
    d3ddev->LightEnable(0, TRUE); // turn on light #0 

    ZeroMemory(&material, sizeof(D3DMATERIAL9)); // clear out the struct for use 
    material.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); // set diffuse color 
    material.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); // set ambient color 

    d3ddev->SetMaterial(&material); // set the globably-used material to &material 
} 

// this is the function that initializes DirectInput 
void initDInput(HINSTANCE hInstance, HWND hWnd) 
{ 
    // create the DirectInput interface 
    DirectInput8Create(hInstance, // the handle to the application 
         DIRECTINPUT_VERSION, // the compatible version 
         IID_IDirectInput8, // the DirectInput interface version 
         (void**)&din, // the pointer to the interface 
         NULL); // COM stuff, so we'll set it to NULL 

    // create the keyboard device 
    din->CreateDevice(GUID_SysKeyboard, // the default keyboard ID being used 
         &dinkeyboard, // the pointer to the device interface 
         NULL); // COM stuff, so we'll set it to NULL 
    din->CreateDevice(GUID_SysMouse, 
         &dinmouse, 
         NULL); 

    // set the data format to keyboard format 
    dinkeyboard->SetDataFormat(&c_dfDIKeyboard); 
    dinmouse->SetDataFormat(&c_dfDIMouse); 

    // set the control you will have over the keyboard 
    dinkeyboard->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND); 
    dinmouse->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND); 
} 

// this is the function that gets the latest input data 
void detect_input(void) 
{ 
    // get access if we don't have it already 
    dinkeyboard->Acquire(); 
    dinmouse->Acquire(); 

    // get the input data 
    dinkeyboard->GetDeviceState(256, (LPVOID)keystate); 
    dinmouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mousestate); 
} 

// this is the function that closes DirectInput 
void cleanDInput(void) 
{ 
    dinkeyboard->Unacquire(); // make sure the keyboard is unacquired 
    dinmouse->Unacquire(); // make sure the mouse in unacquired 
    din->Release(); // close DirectInput before exiting 
} 

void PrintText(char* str, int size, int x, int y, DWORD color) 
{ 
    static RECT textbox; 
    SetRect(&textbox, x, y, SCREEN_WIDTH, SCREEN_HEIGHT); 
    D3DXCreateFont(d3ddev, // the D3D Device 
        size, // font height 
        0, // default font width 
        FW_NORMAL, // font weight 
        1, // not using MipLevels 
        false, // italic font 
        DEFAULT_CHARSET, // default character set 
        OUT_DEFAULT_PRECIS, // default OutputPrecision, 
        DEFAULT_QUALITY, // default Quality 
        DEFAULT_PITCH | FF_DONTCARE, // default pitch and family 
        L"Arial", // use Facename Arial 
        &dxfont); // the font object 
    dxfont->DrawTextA(NULL, 
         str, 
         strlen(str), 
         &textbox, 
         DT_LEFT | DT_TOP, 
         color); 
} 
+0

這是一大堆代碼 - 通過仔細解釋你已經做了什麼來解決問題(希望你已經花了一些時間來自己調試),你會得到最好的服務。這最有可能導致從StackOverflow社區獲得幫助。 – reuben

+1

確實,在「外部」代碼中查找內存泄漏並不好玩。無論哪種方式,查看代碼的幾秒鐘都會顯示一個PrintText()函數,該函數每次調用它時都會創建一個字體,並且永遠不會釋放它...而且我猜測有不止一個這樣的泄漏。 –

+0

我知道,我唯一發現的就是文本是問題,正如斯蒂伯所說,它並沒有被釋放。我只是問,如何在渲染後釋放內存? – Banderi

回答

1

隨着stefan發佈,每次調用PrintText函數時都會創建一個新的字體。解決這個問題

一種方法是將D3DXCreateFont函數調用移動到initD3D功能,並添加匹配dxfont->Release();cleanD3D功能。

+0

好吧,_this_足夠解釋了;謝謝,它完美的工作:L – Banderi

2

每次打印文本時都不要創建新的字體對象。

+0

這並不能說明太多.. – Banderi

+0

@Banderi是的。只需檢查你的代碼。你自己寫了嗎?還是複製/粘貼一個例子?我確信這個例子在每次打印文本時都沒有創建字體對象。 – stefan

+0

我按照一個嚮導解釋我如何寫它,但它沒有說_where_放置代碼:L – Banderi