Jump to content


Problem in Multithreaded rendering


6 replies to this topic

#1 idreamlovey

    Member

  • Members
  • PipPip
  • 91 posts

Posted 03 April 2007 - 07:28 PM

I am using one thread to load the game data and another thread to render the current loading by rendering splash with progress bar.The problem is data loading is working but i can't see any splash rendering. Even not a single time splash appears on the screen. I m new with multithreading.

The following is my code:-


HANDLE hThrd1,hThrd2;

	hThrd1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)LoadMenuObjects, 

			 this,	 CREATE_SUSPENDED,   NULL); 				 ResumeThread(hThrd1);


	SetThreadPriority(hThrd1,THREAD_PRIORITY_HIGHEST);


// Run the secound Thread

      hThrd2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RenderLoadingPage, 

			 this,	 CREATE_SUSPENDED,   NULL); 				 ResumeThread(hThrd2);

							 

	SetThreadPriority(hThrd1,THREAD_PRIORITY_LOWEST);



UINT	LoadMenuObjects(LPVOID lpvoid)

{

	CMyGame *vPt = (CMyGame *)lpvoid;

	vPt->nGlobalMax = 38;

	vPt->nGlobalCt = 1;

	vPt->ConstructMenuObjects(0);

	vPt->RestoreMenuObjects(0);

	vPt->ConstructEngineObjects();

	vPt->RestoreEngineObjects();

	vPt->m_dwAppState = APPSTATE_RESET_TIME2;


	 return 0;

}

UINT	RenderLoadingPage(LPVOID lpvoid)

{

	COvertake *vPt = (COvertake *)lpvoid;


	while(vPt->m_dwAppState != APPSTATE_RESET_TIME2)

	{

		vPt->RenderSplashObjects(1,vPt->nGlobalCt,vPt->nGlobalMax);

		break;	

	}

	return 0;

}



#2 Nils Pipenbrinck

    Senior Member

  • Members
  • PipPipPipPip
  • 597 posts

Posted 03 April 2007 - 08:05 PM

A couple of things:

1. Don't set the thread priorities yourself. That will do more harm than good.

2. You pass the same pointer to the threads and use it from them. (the COvertake class ptr vPt). You must not call function to this class unless you have made sure they are threadsave. As you're new to multithreading programming I assume they are not. This can cause all kinds of strange side-effects.

3rd: What rendering API are you using? OpenGL has not been designed to be called from different threads. If you want to do that you need a opengl context for each thread, and they can't share state like textures, buffers ect. Also I wouldn't be surprised if multithreaded rendering from OpenGL does not work at all (drivers aren't optimized for this). DirectX allows multithreaded rendering to some extend if you pass some kind of parameter to it during creation time.

Hope this helps,
Nils
My music: http://myspace.com/planetarchh <-- my music

My stuff: torus.untergrund.net <-- some diy electronic stuff and more.

#3 Goz

    Senior Member

  • Members
  • PipPipPipPip
  • 575 posts

Posted 03 April 2007 - 09:52 PM

Erm .. why is there that break in the RenderLoadingPage thread's while loop?

Isn't that just gonna cause the while loop to exit and hence the thread will only ever render one frame of the loading screen.

Btw ... what does the main thread do when you kick off the other 2? Personally i'd just kick off a thread for the loading and keep the rendering in the main thread. That way you don't even get any of the threading problems Nils is talking about above. Either that or the rendering ALWAYS remains in another thread and you simply send commands to it. That is a whole lot more full of critical section fun mind ;)

#4 idreamlovey

    Member

  • Members
  • PipPip
  • 91 posts

Posted 04 April 2007 - 04:56 AM

i am using directx and already set the option D3DCREATE_MULTITHREADED at the creation time. On your Advice, i removed the priority option and i set rendering function in main thread and the code becomes like as below:-

if(m_bIsLoading==false)
{
m_bIsLoading = true;
HANDLE hThrd1;
hThrd1 = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE) LoadMenuObjects,
this, CREATE_SUSPENDED, NULL);
}
RenderSplashObjects(1,nGlobalCt,nGlobalMax);
and it appears RenderSplashObjects() function has been executed 13878 times. And it still nothing appears on the screen.

#5 idreamlovey

    Member

  • Members
  • PipPip
  • 91 posts

Posted 04 April 2007 - 05:15 AM

Problem is solved. its not problem in the coding. The only thing that i missed is i haven't put the line
g_pd3dDevice->Present( 0, 0, 0, 0 );

By the way thanks to Nils Pipenbrinck and Goz for there valuable advice. Now i am rendering spalsh in main thread and loading stuff in the another thread that i created. It doesn'y comes to my mind before.
Thanks a lot u guys.

#6 Goz

    Senior Member

  • Members
  • PipPipPipPip
  • 575 posts

Posted 05 April 2007 - 07:49 AM

:lol:

Its always the obvious things ;)

#7 pcwlai

    New Member

  • Members
  • PipPip
  • 19 posts

Posted 25 April 2007 - 05:37 AM

D3DCREATE_MULTITHREADED means, you will issue D3D9 calls from multiple threads in your program. If you only call D3D9 in the thread that creates the D3D9 device, D3DCREATE_MULTITHREADED is not needed. As D3DCREATE_MULTITHREADED will incurs overhead in locking everytime D3D9 is called (though minimum if you calls in one thread only).





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users