CDX faster than B+??

BlitzPlus Forums/BlitzPlus Programming/CDX faster than B+??

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

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+
; 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