Banderi
Banderi

Reputation: 710

D3D Text uses up too much RAM..?

I have a VC++ DirectX application that renders a 3D cube, with the camera that can be moved around with W,A,S,D keys and mouse. In the top-left corner, a text shows the current camera coordinates; however, after 10-15 seconds, the allocated RAM and CPU increase to 1.6Gb and almost 50% of the total.. This happens only if I enable the text (even if the movement is still "FLOPS-based", so it's anyway a little "rusty" sometimes, with or without text print).

I guess having the text to be rendered over and over again causes the RAM to fill up because it won't "release" the previously written one..?

Here's my code (a bit long, I included everything 'cuz maybe is something else - however, I don't recommend you to run it since it could, in the worst case, freeze all the RAM up!):

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

Upvotes: 0

Views: 641

Answers (2)

IanM_Matrix1
IanM_Matrix1

Reputation: 1594

As stefan posted, a new font is being created every time the PrintText function is called.

One way to fix this would be to move the D3DXCreateFont function call into the initD3D function, and add a matching dxfont->Release(); to the cleanD3D function.

Upvotes: 1

stefan
stefan

Reputation: 2886

Don't create a new font object every time you print text.

Upvotes: 2

Related Questions