mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Merge pull request #535 from bunnei/color-modifiers
Implement color/alpha modifiers
This commit is contained in:
		
						commit
						1576a318f2
					
				
					 3 changed files with 103 additions and 73 deletions
				
			
		|  | @ -457,27 +457,41 @@ public: | |||
|     const T& b() const { return z; } | ||||
|     const T& a() const { return w; } | ||||
| 
 | ||||
|     // swizzlers - create a subvector of specific components
 | ||||
|     // Swizzlers - Create a subvector of specific components
 | ||||
|     // e.g. Vec2 uv() { return Vec2(x,y); }
 | ||||
|     // _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all component names (x<->r) and permutations (xy<->yx)
 | ||||
| 
 | ||||
|     // _DEFINE_SWIZZLER2 defines a single such function
 | ||||
|     // DEFINE_SWIZZLER2_COMP1 defines one-component functions for all component names (x<->r) 
 | ||||
|     // DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and permutations (xy<->yx)
 | ||||
| #define _DEFINE_SWIZZLER2(a, b, name) const Vec2<T> name() const { return Vec2<T>(a, b); } | ||||
| #define DEFINE_SWIZZLER2(a, b, a2, b2) \ | ||||
| #define DEFINE_SWIZZLER2_COMP1(a, a2) \ | ||||
|     _DEFINE_SWIZZLER2(a, a, a##a); \ | ||||
|     _DEFINE_SWIZZLER2(a, a, a2##a2) | ||||
| #define DEFINE_SWIZZLER2_COMP2(a, b, a2, b2) \ | ||||
|     _DEFINE_SWIZZLER2(a, b, a##b); \ | ||||
|     _DEFINE_SWIZZLER2(a, b, a2##b2); \ | ||||
|     _DEFINE_SWIZZLER2(b, a, b##a); \ | ||||
|     _DEFINE_SWIZZLER2(b, a, b2##a2) | ||||
| 
 | ||||
|     DEFINE_SWIZZLER2(x, y, r, g); | ||||
|     DEFINE_SWIZZLER2(x, z, r, b); | ||||
|     DEFINE_SWIZZLER2(x, w, r, a); | ||||
|     DEFINE_SWIZZLER2(y, z, g, b); | ||||
|     DEFINE_SWIZZLER2(y, w, g, a); | ||||
|     DEFINE_SWIZZLER2(z, w, b, a); | ||||
| #undef DEFINE_SWIZZLER2 | ||||
|     DEFINE_SWIZZLER2_COMP2(x, y, r, g); | ||||
|     DEFINE_SWIZZLER2_COMP2(x, z, r, b); | ||||
|     DEFINE_SWIZZLER2_COMP2(x, w, r, a); | ||||
|     DEFINE_SWIZZLER2_COMP2(y, z, g, b); | ||||
|     DEFINE_SWIZZLER2_COMP2(y, w, g, a); | ||||
|     DEFINE_SWIZZLER2_COMP2(z, w, b, a); | ||||
|     DEFINE_SWIZZLER2_COMP1(x, r); | ||||
|     DEFINE_SWIZZLER2_COMP1(y, g); | ||||
|     DEFINE_SWIZZLER2_COMP1(z, b); | ||||
|     DEFINE_SWIZZLER2_COMP1(w, a); | ||||
| #undef DEFINE_SWIZZLER2_COMP1 | ||||
| #undef DEFINE_SWIZZLER2_COMP2 | ||||
| #undef _DEFINE_SWIZZLER2 | ||||
| 
 | ||||
| #define _DEFINE_SWIZZLER3(a, b, c, name) const Vec3<T> name() const { return Vec3<T>(a, b, c); } | ||||
| #define DEFINE_SWIZZLER3(a, b, c, a2, b2, c2) \ | ||||
| #define DEFINE_SWIZZLER3_COMP1(a, a2) \ | ||||
|     _DEFINE_SWIZZLER3(a, a, a, a##a##a); \ | ||||
|     _DEFINE_SWIZZLER3(a, a, a, a2##a2##a2) | ||||
| #define DEFINE_SWIZZLER3_COMP3(a, b, c, a2, b2, c2) \ | ||||
|     _DEFINE_SWIZZLER3(a, b, c, a##b##c); \ | ||||
|     _DEFINE_SWIZZLER3(a, c, b, a##c##b); \ | ||||
|     _DEFINE_SWIZZLER3(b, a, c, b##a##c); \ | ||||
|  | @ -491,11 +505,16 @@ public: | |||
|     _DEFINE_SWIZZLER3(c, a, b, c2##a2##b2); \ | ||||
|     _DEFINE_SWIZZLER3(c, b, a, c2##b2##a2) | ||||
| 
 | ||||
|     DEFINE_SWIZZLER3(x, y, z, r, g, b); | ||||
|     DEFINE_SWIZZLER3(x, y, w, r, g, a); | ||||
|     DEFINE_SWIZZLER3(x, z, w, r, b, a); | ||||
|     DEFINE_SWIZZLER3(y, z, w, g, b, a); | ||||
| #undef DEFINE_SWIZZLER3 | ||||
|     DEFINE_SWIZZLER3_COMP3(x, y, z, r, g, b); | ||||
|     DEFINE_SWIZZLER3_COMP3(x, y, w, r, g, a); | ||||
|     DEFINE_SWIZZLER3_COMP3(x, z, w, r, b, a); | ||||
|     DEFINE_SWIZZLER3_COMP3(y, z, w, g, b, a); | ||||
|     DEFINE_SWIZZLER3_COMP1(x, r); | ||||
|     DEFINE_SWIZZLER3_COMP1(y, g); | ||||
|     DEFINE_SWIZZLER3_COMP1(z, b); | ||||
|     DEFINE_SWIZZLER3_COMP1(w, a); | ||||
| #undef DEFINE_SWIZZLER3_COMP1 | ||||
| #undef DEFINE_SWIZZLER3_COMP3 | ||||
| #undef _DEFINE_SWIZZLER3 | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -233,19 +233,29 @@ struct Regs { | |||
|         }; | ||||
| 
 | ||||
|         enum class ColorModifier : u32 { | ||||
|             SourceColor         = 0, | ||||
|             OneMinusSourceColor = 1, | ||||
|             SourceAlpha         = 2, | ||||
|             OneMinusSourceAlpha = 3, | ||||
|             SourceColor         = 0x0, | ||||
|             OneMinusSourceColor = 0x1, | ||||
|             SourceAlpha         = 0x2, | ||||
|             OneMinusSourceAlpha = 0x3, | ||||
|             SourceRed           = 0x4, | ||||
|             OneMinusSourceRed   = 0x5, | ||||
| 
 | ||||
|             // Other values seem to be non-standard extensions
 | ||||
|             SourceGreen         = 0x8, | ||||
|             OneMinusSourceGreen = 0x9, | ||||
| 
 | ||||
|             SourceBlue          = 0xc, | ||||
|             OneMinusSourceBlue  = 0xd, | ||||
|         }; | ||||
| 
 | ||||
|         enum class AlphaModifier : u32 { | ||||
|             SourceAlpha         = 0, | ||||
|             OneMinusSourceAlpha = 1, | ||||
| 
 | ||||
|             // Other values seem to be non-standard extensions
 | ||||
|             SourceAlpha         = 0x0, | ||||
|             OneMinusSourceAlpha = 0x1, | ||||
|             SourceRed           = 0x2, | ||||
|             OneMinusSourceRed   = 0x3, | ||||
|             SourceGreen         = 0x4, | ||||
|             OneMinusSourceGreen = 0x5, | ||||
|             SourceBlue          = 0x6, | ||||
|             OneMinusSourceBlue  = 0x7, | ||||
|         }; | ||||
| 
 | ||||
|         enum class Operation : u32 { | ||||
|  |  | |||
|  | @ -260,7 +260,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||
|                 using AlphaModifier = Regs::TevStageConfig::AlphaModifier; | ||||
|                 using Operation = Regs::TevStageConfig::Operation; | ||||
| 
 | ||||
|                 auto GetColorSource = [&](Source source) -> Math::Vec4<u8> { | ||||
|                 auto GetSource = [&](Source source) -> Math::Vec4<u8> { | ||||
|                     switch (source) { | ||||
|                     case Source::PrimaryColor: | ||||
|                         return primary_color; | ||||
|  | @ -287,36 +287,8 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||
|                     } | ||||
|                 }; | ||||
| 
 | ||||
|                 auto GetAlphaSource = [&](Source source) -> u8 { | ||||
|                     switch (source) { | ||||
|                     case Source::PrimaryColor: | ||||
|                         return primary_color.a(); | ||||
| 
 | ||||
|                     case Source::Texture0: | ||||
|                         return texture_color[0].a(); | ||||
| 
 | ||||
|                     case Source::Texture1: | ||||
|                         return texture_color[1].a(); | ||||
| 
 | ||||
|                     case Source::Texture2: | ||||
|                         return texture_color[2].a(); | ||||
| 
 | ||||
|                     case Source::Constant: | ||||
|                         return tev_stage.const_a; | ||||
| 
 | ||||
|                     case Source::Previous: | ||||
|                         return combiner_output.a(); | ||||
| 
 | ||||
|                     default: | ||||
|                         LOG_ERROR(HW_GPU, "Unknown alpha combiner source %d\n", (int)source); | ||||
|                         _dbg_assert_(HW_GPU, 0); | ||||
|                         return 0; | ||||
|                     } | ||||
|                 }; | ||||
| 
 | ||||
|                 static auto GetColorModifier = [](ColorModifier factor, const Math::Vec4<u8>& values) -> Math::Vec3<u8> { | ||||
|                     switch (factor) | ||||
|                     { | ||||
|                     switch (factor) { | ||||
|                     case ColorModifier::SourceColor: | ||||
|                         return values.rgb(); | ||||
| 
 | ||||
|  | @ -324,27 +296,56 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||
|                         return (Math::Vec3<u8>(255, 255, 255) - values.rgb()).Cast<u8>(); | ||||
| 
 | ||||
|                     case ColorModifier::SourceAlpha: | ||||
|                         return { values.a(), values.a(), values.a() }; | ||||
|                         return values.aaa(); | ||||
| 
 | ||||
|                     default: | ||||
|                         LOG_ERROR(HW_GPU, "Unknown color factor %d\n", (int)factor); | ||||
|                         _dbg_assert_(HW_GPU, 0); | ||||
|                         return {}; | ||||
|                     case ColorModifier::OneMinusSourceAlpha: | ||||
|                         return (Math::Vec3<u8>(255, 255, 255) - values.aaa()).Cast<u8>(); | ||||
| 
 | ||||
|                     case ColorModifier::SourceRed: | ||||
|                         return values.rrr(); | ||||
| 
 | ||||
|                     case ColorModifier::OneMinusSourceRed: | ||||
|                         return (Math::Vec3<u8>(255, 255, 255) - values.rrr()).Cast<u8>(); | ||||
| 
 | ||||
|                     case ColorModifier::SourceGreen: | ||||
|                         return values.ggg(); | ||||
| 
 | ||||
|                     case ColorModifier::OneMinusSourceGreen: | ||||
|                         return (Math::Vec3<u8>(255, 255, 255) - values.ggg()).Cast<u8>(); | ||||
| 
 | ||||
|                     case ColorModifier::SourceBlue: | ||||
|                         return values.bbb(); | ||||
| 
 | ||||
|                     case ColorModifier::OneMinusSourceBlue: | ||||
|                         return (Math::Vec3<u8>(255, 255, 255) - values.bbb()).Cast<u8>(); | ||||
|                     } | ||||
|                 }; | ||||
| 
 | ||||
|                 static auto GetAlphaModifier = [](AlphaModifier factor, u8 value) -> u8 { | ||||
|                 static auto GetAlphaModifier = [](AlphaModifier factor, const Math::Vec4<u8>& values) -> u8 { | ||||
|                     switch (factor) { | ||||
|                     case AlphaModifier::SourceAlpha: | ||||
|                         return value; | ||||
|                         return values.a(); | ||||
| 
 | ||||
|                     case AlphaModifier::OneMinusSourceAlpha: | ||||
|                         return 255 - value; | ||||
|                         return 255 - values.a(); | ||||
| 
 | ||||
|                     default: | ||||
|                         LOG_ERROR(HW_GPU, "Unknown alpha factor %d\n", (int)factor); | ||||
|                         _dbg_assert_(HW_GPU, 0); | ||||
|                         return 0; | ||||
|                     case AlphaModifier::SourceRed: | ||||
|                         return values.r(); | ||||
| 
 | ||||
|                     case AlphaModifier::OneMinusSourceRed: | ||||
|                         return 255 - values.r(); | ||||
| 
 | ||||
|                     case AlphaModifier::SourceGreen: | ||||
|                         return values.g(); | ||||
| 
 | ||||
|                     case AlphaModifier::OneMinusSourceGreen: | ||||
|                         return 255 - values.g(); | ||||
| 
 | ||||
|                     case AlphaModifier::SourceBlue: | ||||
|                         return values.b(); | ||||
| 
 | ||||
|                     case AlphaModifier::OneMinusSourceBlue: | ||||
|                         return 255 - values.b(); | ||||
|                     } | ||||
|                 }; | ||||
| 
 | ||||
|  | @ -414,17 +415,17 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||
|                 //       combiner_output.rgb(), but instead store it in a temporary variable until
 | ||||
|                 //       alpha combining has been done.
 | ||||
|                 Math::Vec3<u8> color_result[3] = { | ||||
|                     GetColorModifier(tev_stage.color_modifier1, GetColorSource(tev_stage.color_source1)), | ||||
|                     GetColorModifier(tev_stage.color_modifier2, GetColorSource(tev_stage.color_source2)), | ||||
|                     GetColorModifier(tev_stage.color_modifier3, GetColorSource(tev_stage.color_source3)) | ||||
|                     GetColorModifier(tev_stage.color_modifier1, GetSource(tev_stage.color_source1)), | ||||
|                     GetColorModifier(tev_stage.color_modifier2, GetSource(tev_stage.color_source2)), | ||||
|                     GetColorModifier(tev_stage.color_modifier3, GetSource(tev_stage.color_source3)) | ||||
|                 }; | ||||
|                 auto color_output = ColorCombine(tev_stage.color_op, color_result); | ||||
| 
 | ||||
|                 // alpha combiner
 | ||||
|                 std::array<u8,3> alpha_result = { | ||||
|                     GetAlphaModifier(tev_stage.alpha_modifier1, GetAlphaSource(tev_stage.alpha_source1)), | ||||
|                     GetAlphaModifier(tev_stage.alpha_modifier2, GetAlphaSource(tev_stage.alpha_source2)), | ||||
|                     GetAlphaModifier(tev_stage.alpha_modifier3, GetAlphaSource(tev_stage.alpha_source3)) | ||||
|                     GetAlphaModifier(tev_stage.alpha_modifier1, GetSource(tev_stage.alpha_source1)), | ||||
|                     GetAlphaModifier(tev_stage.alpha_modifier2, GetSource(tev_stage.alpha_source2)), | ||||
|                     GetAlphaModifier(tev_stage.alpha_modifier3, GetSource(tev_stage.alpha_source3)) | ||||
|                 }; | ||||
|                 auto alpha_output = AlphaCombine(tev_stage.alpha_op, alpha_result); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue