2009-07-28 23:32:10 +02:00
// Copyright (C) 2003 Dolphin Project.
2008-12-08 06:25:12 +01:00
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
2008-12-26 12:23:59 +01:00
# include "Common.h"
2009-09-13 12:18:01 +02:00
# include "VideoConfig.h"
2009-04-19 12:10:45 +02:00
# include "MathUtil.h"
2008-12-08 06:25:12 +01:00
2008-12-26 12:23:59 +01:00
# include <cmath>
2011-01-29 22:13:56 +01:00
# include <sstream>
2008-12-08 06:25:12 +01:00
# include "Statistics.h"
2008-12-26 12:23:59 +01:00
2008-12-26 18:33:53 +01:00
# include "VertexShaderGen.h"
2008-12-08 06:25:12 +01:00
# include "VertexShaderManager.h"
2009-06-22 11:31:30 +02:00
# include "BPMemory.h"
2008-12-26 13:47:32 +01:00
# include "CPMemory.h"
2008-12-08 06:25:12 +01:00
# include "XFMemory.h"
2008-12-26 13:47:32 +01:00
# include "VideoCommon.h"
2010-10-03 02:41:06 +02:00
# include "VertexManagerBase.h"
2008-12-08 06:25:12 +01:00
2011-01-31 02:28:32 +01:00
# include "RenderBase.h"
2009-06-28 22:04:07 +02:00
float GC_ALIGNED16 ( g_fProjectionMatrix [ 16 ] ) ;
2008-12-08 06:25:12 +01:00
// track changes
static bool bTexMatricesChanged [ 2 ] , bPosNormalMatrixChanged , bProjectionChanged , bViewportChanged ;
static int nMaterialsChanged ;
static int nTransformMatricesChanged [ 2 ] ; // min,max
static int nNormalMatricesChanged [ 2 ] ; // min,max
static int nPostTransformMatricesChanged [ 2 ] ; // min,max
static int nLightsChanged [ 2 ] ; // min,max
2011-05-12 04:14:45 +02:00
static Matrix44 s_viewportCorrection ;
2009-04-19 12:10:45 +02:00
static Matrix33 s_viewRotationMatrix ;
static Matrix33 s_viewInvRotationMatrix ;
static float s_fViewTranslationVector [ 3 ] ;
static float s_fViewRotation [ 2 ] ;
2011-05-12 04:14:45 +02:00
void UpdateViewport ( Matrix44 & vpCorrection ) ;
2008-12-08 06:25:12 +01:00
2011-01-31 02:28:32 +01:00
inline void SetVSConstant4f ( unsigned int const_number , float f1 , float f2 , float f3 , float f4 )
{
g_renderer - > SetVSConstant4f ( const_number , f1 , f2 , f3 , f4 ) ;
}
inline void SetVSConstant4fv ( unsigned int const_number , const float * f )
{
g_renderer - > SetVSConstant4fv ( const_number , f ) ;
}
inline void SetMultiVSConstant3fv ( unsigned int const_number , unsigned int count , const float * f )
{
g_renderer - > SetMultiVSConstant3fv ( const_number , count , f ) ;
}
inline void SetMultiVSConstant4fv ( unsigned int const_number , unsigned int count , const float * f )
{
g_renderer - > SetMultiVSConstant4fv ( const_number , count , f ) ;
}
2009-12-05 14:56:23 +01:00
namespace
{
// Control Variables
static ProjectionHack g_ProjHack1 ;
static ProjectionHack g_ProjHack2 ;
2011-01-29 22:13:56 +01:00
static bool g_ProjHack3 ;
2009-12-05 14:56:23 +01:00
} // Namespace
2011-01-29 22:13:56 +01:00
float PHackValue ( std : : string sValue )
2009-12-05 14:56:23 +01:00
{
2011-01-29 22:13:56 +01:00
float f = 0 ;
bool fp = false ;
const char * cStr = sValue . c_str ( ) ;
char * c = new char [ strlen ( cStr ) + 1 ] ;
std : : istringstream sTof ( " " ) ;
for ( unsigned int i = 0 ; i < = strlen ( cStr ) ; + + i )
2009-12-05 14:56:23 +01:00
{
2011-01-29 22:13:56 +01:00
if ( i = = 20 )
{
c [ i ] = ' \0 ' ;
break ;
}
c [ i ] = ( cStr [ i ] = = ' , ' ) ? ' . ' : * ( cStr + i ) ;
if ( c [ i ] = = ' . ' )
fp = true ;
}
cStr = c ;
sTof . str ( cStr ) ;
sTof > > f ;
if ( ! fp ) f / = 0xF4240 ;
delete [ ] c ;
return f ;
}
void UpdateProjectionHack ( int iPhackvalue [ ] , std : : string sPhackvalue [ ] )
{
float fhackvalue1 = 0 , fhackvalue2 = 0 ;
float fhacksign1 = 1.0 , fhacksign2 = 1.0 ;
bool bProjHack3 = false ;
2011-01-29 23:48:33 +01:00
const char * sTemp [ 2 ] ;
2011-01-29 22:13:56 +01:00
2011-01-30 01:56:33 +01:00
if ( iPhackvalue [ 0 ] = = 1 )
{
NOTICE_LOG ( VIDEO , " \t \t --- Ortographic Projection Hack ON --- " ) ;
fhacksign1 * = ( iPhackvalue [ 1 ] = = 1 ) ? - 1.0f : fhacksign1 ;
sTemp [ 0 ] = ( iPhackvalue [ 1 ] = = 1 ) ? " * (-1) " : " " ;
fhacksign2 * = ( iPhackvalue [ 2 ] = = 1 ) ? - 1.0f : fhacksign2 ;
sTemp [ 1 ] = ( iPhackvalue [ 2 ] = = 1 ) ? " * (-1) " : " " ;
fhackvalue1 = PHackValue ( sPhackvalue [ 0 ] ) ;
NOTICE_LOG ( VIDEO , " - zNear Correction = (%f + zNear)%s " , fhackvalue1 , sTemp [ 0 ] ) ;
fhackvalue2 = PHackValue ( sPhackvalue [ 1 ] ) ;
NOTICE_LOG ( VIDEO , " - zFar Correction = (%f + zFar)%s " , fhackvalue2 , sTemp [ 1 ] ) ;
sTemp [ 0 ] = " DISABLED " ;
bProjHack3 = ( iPhackvalue [ 3 ] = = 1 ) ? true : bProjHack3 ;
if ( bProjHack3 )
sTemp [ 0 ] = " ENABLED " ;
NOTICE_LOG ( VIDEO , " - Extra Parameter: %s " , sTemp [ 0 ] ) ;
}
2011-01-29 22:13:56 +01:00
// Set the projections hacks
2011-01-30 01:56:33 +01:00
g_ProjHack1 = ProjectionHack ( fhacksign1 , fhackvalue1 ) ;
g_ProjHack2 = ProjectionHack ( fhacksign2 , fhackvalue2 ) ;
2011-01-29 22:13:56 +01:00
g_ProjHack3 = bProjHack3 ;
2009-12-05 14:56:23 +01:00
}
2008-12-26 11:43:18 +01:00
void VertexShaderManager : : Init ( )
2008-12-08 06:25:12 +01:00
{
2009-09-15 23:49:15 +02:00
Dirty ( ) ;
memset ( & xfregs , 0 , sizeof ( xfregs ) ) ;
2010-06-05 03:38:22 +02:00
memset ( xfmem , 0 , sizeof ( xfmem ) ) ;
ResetView ( ) ;
2012-01-02 11:20:22 +01:00
// TODO: should these go inside ResetView()?
Matrix44 : : LoadIdentity ( s_viewportCorrection ) ;
memset ( g_fProjectionMatrix , 0 , sizeof ( g_fProjectionMatrix ) ) ;
for ( int i = 0 ; i < 4 ; + + i )
g_fProjectionMatrix [ i * 5 ] = 1.0f ;
2008-12-26 11:43:18 +01:00
}
2008-12-08 06:25:12 +01:00
2008-12-26 11:43:18 +01:00
void VertexShaderManager : : Shutdown ( )
{
2008-12-08 06:25:12 +01:00
}
2009-09-15 23:49:15 +02:00
void VertexShaderManager : : Dirty ( )
{
nTransformMatricesChanged [ 0 ] = 0 ; nTransformMatricesChanged [ 1 ] = 256 ;
nNormalMatricesChanged [ 0 ] = 0 ; nNormalMatricesChanged [ 1 ] = 96 ;
nPostTransformMatricesChanged [ 0 ] = 0 ; nPostTransformMatricesChanged [ 1 ] = 256 ;
nLightsChanged [ 0 ] = 0 ; nLightsChanged [ 1 ] = 0x80 ;
bPosNormalMatrixChanged = true ;
bTexMatricesChanged [ 0 ] = bTexMatricesChanged [ 1 ] = true ;
bProjectionChanged = true ;
bPosNormalMatrixChanged = bTexMatricesChanged [ 0 ] = bTexMatricesChanged [ 1 ] = true ;
nMaterialsChanged = 15 ;
}
2008-12-08 06:25:12 +01:00
// Syncs the shader constant buffers with xfmem
2009-07-26 11:52:35 +02:00
// TODO: A cleaner way to control the matricies without making a mess in the parameters field
2009-08-15 09:20:37 +02:00
void VertexShaderManager : : SetConstants ( )
2008-12-08 06:25:12 +01:00
{
2010-06-05 03:38:22 +02:00
if ( nTransformMatricesChanged [ 0 ] > = 0 )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
int startn = nTransformMatricesChanged [ 0 ] / 4 ;
int endn = ( nTransformMatricesChanged [ 1 ] + 3 ) / 4 ;
const float * pstart = ( const float * ) & xfmem [ startn * 4 ] ;
2009-09-12 17:00:08 +02:00
SetMultiVSConstant4fv ( C_TRANSFORMMATRICES + startn , endn - startn , pstart ) ;
2010-06-05 03:38:22 +02:00
nTransformMatricesChanged [ 0 ] = nTransformMatricesChanged [ 1 ] = - 1 ;
}
if ( nNormalMatricesChanged [ 0 ] > = 0 )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
int startn = nNormalMatricesChanged [ 0 ] / 3 ;
int endn = ( nNormalMatricesChanged [ 1 ] + 2 ) / 3 ;
const float * pnstart = ( const float * ) & xfmem [ XFMEM_NORMALMATRICES + 3 * startn ] ;
SetMultiVSConstant3fv ( C_NORMALMATRICES + startn , endn - startn , pnstart ) ;
2009-09-19 12:46:25 +02:00
nNormalMatricesChanged [ 0 ] = nNormalMatricesChanged [ 1 ] = - 1 ;
2010-06-05 03:38:22 +02:00
}
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
if ( nPostTransformMatricesChanged [ 0 ] > = 0 )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
int startn = nPostTransformMatricesChanged [ 0 ] / 4 ;
int endn = ( nPostTransformMatricesChanged [ 1 ] + 3 ) / 4 ;
const float * pstart = ( const float * ) & xfmem [ XFMEM_POSTMATRICES + startn * 4 ] ;
SetMultiVSConstant4fv ( C_POSTTRANSFORMMATRICES + startn , endn - startn , pstart ) ;
}
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
if ( nLightsChanged [ 0 ] > = 0 )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
// lights don't have a 1 to 1 mapping, the color component needs to be converted to 4 floats
int istart = nLightsChanged [ 0 ] / 0x10 ;
int iend = ( nLightsChanged [ 1 ] + 15 ) / 0x10 ;
const float * xfmemptr = ( const float * ) & xfmem [ 0x10 * istart + XFMEM_LIGHTS ] ;
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
for ( int i = istart ; i < iend ; + + i )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
u32 color = * ( const u32 * ) ( xfmemptr + 3 ) ;
2009-09-26 14:39:12 +02:00
float NormalizationCoef = 1 / 255.0f ;
2010-06-05 03:38:22 +02:00
SetVSConstant4f ( C_LIGHTS + 5 * i ,
( ( color > > 24 ) & 0xFF ) * NormalizationCoef ,
2009-09-26 14:39:12 +02:00
( ( color > > 16 ) & 0xFF ) * NormalizationCoef ,
( ( color > > 8 ) & 0xFF ) * NormalizationCoef ,
( ( color ) & 0xFF ) * NormalizationCoef ) ;
2010-06-05 03:38:22 +02:00
xfmemptr + = 4 ;
2009-07-26 11:52:35 +02:00
2010-06-05 03:38:22 +02:00
for ( int j = 0 ; j < 4 ; + + j , xfmemptr + = 3 )
2009-07-26 11:52:35 +02:00
{
2008-12-08 06:25:12 +01:00
if ( j = = 1 & &
fabs ( xfmemptr [ 0 ] ) < 0.00001f & &
fabs ( xfmemptr [ 1 ] ) < 0.00001f & &
2010-06-05 03:38:22 +02:00
fabs ( xfmemptr [ 2 ] ) < 0.00001f )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
// dist attenuation, make sure not equal to 0!!!
SetVSConstant4f ( C_LIGHTS + 5 * i + j + 1 , 0.00001f , xfmemptr [ 1 ] , xfmemptr [ 2 ] , 0 ) ;
}
else
SetVSConstant4fv ( C_LIGHTS + 5 * i + j + 1 , xfmemptr ) ;
}
}
nLightsChanged [ 0 ] = nLightsChanged [ 1 ] = - 1 ;
}
if ( nMaterialsChanged )
2009-07-26 11:52:35 +02:00
{
2011-02-05 19:25:34 +01:00
float GC_ALIGNED16 ( material [ 4 ] ) ;
float NormalizationCoef = 1 / 255.0f ;
2010-06-05 03:38:22 +02:00
for ( int i = 0 ; i < 4 ; + + i )
2011-02-05 19:25:34 +01:00
{
2010-06-05 03:38:22 +02:00
if ( nMaterialsChanged & ( 1 < < i ) )
2011-02-05 19:25:34 +01:00
{
u32 data = * ( xfregs . ambColor + i ) ;
material [ 0 ] = ( ( data > > 24 ) & 0xFF ) * NormalizationCoef ;
material [ 1 ] = ( ( data > > 16 ) & 0xFF ) * NormalizationCoef ;
material [ 2 ] = ( ( data > > 8 ) & 0xFF ) * NormalizationCoef ;
material [ 3 ] = ( data & 0xFF ) * NormalizationCoef ;
SetVSConstant4fv ( C_MATERIALS + i , material ) ;
}
}
2009-07-26 11:52:35 +02:00
2010-06-05 03:38:22 +02:00
nMaterialsChanged = 0 ;
}
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
if ( bPosNormalMatrixChanged )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
bPosNormalMatrixChanged = false ;
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
const float * pos = ( const float * ) xfmem + MatrixIndexA . PosNormalMtxIdx * 4 ;
const float * norm = ( const float * ) xfmem + XFMEM_NORMALMATRICES + 3 * ( MatrixIndexA . PosNormalMtxIdx & 31 ) ;
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
SetMultiVSConstant4fv ( C_POSNORMALMATRIX , 3 , pos ) ;
2009-09-19 12:46:25 +02:00
SetMultiVSConstant3fv ( C_POSNORMALMATRIX + 3 , 3 , norm ) ;
2009-09-12 17:00:08 +02:00
}
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
if ( bTexMatricesChanged [ 0 ] )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
bTexMatricesChanged [ 0 ] = false ;
const float * fptrs [ ] =
2009-07-26 11:52:35 +02:00
{
2009-09-12 17:00:08 +02:00
( const float * ) xfmem + MatrixIndexA . Tex0MtxIdx * 4 , ( const float * ) xfmem + MatrixIndexA . Tex1MtxIdx * 4 ,
2010-06-05 03:38:22 +02:00
( const float * ) xfmem + MatrixIndexA . Tex2MtxIdx * 4 , ( const float * ) xfmem + MatrixIndexA . Tex3MtxIdx * 4
2008-12-08 06:25:12 +01:00
} ;
2010-06-05 03:38:22 +02:00
for ( int i = 0 ; i < 4 ; + + i )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
SetMultiVSConstant4fv ( C_TEXMATRICES + 3 * i , 3 , fptrs [ i ] ) ;
}
}
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
if ( bTexMatricesChanged [ 1 ] )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
bTexMatricesChanged [ 1 ] = false ;
const float * fptrs [ ] = {
2009-09-12 17:00:08 +02:00
( const float * ) xfmem + MatrixIndexB . Tex4MtxIdx * 4 , ( const float * ) xfmem + MatrixIndexB . Tex5MtxIdx * 4 ,
2010-06-05 03:38:22 +02:00
( const float * ) xfmem + MatrixIndexB . Tex6MtxIdx * 4 , ( const float * ) xfmem + MatrixIndexB . Tex7MtxIdx * 4
2009-09-12 17:00:08 +02:00
} ;
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
for ( int i = 0 ; i < 4 ; + + i )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
SetMultiVSConstant4fv ( C_TEXMATRICES + 3 * i + 12 , 3 , fptrs [ i ] ) ;
}
}
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
if ( bViewportChanged )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
bViewportChanged = false ;
2012-03-24 16:30:00 +01:00
SetVSConstant4f ( C_DEPTHPARAMS ,
xfregs . viewport . farZ / 16777216.0f ,
xfregs . viewport . zRange / 16777216.0f ,
- 1.f / ( float ) g_renderer - > EFBToScaledX ( ( int ) ceil ( 2.0f * xfregs . viewport . wd ) ) ,
1.f / ( float ) g_renderer - > EFBToScaledY ( ( int ) ceil ( - 2.0f * xfregs . viewport . ht ) ) ) ;
2008-12-26 13:47:32 +01:00
// This is so implementation-dependent that we can't have it here.
2011-05-12 04:14:45 +02:00
UpdateViewport ( s_viewportCorrection ) ;
bProjectionChanged = true ;
2010-06-05 03:38:22 +02:00
}
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
if ( bProjectionChanged )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
bProjectionChanged = false ;
2009-02-15 21:49:59 +01:00
2010-06-05 03:38:22 +02:00
if ( xfregs . rawProjection [ 6 ] = = 0 )
{
2009-07-26 11:52:35 +02:00
// Perspective
2009-12-05 15:01:29 +01:00
2010-04-05 00:52:27 +02:00
g_fProjectionMatrix [ 0 ] = xfregs . rawProjection [ 0 ] * g_ActiveConfig . fAspectRatioHackW ;
2009-12-05 15:01:29 +01:00
g_fProjectionMatrix [ 1 ] = 0.0f ;
2010-06-05 03:38:22 +02:00
g_fProjectionMatrix [ 2 ] = xfregs . rawProjection [ 1 ] ;
g_fProjectionMatrix [ 3 ] = 0.0f ;
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
g_fProjectionMatrix [ 4 ] = 0.0f ;
g_fProjectionMatrix [ 5 ] = xfregs . rawProjection [ 2 ] * g_ActiveConfig . fAspectRatioHackH ;
g_fProjectionMatrix [ 6 ] = xfregs . rawProjection [ 3 ] ;
g_fProjectionMatrix [ 7 ] = 0.0f ;
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
g_fProjectionMatrix [ 8 ] = 0.0f ;
g_fProjectionMatrix [ 9 ] = 0.0f ;
g_fProjectionMatrix [ 10 ] = xfregs . rawProjection [ 4 ] ;
2009-04-10 12:25:53 +02:00
2009-03-06 22:56:13 +01:00
g_fProjectionMatrix [ 11 ] = xfregs . rawProjection [ 5 ] ;
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
g_fProjectionMatrix [ 12 ] = 0.0f ;
g_fProjectionMatrix [ 13 ] = 0.0f ;
2008-12-08 06:25:12 +01:00
// donkopunchstania: GC GPU rounds differently?
// -(1 + epsilon) so objects are clipped as they are on the real HW
2010-06-05 03:38:22 +02:00
g_fProjectionMatrix [ 14 ] = - 1.00000011921f ;
g_fProjectionMatrix [ 15 ] = 0.0f ;
2009-02-15 21:49:59 +01:00
SETSTAT_FT ( stats . gproj_0 , g_fProjectionMatrix [ 0 ] ) ;
SETSTAT_FT ( stats . gproj_1 , g_fProjectionMatrix [ 1 ] ) ;
SETSTAT_FT ( stats . gproj_2 , g_fProjectionMatrix [ 2 ] ) ;
SETSTAT_FT ( stats . gproj_3 , g_fProjectionMatrix [ 3 ] ) ;
SETSTAT_FT ( stats . gproj_4 , g_fProjectionMatrix [ 4 ] ) ;
SETSTAT_FT ( stats . gproj_5 , g_fProjectionMatrix [ 5 ] ) ;
SETSTAT_FT ( stats . gproj_6 , g_fProjectionMatrix [ 6 ] ) ;
SETSTAT_FT ( stats . gproj_7 , g_fProjectionMatrix [ 7 ] ) ;
SETSTAT_FT ( stats . gproj_8 , g_fProjectionMatrix [ 8 ] ) ;
SETSTAT_FT ( stats . gproj_9 , g_fProjectionMatrix [ 9 ] ) ;
SETSTAT_FT ( stats . gproj_10 , g_fProjectionMatrix [ 10 ] ) ;
SETSTAT_FT ( stats . gproj_11 , g_fProjectionMatrix [ 11 ] ) ;
SETSTAT_FT ( stats . gproj_12 , g_fProjectionMatrix [ 12 ] ) ;
SETSTAT_FT ( stats . gproj_13 , g_fProjectionMatrix [ 13 ] ) ;
SETSTAT_FT ( stats . gproj_14 , g_fProjectionMatrix [ 14 ] ) ;
SETSTAT_FT ( stats . gproj_15 , g_fProjectionMatrix [ 15 ] ) ;
2010-06-05 03:38:22 +02:00
}
else
2009-07-26 11:52:35 +02:00
{
// Orthographic Projection
2010-06-05 03:38:22 +02:00
g_fProjectionMatrix [ 0 ] = xfregs . rawProjection [ 0 ] ;
g_fProjectionMatrix [ 1 ] = 0.0f ;
g_fProjectionMatrix [ 2 ] = 0.0f ;
g_fProjectionMatrix [ 3 ] = xfregs . rawProjection [ 1 ] ;
g_fProjectionMatrix [ 4 ] = 0.0f ;
g_fProjectionMatrix [ 5 ] = xfregs . rawProjection [ 2 ] ;
g_fProjectionMatrix [ 6 ] = 0.0f ;
g_fProjectionMatrix [ 7 ] = xfregs . rawProjection [ 3 ] ;
g_fProjectionMatrix [ 8 ] = 0.0f ;
g_fProjectionMatrix [ 9 ] = 0.0f ;
2011-01-30 01:56:33 +01:00
g_fProjectionMatrix [ 10 ] = ( g_ProjHack1 . value + xfregs . rawProjection [ 4 ] ) * ( ( g_ProjHack1 . sign = = 0 ) ? 1.0f : g_ProjHack1 . sign ) ;
g_fProjectionMatrix [ 11 ] = ( g_ProjHack2 . value + xfregs . rawProjection [ 5 ] ) * ( ( g_ProjHack2 . sign = = 0 ) ? 1.0f : g_ProjHack2 . sign ) ;
2010-06-05 03:38:22 +02:00
g_fProjectionMatrix [ 12 ] = 0.0f ;
g_fProjectionMatrix [ 13 ] = 0.0f ;
2009-02-15 21:49:59 +01:00
2010-11-11 10:22:19 +01:00
/*
projection hack for metroid other m . . . attempt to remove black projection layer from cut scenes .
g_fProjectionMatrix [ 15 ] = 1.0f was the default setting before
this hack was added . . . setting g_fProjectionMatrix [ 14 ] to - 1 might make the hack more stable , needs more testing .
Only works for OGL and DX9 . . . this is not helping DX11
*/
g_fProjectionMatrix [ 14 ] = 0.0f ;
2011-01-29 22:13:56 +01:00
g_fProjectionMatrix [ 15 ] = ( g_ProjHack3 & & xfregs . rawProjection [ 0 ] = = 2.0f ? 0.0f : 1.0f ) ; //causes either the efb copy or bloom layer not to show if proj hack enabled
2010-11-11 10:22:19 +01:00
2009-02-15 21:49:59 +01:00
SETSTAT_FT ( stats . g2proj_0 , g_fProjectionMatrix [ 0 ] ) ;
SETSTAT_FT ( stats . g2proj_1 , g_fProjectionMatrix [ 1 ] ) ;
SETSTAT_FT ( stats . g2proj_2 , g_fProjectionMatrix [ 2 ] ) ;
SETSTAT_FT ( stats . g2proj_3 , g_fProjectionMatrix [ 3 ] ) ;
SETSTAT_FT ( stats . g2proj_4 , g_fProjectionMatrix [ 4 ] ) ;
SETSTAT_FT ( stats . g2proj_5 , g_fProjectionMatrix [ 5 ] ) ;
SETSTAT_FT ( stats . g2proj_6 , g_fProjectionMatrix [ 6 ] ) ;
SETSTAT_FT ( stats . g2proj_7 , g_fProjectionMatrix [ 7 ] ) ;
SETSTAT_FT ( stats . g2proj_8 , g_fProjectionMatrix [ 8 ] ) ;
SETSTAT_FT ( stats . g2proj_9 , g_fProjectionMatrix [ 9 ] ) ;
SETSTAT_FT ( stats . g2proj_10 , g_fProjectionMatrix [ 10 ] ) ;
SETSTAT_FT ( stats . g2proj_11 , g_fProjectionMatrix [ 11 ] ) ;
SETSTAT_FT ( stats . g2proj_12 , g_fProjectionMatrix [ 12 ] ) ;
SETSTAT_FT ( stats . g2proj_13 , g_fProjectionMatrix [ 13 ] ) ;
SETSTAT_FT ( stats . g2proj_14 , g_fProjectionMatrix [ 14 ] ) ;
SETSTAT_FT ( stats . g2proj_15 , g_fProjectionMatrix [ 15 ] ) ;
2009-03-02 22:17:16 +01:00
SETSTAT_FT ( stats . proj_0 , xfregs . rawProjection [ 0 ] ) ;
SETSTAT_FT ( stats . proj_1 , xfregs . rawProjection [ 1 ] ) ;
SETSTAT_FT ( stats . proj_2 , xfregs . rawProjection [ 2 ] ) ;
SETSTAT_FT ( stats . proj_3 , xfregs . rawProjection [ 3 ] ) ;
SETSTAT_FT ( stats . proj_4 , xfregs . rawProjection [ 4 ] ) ;
SETSTAT_FT ( stats . proj_5 , xfregs . rawProjection [ 5 ] ) ;
SETSTAT_FT ( stats . proj_6 , xfregs . rawProjection [ 6 ] ) ;
2010-06-05 03:38:22 +02:00
}
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
PRIM_LOG ( " Projection: %f %f %f %f %f %f \n " , xfregs . rawProjection [ 0 ] , xfregs . rawProjection [ 1 ] , xfregs . rawProjection [ 2 ] , xfregs . rawProjection [ 3 ] , xfregs . rawProjection [ 4 ] , xfregs . rawProjection [ 5 ] ) ;
2009-04-19 12:10:45 +02:00
2010-09-23 04:17:48 +02:00
if ( ( g_ActiveConfig . bFreeLook | | g_ActiveConfig . bAnaglyphStereo ) & & xfregs . rawProjection [ 6 ] = = 0 )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
Matrix44 mtxA ;
Matrix44 mtxB ;
Matrix44 viewMtx ;
Matrix44 : : Translate ( mtxA , s_fViewTranslationVector ) ;
Matrix44 : : LoadMatrix33 ( mtxB , s_viewRotationMatrix ) ;
Matrix44 : : Multiply ( mtxB , mtxA , viewMtx ) ; // view = rotation x translation
Matrix44 : : Set ( mtxB , g_fProjectionMatrix ) ;
Matrix44 : : Multiply ( mtxB , viewMtx , mtxA ) ; // mtxA = projection x view
2011-05-12 04:14:45 +02:00
Matrix44 : : Multiply ( s_viewportCorrection , mtxA , mtxB ) ; // mtxB = viewportCorrection x mtxA
2010-06-05 03:38:22 +02:00
2011-05-12 04:14:45 +02:00
SetMultiVSConstant4fv ( C_PROJECTION , 4 , mtxB . data ) ;
2010-06-05 03:38:22 +02:00
}
else
2009-07-26 11:52:35 +02:00
{
2011-05-12 04:14:45 +02:00
Matrix44 projMtx ;
Matrix44 : : Set ( projMtx , g_fProjectionMatrix ) ;
Matrix44 correctedMtx ;
Matrix44 : : Multiply ( s_viewportCorrection , projMtx , correctedMtx ) ;
SetMultiVSConstant4fv ( C_PROJECTION , 4 , correctedMtx . data ) ;
2010-06-05 03:38:22 +02:00
}
}
2008-12-08 06:25:12 +01:00
}
2008-12-26 11:43:18 +01:00
void VertexShaderManager : : InvalidateXFRange ( int start , int end )
2008-12-08 06:25:12 +01:00
{
2010-06-05 03:38:22 +02:00
if ( ( ( u32 ) start > = ( u32 ) MatrixIndexA . PosNormalMtxIdx * 4 & &
2009-07-26 11:52:35 +02:00
( u32 ) start < ( u32 ) MatrixIndexA . PosNormalMtxIdx * 4 + 12 ) | |
2010-06-05 03:38:22 +02:00
( ( u32 ) start > = XFMEM_NORMALMATRICES + ( ( u32 ) MatrixIndexA . PosNormalMtxIdx & 31 ) * 3 & &
2009-07-26 11:52:35 +02:00
( u32 ) start < XFMEM_NORMALMATRICES + ( ( u32 ) MatrixIndexA . PosNormalMtxIdx & 31 ) * 3 + 9 ) ) {
2010-06-05 03:38:22 +02:00
bPosNormalMatrixChanged = true ;
}
if ( ( ( u32 ) start > = ( u32 ) MatrixIndexA . Tex0MtxIdx * 4 & & ( u32 ) start < ( u32 ) MatrixIndexA . Tex0MtxIdx * 4 + 12 ) | |
( ( u32 ) start > = ( u32 ) MatrixIndexA . Tex1MtxIdx * 4 & & ( u32 ) start < ( u32 ) MatrixIndexA . Tex1MtxIdx * 4 + 12 ) | |
( ( u32 ) start > = ( u32 ) MatrixIndexA . Tex2MtxIdx * 4 & & ( u32 ) start < ( u32 ) MatrixIndexA . Tex2MtxIdx * 4 + 12 ) | |
( ( u32 ) start > = ( u32 ) MatrixIndexA . Tex3MtxIdx * 4 & & ( u32 ) start < ( u32 ) MatrixIndexA . Tex3MtxIdx * 4 + 12 ) ) {
bTexMatricesChanged [ 0 ] = true ;
}
if ( ( ( u32 ) start > = ( u32 ) MatrixIndexB . Tex4MtxIdx * 4 & & ( u32 ) start < ( u32 ) MatrixIndexB . Tex4MtxIdx * 4 + 12 ) | |
( ( u32 ) start > = ( u32 ) MatrixIndexB . Tex5MtxIdx * 4 & & ( u32 ) start < ( u32 ) MatrixIndexB . Tex5MtxIdx * 4 + 12 ) | |
( ( u32 ) start > = ( u32 ) MatrixIndexB . Tex6MtxIdx * 4 & & ( u32 ) start < ( u32 ) MatrixIndexB . Tex6MtxIdx * 4 + 12 ) | |
( ( u32 ) start > = ( u32 ) MatrixIndexB . Tex7MtxIdx * 4 & & ( u32 ) start < ( u32 ) MatrixIndexB . Tex7MtxIdx * 4 + 12 ) ) {
bTexMatricesChanged [ 1 ] = true ;
}
if ( start < XFMEM_POSMATRICES_END )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
if ( nTransformMatricesChanged [ 0 ] = = - 1 )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
nTransformMatricesChanged [ 0 ] = start ;
nTransformMatricesChanged [ 1 ] = end > XFMEM_POSMATRICES_END ? XFMEM_POSMATRICES_END : end ;
}
else
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
if ( nTransformMatricesChanged [ 0 ] > start ) nTransformMatricesChanged [ 0 ] = start ;
if ( nTransformMatricesChanged [ 1 ] < end ) nTransformMatricesChanged [ 1 ] = end > XFMEM_POSMATRICES_END ? XFMEM_POSMATRICES_END : end ;
}
}
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
if ( start < XFMEM_NORMALMATRICES_END & & end > XFMEM_NORMALMATRICES )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
int _start = start < XFMEM_NORMALMATRICES ? 0 : start - XFMEM_NORMALMATRICES ;
int _end = end < XFMEM_NORMALMATRICES_END ? end - XFMEM_NORMALMATRICES : XFMEM_NORMALMATRICES_END - XFMEM_NORMALMATRICES ;
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
if ( nNormalMatricesChanged [ 0 ] = = - 1 )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
nNormalMatricesChanged [ 0 ] = _start ;
nNormalMatricesChanged [ 1 ] = _end ;
}
else
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
if ( nNormalMatricesChanged [ 0 ] > _start ) nNormalMatricesChanged [ 0 ] = _start ;
if ( nNormalMatricesChanged [ 1 ] < _end ) nNormalMatricesChanged [ 1 ] = _end ;
}
}
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
if ( start < XFMEM_POSTMATRICES_END & & end > XFMEM_POSTMATRICES )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
int _start = start < XFMEM_POSTMATRICES ? XFMEM_POSTMATRICES : start - XFMEM_POSTMATRICES ;
int _end = end < XFMEM_POSTMATRICES_END ? end - XFMEM_POSTMATRICES : XFMEM_POSTMATRICES_END - XFMEM_POSTMATRICES ;
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
if ( nPostTransformMatricesChanged [ 0 ] = = - 1 )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
nPostTransformMatricesChanged [ 0 ] = _start ;
nPostTransformMatricesChanged [ 1 ] = _end ;
}
else
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
if ( nPostTransformMatricesChanged [ 0 ] > _start ) nPostTransformMatricesChanged [ 0 ] = _start ;
if ( nPostTransformMatricesChanged [ 1 ] < _end ) nPostTransformMatricesChanged [ 1 ] = _end ;
}
}
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
if ( start < XFMEM_LIGHTS_END & & end > XFMEM_LIGHTS )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
int _start = start < XFMEM_LIGHTS ? XFMEM_LIGHTS : start - XFMEM_LIGHTS ;
int _end = end < XFMEM_LIGHTS_END ? end - XFMEM_LIGHTS : XFMEM_LIGHTS_END - XFMEM_LIGHTS ;
2008-12-08 06:25:12 +01:00
2010-06-05 03:38:22 +02:00
if ( nLightsChanged [ 0 ] = = - 1 )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
nLightsChanged [ 0 ] = _start ;
nLightsChanged [ 1 ] = _end ;
}
else
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
if ( nLightsChanged [ 0 ] > _start ) nLightsChanged [ 0 ] = _start ;
if ( nLightsChanged [ 1 ] < _end ) nLightsChanged [ 1 ] = _end ;
}
}
2008-12-08 06:25:12 +01:00
}
2008-12-26 11:43:18 +01:00
void VertexShaderManager : : SetTexMatrixChangedA ( u32 Value )
2008-12-08 06:25:12 +01:00
{
2010-06-05 03:38:22 +02:00
if ( MatrixIndexA . Hex ! = Value )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
VertexManager : : Flush ( ) ;
if ( MatrixIndexA . PosNormalMtxIdx ! = ( Value & 0x3f ) )
bPosNormalMatrixChanged = true ;
bTexMatricesChanged [ 0 ] = true ;
MatrixIndexA . Hex = Value ;
}
2008-12-08 06:25:12 +01:00
}
2008-12-26 11:43:18 +01:00
void VertexShaderManager : : SetTexMatrixChangedB ( u32 Value )
2008-12-08 06:25:12 +01:00
{
2010-06-05 03:38:22 +02:00
if ( MatrixIndexB . Hex ! = Value )
2009-07-26 11:52:35 +02:00
{
2010-06-05 03:38:22 +02:00
VertexManager : : Flush ( ) ;
bTexMatricesChanged [ 1 ] = true ;
MatrixIndexB . Hex = Value ;
}
2008-12-08 06:25:12 +01:00
}
2008-12-26 11:43:18 +01:00
void VertexShaderManager : : SetViewportChanged ( )
2008-12-08 06:25:12 +01:00
{
2010-06-05 03:38:22 +02:00
bViewportChanged = true ;
2008-12-08 06:25:12 +01:00
}
2011-02-05 19:25:34 +01:00
void VertexShaderManager : : SetProjectionChanged ( )
2008-12-08 06:25:12 +01:00
{
2010-06-05 03:38:22 +02:00
bProjectionChanged = true ;
2008-12-08 06:25:12 +01:00
}
2011-02-05 19:25:34 +01:00
void VertexShaderManager : : SetMaterialColorChanged ( int index )
2008-12-08 06:25:12 +01:00
{
2009-02-22 19:13:50 +01:00
nMaterialsChanged | = ( 1 < < index ) ;
2009-02-08 23:08:20 +01:00
}
2009-04-19 12:10:45 +02:00
void VertexShaderManager : : TranslateView ( float x , float y )
{
2010-06-05 03:38:22 +02:00
float result [ 3 ] ;
float vector [ 3 ] = { x , 0 , y } ;
2009-04-19 12:10:45 +02:00
2010-06-05 03:38:22 +02:00
Matrix33 : : Multiply ( s_viewInvRotationMatrix , vector , result ) ;
2009-04-19 12:10:45 +02:00
2010-06-05 03:38:22 +02:00
for ( int i = 0 ; i < 3 ; i + + )
s_fViewTranslationVector [ i ] + = result [ i ] ;
2009-04-19 12:10:45 +02:00
2010-06-05 03:38:22 +02:00
bProjectionChanged = true ;
2009-04-19 12:10:45 +02:00
}
void VertexShaderManager : : RotateView ( float x , float y )
{
2010-06-05 03:38:22 +02:00
s_fViewRotation [ 0 ] + = x ;
s_fViewRotation [ 1 ] + = y ;
2009-04-19 12:10:45 +02:00
2010-06-05 03:38:22 +02:00
Matrix33 mx ;
Matrix33 my ;
Matrix33 : : RotateX ( mx , s_fViewRotation [ 1 ] ) ;
Matrix33 : : RotateY ( my , s_fViewRotation [ 0 ] ) ;
Matrix33 : : Multiply ( mx , my , s_viewRotationMatrix ) ;
2009-04-19 12:10:45 +02:00
2010-06-05 03:38:22 +02:00
// reverse rotation
Matrix33 : : RotateX ( mx , - s_fViewRotation [ 1 ] ) ;
Matrix33 : : RotateY ( my , - s_fViewRotation [ 0 ] ) ;
Matrix33 : : Multiply ( my , mx , s_viewInvRotationMatrix ) ;
2009-04-19 12:10:45 +02:00
2010-06-05 03:38:22 +02:00
bProjectionChanged = true ;
2009-04-19 12:10:45 +02:00
}
void VertexShaderManager : : ResetView ( )
{
2010-06-05 03:38:22 +02:00
memset ( s_fViewTranslationVector , 0 , sizeof ( s_fViewTranslationVector ) ) ;
Matrix33 : : LoadIdentity ( s_viewRotationMatrix ) ;
Matrix33 : : LoadIdentity ( s_viewInvRotationMatrix ) ;
s_fViewRotation [ 0 ] = s_fViewRotation [ 1 ] = 0.0f ;
2009-04-19 12:10:45 +02:00
2010-06-05 03:38:22 +02:00
bProjectionChanged = true ;
2009-04-19 12:10:45 +02:00
}