AreaLightTest.AreaLightForm.ComputeSAT C# (CSharp) Метод

ComputeSAT() публичный Метод

Builds the SAT
public ComputeSAT ( System _FileName, System _TargetFileName ) : void
_FileName System
_TargetFileName System
Результат void
		public unsafe void	ComputeSAT( System.IO.FileInfo _FileName, System.IO.FileInfo _TargetFileName ) {
			int		W, H;
			byte[]	Content = null;
			using ( System.IO.FileStream S = _FileName.OpenRead() )
				using ( Bitmap B = Bitmap.FromStream( S ) as Bitmap )
				{
					W = B.Width;
					H = B.Height;
					Content = new byte[W*H*4];

					BitmapData	LockedBitmap = B.LockBits( new Rectangle( 0, 0, W, H ), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb );
					for ( int Y=0; Y < H; Y++ )
					{
						byte*	pScanline = (byte*) LockedBitmap.Scan0 + Y * LockedBitmap.Stride;
						int		Offset = 4*W*Y;
						for ( int X=0; X < W; X++, Offset+=4 )
						{
							Content[Offset+2] = *pScanline++;	// B
							Content[Offset+1] = *pScanline++;	// G
							Content[Offset+0] = *pScanline++;	// R
							Content[Offset+3] = *pScanline++;	// A
						}
					}
					B.UnlockBits( LockedBitmap );
				}

			// Build the float4 image
			float4[,]	Image = new float4[W,H];
			for ( int Y=0; Y < H; Y++ ) {
				for ( int X=0; X < W; X++ ) {
					Image[X,Y] = new float4( Content[4*(W*Y+X)+0] / 255.0f, Content[4*(W*Y+X)+1] / 255.0f, Content[4*(W*Y+X)+2] / 255.0f, 0.0f );

					// Linearize from gamma space
					Image[X,Y].x = (float) Math.Pow( Image[X,Y].x, 2.2 );
					Image[X,Y].y = (float) Math.Pow( Image[X,Y].y, 2.2 );
					Image[X,Y].z = (float) Math.Pow( Image[X,Y].z, 2.2 );
				}
			}

			//////////////////////////////////////////////////////////////////////////
			// Build mips and save as a simple format
			{
				int	MaxSize = Math.Max( W, H );
				int	MipsCount = (int) (Math.Ceiling( Math.Log( MaxSize+1 ) / Math.Log( 2 ) ));
				float4[][,]	Mips = new float4[MipsCount][,];
				Mips[0] = Image;

				int	TargetWidth = W;
				int	TargetHeight = H;
				for ( int MipLevel=1; MipLevel < Mips.Length; MipLevel++ ) {
					TargetWidth = Math.Max( 1, TargetWidth >> 1 );
					TargetHeight = Math.Max( 1, TargetHeight >> 1 );

					float	MipPixelSizeX = W / TargetWidth;	// Size of a mip pixel; in amount of original image pixels (i.e. mip #0)
					float	MipPixelSizeY = H / TargetHeight;	// Size of a mip pixel; in amount of original image pixels (i.e. mip #0)
					int		KernelSize = 2 * (int) Math.Pow( 2, MipLevel );
					float	Sigma = (float) Math.Sqrt( -KernelSize*KernelSize / (2.0 * Math.Log( 0.01 )) );	// So we have a weight of 0.01 at a Kernel Size distance
					float[]	KernelFactors = new float[1+KernelSize];
					float	SumWeights = 0.0f;
					for ( int i=0; i <= KernelSize; i++ ) {
						KernelFactors[i] = (float) (Math.Exp( -i*i / (2.0 * Sigma * Sigma)) / Math.Sqrt( 2 * Math.PI * Sigma * Sigma ) );
						SumWeights += KernelFactors[i];
					}

					// Perform a horizontal blur first
					float4[,]	Source = Image;
					float4[,]	Target = new float4[TargetWidth,H];
					for ( int Y=0; Y < H; Y++ ) {
						for ( int X=0; X < TargetWidth; X++ ) {
							float	CenterX = X * MipPixelSizeX + 0.5f * (MipPixelSizeX-1);
							float4	Sum = KernelFactors[0] * BilinearSample( Source, CenterX, Y );
							for ( int i=1; i <= KernelSize; i++ ) {
								Sum += KernelFactors[i] * BilinearSample( Image, CenterX - i, Y );
								Sum += KernelFactors[i] * BilinearSample( Image, CenterX + i, Y );
							}
							Target[X,Y] = Sum;
						}
					}

					// Perform vertical blur
					Source = Target;
					Mips[MipLevel] = new float4[TargetWidth,TargetHeight];
					Target = Mips[MipLevel];
					for ( int X=0; X < TargetWidth; X++ ) {
						for ( int Y=0; Y < TargetHeight; Y++ ) {
							float	CenterY = Y * MipPixelSizeY + 0.5f * (MipPixelSizeY-1);
							float4	Sum = KernelFactors[0] * BilinearSample( Source, X, CenterY );
							for ( int i=1; i <= KernelSize; i++ ) {
								Sum += KernelFactors[i] * BilinearSample( Source, X, CenterY - i );
								Sum += KernelFactors[i] * BilinearSample( Source, X, CenterY + i );
							}
							Target[X,Y] = Sum;
						}
					}
				}


				string	Pipi = _TargetFileName.FullName;
				Pipi = System.IO.Path.GetFileNameWithoutExtension( Pipi ) + ".pipi";
				System.IO.FileInfo	SimpleTargetFileName2 = new System.IO.FileInfo(  Pipi );
				using ( System.IO.FileStream S = SimpleTargetFileName2.OpenWrite() )
					using ( System.IO.BinaryWriter Wr = new System.IO.BinaryWriter( S ) ) {
						Wr.Write( Mips.Length );
						for ( int MipLevel=0; MipLevel < Mips.Length; MipLevel++ ) {
							float4[,]	Mip = Mips[MipLevel];

							int	MipWidth = Mip.GetLength( 0 );
							int	MipHeight = Mip.GetLength( 1 );
							Wr.Write( MipWidth );
							Wr.Write( MipHeight );

							for ( int Y=0; Y < MipHeight; Y++ ) {
								for ( int X=0; X < MipWidth; X++ ) {
									Wr.Write( Mip[X,Y].x );
									Wr.Write( Mip[X,Y].y );
									Wr.Write( Mip[X,Y].z );
									Wr.Write( Mip[X,Y].w );
								}
							}
						}
					}
			}


// 			//////////////////////////////////////////////////////////////////////////
// 			// Build "3D mips" and save as a simple format
// 			{
// 				int	MaxSize = Math.Max( W, H );
// 				int	MipsCount = (int) (Math.Ceiling( Math.Log( MaxSize+1 ) / Math.Log( 2 ) ));
// 
// 				// 1] Build vertical mips
// 				float4[][,]	VerticalMips = new float4[MipsCount][,];
// 				VerticalMips[0] = Image;
// 
// 				int	TargetHeight = H;
// 				for ( int MipLevel=1; MipLevel < MipsCount; MipLevel++ ) {
// 					int	SourceHeight = TargetHeight;
// 
// 					int	BorderSize = (int) Math.Pow( 2, MipLevel-1 );
// 					TargetHeight = Math.Max( 1, H - 2*BorderSize );
// 
// 					float4[,]	SourceMip = VerticalMips[MipLevel-1];
// 					float4[,]	TargetMip = new float4[W,TargetHeight];
// 					VerticalMips[MipLevel] = TargetMip;
// 					for ( int Y=0; Y < TargetHeight; Y++ ) {
// 						float	fY = (float) (Y+0.5f) * SourceHeight / TargetHeight;
// 						for ( int X=0; X < W; X++ ) {
// 							TargetMip[X,Y] = BilinearSample( SourceMip, X, fY );
// 						}
// 					}
// 				}
// 
// 
// //MipsCount = 6;
// 
// 				// 2] Build smoothed slices
// 				float4[][,]	Slices = new float4[MipsCount][,];
// 				Slices[0] = Image;
// 
// 				for ( int MipLevel=1; MipLevel < Slices.Length; MipLevel++ ) {
// 
// 					int		BorderSize = (int) Math.Pow( 2, MipLevel-1 );		// Each new "mip" has a border twice the size of the previous level
// 
// 					int		InsetWidth = Math.Max( 1, W - 2 * BorderSize );		// The inset image is now reduced to account for borders
// 					int		InsetHeight = Math.Max( 1, H - 2 * BorderSize );
// 
// 					int		WidthWithBorders = W + 2 * BorderSize;				// The larger image with borders that will be stored in the specific mip
// 					int		HeightWithBorders = H + 2 * BorderSize;
// 
// 					int		Y0 = BorderSize;
// 					int		Y1 = H - BorderSize;
// 
// 					// Build gaussian weights
// 					int		KernelSize = 2 * (int) BorderSize;
// 					float	Sigma = (float) Math.Sqrt( -KernelSize*KernelSize / (2.0 * Math.Log( 0.01 )) );	// So we have a weight of 0.01 at a Kernel Size distance
// 					float[]	KernelFactors = new float[1+KernelSize];
// 					float	SumWeights = 0.0f;
// 					for ( int i=0; i <= KernelSize; i++ ) {
// 						KernelFactors[i] = (float) (Math.Exp( -i*i / (2.0 * Sigma * Sigma)) / Math.Sqrt( 2 * Math.PI * Sigma * Sigma ) );
// 						SumWeights += KernelFactors[i];
// 					}
// 
// 					// Perform a horizontal blur first
// 					float4[,]	Source = VerticalMips[MipLevel];
// 					float4[,]	Target = new float4[W,H];
// 					for ( int Y=0; Y < H; Y++ ) {
// 						if ( Y < Y0 || Y >= Y1 ) {
// 							// In the borderlands
// 							for ( int X=0; X < W; X++ ) {
// 								Target[X,Y] = float4.Zero;
// 							}
// 							continue;
// 						}
// 
// 						float	fY = (float) (Y - Y0) * H / InsetHeight;
// 						for ( int X=0; X < W; X++ ) {
// 							float			CenterX = 0.5f * W + ((float) (X+0.5f) / W - 0.5f) * WidthWithBorders;
// 							float4	Sum = KernelFactors[0] * BilinearSample( Source, CenterX, fY );
// 							for ( int i=1; i <= KernelSize; i++ ) {
// 								Sum += KernelFactors[i] * BilinearSample( Image, CenterX - i, fY );
// 								Sum += KernelFactors[i] * BilinearSample( Image, CenterX + i, fY );
// 							}
// 							Target[X,Y] = Sum;
// 						}
// 					}
// 
// 					// Perform vertical blur
// 					Source = Target;
// 					Slices[MipLevel] = new float4[W,H];
// 					Target = Slices[MipLevel];
// 					for ( int X=0; X < W; X++ ) {
// 						for ( int Y=0; Y < H; Y++ ) {
// 							float			CenterY = 0.5f * H + ((float) (Y+0.5f) / H - 0.5f) * HeightWithBorders;
// 							float4	Sum = KernelFactors[0] * BilinearSample( Source, X, CenterY );
// 							for ( int i=1; i <= KernelSize; i++ ) {
// 								Sum += KernelFactors[i] * BilinearSample( Source, X, CenterY - i );
// 								Sum += KernelFactors[i] * BilinearSample( Source, X, CenterY + i );
// 							}
// 							Target[X,Y] = Sum;
// 						}
// 					}
// 				}
// 
// 
// 				string	Pipu = _TargetFileName.FullName;
// 				Pipu = System.IO.Path.GetFileNameWithoutExtension( Pipu ) + ".pipu";
// 				System.IO.FileInfo	SimpleTargetFileName2 = new System.IO.FileInfo(  Pipu );
// 				using ( System.IO.FileStream S = SimpleTargetFileName2.OpenWrite() )
// 					using ( System.IO.BinaryWriter Wr = new System.IO.BinaryWriter( S ) ) {
// 						Wr.Write( Slices.Length );
// 						Wr.Write( W );
// 						Wr.Write( H );
// 
// 						for ( int MipLevel=0; MipLevel < Slices.Length; MipLevel++ ) {
// 							float4[,]	Mip = Slices[MipLevel];
// 							for ( int Y=0; Y < H; Y++ ) {
// 								for ( int X=0; X < W; X++ ) {
// 									Wr.Write( Mip[X,Y].x );
// 									Wr.Write( Mip[X,Y].y );
// 									Wr.Write( Mip[X,Y].z );
// 									Wr.Write( Mip[X,Y].w );
// 								}
// 							}
// 						}
// 					}
// 			}

			//////////////////////////////////////////////////////////////////////////
			// Build the SAT
			for ( int Y=0; Y < H; Y++ ) {
				for ( int X=1; X < W; X++ ) {
					Image[X,Y] += Image[X-1,Y];	// Accumulate along X
				}
			}

			for ( int X=0; X < W; X++ ) {
				for ( int Y=1; Y < H; Y++ ) {
					Image[X,Y] += Image[X,Y-1];	// Accumulate along Y
				}
			}

//			DirectXTexManaged.TextureCreator.CreateRGBA16FFile( _TargetFileName.FullName, Image );
throw new Exception( "Deprecated!" );

			// Save as a simple format
			string	Pipo = _TargetFileName.FullName;
			Pipo = System.IO.Path.GetFileNameWithoutExtension( Pipo ) + ".pipo";
			System.IO.FileInfo	SimpleTargetFileName = new System.IO.FileInfo(  Pipo );
			using ( System.IO.FileStream S = SimpleTargetFileName.OpenWrite() )
				using ( System.IO.BinaryWriter Wr = new System.IO.BinaryWriter( S ) ) {

					Wr.Write( W );
					Wr.Write( H );
					for ( int Y=0; Y < H; Y++ ) {
						for ( int X=0; X < W; X++ ) {
							Wr.Write( Image[X,Y].x );
							Wr.Write( Image[X,Y].y );
							Wr.Write( Image[X,Y].z );
							Wr.Write( Image[X,Y].w );
						}
					}
				}
		}