For those that don't know, CDX is a C++ wrapper for DirectX. Even though the community seems quite dead, the source is free and very stable.
Anyway, today I did a small experiment. I created two applications. One in B+ and one in CDX. Both apps simply loaded an image (548x480) and blitted it to the screen. Both apps also cleared the backbuffer to black before blitting. Both apps used the exact same image. Both apps were in "release" mode (no debugging). Both apps on the exact same machine with nothing else running. Both ran for about 5 minutes.
Here are the specs:
Blitz+: FPS peaked at 796 FPS
CDX: FPS peaked at 1035 FPS!!!
That's 239 FPS for CDX. While I always thought pure C++ would be a little faster and my single machine may have different results on other machines but 239 FPS is a lot. Granted, I am NOT saying that B+ can't make fast games. It's just that for pure speed, looks like CDX is faster.
Here are the codes:
Blitz+
CDX (C++)
Of course, the B+ is about a million lines shorter...lol
What do you guys think? I think I will do some more testing over the next few days. Things like seeing who can draw 10,100,1000,10000 sprites the quickest.
cb
Anyway, today I did a small experiment. I created two applications. One in B+ and one in CDX. Both apps simply loaded an image (548x480) and blitted it to the screen. Both apps also cleared the backbuffer to black before blitting. Both apps used the exact same image. Both apps were in "release" mode (no debugging). Both apps on the exact same machine with nothing else running. Both ran for about 5 minutes.
Here are the specs:
Blitz+: FPS peaked at 796 FPS
CDX: FPS peaked at 1035 FPS!!!
That's 239 FPS for CDX. While I always thought pure C++ would be a little faster and my single machine may have different results on other machines but 239 FPS is a lot. Granted, I am NOT saying that B+ can't make fast games. It's just that for pure speed, looks like CDX is faster.
Here are the codes:
Blitz+
; Peaks at 796 FPS Global Timer, FPS_Real, FPS_Temp,FPS Graphics 640,480,16,1 SetBuffer BackBuffer() Global background = LoadImage("Room.bmp") While Not KeyHit(1) Cls DrawImage background,46,0 DisplayFPS(0,0) Flip False Wend End Function DisplayFPS(x#,y#) Color 255,255,255 If Timer + 1000 <= MilliSecs() Timer = MilliSecs() : FPS_Real = FPS_Temp : FPS_Temp = 0 FPS_Temp = FPS_Temp + 1 : Text x#,y#,"FPS: " + FPS_Real End Function
CDX (C++)
//peaked at 1035 FPS #define WIN32_LEAN_AND_MEAN #include <windows.h> #define CDXINCLUDEALL // this define includes all headers, otherwise include one by one #include <cdx.h> #include "resource.h" // ------------------------------------------------------------------ // Global Variables // ------------------------------------------------------------------ char szAppName[] = "Alpha"; char szClassName[] = "AlphaWndClass"; HINSTANCE g_hInst; // instance handle HWND g_hWnd; // window handle BOOL g_IsAppActive; // is the app active // ------------------------------------------------------------------ // CDX Objects // ------------------------------------------------------------------ CDXScreen * Screen = 0; // The screen object, every program must have one CDXSurface * Splash = 0; // splash screen surface CDXInput * Input = 0; // The input object // ------------------------------------------------------------------ // cdx_Init - handles initialization of the CDX objects // ------------------------------------------------------------------ BOOL cdx_Init() { // Create the CDXSreen object Screen = new CDXScreen(); if (Screen==NULL) CDXError( NULL , "Could not create CDXScreen object" ); // start app fullscreen if( Screen->CheckIfVideoModeExists( 640 , 480 , 16 ) == TRUE ) { if(FAILED(Screen->CreateFullScreen(g_hWnd, 640, 480, 16))) CDXError( Screen , "Could not set 640x480x16 video mode" ); } else { if(FAILED(Screen->CreateFullScreen(g_hWnd, 640, 480, 15))) CDXError( Screen , "Could not set 640x480x15 video mode" ); } // load the splash screen Splash = new CDXSurface( ); if(FAILED(Splash->Create( Screen , "Room.bmp" ))) CDXError( Screen , "Could not load file ROOM into surface" ); // create our input object Input = new CDXInput( ); if( Input == NULL ) CDXError( Screen , "Could not create CDXInput object" ); // Create input devices if(FAILED(Input->Create( g_hInst , g_hWnd ))) CDXError( Screen , "Could not create direct input object" ); return TRUE; } // ------------------------------------------------------------------ // cdx_DeInit - handles cleanup of CDX objects // ------------------------------------------------------------------ void cdx_DeInit( void ) { SAFEDELETE( Splash ); SAFEDELETE( Input ); SAFEDELETE( Screen ); } // ------------------------------------------------------------------ // cdx_DoFrame - performs drawing of the current frame // ------------------------------------------------------------------ void cdx_DoFrame() { // read input from devices Input->Update(); // handle keyboard input // if Escape is pressed, close the application if (Input->GetKeyState(CDXKEY_ESCAPE)==CDXKEY_PRESS) { SendMessage(g_hWnd, WM_CLOSE, 0, 0); // return out as the code below is invalid now return; } // clear the current frame Screen->GetBack()->Fill(0); Splash->DrawBlk(Screen->GetBack(),46,0); Screen->Flip(0,0,1); // Flip the back buffer to the front with NO VSYNC } // ------------------------------------------------------------------ // WinProc - handles application messages // ------------------------------------------------------------------ static long PASCAL WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_ACTIVATEAPP: g_IsAppActive = wParam; // set if app is active or not return 0; case WM_SETCURSOR: SetCursor(NULL); // hide the mouse cursor return 1; case WM_CLOSE: cdx_DeInit(); case WM_DESTROY: PostQuitMessage(0); return 0; default: return DefWindowProc(hWnd, message, wParam, lParam); } } // ------------------------------------------------------------------ // ChangeToEXEDir - sets CWD to the DIR the EXE is in // ------------------------------------------------------------------ static void ChangeToEXEDir() { char buf[MAX_PATH]; char *cptr; //now change the directory //to make sure were accessing the proper file GetModuleFileName(NULL, buf, MAX_PATH); //move pointer to end of string cptr = buf + lstrlen(buf); //find the end of the path do { cptr--; } while (*cptr != '\\'); cptr++; *cptr='\0'; //change directory SetCurrentDirectory(buf); } // ------------------------------------------------------------------ // InitApp - Create the window and the CDX objects // ------------------------------------------------------------------ static BOOL InitApp(int nCmdShow) { WNDCLASS WndClass; WndClass.style = CS_HREDRAW | CS_VREDRAW; WndClass.lpfnWndProc = WinProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = g_hInst; WndClass.hIcon = LoadIcon(g_hInst, "APPICON"); WndClass.hCursor = LoadCursor(0, IDC_ARROW); WndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); WndClass.lpszMenuName = 0; WndClass.lpszClassName = szClassName; RegisterClass(&WndClass); g_hWnd = CreateWindowEx( WS_EX_TOPMOST, szClassName, szAppName, WS_POPUP, 0, 0, GetSystemMetrics(SM_CXFULLSCREEN), GetSystemMetrics(SM_CYFULLSCREEN), NULL, NULL, g_hInst, NULL); // when hWnd = -1 there was an error creating the main window // CDXError needs a CDXScreen object, if there is none at this early // program stage, pass it NULL if( !g_hWnd ) CDXError( NULL , "could not create the main window" ); ShowWindow(g_hWnd, nCmdShow); UpdateWindow(g_hWnd); ChangeToEXEDir(); return TRUE; } // ------------------------------------------------------------------ // WinMain - inital function called by windows // ------------------------------------------------------------------ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow) { MSG msg; // save the app instance g_hInst = hInstance; if(!InitApp(nCmdShow)) CDXError( NULL , "could not initialize application" ); if(!cdx_Init()) { PostQuitMessage(0); return FALSE; } while(1) { if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if(!GetMessage(&msg, NULL, 0, 0 )) return msg.wParam; TranslateMessage(&msg); DispatchMessage(&msg); } else if(g_IsAppActive) { cdx_DoFrame(); } else { WaitMessage(); } } }
Of course, the B+ is about a million lines shorter...lol
What do you guys think? I think I will do some more testing over the next few days. Things like seeing who can draw 10,100,1000,10000 sprites the quickest.
cb