问题
I am maintaining a multiplatform codebase for Xbox360 and WinXP. I am seeing an issue on the XP side that appears to be related to D3DRS_VIEWPORTENABLE on the Xbox360 version not having an equivalent on WinXP D3D9. This article had an interesting idea, but the only way to construct an identity matrix is to supply negative numbers to D3DVIEWPORT9::X and D3DVIEWPORT9::Height, but they are unsigned numbers. (I tried to put in negative numbers anyway, but nothing interesting happened.)
So, how does one emulate the behavior of D3DRS_VIEWPORTENABLE under WinXP/D3D9?
(For clarity, the result I'm seeing is that a 2d screen-aligned quad works fine on Xbox360 but is offset/stretched on WinXP. In fact, the (0, 0) starts in the center of the screen on WinXP instead of in the lower-left corner like on the Xbox360 as a result of applying the viewport transform.)
Update: I didn't have an Xbox360 devkit at the time I wrote up this question, but I've since gotten one. I commented out the disabling of the D3DRS_VIEWPORTENABLE state, and the exact same behavior resulted on the Xbox360 as on the WinXP build. So, there must be some DirectX magic to bridge the gap here for emulating D3DRS_VIEWPORTENABLE being turned off on WinXP.
回答1:
Instead of thinking about how you could put negatives into the viewport matrix think about it from the projection matrix.
The viewport matrix is applied directly after the projection matrix. So if you imagine setting the viewport to identity and the multiply it with the wvp (world-view-projection) matrix. ie
world * view * projection * viewport
You can now set the viewport to anything you want.
Of course this isn't actually the best way to attack the problem either. Some drivers will probably make optimisations based upon entries in t e viewport (they may not actually do a matrix multiply, for one). I wouldn't personally use the above system I can foresee too many issues coming from it.
So where does that leave you?
Well actually its still pretty simple. If you multiply the projection matrix by a matrix that is the inverse of the viewport matrix then you will find that when the viewport "matrix" is applied they cancel each other out and you are left with the direct output of the projection. The viewport has now been, effectively, "disabled".
来源:https://stackoverflow.com/questions/4583380/what-is-the-xbox360s-d3drs-viewportenable-equivalent-on-winxp-d3d9