Archived

This topic is now archived and is closed to further replies.

Check this code.. why is dx7 ddraw so slow...

This topic is 5897 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Please refer to the code below: compiled in Dev-C++.. even in 640x480, the ''sprite'' moves slowly across the screen, the mouse is instantaneous but the sprite, when i''m holding down the left arrow key, moves slow. I even put the main code into a while(running=true) type of loop and used getasynckeystates to detect when you hit VK_ESCAPE or VK_LEFT.. moves smoother but still slow. I know in win32 api, it would zip across the screen, even CDXLIB using MSVC v5.0, I had to add a delay. i''m blitting the background (bypassing the clearscreen), to gain a little speed, is there something I am overlooking? thanx in advance it compiles to 17kb Feel free to use this code as I have begged/borrowed/stolen from the net, but if you make lotsa money using it in your next great 2D engine, I want a cut. haha #include "stdafx.h" #include #include #include HINSTANCE g_hinstance; HWND g_hwnd; bool g_running; bool g_active; const char* g_appName = "My DirectDraw Program"; char szBitmap[ ] = "Greenstone.bmp"; char szBckgnd[ ] = "backgrnd.bmp"; int ef=32; int f=0; HBITMAP hbm; HDC hdcImage= NULL; HDC hdcSurf= NULL; IDirectDraw7* dd; IDirectDrawSurface7* primary; IDirectDrawSurface7* backgrnd; IDirectDrawSurface7* back; IDirectDrawSurface7* lpA; DDSURFACEDESC2 ddsd; void update(); bool createWindow(); LRESULT CALLBACK wndProc(HWND, UINT, WPARAM, LPARAM); bool initDirectDraw(int,int,int); void clearScreen(); void flip(); void cleanUp(); void lock(); void unlock(); void setPixel(int, int, unsigned char); void CopyBitmap(IDirectDrawSurface7*, HBITMAP, int, int, int, int); int APIENTRY WinMain(HINSTANCE hinstance, HINSTANCE, LPSTR cmdLine, int) { g_hinstance = hinstance; RECT lpR; RECT lpB; int e=0; POINT p; if(!createWindow()) return 0; SetFocus(g_hwnd); ShowWindow(g_hwnd, SW_SHOWNORMAL); UpdateWindow(g_hwnd); if(!initDirectDraw(800,600,16)) return 0; g_running = true; backgrnd = DDLoadBitmap(dd, "backgrnd.bmp", 0, 0); lpA = DDLoadBitmap(dd, "Greenstone.bmp", 0, 0); DDSetColorKey(lpA, RGB(0, 0, 0)); lpB.left=0; lpB.right=800; lpB.top=0; lpB.bottom=600; lpR.left=0; lpR.right=64; lpR.top=0; lpR.bottom=64; back->BltFast(0, 0, backgrnd, &lpB, DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT); back->BltFast(0, 0, lpA, &lpR, DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT); while(true) { MSG msg; if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { if(msg.message == WM_QUIT) return msg.wParam; // Send messages to WindowProc TranslateMessage(&msg); DispatchMessage(&msg); } else if(g_running && g_active) // call variable updates here // then update() to call screen updates, which flips screen at the end while (g_running) { // update(); // for (e=0; eBltFast(0, 0, backgrnd, &lpB, DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT); back->BltFast(ef, 0, lpA, &lpR, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT); GetCursorPos(&p); back->BltFast(p.x, p.y, lpA, &lpR, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT); if (GetAsyncKeyState(VK_ESCAPE)) g_running = false; if (GetAsyncKeyState(VK_RIGHT)) ef+=1; flip(); } } // Prevent compiler warning even though we never get here return -1; } bool createWindow() { WNDCLASSEX wc; ZeroMemory(&wc, sizeof(wc)); wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wc.hCursor = LoadCursor(0, IDC_ARROW); wc.hIcon = LoadIcon(0, IDI_APPLICATION); wc.hIconSm = LoadIcon(0, IDI_WINLOGO); wc.hInstance = g_hinstance; wc.lpfnWndProc = wndProc; wc.lpszClassName = g_appName; wc.cbSize = sizeof(wc); wc.style = CS_VREDRAW | CS_HREDRAW; if(RegisterClassEx(&wc)) { g_hwnd = CreateWindowEx( WS_EX_TOPMOST, g_appName, g_appName, WS_POPUP | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, g_hinstance, 0 ); return g_hwnd != 0; } return false; } LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM w, LPARAM l) { switch(msg) { case WM_SETCURSOR: SetCursor(NULL); return 0; case WM_KEYDOWN: if (GetAsyncKeyState(VK_ESCAPE)) msg = WM_DESTROY; case WM_DESTROY: cleanUp(); PostQuitMessage(0); return 0; case WM_ACTIVATE: g_active = (LOWORD(w) != WA_INACTIVE) && !((BOOL)HIWORD(w)); break; } return DefWindowProc(hwnd, msg, w, l); } bool initDirectDraw(int Sx, int Sy, int Sc) { HRESULT r = DirectDrawCreateEx(0, (void**)&dd, IID_IDirectDraw7, 0); if(FAILED(r)) return false; r = dd->SetCooperativeLevel(g_hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT); if(FAILED(r)) return false; r = dd->SetDisplayMode(Sx, Sy, Sc, 0, 0); if(FAILED(r)) { dd->Release(); return false; } ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd.dwBackBufferCount = 1; r = dd->CreateSurface(&ddsd, &primary, 0); if(FAILED(r)) { dd->Release(); return false; } ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; r = primary->GetAttachedSurface(&ddsd.ddsCaps, &back); if(FAILED(r)) { primary->Release(); dd->Release(); return false; } return true; } void clearScreen() { DDBLTFX clsBltFX; ZeroMemory(&clsBltFX, sizeof(clsBltFX)); clsBltFX.dwSize = sizeof(clsBltFX); back->Blt(0, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &clsBltFX); } void flip() { // dd->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0); primary->Flip(0, DDFLIP_WAIT); } void cleanUp() { if(dd) { dd->Release(); if(primary) primary->Release(); } } unsigned char* videoMemory; long pitch; void lock() { DDSURFACEDESC2 ddsd; ddsd.dwSize = sizeof(ddsd); back->Lock(0, &ddsd, DDLOCK_WAIT, 0); videoMemory = (unsigned char*)ddsd.lpSurface; pitch = ddsd.lPitch; } void unlock() { back->Unlock(0); } void setPixel(int x, int y, int c) { videoMemory[x + pitch * y] = c; } void update() { flip(); // clearScreen(); }

Share this post


Link to post
Share on other sites
I don''t think there is any problem with speed here. The problem is that DDraw probably locks along your screen''s refresh rate, so you only get about 60 or 75 frames per second. And since you are moving the sprite a single pixel each frame, it will only move 60 or 75 pixels per second, which feels slow.

Either try to disable the "vertical retrace", or just speed up the movement of the sprite. I don''t think this is a performance problem, anyway.

Share this post


Link to post
Share on other sites
Thank you thank you! It does speed it up and yet it looks smooth, which confuses me..

with this command:

primary->Flip(0, DDFLIP_WAIT);
it looks very smooth and fast, I would think it would move in chunks..

however with this command:

dd->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0);
it moves in chunks (however many pels/framerate I set it for)...

why is that?




I fseek, therefore I fam.

Share this post


Link to post
Share on other sites