Jump to content
  • Advertisement
Sign in to follow this  
jsg007

OpenGL OpenGL clear screen much slower than DirectX

This topic is 3776 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

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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

This topic is 3776 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.

Guest
This topic is now closed to further replies.
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!