The official VP 9.9.0 has been released in the meanwhile! Go download that instead:
Table upgrade guide for DX9: https://github.com/c...e-Upgrade-Guide
----------- The post below is now out of date ---------------------
I decided to start a new thread to give people an idea what exactly I'm doing, as well as some kind of ongoing progress report.
What I'm trying to do, as some of you already realized, is to port VP to DX9. This is kind of the easiest target to shoot for, because it's still roughly similar in interface to DX7, but has much better driver and hardware support on modern machines. In particular, we have to get rid of DirectDraw, for which support is very spotty nowadays. The hope is that this will fix many of the compatibility issues that are plaguing VP right now, as well as give us better performance in certain aspects. Also it will give us access to cool features like shaders and so on, but that is for the future.
I know that I'm not the first to try my hand at this, but I'm kind of stubborn about this and won't give up until I have crashed and burned myself
The general plan is like this:
- Get rid of all DirectDraw-specific functionality. In particular, this means that we must change the rendering of all moving objects like flippers, bumpers, spinners and so on from the current sprite-based technique to full 3D rendering. This will cost us some performance upfront. I hope that in the long run we can recoup most of that loss by the better hardware support in DX9 as well as optimization.
- Abstract the interface to the renderer. Right now, many places in the code refer to DX7-specific structures and methods. The idea here is to make as much of the codebase API-independent by providing an abstract renderer interface, so that all the DX-specific code is localized in just a few classes. This will also help immensely if, down the road, a port to, say, DX11 or OpenGL is desired.
- Once we have all our ducks in a row, so to speak, switch out the core rendering classes for DX9 versions. Hopefully, with a well-abstracted renderer, this will not be terribly intrusive. Of course, issues will certainly arise, but it should be nothing that's insurmountable.
- After this crucial step, the period of re-integration can start: put features back in which had to be disabled to make the jump, optimize all the render calls, do an overall clean-up pass over the code.
In order not to disrupt the mainstream VP development, I've started doing this in my own repository, separate from the official VP repo. You can have a look at it here: https://github.com/c-f-h/vpinball. My hope is that, once a proof-of-concept of the DX9 engine is up and running, this code can be integrated as a branch into the official VP repository and the other devs will maybe offer valuable support in the important step 4. This could form the basis for an eventual VP10 release, if the other devs deem it a good starting point.
Progress on step 1
The following objects have been converted to dynamic 3D rendering:
- Drop targets
- Kickers (though they render a bit glitchy at the moment)
Still to do (might have missed some):
A few are remaining, but this is in general an easy process and I can do a few per day when I put my mind to it. I'm doing this in a very brute-force way, basically just copying the stuff which was previously rendering into sprites into a per-frame dynamic render method. Typically, this is extremely inefficient. Make no mistake: performance is horrible at the moment. However, I have decided to put off all optimization until after the switch to DX9, both to get a DX9 proof of concept ASAP and because the performance characteristics will be different anyway, making it pointless to optimize for DX7 at this point.
a few three two are left, those are substantially harder though since they use more sprite functionality. I might just disable a few of them initially, just to get to the meat and potatoes of the actual port sooner.
Progress on step 2
I've also started on step 2, i.e., creating an abstract renderer interface. I've already ripped out many of the DX7-specific types and replaced them with generic typedefs. In many places, though, the structure of the code is still very particular to DX7 and will need to change. One particular area of trouble will be texture management, which will probably have to be rewritten in large parts. The other big thing is the initialization code, which works completely differently in DX9. I hope that this change can be localized, though.
UPDATE: I have a pretty good picture of how the rendering should be structured now. I'll have the RenderDevice, which already existed in the original code, deal with all the API-specific stuff, and all the classes that are built on top of it (most importantly Pin3D, Player) should only use its abstract interface instead of actual DirectX methods. I made good progress towards that goal today, the Pin3D class, which was the main offender, is now fully abstract. I had to disable a few features to get there however (AA, Stereo 3D). These ought to be put back in again in the reintegration phase. Texture management is still giving me a headache.
UPDATE 2: I made major steps here. Barring a few exceptions (basically the objects listed in step 1), all the API-specific code is now contained in three classes, namely RenderDevice, Texture and the legacy PinDirectDraw. I'm still not sure what to do with the latter, eliminate it completely or repurpose it into a general texture manager. Speaking of it, I also did major changes to the texture management code, eliminating heaps of duplicated code (I have to say this part of VP was an unholy mess before; entire functions existed in two, often subtly different versions) and cleaning up interfaces.
Progress on step 3
Baby steps. Since the interface is now solidifying, I started implementing a few methods of the RenderDevice in a DX9 version, just not to have to do all of those at once when the switchover starts. I don't compile this version yet though, since mixing D3D7 and D3D9 headers won't go down well.
UPDATE: The DX9 RenderDevice is maturing, the majority of methods is already implemented. I've also added a build switch which is used to choose between the legacy DX7 and the DX9 renderer. It doesn't compile yet on DX9 because of dependencies in other parts of the code (again, mainly texture management), but the DX9 RenderDevice class does compile at this point already. While I was at it, I also used the opportunity to do a clean-up pass over the general renderer interface, renaming methods, throwing out unused arguments and so on. It's definitely a lot cleaner now.
That's all so far. I'll try to keep this thread updated as I go along, and hope to engage in discussions with the other devs here as to the best way of proceeding on the harder questions. Also if you have any questions or suggestions I'd be happy to hear them!
Edited by mukuste, 01 May 2014 - 06:38 AM.