2009-07-28 21:32:10 +00:00
// Copyright (C) 2003 Dolphin Project.
2008-12-08 05:25:12 +00: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 11:23:59 +00:00
# include "Common.h"
2009-09-13 10:18:01 +00:00
# include "VideoConfig.h"
2009-04-19 10:10:45 +00:00
# include "MathUtil.h"
2008-12-08 05:25:12 +00:00
# include "Profiler.h"
2008-12-26 11:23:59 +00:00
# include <cmath>
2008-12-08 05:25:12 +00:00
# include "Statistics.h"
2008-12-26 11:23:59 +00:00
2008-12-26 17:33:53 +00:00
# include "VertexShaderGen.h"
2008-12-08 05:25:12 +00:00
# include "VertexShaderManager.h"
2009-06-22 09:31:30 +00:00
# include "BPMemory.h"
2008-12-26 12:47:32 +00:00
# include "CPMemory.h"
2008-12-08 05:25:12 +00:00
# include "XFMemory.h"
2008-12-26 12:47:32 +00:00
# include "VideoCommon.h"
2010-10-03 00:41:06 +00:00
# include "VertexManagerBase.h"
2008-12-08 05:25:12 +00:00
2009-06-28 20:04:07 +00:00
static float GC_ALIGNED16 ( s_fMaterials [ 16 ] ) ;
float GC_ALIGNED16 ( g_fProjectionMatrix [ 16 ] ) ;
2008-12-08 05:25:12 +00: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
2009-04-19 10:10:45 +00:00
static Matrix33 s_viewRotationMatrix ;
static Matrix33 s_viewInvRotationMatrix ;
static float s_fViewTranslationVector [ 3 ] ;
static float s_fViewRotation [ 2 ] ;
2008-12-26 12:47:32 +00:00
void UpdateViewport ( ) ;
2008-12-08 05:25:12 +00:00
2009-12-05 13:56:23 +00:00
namespace
{
// Control Variables
static bool g_ProjHack0 ;
static ProjectionHack g_ProjHack1 ;
static ProjectionHack g_ProjHack2 ;
2010-11-11 09:22:19 +00:00
static ProjectionHack g_ProjHack3 ;
2009-12-05 13:56:23 +00:00
} // Namespace
void UpdateProjectionHack ( int iPhackvalue )
{
2010-11-11 09:22:19 +00:00
bool bProjHack1 = 0 , bPhackvalue1 = 0 , bPhackvalue2 = 0 , bPhackvalue3 = 0 ;
2009-12-05 14:01:29 +00:00
float fhackvalue1 = 0 , fhackvalue2 = 0 ;
2009-12-05 13:56:23 +00:00
switch ( iPhackvalue )
{
case PROJECTION_HACK_NONE :
bProjHack1 = 0 ;
bPhackvalue1 = 0 ;
bPhackvalue2 = 0 ;
2010-11-11 09:22:19 +00:00
bPhackvalue3 = 0 ;
2009-12-05 13:56:23 +00:00
break ;
case PROJECTION_HACK_ZELDA_TP_BLOOM_HACK :
bPhackvalue1 = 1 ;
bProjHack1 = 1 ;
break ;
case PROJECTION_HACK_SONIC_AND_THE_BLACK_KNIGHT :
bPhackvalue1 = 1 ;
fhackvalue1 = 0.00002f ;
bPhackvalue2 = 1 ;
fhackvalue2 = 1.999980f ;
break ;
case PROJECTION_HACK_BLEACH_VERSUS_CRUSADE :
bPhackvalue2 = 1 ;
fhackvalue2 = 0.5f ;
bPhackvalue1 = 0 ;
bProjHack1 = 0 ;
break ;
2010-04-15 09:23:59 +00:00
case PROJECTION_HACK_SKIES_OF_ARCADIA :
bPhackvalue1 = 1 ;
fhackvalue1 = 0.04f ;
bPhackvalue2 = 0 ;
bProjHack1 = 0 ;
break ;
2010-11-11 09:22:19 +00:00
case PROJECTION_HACK_METROID_OTHER_M : //temp fix for black screens during cut scenes
bPhackvalue3 = 1 ;
break ;
2010-04-02 21:28:56 +00:00
/* // Unused - kept for reference
2009-12-05 13:56:23 +00:00
case PROJECTION_HACK_FINAL_FANTASY_CC_ECHO_OF_TIME :
bPhackvalue1 = 1 ;
fhackvalue1 = 0.8f ;
bPhackvalue2 = 1 ;
fhackvalue2 = 1.2f ;
bProjHack1 = 0 ;
break ;
case PROJECTION_HACK_HARVESTMOON_MM :
bPhackvalue1 = 1 ;
fhackvalue1 = 0.0075f ;
bPhackvalue2 = 0 ;
bProjHack1 = 0 ;
break ;
case PROJECTION_HACK_BATEN_KAITOS :
bPhackvalue1 = 1 ;
fhackvalue1 = 0.0026f ;
bPhackvalue2 = 1 ;
fhackvalue2 = 1.9974f ;
bProjHack1 = 1 ;
break ;
case PROJECTION_HACK_BATEN_KAITOS_ORIGIN :
bPhackvalue1 = 1 ;
fhackvalue1 = 0.0012f ;
bPhackvalue2 = 1 ;
fhackvalue2 = 1.9988f ;
bProjHack1 = 1 ;
break ;
2010-04-02 21:28:56 +00:00
*/
2009-12-05 13:56:23 +00:00
}
// Set the projections hacks
2009-12-05 14:01:29 +00:00
g_ProjHack0 = bProjHack1 ;
g_ProjHack1 = ProjectionHack ( bPhackvalue1 = = 0 ? false : true , fhackvalue1 ) ;
g_ProjHack2 = ProjectionHack ( bPhackvalue2 = = 0 ? false : true , fhackvalue2 ) ;
2010-11-11 09:22:19 +00:00
g_ProjHack3 = ProjectionHack ( bPhackvalue3 , 0 ) ;
2009-12-05 13:56:23 +00:00
}
2008-12-26 10:43:18 +00:00
void VertexShaderManager : : Init ( )
2008-12-08 05:25:12 +00:00
{
2009-09-15 21:49:15 +00:00
Dirty ( ) ;
memset ( & xfregs , 0 , sizeof ( xfregs ) ) ;
2010-06-05 01:38:22 +00:00
memset ( xfmem , 0 , sizeof ( xfmem ) ) ;
ResetView ( ) ;
2008-12-26 10:43:18 +00:00
}
2008-12-08 05:25:12 +00:00
2008-12-26 10:43:18 +00:00
void VertexShaderManager : : Shutdown ( )
{
2008-12-08 05:25:12 +00:00
}
2009-09-15 21:49:15 +00: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 05:25:12 +00:00
// Syncs the shader constant buffers with xfmem
2009-07-26 09:52:35 +00:00
// TODO: A cleaner way to control the matricies without making a mess in the parameters field
2009-08-15 07:20:37 +00:00
void VertexShaderManager : : SetConstants ( )
2008-12-08 05:25:12 +00:00
{
2010-06-05 01:38:22 +00:00
if ( nTransformMatricesChanged [ 0 ] > = 0 )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
int startn = nTransformMatricesChanged [ 0 ] / 4 ;
int endn = ( nTransformMatricesChanged [ 1 ] + 3 ) / 4 ;
const float * pstart = ( const float * ) & xfmem [ startn * 4 ] ;
2009-09-12 15:00:08 +00:00
SetMultiVSConstant4fv ( C_TRANSFORMMATRICES + startn , endn - startn , pstart ) ;
2010-06-05 01:38:22 +00:00
nTransformMatricesChanged [ 0 ] = nTransformMatricesChanged [ 1 ] = - 1 ;
}
if ( nNormalMatricesChanged [ 0 ] > = 0 )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00: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 10:46:25 +00:00
nNormalMatricesChanged [ 0 ] = nNormalMatricesChanged [ 1 ] = - 1 ;
2010-06-05 01:38:22 +00:00
}
2008-12-08 05:25:12 +00:00
2010-06-05 01:38:22 +00:00
if ( nPostTransformMatricesChanged [ 0 ] > = 0 )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00: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 05:25:12 +00:00
2010-06-05 01:38:22 +00:00
if ( nLightsChanged [ 0 ] > = 0 )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00: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 05:25:12 +00:00
2010-06-05 01:38:22 +00:00
for ( int i = istart ; i < iend ; + + i )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
u32 color = * ( const u32 * ) ( xfmemptr + 3 ) ;
2009-09-26 12:39:12 +00:00
float NormalizationCoef = 1 / 255.0f ;
2010-06-05 01:38:22 +00:00
SetVSConstant4f ( C_LIGHTS + 5 * i ,
( ( color > > 24 ) & 0xFF ) * NormalizationCoef ,
2009-09-26 12:39:12 +00:00
( ( color > > 16 ) & 0xFF ) * NormalizationCoef ,
( ( color > > 8 ) & 0xFF ) * NormalizationCoef ,
( ( color ) & 0xFF ) * NormalizationCoef ) ;
2010-06-05 01:38:22 +00:00
xfmemptr + = 4 ;
2009-07-26 09:52:35 +00:00
2010-06-05 01:38:22 +00:00
for ( int j = 0 ; j < 4 ; + + j , xfmemptr + = 3 )
2009-07-26 09:52:35 +00:00
{
2008-12-08 05:25:12 +00:00
if ( j = = 1 & &
fabs ( xfmemptr [ 0 ] ) < 0.00001f & &
fabs ( xfmemptr [ 1 ] ) < 0.00001f & &
2010-06-05 01:38:22 +00:00
fabs ( xfmemptr [ 2 ] ) < 0.00001f )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00: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 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
for ( int i = 0 ; i < 4 ; + + i )
if ( nMaterialsChanged & ( 1 < < i ) )
SetVSConstant4fv ( C_MATERIALS + i , & s_fMaterials [ 4 * i ] ) ;
2009-07-26 09:52:35 +00:00
2010-06-05 01:38:22 +00:00
nMaterialsChanged = 0 ;
}
2008-12-08 05:25:12 +00:00
2010-06-05 01:38:22 +00:00
if ( bPosNormalMatrixChanged )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
bPosNormalMatrixChanged = false ;
2008-12-08 05:25:12 +00:00
2010-06-05 01:38:22 +00: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 05:25:12 +00:00
2010-06-05 01:38:22 +00:00
SetMultiVSConstant4fv ( C_POSNORMALMATRIX , 3 , pos ) ;
2009-09-19 10:46:25 +00:00
SetMultiVSConstant3fv ( C_POSNORMALMATRIX + 3 , 3 , norm ) ;
2009-09-12 15:00:08 +00:00
}
2008-12-08 05:25:12 +00:00
2010-06-05 01:38:22 +00:00
if ( bTexMatricesChanged [ 0 ] )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
bTexMatricesChanged [ 0 ] = false ;
const float * fptrs [ ] =
2009-07-26 09:52:35 +00:00
{
2009-09-12 15:00:08 +00:00
( const float * ) xfmem + MatrixIndexA . Tex0MtxIdx * 4 , ( const float * ) xfmem + MatrixIndexA . Tex1MtxIdx * 4 ,
2010-06-05 01:38:22 +00:00
( const float * ) xfmem + MatrixIndexA . Tex2MtxIdx * 4 , ( const float * ) xfmem + MatrixIndexA . Tex3MtxIdx * 4
2008-12-08 05:25:12 +00:00
} ;
2010-06-05 01:38:22 +00:00
for ( int i = 0 ; i < 4 ; + + i )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
SetMultiVSConstant4fv ( C_TEXMATRICES + 3 * i , 3 , fptrs [ i ] ) ;
}
}
2008-12-08 05:25:12 +00:00
2010-06-05 01:38:22 +00:00
if ( bTexMatricesChanged [ 1 ] )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
bTexMatricesChanged [ 1 ] = false ;
const float * fptrs [ ] = {
2009-09-12 15:00:08 +00:00
( const float * ) xfmem + MatrixIndexB . Tex4MtxIdx * 4 , ( const float * ) xfmem + MatrixIndexB . Tex5MtxIdx * 4 ,
2010-06-05 01:38:22 +00:00
( const float * ) xfmem + MatrixIndexB . Tex6MtxIdx * 4 , ( const float * ) xfmem + MatrixIndexB . Tex7MtxIdx * 4
2009-09-12 15:00:08 +00:00
} ;
2008-12-08 05:25:12 +00:00
2010-06-05 01:38:22 +00:00
for ( int i = 0 ; i < 4 ; + + i )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
SetMultiVSConstant4fv ( C_TEXMATRICES + 3 * i + 12 , 3 , fptrs [ i ] ) ;
}
}
2008-12-08 05:25:12 +00:00
2010-06-05 01:38:22 +00:00
if ( bViewportChanged )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
bViewportChanged = false ;
2010-07-18 00:18:31 +00:00
SetVSConstant4f ( C_DEPTHPARAMS , xfregs . rawViewport [ 5 ] / 16777216.0f , xfregs . rawViewport [ 2 ] / 16777216.0f , 0.0f , 0.0f ) ;
2008-12-26 12:47:32 +00:00
// This is so implementation-dependent that we can't have it here.
UpdateViewport ( ) ;
2010-06-05 01:38:22 +00:00
}
2008-12-08 05:25:12 +00:00
2010-06-05 01:38:22 +00:00
if ( bProjectionChanged )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
bProjectionChanged = false ;
2009-02-15 20:49:59 +00:00
2010-06-05 01:38:22 +00:00
if ( xfregs . rawProjection [ 6 ] = = 0 )
{
2009-07-26 09:52:35 +00:00
// Perspective
2009-12-05 14:01:29 +00:00
2010-04-04 22:52:27 +00:00
g_fProjectionMatrix [ 0 ] = xfregs . rawProjection [ 0 ] * g_ActiveConfig . fAspectRatioHackW ;
2009-12-05 14:01:29 +00:00
g_fProjectionMatrix [ 1 ] = 0.0f ;
2010-06-05 01:38:22 +00:00
g_fProjectionMatrix [ 2 ] = xfregs . rawProjection [ 1 ] ;
g_fProjectionMatrix [ 3 ] = 0.0f ;
2008-12-08 05:25:12 +00:00
2010-06-05 01:38:22 +00: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 05:25:12 +00:00
2010-06-05 01:38:22 +00:00
g_fProjectionMatrix [ 8 ] = 0.0f ;
g_fProjectionMatrix [ 9 ] = 0.0f ;
g_fProjectionMatrix [ 10 ] = xfregs . rawProjection [ 4 ] ;
2009-04-10 10:25:53 +00:00
2009-03-06 21:56:13 +00:00
g_fProjectionMatrix [ 11 ] = xfregs . rawProjection [ 5 ] ;
2008-12-08 05:25:12 +00:00
2010-06-05 01:38:22 +00:00
g_fProjectionMatrix [ 12 ] = 0.0f ;
g_fProjectionMatrix [ 13 ] = 0.0f ;
2008-12-08 05:25:12 +00:00
// donkopunchstania: GC GPU rounds differently?
// -(1 + epsilon) so objects are clipped as they are on the real HW
2010-06-05 01:38:22 +00:00
g_fProjectionMatrix [ 14 ] = - 1.00000011921f ;
g_fProjectionMatrix [ 15 ] = 0.0f ;
2009-02-15 20:49:59 +00: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 01:38:22 +00:00
}
else
2009-07-26 09:52:35 +00:00
{
// Orthographic Projection
2010-06-05 01:38:22 +00: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 ;
g_fProjectionMatrix [ 10 ] = ( g_ProjHack1 . enabled ? - ( g_ProjHack1 . value + xfregs . rawProjection [ 4 ] ) : xfregs . rawProjection [ 4 ] ) ;
g_fProjectionMatrix [ 11 ] = ( g_ProjHack2 . enabled ? - ( g_ProjHack2 . value + xfregs . rawProjection [ 5 ] ) : xfregs . rawProjection [ 5 ] ) + ( g_ProjHack0 ? 0.1f : 0.0f ) ;
g_fProjectionMatrix [ 12 ] = 0.0f ;
g_fProjectionMatrix [ 13 ] = 0.0f ;
2009-02-15 20:49:59 +00:00
2010-11-11 09:22:19 +00: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 ;
g_fProjectionMatrix [ 15 ] = ( g_ProjHack3 . enabled & & xfregs . rawProjection [ 0 ] = = 2.0f ? 0.0f : 1.0f ) ; //causes either the efb copy or bloom layer not to show if proj hack enabled
2009-02-15 20:49:59 +00: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 21:17:16 +00: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 01:38:22 +00:00
}
2008-12-08 05:25:12 +00:00
2010-06-05 01:38:22 +00: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 10:10:45 +00:00
2010-09-23 02:17:48 +00:00
if ( ( g_ActiveConfig . bFreeLook | | g_ActiveConfig . bAnaglyphStereo ) & & xfregs . rawProjection [ 6 ] = = 0 )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00: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
SetMultiVSConstant4fv ( C_PROJECTION , 4 , & mtxA . data [ 0 ] ) ;
}
else
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
SetMultiVSConstant4fv ( C_PROJECTION , 4 , & g_fProjectionMatrix [ 0 ] ) ;
}
}
2008-12-08 05:25:12 +00:00
}
2008-12-26 10:43:18 +00:00
void VertexShaderManager : : InvalidateXFRange ( int start , int end )
2008-12-08 05:25:12 +00:00
{
2010-06-05 01:38:22 +00:00
if ( ( ( u32 ) start > = ( u32 ) MatrixIndexA . PosNormalMtxIdx * 4 & &
2009-07-26 09:52:35 +00:00
( u32 ) start < ( u32 ) MatrixIndexA . PosNormalMtxIdx * 4 + 12 ) | |
2010-06-05 01:38:22 +00:00
( ( u32 ) start > = XFMEM_NORMALMATRICES + ( ( u32 ) MatrixIndexA . PosNormalMtxIdx & 31 ) * 3 & &
2009-07-26 09:52:35 +00:00
( u32 ) start < XFMEM_NORMALMATRICES + ( ( u32 ) MatrixIndexA . PosNormalMtxIdx & 31 ) * 3 + 9 ) ) {
2010-06-05 01:38:22 +00: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 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
if ( nTransformMatricesChanged [ 0 ] = = - 1 )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
nTransformMatricesChanged [ 0 ] = start ;
nTransformMatricesChanged [ 1 ] = end > XFMEM_POSMATRICES_END ? XFMEM_POSMATRICES_END : end ;
}
else
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00: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 05:25:12 +00:00
2010-06-05 01:38:22 +00:00
if ( start < XFMEM_NORMALMATRICES_END & & end > XFMEM_NORMALMATRICES )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00: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 05:25:12 +00:00
2010-06-05 01:38:22 +00:00
if ( nNormalMatricesChanged [ 0 ] = = - 1 )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
nNormalMatricesChanged [ 0 ] = _start ;
nNormalMatricesChanged [ 1 ] = _end ;
}
else
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
if ( nNormalMatricesChanged [ 0 ] > _start ) nNormalMatricesChanged [ 0 ] = _start ;
if ( nNormalMatricesChanged [ 1 ] < _end ) nNormalMatricesChanged [ 1 ] = _end ;
}
}
2008-12-08 05:25:12 +00:00
2010-06-05 01:38:22 +00:00
if ( start < XFMEM_POSTMATRICES_END & & end > XFMEM_POSTMATRICES )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00: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 05:25:12 +00:00
2010-06-05 01:38:22 +00:00
if ( nPostTransformMatricesChanged [ 0 ] = = - 1 )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
nPostTransformMatricesChanged [ 0 ] = _start ;
nPostTransformMatricesChanged [ 1 ] = _end ;
}
else
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
if ( nPostTransformMatricesChanged [ 0 ] > _start ) nPostTransformMatricesChanged [ 0 ] = _start ;
if ( nPostTransformMatricesChanged [ 1 ] < _end ) nPostTransformMatricesChanged [ 1 ] = _end ;
}
}
2008-12-08 05:25:12 +00:00
2010-06-05 01:38:22 +00:00
if ( start < XFMEM_LIGHTS_END & & end > XFMEM_LIGHTS )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00: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 05:25:12 +00:00
2010-06-05 01:38:22 +00:00
if ( nLightsChanged [ 0 ] = = - 1 )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
nLightsChanged [ 0 ] = _start ;
nLightsChanged [ 1 ] = _end ;
}
else
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
if ( nLightsChanged [ 0 ] > _start ) nLightsChanged [ 0 ] = _start ;
if ( nLightsChanged [ 1 ] < _end ) nLightsChanged [ 1 ] = _end ;
}
}
2008-12-08 05:25:12 +00:00
}
2008-12-26 10:43:18 +00:00
void VertexShaderManager : : SetTexMatrixChangedA ( u32 Value )
2008-12-08 05:25:12 +00:00
{
2010-06-05 01:38:22 +00:00
if ( MatrixIndexA . Hex ! = Value )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
VertexManager : : Flush ( ) ;
if ( MatrixIndexA . PosNormalMtxIdx ! = ( Value & 0x3f ) )
bPosNormalMatrixChanged = true ;
bTexMatricesChanged [ 0 ] = true ;
MatrixIndexA . Hex = Value ;
}
2008-12-08 05:25:12 +00:00
}
2008-12-26 10:43:18 +00:00
void VertexShaderManager : : SetTexMatrixChangedB ( u32 Value )
2008-12-08 05:25:12 +00:00
{
2010-06-05 01:38:22 +00:00
if ( MatrixIndexB . Hex ! = Value )
2009-07-26 09:52:35 +00:00
{
2010-06-05 01:38:22 +00:00
VertexManager : : Flush ( ) ;
bTexMatricesChanged [ 1 ] = true ;
MatrixIndexB . Hex = Value ;
}
2008-12-08 05:25:12 +00:00
}
2009-11-19 02:28:41 +00:00
void VertexShaderManager : : SetViewport ( float * _Viewport , int constantIndex )
2008-12-08 05:25:12 +00:00
{
2009-11-19 02:28:41 +00:00
if ( constantIndex < = 0 )
{
memcpy ( xfregs . rawViewport , _Viewport , sizeof ( xfregs . rawViewport ) ) ;
}
else
{
xfregs . rawViewport [ constantIndex ] = _Viewport [ 0 ] ;
}
2010-06-05 01:38:22 +00:00
bViewportChanged = true ;
2009-10-25 23:10:30 +00:00
}
2008-12-26 10:43:18 +00:00
void VertexShaderManager : : SetViewportChanged ( )
2008-12-08 05:25:12 +00:00
{
2010-06-05 01:38:22 +00:00
bViewportChanged = true ;
2008-12-08 05:25:12 +00:00
}
2008-12-26 10:43:18 +00:00
void VertexShaderManager : : SetProjection ( float * _pProjection , int constantIndex )
2008-12-08 05:25:12 +00:00
{
2009-11-19 02:28:41 +00:00
if ( constantIndex < = 0 )
{
memcpy ( xfregs . rawProjection , _pProjection , sizeof ( xfregs . rawProjection ) ) ;
}
else
{
xfregs . rawProjection [ constantIndex ] = _pProjection [ 0 ] ;
}
2010-06-05 01:38:22 +00:00
bProjectionChanged = true ;
2008-12-08 05:25:12 +00:00
}
2008-12-26 11:23:59 +00:00
void VertexShaderManager : : SetMaterialColor ( int index , u32 data )
2008-12-08 05:25:12 +00:00
{
2009-02-22 18:13:50 +00:00
int ind = index * 4 ;
nMaterialsChanged | = ( 1 < < index ) ;
2009-09-26 12:39:12 +00:00
float NormalizationCoef = 1 / 255.0f ;
s_fMaterials [ ind + + ] = ( ( data > > 24 ) & 0xFF ) * NormalizationCoef ;
s_fMaterials [ ind + + ] = ( ( data > > 16 ) & 0xFF ) * NormalizationCoef ;
s_fMaterials [ ind + + ] = ( ( data > > 8 ) & 0xFF ) * NormalizationCoef ;
s_fMaterials [ ind ] = ( data & 0xFF ) * NormalizationCoef ;
2009-02-08 22:08:20 +00:00
}
2009-04-19 10:10:45 +00:00
void VertexShaderManager : : TranslateView ( float x , float y )
{
2010-06-05 01:38:22 +00:00
float result [ 3 ] ;
float vector [ 3 ] = { x , 0 , y } ;
2009-04-19 10:10:45 +00:00
2010-06-05 01:38:22 +00:00
Matrix33 : : Multiply ( s_viewInvRotationMatrix , vector , result ) ;
2009-04-19 10:10:45 +00:00
2010-06-05 01:38:22 +00:00
for ( int i = 0 ; i < 3 ; i + + )
s_fViewTranslationVector [ i ] + = result [ i ] ;
2009-04-19 10:10:45 +00:00
2010-06-05 01:38:22 +00:00
bProjectionChanged = true ;
2009-04-19 10:10:45 +00:00
}
void VertexShaderManager : : RotateView ( float x , float y )
{
2010-06-05 01:38:22 +00:00
s_fViewRotation [ 0 ] + = x ;
s_fViewRotation [ 1 ] + = y ;
2009-04-19 10:10:45 +00:00
2010-06-05 01:38:22 +00: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 10:10:45 +00:00
2010-06-05 01:38:22 +00:00
// reverse rotation
Matrix33 : : RotateX ( mx , - s_fViewRotation [ 1 ] ) ;
Matrix33 : : RotateY ( my , - s_fViewRotation [ 0 ] ) ;
Matrix33 : : Multiply ( my , mx , s_viewInvRotationMatrix ) ;
2009-04-19 10:10:45 +00:00
2010-06-05 01:38:22 +00:00
bProjectionChanged = true ;
2009-04-19 10:10:45 +00:00
}
void VertexShaderManager : : ResetView ( )
{
2010-06-05 01:38:22 +00: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 10:10:45 +00:00
2010-06-05 01:38:22 +00:00
bProjectionChanged = true ;
2009-04-19 10:10:45 +00:00
}