Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm trying to create a RPG game and for a test I thought I might draw the same tile(20x20 pixels) over the whole window(720x480), it works and renders the tiles fine but the amount of memory and CPU power it requires is way too much. It roughly allocates 400MB and uses roughly 35% of the CPU, the image is a .bmp file format and it's file size is 856 bytes. I use new on each object and add each one to a vector, I also delete each one for clear up. Here's the code:

This the main class

main.h

#ifndef MAIN_H
#define MAIN_H

#include <vector>
#include <d3d9.h>

#include "Keyboard.h"
#include "Mouse.h"
#include "Graphics.h"
#include "Tile.h"
#include "Timer.h"

#define WIDTH 720
#define HEIGHT 480

class Main
{
public:
    Main(HWND hWnd, const KeyboardServer& kServer, const MouseServer& mServer);
    ~Main();
public:
    void Go();
    void ComposeFrame();
public:
    IDirect3DDevice9* device;
private:
    Graphics gfx;
    KeyboardClient kbd;
    MouseClient mouse;
    Timer time;
};

#endif

main.cpp

#include "Main.h"
std::vector<Tile*> tileList;
Main::Main(HWND hWnd, const KeyboardServer& kServer, const MouseServer& mServer)
:
gfx(hWnd),
kbd(kServer),
mouse(mServer)
{
device = gfx.device;

for (int y = 0; y < HEIGHT; y += 20)
{
    for (int x = 0; x < WIDTH; x += 20)
    {
        // Set the current index for the map and add it to the tile list
        Tile* temp = new Tile;
        temp->Init(x, y);
        tileList.push_back(temp);
    }
}

for (int x = 0; x < tileList.size(); x++){
    tileList[x]->Create(device);
    }
}

Main::~Main()
{}

void Main::Go(){
   gfx.beginFrame();
   ComposeFrame();
   gfx.endFrame();
}

void Main::ComposeFrame(){
    for (int x = 0; x < tileList.size(); x++){
        tileList[x]->Draw();
    }
}

Here is the tile class

tile.h

#pragma once
#include <d3dx9.h>
#include <string>
#include "Keyboard.h"
#include "Mouse.h"
#include "Tile.h"

class Tile
{
public:
    Tile();
    ~Tile();
public:
    void Draw();
    void Create(IDirect3DDevice9* device);
    void Init(int x, int y);
private:
    LPDIRECT3DTEXTURE9 tex;
    LPD3DXSPRITE sprite;
    D3DXVECTOR3 position;
    D3DCOLOR colour;
    int width, height, x, y;

    char filePath[50];
};

tile.cpp

#include "Tile.h"

Tile::Tile()
{
    colour = D3DCOLOR_ARGB(255, 255, 255, 255);

    width = 20;
    height = 20;

    position.x = 0;
    position.y = 0;
    position.z = 0;

    strcpy(filePath, "Grass.bmp");
}

Tile::~Tile()
{}

void Tile::Init(int x, int y){
    position.x = x;
    position.y = y;
}

void Tile::Create(IDirect3DDevice9* device){
    D3DXCreateTextureFromFileEx(device, filePath, width, height, 1, D3DPOOL_DEFAULT,
    D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &tex);

    //Attempt to create the sprite
    D3DXCreateSprite(device, &sprite);
}

void Tile::Draw(){
    sprite->Begin(D3DXSPRITE_ALPHABLEND); //method of drawing 
    sprite->Draw(tex, NULL, NULL, &position, colour); //actually drawing
    sprite->End(); //ending the drawing
}

I just want to make it so the game doesn't allocate as much memory and use much less of CPU. Sorry if I have used code incorrectly it is my first time for programming a game, advice would be appreciated, thank you.

EDIT This is the window cpp

Window.cpp

#include <Windows.h>
#include "Keyboard.h"
#include "Mouse.h"
#include "Main.h"

#define WIDTH 720
#define HEIGHT 480

static KeyboardServer kServ;
static MouseServer mServ;

#define VK_W 87 //W keycode 
#define VK_A 65 //A keycode 
#define VK_S 83 //S keycode
#define VK_D 68 //D keycode


LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
    switch (msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    // ************ KEYBOARD MESSAGES ************ //
    case WM_KEYDOWN:
        switch (wParam)
    {
    case VK_UP:
        kServ.OnUpPressed();
        break;
    case VK_DOWN:
        kServ.OnDownPressed();
        break;
    case VK_LEFT:
        kServ.OnLeftPressed();
        break;
    case VK_RIGHT:
        kServ.OnRightPressed();
        break;
    case VK_SPACE:
        kServ.OnSpacePressed();
        break;
    case VK_RETURN:
        kServ.OnEnterPressed();
        break;
    case VK_W:
        kServ.OnWPressed();
        break;
    case VK_A:
        kServ.OnAPressed();
        break;
    case VK_S:
        kServ.OnSPressed();
        break;
    case VK_D:
        kServ.OnDPressed();
        break;
    case VK_ESCAPE:
        kServ.OnEscPressed();
        break;
    case VK_SHIFT:
        kServ.OnShiftPressed();
        break;
    }
    break;
case WM_KEYUP:
    switch (wParam)
    {
    case VK_UP:
        kServ.OnUpReleased();
        break;
    case VK_DOWN:
        kServ.OnDownReleased();
        break;
    case VK_LEFT:
        kServ.OnLeftReleased();
        break;
    case VK_RIGHT:
        kServ.OnRightReleased();
        break;
    case VK_SPACE:
        kServ.OnSpaceReleased();
        break;
    case VK_RETURN:
        kServ.OnEnterReleased();
        break;
    case VK_W:
        kServ.OnWReleased();
        break;
    case VK_A:
        kServ.OnAReleased();
        break;
    case VK_S:
        kServ.OnSReleased();
        break;
    case VK_D:
        kServ.OnDReleased();
        break;
    case VK_SHIFT:
        kServ.OnShiftReleased();
        break;
    }
    break;
    // ************ END KEYBOARD MESSAGES ************ //

    // ************ MOUSE MESSAGES ************ //
case WM_MOUSEMOVE:
{
    int x = (short)LOWORD(lParam);
    int y = (short)HIWORD(lParam);
    if (x > 0 && x < WIDTH && y > 0 && y < HEIGHT)
    {
        mServ.OnMouseMove(x, y);
        if (!mServ.IsInWindow())
        {
            SetCapture(hWnd);
            mServ.OnMouseEnter();
        }
    }
    else
    {
        if (wParam & (MK_LBUTTON | MK_RBUTTON))
        {
            x = max(0, x);
            x = min(x - 1, x);
            y = max(0, y);
            y = min(y - 1, y);
            mServ.OnMouseMove(x, y);
        }
        else
        {
            ReleaseCapture();
            mServ.OnMouseLeave();
            mServ.OnLeftReleased();
            mServ.OnRightReleased();
        }
    }
}
break;
case WM_LBUTTONDOWN:
    mServ.OnLeftPressed();
    break;
case WM_RBUTTONDOWN:
    mServ.OnRightPressed();
    break;
case WM_LBUTTONUP:
    mServ.OnLeftReleased();
    break;
case WM_RBUTTONUP:
    mServ.OnRightReleased();
    break;
    // ************ END MOUSE MESSAGES ************ //
}

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

int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, INT)
{
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0, 0,
    GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
    "Win32Window", NULL };
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    RegisterClassEx(&wc);

    RECT wr;
    GetClientRect(GetDesktopWindow(), &wr); //gets size of window and sets it to wr RECT
    wr.left = (wr.right / 2) - (WIDTH / 2);
    wr.top = (wr.bottom / 2) - (HEIGHT / 2);
    AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
    HWND hWnd = CreateWindowW(L"Win32Window", L"Win32Window",
    WS_OVERLAPPEDWINDOW, wr.left, wr.top, WIDTH, HEIGHT,
    NULL, NULL, wc.hInstance, NULL);

    ShowWindow(hWnd, SW_SHOWDEFAULT);
    UpdateWindow(hWnd);
    Main *main;

    MSG msg;

    main = new Main(hWnd, kServ, mServ);

    ZeroMemory(&msg, sizeof(msg));
    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            main->Go();
        }
    }

UnregisterClass("Win32Window", wc.hInstance);
return 0;

}

share|improve this question

closed as off-topic by Josh Petrie Mar 9 at 22:10

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions about debugging a problem in your project must present a concise selection of code and context so as to allow a reader to diagnose the issue without needing to read all of your code or to engage in extensive back-and-forth dialog. For more information, see this meta thread." – Josh Petrie
If this question can be reworded to fit the rules in the help center, please edit the question.

    
About of the 35% usage of your CPU, I don't see where is your main loop, so I would assume that you don't throttle the frame rate yourself. And if you don't throttle the frame rate yourself, and your GPU doesn't do it either, then it's not throttled, and your program runs as many frames as it can... –  Alexandre Vaillancourt Mar 9 at 20:26
    
@AlexandreVaillancourt I have edited the post and the main loop is shown now. –  Jack Mar 9 at 21:15
    
Ok, so this is about what I thought; you could add a call to Sleep(0.033); after the main->Go();. I'm not too familiar with the windows way of doing things so there might be a better place to make that call. You might want to take a peek there to get a bit more info on this particular issue: gameprogrammingpatterns.com/game-loop.html#take-a-little-nap –  Alexandre Vaillancourt Mar 9 at 21:37