Просмотр исходного кода

Add more blend equations from 3dbrew

Darius Goad 11 лет назад
Родитель
Сommit
536958fb29
2 измененных файлов с 49 добавлено и 2 удалено
  1. 5 1
      src/video_core/pica.h
  2. 44 1
      src/video_core/rasterizer.cpp

+ 5 - 1
src/video_core/pica.h

@@ -338,7 +338,11 @@ struct Regs {
 
 
         union {
         union {
             enum BlendEquation : u32 {
             enum BlendEquation : u32 {
-                Add = 0,
+                Add             = 0,
+                Subtract        = 1,
+                ReverseSubtract = 2,
+                Min             = 3,
+                Max             = 4
             };
             };
 
 
             enum BlendFactor : u32 {
             enum BlendFactor : u32 {

+ 44 - 1
src/video_core/rasterizer.cpp

@@ -616,17 +616,60 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
                                                LookupFactorA(params.factor_source_a));
                                                LookupFactorA(params.factor_source_a));
                 auto dstfactor = Math::MakeVec(LookupFactorRGB(params.factor_dest_rgb),
                 auto dstfactor = Math::MakeVec(LookupFactorRGB(params.factor_dest_rgb),
                                                LookupFactorA(params.factor_dest_a));
                                                LookupFactorA(params.factor_dest_a));
+                                               
+                auto src_result = (combiner_output * srcfactor).Cast<int>();
+                auto dst_result = (dest * dstfactor).Cast<int>();
 
 
                 switch (params.blend_equation_rgb) {
                 switch (params.blend_equation_rgb) {
                 case params.Add:
                 case params.Add:
                 {
                 {
-                    auto result = (combiner_output * srcfactor + dest * dstfactor) / 255;
+                    auto result = (src_result + dst_result) / 255;
                     result.r() = std::min(255, result.r());
                     result.r() = std::min(255, result.r());
                     result.g() = std::min(255, result.g());
                     result.g() = std::min(255, result.g());
                     result.b() = std::min(255, result.b());
                     result.b() = std::min(255, result.b());
                     combiner_output = result.Cast<u8>();
                     combiner_output = result.Cast<u8>();
                     break;
                     break;
                 }
                 }
+                
+                case params.Subtract:
+                {
+                    auto result = (src_result - dst_result) / 255;
+                    result.r() = std::max(0, result.r());
+                    result.g() = std::max(0, result.g());
+                    result.b() = std::max(0, result.b());
+                    combiner_output = result.Cast<u8>();
+                    break;
+                }
+                
+                case params.ReverseSubtract:
+                {
+                    auto result = (dst_result - src_result) / 255;
+                    result.r() = std::max(0, result.r());
+                    result.g() = std::max(0, result.g());
+                    result.b() = std::max(0, result.b());
+                    combiner_output = result.Cast<u8>();
+                    break;
+                }
+                
+                case params.Min:
+                {
+                    Math::Vec4<int> result;
+                    result.r() = std::min(src_result.r(),dst_result.r());
+                    result.g() = std::min(src_result.g(),dst_result.g());
+                    result.b() = std::min(src_result.b(),dst_result.b());
+                    combiner_output = result.Cast<u8>();
+                    break;
+                }
+                
+                case params.Max:
+                {
+                    Math::Vec4<int> result;
+                    result.r() = std::max(src_result.r(),dst_result.r());
+                    result.g() = std::max(src_result.g(),dst_result.g());
+                    result.b() = std::max(src_result.b(),dst_result.b());
+                    combiner_output = result.Cast<u8>();
+                    break;
+                }
 
 
                 default:
                 default:
                     LOG_CRITICAL(HW_GPU, "Unknown RGB blend equation %x", params.blend_equation_rgb.Value());
                     LOG_CRITICAL(HW_GPU, "Unknown RGB blend equation %x", params.blend_equation_rgb.Value());