Am Dienstag 25 Juli 2006 04:21 schrieb Jason Green:
I've spent a couple of days researching the issue of broken/upside-down character/object models in Wine in almost all newer games when you have vertex shaders enabled (Civ4, Half Life 2, Oblivion, Max Payne 2, etc.). I think I've boiled it down to a single case: When "device->renderUpsideDown" is set in the case where vertex shaders are enabled. That flag gets set in device.c:7395 when the current renderTarget is not on the current swapchain. The comments in the source say that the upside-downedness is produced by glCopyTexImage, so it sets a flag to flip everything over.
In the case w/o shaders, there is code in drawprim.c which loads the WORLDVIEW and PROJECTION matrices and then multiplies those matrices by one which inverts the y coordinates when that flag is set. That seems to work in the case without vertex shaders, but when shaders are enabled, they bypass the WORLD, VIEW, and PROJECTION matrices entirely. The shader case was written when only software shaders worked, but that is no longer true. It loads identity matrices and performs the y flip, but that code is entirely irrelevant since the vertex shader doesn't reference those matrices; it only uses constants that are passed by the app, which we can't perform any type of fixup on since we don't know which constants will be used for which calculation.
So, I think what we need to do is prevent ourselves from having to do any flipping whatsoever. That's the part that I'm not sure how to do and is the reason for this email. Can we load the textures in system memory first, perform a software reversing process, then load that up with glCopyTexImage instead? Will we need to do that type of fixup every time the app locks/unlocks/changes part of the texture? Or, is there a better way?
I think I've figured out the problem, it's just the next step of fixing it that I'm unsure of. :-)
Can we flip around the y axis in the shader? Or can we flip around the texture coords when drawing from the offscreen texture? If I understand it correctly this only affects offscreen rendering.