OpenGL clear screen much slower than DirectX

Started by
22 comments, last by _the_phantom_ 16 years, 2 months ago
Hello! I was trying to make an app which renders both in OpenGL and Direct3D. When I got to the point to clear the screen I noticed that OpenGL is much slower than Direct3D. So I made an iteration to clear the screen 100 times. The DirectX version always performs 2 times faster. The framebuffer format is 32bit color / 24bit depth / 8bit stencil. Is this normal? Or I did something wrong in my code? This is the code:

#include <windows.h>
#include <string.h>
#include <sstream>
#include <gl/gl.h>
#include <gl/glu.h>
#include <d3d9.h> 
#include <d3dx9.h>

//Windows Specific

HWND            hWnd=NULL;							
HINSTANCE       hInstance;							
MSG				msg;

//OpenGL specific

HGLRC           hRC=NULL;							
HDC             hDC=NULL;							
PIXELFORMATDESCRIPTOR pfd;

//DirectX Specific

LPDIRECT3D9				dx_Object;
D3DPRESENT_PARAMETERS	dx_Params;
LPDIRECT3DDEVICE9		dx_Device;




LPCSTR errmsg;

bool AppRunning=true;


bool OpenGL=false;
bool DirectX=false;

int frame_count=0;

int frame_start;
unsigned int curr_time;
unsigned int start_time;
int fps;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


LRESULT CALLBACK WinProc(HWND han_Wind,UINT uint_Message,WPARAM parameter1,LPARAM parameter2)
{
   switch(uint_Message)
     {
         case WM_KEYDOWN:
		 case WM_DESTROY:
         {
             AppRunning = false;
             break;
         }
		 
		 break;
     }

return DefWindowProc(han_Wind,uint_Message,parameter1,parameter2);    	
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


bool Init()
{


		WNDCLASSEX wnd_Structure;

		wnd_Structure.cbSize = sizeof(WNDCLASSEX);
		wnd_Structure.style = CS_HREDRAW | CS_VREDRAW;


		wnd_Structure.lpfnWndProc = WinProc;

		wnd_Structure.cbClsExtra = 0;
		wnd_Structure.cbWndExtra = 0;
		wnd_Structure.hInstance = GetModuleHandle(NULL);
		wnd_Structure.hIcon = NULL;
		wnd_Structure.hCursor = NULL;
		wnd_Structure.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
		wnd_Structure.lpszMenuName = NULL;
		wnd_Structure.lpszClassName = "CLASS";
		wnd_Structure.hIconSm = LoadIcon(NULL,IDI_APPLICATION);
	 
		RegisterClassEx(&wnd_Structure);
	    
		LPCSTR title;
		
		if (OpenGL)  title="Test (OpenGL)";
        if (DirectX) title="Test (DirectX)";

		hWnd=CreateWindowEx(WS_EX_TOPMOST,
							"CLASS",
							title,
		                    WS_VISIBLE
							| WS_OVERLAPPED
							| WS_CAPTION
							| WS_SYSMENU							
							| WS_MINIMIZEBOX
							| WS_POPUPWINDOW 
							,0, 0, 
							1024, 768, 
							NULL, 
							NULL, 
							NULL, 
							NULL);

		if (hWnd==0) 
			{
			 errmsg="Error creating window!";
 			 return false;
			}


		//Initialize OpenGL

		if (OpenGL)
		{

			hDC=GetDC(hWnd); 
			
			ZeroMemory( &pfd, sizeof( pfd ) );
			pfd.nSize = sizeof(pfd);
			pfd.nVersion = 1;
			pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
			pfd.iPixelType = PFD_TYPE_RGBA;
			pfd.cColorBits = 32;
			pfd.cDepthBits = 24;
			pfd.cStencilBits = 8;
			

			int pf=ChoosePixelFormat(hDC,&pfd);

			if (pf==0) 
				{
				 errmsg="Error setting pixel format!";
 				 return false;
				}

			SetPixelFormat( hDC, pf, &pfd );

			hRC = wglCreateContext( hDC );

			if (hRC==0) 
				{
				 errmsg="Error creating render context!";
 				 return false;
				}

			wglMakeCurrent( hDC, hRC );
		}

                //Initialize DirectX

		if (DirectX)
		{
			dx_Object = Direct3DCreate9(D3D_SDK_VERSION);
			if (dx_Object==NULL)
			{
				errmsg="DirectX 9 not supported!";
				return false;
			}
			 
			ZeroMemory( &dx_Params,sizeof(dx_Params));
			dx_Params.Windowed = TRUE;
			dx_Params.SwapEffect = D3DSWAPEFFECT_DISCARD;
			dx_Params.BackBufferFormat = D3DFMT_UNKNOWN;
			//dx_Params.BackBufferFormat = D3DFMT_A8R8G8B8;
			
			dx_Params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
			dx_Params.EnableAutoDepthStencil = true;
			dx_Params.AutoDepthStencilFormat = D3DFMT_D24S8;
			
			
			dx_Object->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &dx_Params, &dx_Device);
			if (dx_Device==NULL)
			{
				errmsg="No hardware support for DirectX 9!";
				return false;
			}
						
		}
			  
				



return true;
		
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ShutDown()
{
	if (OpenGL)
	{
		ReleaseDC(hWnd,hDC);
	}

	if (DirectX)
	{
		dx_Device->Release();
	}

	
	DestroyWindow(hWnd);
}
 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Render()
{
	if (OpenGL)
	{
		for (int i=1;i<=100;i++)	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);		
	}

	if (DirectX)
	{
		for (int i=1;i<=100;i++)	dx_Device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
	}
}

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


int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
	int res=MessageBox(0,"","OpenGL or DirectX",MB_YESNO);

	if (res==IDYES) OpenGL=true;
    if (res==IDNO) DirectX=true;

	if (!Init())
	{
		MessageBox(0,errmsg,"Error",MB_OK);
		return 0;
	}

	

	while(AppRunning)
	 {
	     Render();
		 
		 if (OpenGL) SwapBuffers(hDC);
		 if (DirectX) dx_Device->Present(NULL, NULL, NULL, NULL);

         frame_count++;
		 
		 curr_time=GetTickCount();

		 if ((curr_time-start_time)>=1000)
		 {
			 fps=frame_count-frame_start;
			 frame_start=frame_count;
			 start_time=curr_time;
			 
			 std::ostringstream myStream;
			 myStream << "fps:" << fps << ";";
			 
			 SetWindowText(hWnd,LPCSTR(myStream.str().c_str()));
		 }


		 if(PeekMessage(&msg,hWnd,0,0,PM_REMOVE))
		 {
			 if(!IsDialogMessage(hWnd,&msg))
			 {
				 DispatchMessage(&msg);
			 }
		 }
	 }


	ShutDown();
  return 0;
}


My specs: GeForce 6600 (latest 64 bit drivers) AthlonXP 64 3000+ 512RAM WinXP 64 bit
Advertisement
Does it really matter? It's just one call. After the thousands of calls it takes to render any normal scene, I'm sure the differences will be negligible.
Quote:Original post by Vampyre_Dark
Does it really matter? It's just one call. After the thousands of calls it takes to render any normal scene, I'm sure the differences will be negligible.


Well, I'm just surprised about the big difference (2X). It doesn't seem normal to me...

I only got to the point to clear the screen. I wonder what will happen when I render something.
It's probably due to vsync, with your directx initialization you have the presentation interval set to immediate which will cause directx to ignore the vsync. This would in turn cause directx to be faster then openGL.
It's a bogus measurement. Render something worthwhile. Something that brings the FPS down to around 20 to 100 FPS. This will tell if the driver is good at dealing with your GL or D3D calls.
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
Quote:Original post by Dancin_Fool
It's probably due to vsync, with your directx initialization you have the presentation interval set to immediate which will cause directx to ignore the vsync. This would in turn cause directx to be faster then openGL.


I already checked that, vsync is forced off...
Quote:Original post by V-man
It's a bogus measurement. Render something worthwhile. Something that brings the FPS down to around 20 to 100 FPS. This will tell if the driver is good at dealing with your GL or D3D calls.


As I told I clear the screen 100 times. OpenGL renders 20 fps. DirectX renders 39fps.
Quote:Original post by jsg007
Quote:Original post by V-man
It's a bogus measurement. Render something worthwhile. Something that brings the FPS down to around 20 to 100 FPS. This will tell if the driver is good at dealing with your GL or D3D calls.


As I told I clear the screen 100 times. OpenGL renders 20 fps. DirectX renders 39fps.
So? Your test is idiotic. It fabricates a situation that never exists in reality and turns out useless benchmark information.

Come back after you've written something productive.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
For an empty loop you should be looking at more like a few thousand iterations in 1 second. Sorry I cant be more helpful but there's something wrong with the measure.
If you're rendering full environments, should you even be clearing the screen at all?

And although a little cold, Promit has a point. Render a scene that brings your FPS down to, say 50, and THEN perform your 100x test. Simply clearing an already blank scene will produce very inaccurate results.

"The right, man, in the wrong, place, can make all the dif-fer-rence in the world..." - GMan, Half-Life 2

A blog of my SEGA Megadrive development adventures: http://www.bigevilcorporation.co.uk

This topic is closed to new replies.

Advertisement