瀏覽代碼

Merge pull request #2078 from rextimmy/zbias_fixes

Corrects OpenGL projection matrix
Areloch 8 年之前
父節點
當前提交
c57e4f14d2

+ 3 - 1
Engine/source/gfx/D3D11/gfxD3D11StateBlock.cpp

@@ -110,7 +110,9 @@ GFXD3D11StateBlock::GFXD3D11StateBlock(const GFXStateBlockDesc& desc)
    ZeroMemory(&mRasterizerDesc, sizeof(D3D11_RASTERIZER_DESC));
    mRasterizerDesc.CullMode = GFXD3D11CullMode[mDesc.cullMode];
    mRasterizerDesc.FillMode = GFXD3D11FillMode[mDesc.fillMode];
-   mRasterizerDesc.DepthBias = mDesc.zBias;
+   //this assumes 24bit depth
+   const INT depthMul = INT((1 << 24) - 1);
+   mRasterizerDesc.DepthBias = mDesc.zBias * depthMul;
    mRasterizerDesc.SlopeScaledDepthBias = mDesc.zSlopeBias;
    mRasterizerDesc.AntialiasedLineEnable = FALSE;
    mRasterizerDesc.MultisampleEnable = FALSE;

+ 8 - 5
Engine/source/gfx/gl/gfxGLStateBlock.cpp

@@ -139,16 +139,19 @@ void GFXGLStateBlock::activate(const GFXGLStateBlock* oldState)
    if(STATE_CHANGE(zFunc))
       glDepthFunc(GFXGLCmpFunc[mDesc.zFunc]);
    
-   if(STATE_CHANGE(zBias))
+   if (STATE_CHANGE(zBias))
    {
       if (mDesc.zBias == 0)
       {
          glDisable(GL_POLYGON_OFFSET_FILL);
-      } else {
-         F32 bias = mDesc.zBias * 10000.0f;
+      }
+      else 
+      {
+         //this assumes 24bit depth
+         const F32 depthMul = F32((1 << 24) - 1);
          glEnable(GL_POLYGON_OFFSET_FILL);
-         glPolygonOffset(bias, bias);
-      } 
+         glPolygonOffset(mDesc.zSlopeBias, mDesc.zBias * depthMul);
+      }
    }
    
    if(STATE_CHANGE(zWriteEnable))

+ 32 - 33
Engine/source/math/mathUtils.cpp

@@ -29,6 +29,7 @@
 #include "math/util/frustum.h"
 #include "platform/profiler.h"
 #include "core/tAlgorithm.h"
+#include "gfx/gfxDevice.h"
 
 namespace MathUtils
 {
@@ -1462,44 +1463,45 @@ void makeFovPortFrustum(
 ///
 static const MatrixF sGFXProjRotMatrix( EulerF( (M_PI_F / 2.0f), 0.0f, 0.0f ) );
 
-void makeProjection( MatrixF *outMatrix, 
-                     F32 left, 
-                     F32 right, 
-                     F32 top, 
-                     F32 bottom, 
-                     F32 nearPlane, 
+void makeProjection( MatrixF *outMatrix,
+                     F32 left,
+                     F32 right,
+                     F32 top,
+                     F32 bottom,
+                     F32 nearPlane,
                      F32 farPlane,
-                     bool gfxRotate )
+                     bool gfxRotate)
 {
+   const bool isGL = GFX->getAdapterType() == OpenGL;
    Point4F row;
-   row.x = 2.0*nearPlane / (right-left);
-   row.y = 0.0;
-   row.z = 0.0;
-   row.w = 0.0;
-   outMatrix->setRow( 0, row );
+   row.x = 2.0f * nearPlane / (right - left);
+   row.y = 0.0f;
+   row.z = 0.0f;
+   row.w = 0.0f;
+   outMatrix->setRow(0, row);
 
-   row.x = 0.0;
-   row.y = 2.0 * nearPlane / (top-bottom);
-   row.z = 0.0;
-   row.w = 0.0;
-   outMatrix->setRow( 1, row );
+   row.x = 0.0f;
+   row.y = 2.0f * nearPlane / (top - bottom);
+   row.z = 0.0f;
+   row.w = 0.0f;
+   outMatrix->setRow(1, row);
 
-   row.x = (left+right) / (right-left);
-   row.y = (top+bottom) / (top-bottom);
-   row.z = farPlane / (nearPlane - farPlane);
-   row.w = -1.0;
-   outMatrix->setRow( 2, row );
+   row.x = (left + right) / (right - left);
+   row.y = (top + bottom) / (top - bottom);
+   row.z = isGL ? (nearPlane + farPlane) / (nearPlane - farPlane) : farPlane / (nearPlane - farPlane);
+   row.w = -1.0f;
+   outMatrix->setRow(2, row);
 
-   row.x = 0.0;
-   row.y = 0.0;
-   row.z = nearPlane * farPlane / (nearPlane - farPlane);
-   row.w = 0.0;
-   outMatrix->setRow( 3, row );
+   row.x = 0.0f;
+   row.y = 0.0f;
+   row.z = isGL ? 2.0f * nearPlane * farPlane / (nearPlane - farPlane) : farPlane * nearPlane / (nearPlane - farPlane);
+   row.w = 0.0f;
+   outMatrix->setRow(3, row);
 
    outMatrix->transpose();
 
-   if ( gfxRotate )
-      outMatrix->mul( sGFXProjRotMatrix );
+   if (gfxRotate)
+      outMatrix->mul(sGFXProjRotMatrix);
 }
 
 //-----------------------------------------------------------------------------
@@ -1528,11 +1530,8 @@ void makeOrthoProjection(  MatrixF *outMatrix,
 
    row.x = 0.0f;
    row.y = 0.0f;
-   row.w = 0.0f;
-
-   //Unlike D3D, which has a 0-1 range, OpenGL uses a -1-1 range. 
-   //However, epoxy internally handles the swap, so the math here is the same for both APIs
    row.z = 1.0f / (nearPlane - farPlane);
+   row.w = 0.0f;
 
    outMatrix->setRow( 2, row );