Two feature requests for T3D
by Sean H. · in Torque 3D Professional · 10/16/2010 (1:59 pm) · 3 replies
T3D needs two things badly: multi-threaded rendering and high-precision mouse input.
For anyone who may not know, multi-threaded programming allows the program to process multiple things at the same time. For instance, the game could be rendering the scene at the same time it's updating object states. Multi-threading is supported in T3D it's just not currently being utilized to allow rendering to take place in a separate process. Please use T3D's multi threading facilities to perform all rendering in a separate thread.
Torque still uses WM_MOUSEMOVE which is very outdated. This is why mouse movement in torque feels so jittery at times. WM_MOUSEMOVE should be used for menu-based applications only. For 3d games, especially fps, it's highly recommended that high precision mouse input(WM_INPUT) be used instead. T3D should be using WM_INPUT and apply pointer ballistics if the mouse event is heading to a gui and use the raw input if it's destination is the action map.
For anyone who may not know, multi-threaded programming allows the program to process multiple things at the same time. For instance, the game could be rendering the scene at the same time it's updating object states. Multi-threading is supported in T3D it's just not currently being utilized to allow rendering to take place in a separate process. Please use T3D's multi threading facilities to perform all rendering in a separate thread.
Torque still uses WM_MOUSEMOVE which is very outdated. This is why mouse movement in torque feels so jittery at times. WM_MOUSEMOVE should be used for menu-based applications only. For 3d games, especially fps, it's highly recommended that high precision mouse input(WM_INPUT) be used instead. T3D should be using WM_INPUT and apply pointer ballistics if the mouse event is heading to a gui and use the raw input if it's destination is the action map.
#2
10/18/2010 (2:09 am)
Interesting Sean, thank you for your input. I'm sure we can all appreciate learning more about the inner workings of Torque. You wouldn't happen to have a working code example would you? I'm very interested in seeing what exactly you are trying to explain.
#3
the code for implementing WM_INPUT is fairly straightforward and an example can be found on microsoft's website. the only part that's somewhat complex is applying the pointer ballistics but even this isn't that hard to do. in fact, torque already does apply pointer ballistics although it uses WM_MOUSEMOVE which is redundant. however, mickeys is initialized to a value of 1 which means no actual ballistics are being applied. for WM_INPUT a good general conversion factor for converting physical mouse increments to screen pixels is 4. again, this is only the case for gui cursor movements. the raw input value should be used if the mouse event is consumed by the action map and a simple linear factor should be used based on mouse sensitivity, probably at the script level.
when it comes to using multi-threading for rendering, again I don't have a working example but ive thought about it and I don't think it would be that difficult to do.
object rendering in torque can be broken up into 3 broad sections: object updating, rendering prep, and actual rendering. object updating is where the transform for an object is updated(processtick(),interpolatetick()). rendering prep is where transform, material, and lighting information is encapsulated in a render object and stored in the render instance manager. actual rendering is where the information in the render object is used for the actual render calls.
none of these areas are totally thread-safe. the main problem is that
the render instance manager is used by both render prep, and actual rendering so, as the code stands now, these can't both happen at the same time. however, i think ive got a preliminary idea of how this could work.
the code would work as follows:
the idea is to use a semaphore to prevent prep render and actual render from happening at the same time since they both require usage of the render instance manager. everything else is allowed to happen while the scene is rendering in a separate thread up until the next prep render. prep render will wait until the scene has finished rendering before it takes place. acquire_semaphore is called the second time *outside* the separate rendering thread to prevent a race condition from occuring and the second release_semaphore signals that rendering has finished and the next batch of render instances may be sent(prep render).
This is a relatively simple multithreaded rendering idea. it woudlnt require monumental changes to the application to achieve multithreaded rendering. it would be fairly simple to implement and could give a substantial performance boost especially in scenes with many objects.
10/18/2010 (5:17 pm)
I dont have any working code examples although it wouldn't be that hard to implement. My hope is that the T3D folks will implement these changes for the upcoming beta or next release version.the code for implementing WM_INPUT is fairly straightforward and an example can be found on microsoft's website. the only part that's somewhat complex is applying the pointer ballistics but even this isn't that hard to do. in fact, torque already does apply pointer ballistics although it uses WM_MOUSEMOVE which is redundant. however, mickeys is initialized to a value of 1 which means no actual ballistics are being applied. for WM_INPUT a good general conversion factor for converting physical mouse increments to screen pixels is 4. again, this is only the case for gui cursor movements. the raw input value should be used if the mouse event is consumed by the action map and a simple linear factor should be used based on mouse sensitivity, probably at the script level.
when it comes to using multi-threading for rendering, again I don't have a working example but ive thought about it and I don't think it would be that difficult to do.
object rendering in torque can be broken up into 3 broad sections: object updating, rendering prep, and actual rendering. object updating is where the transform for an object is updated(processtick(),interpolatetick()). rendering prep is where transform, material, and lighting information is encapsulated in a render object and stored in the render instance manager. actual rendering is where the information in the render object is used for the actual render calls.
none of these areas are totally thread-safe. the main problem is that
the render instance manager is used by both render prep, and actual rendering so, as the code stands now, these can't both happen at the same time. however, i think ive got a preliminary idea of how this could work.
the code would work as follows:
- update objects
- prep render
acquire_semaphore(rendering) //make sure scene has finished rendering
submit new instances to render instance manager
release_semaphore(rendering)//new render instances have been sent
- actual rendering
acquire_semaphore(rendering)
-spawn a separate thread for actual rendering
- render scene
- release_semaphore(rendering)//allow prep render to start
- end of new threadthe idea is to use a semaphore to prevent prep render and actual render from happening at the same time since they both require usage of the render instance manager. everything else is allowed to happen while the scene is rendering in a separate thread up until the next prep render. prep render will wait until the scene has finished rendering before it takes place. acquire_semaphore is called the second time *outside* the separate rendering thread to prevent a race condition from occuring and the second release_semaphore signals that rendering has finished and the next batch of render instances may be sent(prep render).
This is a relatively simple multithreaded rendering idea. it woudlnt require monumental changes to the application to achieve multithreaded rendering. it would be fairly simple to implement and could give a substantial performance boost especially in scenes with many objects.
Torque 3D Owner Dark Tengu