wined3d: Fix the half pixel offset.
Turns out the original fix was correct for fixed function, but for the
wrong reason. The shader path was already correct. This fixes a
regresssion introduced by 932e95c111
.
This commit is contained in:
parent
d266abee14
commit
27b8f719ca
|
@ -3905,16 +3905,6 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
|
|||
divide by the Width/Height, so we need the half range(1.0) to translate by
|
||||
half a pixel.
|
||||
|
||||
Note that when rendering offscreen, we need to translate 1 pixel
|
||||
(2/h in normalized device coordinates) down after doing the flip,
|
||||
because of the way the viewport transformation works in OpenGL:
|
||||
(-1,1) in normalized device coordinates corresponds to the upper
|
||||
left corner of the upper left pixel in the viewport. (-1,-1)
|
||||
corresponds to lower left corner of the lower left pixel in the
|
||||
viewport. In other words, the upper left corner of the pixel
|
||||
*below* the lower left pixel in the viewport. See also section
|
||||
2.11.1 "Controlling the Viewport" of the GL 2.1 spec.
|
||||
|
||||
The other fun is that d3d's output z range after the transformation is [0;1],
|
||||
but opengl's is [-1;1]. Since the z buffer is in range [0;1] for both, gl
|
||||
scales [-1;1] to [0;1]. This would mean that we end up in [0.5;1] and loose a lot
|
||||
|
@ -3922,6 +3912,24 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
|
|||
[0;1] to [-1;1], so when gl undoes that we utilize the full z range
|
||||
*/
|
||||
|
||||
/*
|
||||
* Careful with the order of operations here, we're essentially working backwards:
|
||||
* x = x + 1/w;
|
||||
* y = (y - 1/h) * flip;
|
||||
* z = z * 2 - 1;
|
||||
*
|
||||
* Becomes:
|
||||
* glTranslatef(0.0, 0.0, -1.0);
|
||||
* glScalef(1.0, 1.0, 2.0);
|
||||
*
|
||||
* glScalef(1.0, flip, 1.0);
|
||||
* glTranslatef(1/w, -1/h, 0.0);
|
||||
*
|
||||
* This is equivalent to:
|
||||
* glTranslatef(1/w, -flip/h, -1.0)
|
||||
* glScalef(1.0, flip, 2.0);
|
||||
*/
|
||||
|
||||
if (stateblock->wineD3DDevice->render_offscreen) {
|
||||
/* D3D texture coordinates are flipped compared to OpenGL ones, so
|
||||
* render everything upside down when rendering offscreen. */
|
||||
|
@ -4517,7 +4525,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
|
|||
*/
|
||||
if (useVertexShaderFunction) {
|
||||
device->posFixup[1] = device->render_offscreen ? -1.0 : 1.0;
|
||||
device->posFixup[3] = -1.0 / stateblock->viewport.Height;
|
||||
device->posFixup[3] = -device->posFixup[1] / stateblock->viewport.Height;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4649,7 +4657,7 @@ static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, W
|
|||
|
||||
static void viewport_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
|
||||
stateblock->wineD3DDevice->posFixup[2] = 1.0 / stateblock->viewport.Width;
|
||||
stateblock->wineD3DDevice->posFixup[3] = -1.0 / stateblock->viewport.Height;
|
||||
stateblock->wineD3DDevice->posFixup[3] = -stateblock->wineD3DDevice->posFixup[1] / stateblock->viewport.Height;
|
||||
if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
|
||||
transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue