Gamestudio Links
Zorro Links
Newest Posts
lookback setting performance issue
by 7th_zorro. 04/16/24 03:08
folder management functions
by 7th_zorro. 04/15/24 10:10
zorro 64bit command line support
by 7th_zorro. 04/15/24 09:36
Zorro FIX plugin - Experimental
by flink. 04/14/24 07:48
Zorro FIX plugin - Experimental
by flink. 04/14/24 07:46
LPDIRECT3DCUBETEXTUR
E9

by Ayumi. 04/12/24 11:00
Sam Foster Sound | Experienced Game Composer for Hire
by titanicpiano14. 04/11/24 14:56
SGT_FW
by Aku_Aku. 04/10/24 16:09
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
2 registered members (7th_zorro, Quad), 373 guests, and 3 spiders.
Key: Admin, Global Mod, Mod
Newest Members
11honza11, ccorrea, sakolin, rajesh7827, juergen_wue
19045 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Draw stuff from other thread #473530
07/19/18 21:25
07/19/18 21:25
Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
Superku Offline OP
Senior Expert
Superku  Offline OP
Senior Expert

Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
Hello!
For my level loading screen I used to have a LPD3DXEFFECT->SetFloat, bmap_process + draw_quad combination in my on_level event (and beyond because there's more stuff to setup after level_load). This faked a "smooth" transition between levels but was obviously chunky and juddery, putting most of the people off nowadays.

As an improvement I've tried to do multithreaded rendering instead.
I use CreateThread, then in the worker function loop I have code as follows:
Code:
LPDIRECT3DDEVICE9 pd3dDevKu = (LPDIRECT3DDEVICE9)pd3ddev;
if( SUCCEEDED( pd3dDevKu->BeginScene() ) )
{
	either old code from on_level
	or just a plain draw_quad
	or DrawPrimitiveUP
	or nothing at all, no draw instructions

	pd3dDevKu->EndScene();
	pd3dDevKu->Present(NULL, NULL, NULL, NULL);
}


Before level_load in the main thread I set a variable to 1 that encapsulates the previous code. I make sure to not draw anything manually while that secondary thread is running (I put a WaitForSingleObject(MUTEX) around it, just to be sure).

It's working to some degree, all 3 different draw approaches mentioned in the code above (although bmap_process seems to be crashing it easily), however after some level_loads and thus multithreaded drawing the game breaks.
It either gives an error (for bmap_process), closes the game after a 1sec freeze, messes up 2d panels (or rather draw_quad and draw_text, which is what I use) or just shows a frozen screen while the game continues to run normally.

So I assume it's either the fact that I'm *beginning* and *ending* a scene which might conflict (randomly, because of the 2 separate threads) with the engine's rendering process, or *presenting* it to the screen.
I've thought about using let's say render_sky to halt the main rendering process (with a MUTEX) when my other thread is rendering but I think it's already too late at that point (and there's no function that is called after the 2D elements, right?).




Is there any light at the end of my loading screen tunnel, can this be done with the current state of A8?

Thanks.


"Falls das Resultat nicht einfach nur dermassen gut aussieht, sollten Sie nochmal von vorn anfangen..." - Manual

Check out my new game: Pogostuck: Rage With Your Friends
Re: Draw stuff from other thread [Re: Superku] #473537
07/20/18 13:51
07/20/18 13:51
Joined: Jul 2000
Posts: 27,978
Frankfurt
jcl Offline

Chief Engineer
jcl  Offline

Chief Engineer

Joined: Jul 2000
Posts: 27,978
Frankfurt
Yes, this will probably cause a problem if BeginScene() and EndScene() of different threads overlap. One of the threads might at some point render on while the scene is not open. I see no quick solution for this at the moment.

Re: Draw stuff from other thread [Re: jcl] #473538
07/20/18 15:27
07/20/18 15:27
Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
Superku Offline OP
Senior Expert
Superku  Offline OP
Senior Expert

Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
Hmm okay.
Could I replace the BeginScene() and EndScene() functions with my own somehow?
What I'm at right now: Those functions are defined as COM IDirect3DDevice9 interface functions. pd3ddev holds a pointer to that device/ interface ("d3d9.h") at runtime. The functions are stored in a lpVtbl table but I can ignore that in lite-C.
The function address is ((LPDIRECT3DDEVICE9)pd3ddev)->BeginScene (?). I can save that and replace it with my own function (?). This leads me to a code as follows:
Click to reveal..
Code:
HRESULT BeginSceneOld(void *This);
HRESULT EndSceneOld(void *This);
HRESULT EndSceneKu(void *This);
HRESULT BeginSceneKu(void *This)
{
	cprintf1("nBeginSceneKu at frame %d",(int)total_frames);
	LPDIRECT3DDEVICE9 pd3dDevKu = (LPDIRECT3DDEVICE9)pd3ddev;
	return BeginSceneOld(pd3dDevKu); //pd3dDevKu->lpVtbl->
}

HRESULT EndSceneKu(void *This)
{
	cprintf1("nEndSceneKu at frame %d",(int)total_frames);
	LPDIRECT3DDEVICE9 pd3dDevKu = (LPDIRECT3DDEVICE9)pd3ddev;
	return EndSceneOld(pd3dDevKu);
}

void main()
{
	fps_max = 60;
	level_load(NULL);
	wait(1);
	LPDIRECT3DDEVICE9 pd3dDevKu = (LPDIRECT3DDEVICE9)pd3ddev;
	BeginSceneOld = pd3dDevKu->BeginScene;
	pd3dDevKu->BeginScene = BeginSceneKu;
	EndSceneOld = pd3dDevKu->EndScene;
	pd3dDevKu->EndScene = EndSceneKu;
}


Probably an absolute mess to everyone who knows what they are doing. This leads to a script crash after the first execution of BeginSceneKu (does not close the program) - returning the old BeginSceneOld() (with or without parameter) is correct, right?
I'm guessing the fact that I'm dealing with an interface is leading to a crash ("this" not working right for me/ ...).

I can code it even worse though, that is switch around function pointers in every Begin/EndScene call:
Click to reveal..
Code:
HRESULT BeginSceneKu(void *This)
{
	cprintf1("nBeginSceneKu at frame %d",(int)total_frames);
	LPDIRECT3DDEVICE9 pd3dDevKu = (LPDIRECT3DDEVICE9)pd3ddev;
	pd3dDevKu->EndScene = EndSceneKu;
	pd3dDevKu->BeginScene = BeginSceneOld;
	return pd3dDevKu->BeginScene();
}

HRESULT EndSceneKu(void *This)
{
	cprintf1("nEndSceneKu at frame %d",(int)total_frames);
	LPDIRECT3DDEVICE9 pd3dDevKu = (LPDIRECT3DDEVICE9)pd3ddev;
	pd3dDevKu->BeginScene = BeginSceneKu;
	pd3dDevKu->EndScene = EndSceneOld;
	return pd3dDevKu->EndScene();
}


This prints both functions to the console "at frame 1", then waits a second and closes the program without error message.

Could I easily hook those functions somehow (to let's say put a WaitForSingleObject(MUTEX) in BeginScene and a release in EndScene)?

Thanks!

EDIT: If I wait for more than 1 frame at the start of the main function my pointer shenanigans don't seem to have any effect, the game runs as normal but doesn't print anything to the console either. confused

Last edited by Superku; 07/20/18 16:19.

"Falls das Resultat nicht einfach nur dermassen gut aussieht, sollten Sie nochmal von vorn anfangen..." - Manual

Check out my new game: Pogostuck: Rage With Your Friends
Re: Draw stuff from other thread [Re: Superku] #473567
07/22/18 20:00
07/22/18 20:00
Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
Superku Offline OP
Senior Expert
Superku  Offline OP
Senior Expert

Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
I was missing a __stdcall prefix in the function declarations.

pd3dDev->BeginScene and similar functions seem to be reset internally at various occasions (where does the old/ initial pointer come from? QueryInterface does not seem to get called). You can ""hook"" them in lite-C if you replace the function pointer each frame but that's a recipe for disaster, and even then I don't think it will go anywhere.

Apparently, after all, you need to create the device with D3DCREATE_MULTITHREADED though, which is out of reach.


"Falls das Resultat nicht einfach nur dermassen gut aussieht, sollten Sie nochmal von vorn anfangen..." - Manual

Check out my new game: Pogostuck: Rage With Your Friends

Moderated by  old_bill, Tobias 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1