Corrects OpenGL projection matrix

Corrects OpenGL glPolygonOffset values
Corrects Direct3D11 DepthBias values
This commit is contained in:
rextimmy 2017-08-25 13:13:47 +10:00
parent ad612e218b
commit 54970b0ad6
3 changed files with 43 additions and 39 deletions

View file

@ -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;

View file

@ -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))

View file

@ -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 );