Frame rate trouble

Started by
9 comments, last by ApochPiQ 14 years, 9 months ago
Hi, i cant find a tutorial anywhere on the internet. And its not in any of my c++ books. I'm using directx9 and c++ win32. I desperately need to know how to keep my framerate low. Because with creating a small menu, it goes too quick after a keypress. I need to limit this. Thanks. [Edited by - ApochPiQ on June 24, 2009 3:52:55 PM]
Advertisement
Quote:Original post by ryanp321
Hi, i cant find a tutorial anywhere on the internet.
And its not in any of my c++ books.

I'm using directx9 and c++ win32.
I desperately need to know how to keep my framerate low. Because with creating a small menu, it goes too quick after a keypress.

I need to limit this.
Thanks.
That sounds more like a program logic problem than an FPS problem. (Also, the reason it's not in any of your C++ books is that C++ knows nothing about framerate, menus, or anything of that sort; as such, those topics won't be covered in a book on the language itself.)

A good first step would be to clarify what you mean by 'goes too quick after a keypress'. If I had to guess, I would guess that your timing is not framerate-independent, but without more information it's difficult to say for sure.
Thanks for getting back to me.

I see what you mean actually,
my menu is 3 sprites in a switch statment.
And i have 4 if functions which looks like this

if (key down.. blah.)
i++

'i' is an array of 3 (my menu contains newgame load and credits)
in the 4 if statments there is , i++ , i-- and
if(i==0){
if (keyisdown..)
go to 3
}

I know its not the best way to do it, but when i press the down or up key.
It quickly runs through the script so by the time i've pressed the key, it acts as if im holding it.
why dont you read the keyup value instead?
that way it only reads once for key press and prevents it from keep reading the same key for as long as you keep pressing it.
yet, another stupid signature..
What you want to do is compare the key down status last frame, with the current key down status. Only do the i++ if the key was up on the previous frame, and is down on the current frame. That way it will change once per keypress.
Thank you for the help adam and a2ps.

Unfortunately adam_42 im not quite sure how to do that ^_^
although it does look like something that'd come in handy learning, so if you'd possibly be able to point us to a link or a book where you learned about key controll status's. That'd be great.

a2ps i realise what you say now, and it does make sense.
I'm just having trouble figuring how to do it without it constantly running due to the keys not being pressed.

if(KEY_DOWN(VK_DOWN)){if(KEY_UP(VK_UP)){i++;}}


This doesnt work, and it could be due to way my menu is drawn. I'm not sure myself if integers can be negative numbers either. so my array idea may be flawed by that. My code is displayd below.

It is 6 .png textures.
New game
continue
Credits

each one has 2 versions, to show a highlighted selection..
these are labled newgame1, newgame2.
They are drawn in a very from what i'd guess would be a big cpu eater switchstatment. and im always up for changing the way its done if anyone can point me in the right direction. Its incredibly hard to find something on the internet which is so comonly used.
Main.cpp

#include "main.h"/*------------------------------------------ Main function ------------------------------------------------//                        // 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));
//Filling in the windows class structure
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = "WindowClass";

RegisterClassEx(&wc);

hWnd = CreateWindowEx(NULL,"WindowClass","Creating a menu - Dx9",
WS_OVERLAPPEDWINDOW
,0, 0,
SCREEN_WIDTH, SCREEN_HEIGHT,
NULL,NULL,hInstance,NULL);

ShowWindow(hWnd, nCmdShow);

initD3D(hWnd); // set up and initialize Direct3D

MSG msg;

while(TRUE)
{
DWORD starting_point = GetTickCount();

if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;

TranslateMessage(&msg);
DispatchMessage(&msg);
}

//Key functions
if(KEY_DOWN(VK_UP)){
if(KEY_UP(VK_UP)){
i--;
}}

if(KEY_DOWN(VK_DOWN)){
if(KEY_UP(VK_UP)){
i++;
}}

if (i<=0){
if(KEY_DOWN(VK_DOWN)){
if(KEY_UP(VK_DOWN)){
i=3;
}}}

if (i>=3){
if(KEY_DOWN(VK_UP)){
if(KEY_UP(VK_UP)){
i=0;
}}}


render_frame();


if(KEY_DOWN(VK_ESCAPE)){
PostMessage(hWnd, WM_DESTROY, 0, 0);
}


while ((GetTickCount() - starting_point) < 25);

}

cleanD3D();// clean up DirectX and COM

return msg.wParam;
}

/*----------------------------------------Windows Procedure ----------------------------------------------//
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);
}

/*----------------------------------------initD3D function ------------------------------------------------//
this function initializes and prepares Direct3D for use
//---------------------------------------------------------------------------------------------------------*/

void initD3D(HWND hWnd){

d3d = Direct3DCreate9(D3D_SDK_VERSION);

D3DPRESENT_PARAMETERS d3dpp;

ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = true;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = SCREEN_WIDTH;
d3dpp.BackBufferHeight = SCREEN_HEIGHT;

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

D3DXCreateSprite(d3ddev, &d3dspt); // create the Direct3D Sprite object

D3DXCreateTextureFromFileEx(d3ddev, // the device pointer
"newgame2.png", // the new file name
D3DX_DEFAULT, // default width
D3DX_DEFAULT, // default height
D3DX_DEFAULT, // no mip mapping
NULL, // regular usage
D3DFMT_A8R8G8B8, // 32-bit pixels with alpha
D3DPOOL_MANAGED, // typical memory handling
D3DX_DEFAULT, // no filtering
D3DX_DEFAULT, // no mip filtering
D3DCOLOR_XRGB(0, 0, 250), // the color key
NULL, // no image info struct
NULL, // not using 256 colors
&newgame2); // load to sprite

D3DXCreateTextureFromFileEx(d3ddev, // the device pointer
"newgame1.png", // the new file name
D3DX_DEFAULT, // default width
D3DX_DEFAULT, // default height
D3DX_DEFAULT, // no mip mapping
NULL, // regular usage
D3DFMT_A8R8G8B8, // 32-bit pixels with alpha
D3DPOOL_MANAGED, // typical memory handling
D3DX_DEFAULT, // no filtering
D3DX_DEFAULT, // no mip filtering
D3DCOLOR_XRGB(0, 0, 250), // the color key
NULL, // no image info struct
NULL, // not using 256 colors
&newgame1); // load to sprite

D3DXCreateTextureFromFileEx(d3ddev, // the device pointer
"credits2.png", // the new file name
D3DX_DEFAULT, // default width
D3DX_DEFAULT, // default height
D3DX_DEFAULT, // no mip mapping
NULL, // regular usage
D3DFMT_A8R8G8B8, // 32-bit pixels with alpha
D3DPOOL_MANAGED, // typical memory handling
D3DX_DEFAULT, // no filtering
D3DX_DEFAULT, // no mip filtering
D3DCOLOR_XRGB(0,0, 250), // the color key
NULL, // no image info struct
NULL, // not using 256 colors
&credits2); // load to sprite

D3DXCreateTextureFromFileEx(d3ddev, // the device pointer
"credits1.png", // the new file name
D3DX_DEFAULT, // default width
D3DX_DEFAULT, // default height
D3DX_DEFAULT, // no mip mapping
NULL, // regular usage
D3DFMT_A8R8G8B8, // 32-bit pixels with alpha
D3DPOOL_MANAGED, // typical memory handling
D3DX_DEFAULT, // no filtering
D3DX_DEFAULT, // no mip filtering
D3DCOLOR_XRGB(0,0,250), // the color key
NULL, // no image info struct
NULL, // not using 256 colors
&credits1); // load to sprite

D3DXCreateTextureFromFileEx(d3ddev, // the device pointer
"continue2.png", // the new file name
D3DX_DEFAULT, // default width
D3DX_DEFAULT, // default height
D3DX_DEFAULT, // no mip mapping
NULL, // regular usage
D3DFMT_A8R8G8B8, // 32-bit pixels with alpha
D3DPOOL_MANAGED, // typical memory handling
D3DX_DEFAULT, // no filtering
D3DX_DEFAULT, // no mip filtering
D3DCOLOR_XRGB(0,0,250), // the color key
NULL, // no image info struct
NULL, // not using 256 colors
&continue2); // load to sprite

D3DXCreateTextureFromFileEx(d3ddev, // the device pointer
"continue1.png", // the new file name
D3DX_DEFAULT, // default width
D3DX_DEFAULT, // default height
D3DX_DEFAULT, // no mip mapping
NULL, // regular usage
D3DFMT_A8R8G8B8, // 32-bit pixels with alpha
D3DPOOL_MANAGED, // typical memory handling
D3DX_DEFAULT, // no filtering
D3DX_DEFAULT, // no mip filtering
D3DCOLOR_XRGB(0,0,250), // the color key
NULL, // no image info struct
NULL, // not using 256 colors
&continue1); // load to sprite

return;
}


/*----------------------------------------Render Frame function -------------------------------------------//
//---------------------------------------------------------------------------------------------------------*/

void render_frame(void){
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

d3ddev->BeginScene();

//Begin sprite rendering
d3dspt->Begin(D3DXSPRITE_ALPHABLEND);

D3DXVECTOR3 center1(0.0f,0.0f,0.0f), position1(30.0f,400.0f,0.0f);
D3DXVECTOR3 center2(0.0f,0.0f,0.0f), position2(30.0f,450.0f,0.0f);
D3DXVECTOR3 center3(0.0f,0.0f,0.0f), position3(30.0f,500.0f,0.0f);


switch (i){
case 0:
d3dspt->Draw(newgame2, NULL, &center1, &position1, D3DCOLOR_ARGB(255, 255, 255, 255));
d3dspt->Draw(continue1, NULL, &center2, &position2, D3DCOLOR_ARGB(255, 255, 255, 255));
d3dspt->Draw(credits1, NULL, &center3, &position3, D3DCOLOR_ARGB(255, 255, 255, 255));
break;
case 1:
d3dspt->Draw(newgame1, NULL, &center1, &position1, D3DCOLOR_ARGB(255, 255, 255, 255));
d3dspt->Draw(continue2, NULL, &center2, &position2, D3DCOLOR_ARGB(255, 255, 255, 255));
d3dspt->Draw(credits1, NULL, &center3, &position3, D3DCOLOR_ARGB(255, 255, 255, 255));
break;
case 2:
d3dspt->Draw(newgame1, NULL, &center1, &position1, D3DCOLOR_ARGB(255, 255, 255, 255));
d3dspt->Draw(continue1, NULL, &center2, &position2, D3DCOLOR_ARGB(255, 255, 255, 255));
d3dspt->Draw(credits2, NULL, &center3, &position3, D3DCOLOR_ARGB(255, 255, 255, 255));
break;
}

d3dspt->End();


d3ddev->EndScene();

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

return;
}

/*----------------------------------------cleanD3D function ------------------------------------------------//
this is the function that cleans up direct3d and COM
//---------------------------------------------------------------------------------------------------------*/

void cleanD3D(void){
d3dspt->Release();
d3ddev->Release(); // close and release the 3D device
d3d->Release(); // close and release Direct3D
return;
}



[Edited by - ApochPiQ on June 24, 2009 3:03:28 PM]
Main.h

/*----------------------------------Include Files-------------------------------------------////------------------------------------------------------------------------------------------*/#include <windows.h>#include <windowsx.h>#include <d3d9.h>#include <d3dx9.h>#include <d3dx9core.h>/*----------------define the screen resolution and keyboard macros--------------------------////------------------------------------------------------------------------------------------*/#define SCREEN_WIDTH 1280#define SCREEN_HEIGHT 800#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)#pragma comment (lib, "d3d9.lib")#pragma comment (lib, "d3dx9.lib")// global declarationsLPDIRECT3D9 d3d;    // the pointer to our Direct3D interfaceLPDIRECT3DDEVICE9 d3ddev;    // the pointer to the device classLPD3DXSPRITE d3dspt;LPDIRECT3DTEXTURE9 newgame1;    // the pointer to the spriteLPDIRECT3DTEXTURE9 newgame2;LPDIRECT3DTEXTURE9 credits1;LPDIRECT3DTEXTURE9 credits2;LPDIRECT3DTEXTURE9 continue1;LPDIRECT3DTEXTURE9 continue2;// function prototypesvoid initD3D(HWND hWnd);    // sets up and initializes Direct3Dvoid render_frame(void);    // renders a single framevoid cleanD3D(void);    // closes Direct3D and releases memory    int i = 0;LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); // the WindowProc function prototype
You should use WM_KEYDOWN (or WM_KEYUP) in your WindowProc function, you don't need GetAsyncKeyState.
If im honest, i know nothing about programming for keyboard use. I realise now what i need to do. So im going to class this thread as solved. and go back to the basics for a while.
Thanks for all the help guys, Its the little things which keep getting in my way.

This topic is closed to new replies.

Advertisement