Loading scenes in a seperate thread

Started by
8 comments, last by Noggs 13 years, 4 months ago
Hi all,

For my scene , i want to do the meat of work , which is loading about hundreds of objectss in a seperate thread

Before launching the thread , d3d device is created , rendering parameters set , lights are created so everything except the meshes

And after that i lauch a seperate thread which loads the meshes in the scene and rotates/translates them

In mean time , based on a flag variable , I know whether the scene is loaded or not so if it is not loaded i render a simple `loading` text

And of that loader thread i set this variable accordingly to be able to render
what is loaded instead of a `loading` text

But it never loaded... Program always crashed, Alsi when I debug the loader thread it seems it does its job and sets the flag properly , however couldt not find the problem

Then when I put a sleep to the render loop at the main thread then it worked
which was interesting

I want to learn what is the appropriate way to do this
Advertisement
a directx device is attached to the thread it was created from, it is also recommended to create the hWnd in the same thread.

The device is not thread safe so you can not call an api from a directx resource (device, texture, ...) from another thread.


In fact, you can if you use a creation flag that ask a multithread safe device. But it is overkill for the performance, so it is not something that you should use (after all, you create threads to optimise!)
That suggests me to think a workaround like this:

All loading stuff will be in the same thread, in which my graphics device is being used

I will have the `loading` scene in another thread with another window and d3d device which is just for loading text rendering ?

What do you think , would that work ?
It's usually better to just load any resources into RAM in another thread, and then set up the actual device resources in the same thread that already has the device.
So for example if you need to read textures from disk, or if you need to run some expensive setup calculations that take a long time, then do all that in a separate thread and store the complete data in RAM. Then message the main thread to carry out the very last step and actually put the data on the graphics card.
Couln't this be done with overlapped I/O and I/O completion ports?
I am a beginner so this might not be good idea,
i have done something like this (single thread):
load_gui_elements();load_model_data_1();dev->Clear(...);dev->BeginScene(...);gui_draw_10percent();// Loading... 10% <--- on screendev->EndScene();dev->Present(...);load_model_data_2();dev->Clear(...);dev->BeginScene(...);gui_draw_20percent();// Loading... 20% <--- on screendev->EndScene();dev->Present(...);...and so on until all lodaded

simple and effective.
I have some idea about this "loading process" that i want to try but
i cannot wrap my head how to get it to work with above (single thread) system.
I want to be able to abort/stop loading process in a middle of it (for example
key esc. pressed or press "äbort" button on loading screen) and then return to loading options.
This would be useful if user change his mind about loading certain level and dont
want to wait until loading is finished (especially if level is large) and i never see
this in any game so far. If you people have some idea what should i look for i would
like to here it.
Sorry for intrusion on this thread.
to get it work with single thread, even though it d be limited , by using DirectInput , in a buffer store keyboard key states , so you will be able to detect keystates in which a sequence of loading was occuring , or in your windows message proc you would store keys to an accessible buffer and instead of using dinput states you would have detect key stroke there and take necessary actions , however , the user will be able to cancel loading just after whichever loading sequence does occur

never tried , but it should be like this

the main thing is what about `roll back` regarding already loaded resources ,
a file bases resource manager ?
1. Don't use DirectInput for keyboard or mouse input.
2. Why not do as Erik Rufelt suggested - load the resources into RAM on a secondard thread, and do any unpacking of textures or other resources, and then the main thread can just be processing window messages, rendering the "Loading..." message, and whenever signalled by the worker thread, can create a texture or other resource using the data loaded by the worker thread.
Quote:Original post by Madhed
Couln't this be done with overlapped I/O and I/O completion ports?


Somehow this excellent suggestion was totally ignored. This is by far the easiest way to implement multi-threaded loading. Let the O/S handle all the data loading in the background and basically just poll for completion as part of your game loop. As soon as one is completed, start the next load, create the resource for the thing you just loaded and carry on with the game loop.

No mutexes, no race conditions, no complicated situations to handle. It's a win-win situation!

This topic is closed to new replies.

Advertisement