mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Pica/Rasterizer: Implement alpha blending.
This commit is contained in:
		
							parent
							
								
									e229ff8c83
								
							
						
					
					
						commit
						a7ae0330b1
					
				
					 1 changed files with 84 additions and 0 deletions
				
			
		|  | @ -25,6 +25,18 @@ static void DrawPixel(int x, int y, const Math::Vec4<u8>& color) { | |||
|     *(color_buffer + x + y * registers.framebuffer.GetWidth()) = value; | ||||
| } | ||||
| 
 | ||||
| static const Math::Vec4<u8> GetPixel(int x, int y) { | ||||
|     u32* color_buffer_u32 = reinterpret_cast<u32*>(Memory::GetPointer(PAddrToVAddr(registers.framebuffer.GetColorBufferPhysicalAddress()))); | ||||
| 
 | ||||
|     u32 value = *(color_buffer_u32 + x + y * registers.framebuffer.GetWidth()); | ||||
|     Math::Vec4<u8> ret; | ||||
|     ret.a() = value >> 24; | ||||
|     ret.r() = (value >> 16) & 0xFF; | ||||
|     ret.g() = (value >> 8) & 0xFF; | ||||
|     ret.b() = value & 0xFF; | ||||
|     return ret; | ||||
|  } | ||||
| 
 | ||||
| static u32 GetDepth(int x, int y) { | ||||
|     u16* depth_buffer = reinterpret_cast<u16*>(Memory::GetPointer(PAddrToVAddr(registers.framebuffer.GetDepthBufferPhysicalAddress()))); | ||||
| 
 | ||||
|  | @ -430,6 +442,78 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||
|                     SetDepth(x >> 4, y >> 4, z); | ||||
|             } | ||||
| 
 | ||||
|             auto dest = GetPixel(x >> 4, y >> 4); | ||||
| 
 | ||||
|             if (registers.output_merger.alphablend_enable) { | ||||
|                 auto params = registers.output_merger.alpha_blending; | ||||
| 
 | ||||
|                 auto LookupFactorRGB = [&](decltype(params)::BlendFactor factor) -> Math::Vec3<u8> { | ||||
|                     switch(factor) { | ||||
|                     case params.Zero: | ||||
|                         return Math::Vec3<u8>(0, 0, 0); | ||||
| 
 | ||||
|                     case params.One: | ||||
|                         return Math::Vec3<u8>(255, 255, 255); | ||||
| 
 | ||||
|                     case params.SourceAlpha: | ||||
|                         return Math::MakeVec(combiner_output.a(), combiner_output.a(), combiner_output.a()); | ||||
| 
 | ||||
|                     case params.OneMinusSourceAlpha: | ||||
|                         return Math::Vec3<u8>(255-combiner_output.a(), 255-combiner_output.a(), 255-combiner_output.a()); | ||||
| 
 | ||||
|                     default: | ||||
|                         LOG_CRITICAL(HW_GPU, "Unknown color blend factor %x", factor); | ||||
|                         exit(0); | ||||
|                         break; | ||||
|                     } | ||||
|                 }; | ||||
| 
 | ||||
|                 auto LookupFactorA = [&](decltype(params)::BlendFactor factor) -> u8 { | ||||
|                     switch(factor) { | ||||
|                     case params.Zero: | ||||
|                         return 0; | ||||
| 
 | ||||
|                     case params.One: | ||||
|                         return 255; | ||||
| 
 | ||||
|                     case params.SourceAlpha: | ||||
|                         return combiner_output.a(); | ||||
| 
 | ||||
|                     case params.OneMinusSourceAlpha: | ||||
|                         return 255 - combiner_output.a(); | ||||
| 
 | ||||
|                     default: | ||||
|                         LOG_CRITICAL(HW_GPU, "Unknown alpha blend factor %x", factor); | ||||
|                         exit(0); | ||||
|                         break; | ||||
|                     } | ||||
|                 }; | ||||
| 
 | ||||
|                 auto srcfactor = Math::MakeVec(LookupFactorRGB(params.factor_source_rgb), | ||||
|                                                LookupFactorA(params.factor_source_a)); | ||||
|                 auto dstfactor = Math::MakeVec(LookupFactorRGB(params.factor_dest_rgb), | ||||
|                                                LookupFactorA(params.factor_dest_a)); | ||||
| 
 | ||||
|                 switch (params.blend_equation_rgb) { | ||||
|                 case params.Add: | ||||
|                 { | ||||
|                     auto result = (combiner_output * srcfactor + dest * dstfactor) / 255; | ||||
|                     result.r() = std::min(255, result.r()); | ||||
|                     result.g() = std::min(255, result.g()); | ||||
|                     result.b() = std::min(255, result.b()); | ||||
|                     combiner_output = result.Cast<u8>(); | ||||
|                     break; | ||||
|                 } | ||||
| 
 | ||||
|                 default: | ||||
|                     LOG_CRITICAL(HW_GPU, "Unknown RGB blend equation %x", params.blend_equation_rgb.Value()); | ||||
|                     exit(0); | ||||
|                 } | ||||
|             } else { | ||||
|                 LOG_CRITICAL(HW_GPU, "logic op: %x", registers.output_merger.logic_op); | ||||
|                 exit(0); | ||||
|             } | ||||
| 
 | ||||
|             DrawPixel(x >> 4, y >> 4, combiner_output); | ||||
|         } | ||||
|     } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue