SLOW!!!!

Started by
3 comments, last by [GaNoN] 24 years, 5 months ago
I haven't had enough time to go through your whole program yet....but from the first half I have one idea you might check.

DirectX is known for being bad at ModeX and Mode13H (at least according to a few books I have...i haven't tried it myself), and also many windows drivers do not properly implement one or both of these modes...so I suggest you perform one simple test before spending more time on the problem.

Switch the Resolution to 640x480 and run the program...if the program is just as fast or faster...you might have found the problem...if not...post that you tried it...and we'll look deeper into your code

Advertisement
640x480 is the same speed as 320x240
Overall it looks pretty good. But from my own experience using lock/unlock can do some really crazy stuff. First I would check for keyboard states before you lock your surface, I think GetAsyncKeyState has some delay to it. By keeping the time between your lock and unlock short you reduce the chance that something wierd is happening.

Thats all I can figure.

Just because the church was wrong doesn't mean Galileo wasn't a heretic.It just means he was a heretic who was right.
I was just wondering why this fire example is so slow. When I try a new graphics library or programming language I allways make a fire thing. In DJGPP this is fast but in DirectX it's SLOW!!! Could someone help make this fast.

// LISTING 1.0 - DIRECT X 5.0 GAME CONSOLE ////////////////////////////////////

// INCLUDES ///////////////////////////////////////////////////////////////////

#define WIN32_LEAN_AND_MEAN // make sure certain headers are included correctly

#include // include the standard windows stuff
#include // include the 32 bit stuff
#include // include the multi media stuff
// note you need winmm.lib also
#include // include direct draw components

#include // include all the good stuff
#include
#include
#include

// DEFINES ////////////////////////////////////////////////////////////////////

#define WINDOW_CLASS_NAME "WINDOW_CLASS" // this is the name of the window class

// defines for screen parameters

#define SCREEN_WIDTH 320 // the width of the viewing surface
#define SCREEN_HEIGHT 240 // the height of the viewing surface
#define SCREEN_BPP 8 // the bits per pixel
#define MAX_COLORS 256 // the maximum number of colors

// TYPES //////////////////////////////////////////////////////////////////////

typedef unsigned char UCHAR;

// MACROS /////////////////////////////////////////////////////////////////////

// these query the keyboard in real-time

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

// PROTOTYPES /////////////////////////////////////////////////////////////////

int DD_Init(HWND hwnd);
int DD_Shutdown(void);
int Set_Pal_Entry(int index, int red, int green, int blue);

void Game_Init(void);
void Game_Main(void);
void Game_Shutdown(void);

// DIRECTDRAW GLOBALS ////////////////////////////////////////////////////////

LPDIRECTDRAW lpdd = NULL; // dd object
LPDIRECTDRAWSURFACE lpddsprimary = NULL; // dd primary surface
LPDIRECTDRAWPALETTE lpddpal = NULL; // a pointer to the created dd palette
PALETTEENTRY color_palette[256]; // holds the shadow palette entries
DDSURFACEDESC ddsd; // a direct draw surface description struct
DDSCAPS ddscaps; // a direct draw surface capabilities struct
HRESULT ddrval; // result back from dd calls
HWND main_window_handle = NULL; // used to store the window handle
UCHAR *video_buffer = NULL; // pointer to video ram


// GAME GLOBALS GO HERE /////////////////////////////////////////////////////

// DIRECT X FUNCTIONS /////////////////////////////////////////////////////////

int DD_Init(HWND hwnd)
{
// this function is responsible for initializing direct draw, it creates a
// primary surface

int index; // looping index

// now that the windows portion is complete, start up direct draw
if (DirectDrawCreate(NULL,&lpdd,NULL)!=DD_OK)
{
// shutdown any other dd objects and kill window
DD_Shutdown();
return(0);
} // end if

// now set the coop level to exclusive and set for full screen and mode x
if (lpdd->SetCooperativeLevel(hwnd, DDSCL_EXCLUSIVE |
DDSCL_FULLSCREEN)!=DD_OK)
{
// shutdown any other dd objects and kill window
DD_Shutdown();
return(0);
} // end if

// now set the display mode
if (lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP)!=DD_OK)
{
// shutdown any other dd objects and kill window
DD_Shutdown();
return(0);
} // end if

// Create the primary surface
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

if
(lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL)!=DD_OK)
{
// shutdown any other dd objects and kill window
DD_Shutdown();
return(0);
} // end if

// create the palette and attach it to the primary surface

// clear all the palette entries to RGB 0,0,0
memset(color_palette,0,256*sizeof(PALETTEENTRY));


for (index = 0; index < 64; index++) {
color_palette[index].peRed=index*3;
color_palette[index].peGreen=0;
color_palette[index].peBlue=0;

color_palette[index+64].peRed=63*3 ;
color_palette[index+64].peGreen=index*3;
color_palette[index+64].peBlue=0;

color_palette[index+128].peRed=63*3;
color_palette[index+128].peGreen=63*3;
color_palette[index+128].peBlue=index*3;

color_palette[index+192].peRed=63*3;
color_palette[index+192].peGreen=63*3;
color_palette[index+192].peBlue=63*3;
}


// now create the palette object, note that it is a member of the dd object itself
if (lpdd->CreatePalette((DDPCAPS_8BIT | DDPCAPS_INITIALIZE),color_palette,&lpddpal,NULL)!=DD_OK)
{
// shutdown any other dd objects and kill window
DD_Shutdown();
return(0);
} // end if

// now attach the palette to the primary surface
lpddsprimary->SetPalette(lpddpal);

// return success if we got this far
return(1);

} // end DD_Init

///////////////////////////////////////////////////////////////////////////////

int DD_Shutdown(void)
{
// this function tests for dd components that have been created and releases
// them back to the operating system

// test if the dd object exists
if (lpdd)
{
// test if there is a primary surface
if(lpddsprimary)
{
// release the memory and set pointer to NULL
lpddsprimary->Release();
lpddsprimary = NULL;
} // end if

// now release the dd object itself
lpdd->Release();
lpdd = NULL;

// return success
return(1);

} // end if
else
return(0);

} // end DD_Shutdown

//////////////////////////////////////////////////////////////////////////////

int Set_Pal_Entry(int index, int red, int green, int blue)
{
// this function sets a palette entry with the sent color

PALETTEENTRY color; // used to build up color

// set RGB value in structure
color.peRed = (BYTE)red;
color.peGreen = (BYTE)green;
color.peBlue = (BYTE)blue;
color.peFlags = PC_NOCOLLAPSE;

// set the color palette entry
lpddpal->SetEntries(0,index,1,&color);

// make copy in shadow palette
memcpy(&color_palette[index],
&color,
sizeof(PALETTEENTRY));

// return success
return(1);

} // end Set_Pal_Entry

// WINDOWS CALLBACK FUNCTION //////////////////////////////////////////////////

LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
// this is the main message handler of the system

HDC hdc; // handle to graphics context
PAINTSTRUCT ps; // used to hold the paint info

// what is the message?

switch(msg)
{
case WM_CREATE:
{
// do windows inits here
return(0);
} break;

case WM_PAINT:
{
// this message occurs when your window needs repainting
hdc = BeginPaint(hwnd,&ps);
// EndPaint(hdc,&ps);

return(0);
} break;

case WM_DESTROY:
{
// this message is sent when your window is destroyed
PostQuitMessage(0);
return(0);
} break;

default:break;

} // end switch

// let windows process any messages that we didn't take care of
return (DefWindowProc(hwnd, msg, wparam, lparam));

} // end WinProc

// WINMAIN ////////////////////////////////////////////////////////////////////

int WINAPI WinMain( HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow)
{
WNDCLASSEX winclass; // this holds the windows class info
HWND hwnd; // this holds the handle of our new window
MSG msg; // this holds a generic message

// first fill in the window class stucture

winclass.cbSize = sizeof(WNDCLASSEX);
winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WindowProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hinstance;
winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = NULL;
winclass.lpszMenuName = NULL;
winclass.lpszClassName = WINDOW_CLASS_NAME;

// register the window class
if (!RegisterClassEx(&winclass))
return(0);

// create the window
if (!(hwnd = CreateWindowEx(WS_EX_TOPMOST,
WINDOW_CLASS_NAME, // class
"You can't See This!", // title
WS_VISIBLE | WS_POPUP,
0,0, // x,y
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN),
NULL, // parent
NULL, // menu
hinstance, // instance
NULL))) // creation parms
return(0);

// hide the mouse cursor
ShowCursor(0);

// save the window handle
main_window_handle = hwnd;

// initialize direct draw
if (!DD_Init(hwnd))
{
DestroyWindow(hwnd);
return(0);
} // end if

// initialize game
Game_Init();

// enter main event loop
while(1)
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
// test if this is a quit
if (msg.message == WM_QUIT)
break;

// translate any accelerator keys
TranslateMessage(&msg);

// send the message to the window proc
DispatchMessage(&msg);
} // end if
else
{
// do asynchronous processing here

// acquire pointer to video ram, note it is always linear
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
lpddsprimary->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR,NULL);
video_buffer = (UCHAR *)ddsd.lpSurface;

// call main logic module
Game_Main();

// release pointer to video ram
lpddsprimary->Unlock(ddsd.lpSurface);

} // end else

} // end while

// shut down direct draw
DD_Shutdown();

// shutdown game
Game_Shutdown();

// return to Windows
return(msg.wParam);

} // end WinMain

// HERE ARE OUR GAME CONSOLE FUNCTIONS ///////////////////////////////////////////////////////

void Game_Init(void)
{
// do any initialization here
} // end Game_Init

/////////////////////////////////////////////////////////////////////////////////////////////

void Game_Shutdown(void)
{
// cleanup and release all resources here
} // end Game_Shutdown

/////////////////////////////////////////////////////////////////////////////////////////////

void Game_Main(void)
{

static int px = SCREEN_WIDTH/2, // position of player
py = SCREEN_HEIGHT/2,
color = 0; // color of blob 0..3, gray, red, green, blue

if (KEY_DOWN(VK_ESCAPE))
PostMessage(main_window_handle,WM_CLOSE,0,0); // this is how you exit you game

if (KEY_DOWN('C')){
if (color == 0){
color = 1;
}
else if (color == 1){
color = 0;
}
}

// draw graphics
if (color == 0) {
for(int i = 0;i<320;i++){
video_buffer[239*320+i]=((rand()%128)+192-128);
}
}
else{
for(int i = 0;i<320;i++){
video_buffer[239*320+i]=((rand()%64)+192);
}
}
for(int i=150;i<240;i++){
for(int j =0;j<320;j++){
video_buffer[(i-1)*320+j]=((video_buffer[(i)*320+j-1]+video_buffer[(i)*320+j+1]+video_buffer[(i-1)*320+j]+video_buffer[(i)*320+j])/4)-0.01;
}
}


} // end Game_Main


I think the main cause is that you're writing/reading to/from vram directly. Try drawing to a system memory buffer first and then copy the whole thing to vram.

Also, I noticed a slight problem with the drawing code: you are assuming your surface pitch instead of using lPitch member obtained after calling Lock.

This topic is closed to new replies.

Advertisement