private unsafe void viewportPanelResult_Click(object sender, EventArgs e) { if (m_BitmapResult == null) { MessageBox("There is no result image to save!"); return; } string SourceFileName = m_SourceFileName.FullName; string TargetFileName = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(SourceFileName), System.IO.Path.GetFileNameWithoutExtension(SourceFileName) + "_ssbump.png"); saveFileDialogImage.InitialDirectory = System.IO.Path.GetFullPath(TargetFileName); saveFileDialogImage.FileName = System.IO.Path.GetFileName(TargetFileName); if (saveFileDialogImage.ShowDialog(this) != DialogResult.OK) { return; } try { m_BitmapResult.Save(new System.IO.FileInfo(saveFileDialogImage.FileName)); MessageBox("Success!", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception _e) { MessageBox("An error occurred while saving the image:\n\n", _e); } }
public void Build(BuildArguments _args) { // Setup arguments floatTrackbarControlHeight.Value = _args.displacementSize_cm; floatTrackbarControlPixelDensity.Value = _args.textureSize_cm; integerTrackbarControlRaysCount.Value = _args.raysCount; integerTrackbarControlMaxStepsCount.Value = _args.searchRange; floatTrackbarControlMaxConeAngle.Value = _args.coneAngle; floatTrackbarControlBilateralRadius.Value = _args.bilateralRadius; floatTrackbarControlBilateralTolerance.Value = _args.bilateralTolerance; checkBoxWrap.Checked = _args.tile; m_silentMode = true; // Create device, shaders and structures OnLoad(EventArgs.Empty); // Load height map System.IO.FileInfo HeightMapFileName = new System.IO.FileInfo(_args.heightMapFileName); LoadHeightMap(HeightMapFileName); // Load normal map if (_args.normalMapFileName != null) { System.IO.FileInfo NormalMapFileName = new System.IO.FileInfo(_args.normalMapFileName); LoadNormalMap(NormalMapFileName); } // Generate Generate(); // Save results m_BitmapResult.Save(new System.IO.FileInfo(_args.AOMapFileName)); // Dispose CancelEventArgs onsenfout = new CancelEventArgs(); OnClosing((CancelEventArgs)onsenfout); }
static void SaveTestsRGB() { ImageUtility.ColorProfile Profile_sRGB = new ImageUtility.ColorProfile(ImageUtility.ColorProfile.STANDARD_PROFILE.sRGB); ImageUtility.ColorProfile Profile_Linear = new ImageUtility.ColorProfile(ImageUtility.ColorProfile.Chromaticities.sRGB, ImageUtility.ColorProfile.GAMMA_CURVE.STANDARD, 1.0f); ImageUtility.Bitmap Gray_sRGB = new ImageUtility.Bitmap(64, 64, Profile_sRGB); ImageUtility.Bitmap Gray_Linear = new ImageUtility.Bitmap(64, 64, Profile_Linear); ImageUtility.Bitmap Gradient_sRGB = new ImageUtility.Bitmap(128, 16, Profile_sRGB); ImageUtility.Bitmap Gradient_Linear = new ImageUtility.Bitmap(128, 16, Profile_Linear); for (int Y = 0; Y < Gray_sRGB.Height; Y++) { for (int X = 0; X < Gray_sRGB.Width; X++) { Gray_sRGB.ContentXYZ[X, Y] = Profile_Linear.RGB2XYZ(new ImageUtility.float4(0.5f, 0.5f, 0.5f, 1.0f)); Gray_Linear.ContentXYZ[X, Y] = Profile_Linear.RGB2XYZ(new ImageUtility.float4(0.5f, 0.5f, 0.5f, 1.0f)); } } int W = Gradient_sRGB.Width; for (int Y = 0; Y < Gradient_sRGB.Height; Y++) { for (int X = 0; X < Gradient_sRGB.Width; X++) { float C = (float)(X + 0.5f) / W; Gradient_sRGB.ContentXYZ[X, Y] = Profile_Linear.RGB2XYZ(new ImageUtility.float4(C, C, C, 1.0f)); Gradient_Linear.ContentXYZ[X, Y] = Profile_Linear.RGB2XYZ(new ImageUtility.float4(C, C, C, 1.0f)); } } Gray_sRGB.Save(new FileInfo("./Gray128_sRGB.png")); Gray_Linear.Save(new FileInfo("./Gray128_Linear.png")); Gradient_sRGB.Save(new FileInfo("./Gradient_sRGB.png")); Gradient_Linear.Save(new FileInfo("./Gradient_Linear.png")); }
/// <summary> /// Generates a (diffuse+gloss) texture from 2 distinct textures /// </summary> public void GenerateDiffuseGlossTexture() { if ( m_diffuse == null ) throw new Exception( "Invalid source diffuse image file!" ); if ( !m_diffuse.m_fileName.Exists ) throw new Exception( "Source diffuse image file \"" + m_diffuse.m_fileName.FullName + "\" does not exist on disk!" ); FileInfo targetFileName = GetDiffuseGlossTextureFileName(); using ( ImageUtility.Bitmap diffuse = new ImageUtility.Bitmap( m_diffuse.m_fileName ) ) { int W = diffuse.Width; int H = diffuse.Height; ImageUtility.Bitmap gloss = null; if ( m_gloss != null ) { gloss = new ImageUtility.Bitmap( m_gloss.m_fileName ); // int gW = gloss.Width; // int gH = gloss.Height; // for ( int Y=0; Y < gH; Y++ ) // for ( int X=0; X < gW; X++ ) { // gloss.ContentXYZ[X,Y].x = ImageUtility.ColorProfile.sRGB2Linear( gloss.ContentXYZ[X,Y].x ); // } } bool needsScale = false; if ( gloss != null && (gloss.Width != W || gloss.Height != H) ) { needsScale = true; } if ( gloss != null ) { if ( needsScale ) { // Set gloss as alpha with re-scaling int W2 = gloss.Width; int H2 = gloss.Height; float[,] source = new float[W2,H2]; for ( int Y=0; Y < H2; Y++ ) for ( int X=0; X < W2; X++ ) source[X,Y] = 0.3f * gloss.ContentXYZ[X,Y].x + 0.5f * gloss.ContentXYZ[X,Y].y + 0.2f * gloss.ContentXYZ[X,Y].z; // Downscale first while ( W2 > W ) { int halfW2 = W2 >> 1; float[,] temp = new float[halfW2,H2]; for ( int Y=0; Y < H2; Y++ ) for ( int X=0; X < halfW2; X++ ) temp[X,Y] = 0.5f * (source[2*X+0,Y] + source[2*X+1,Y]); source = temp; W2 = halfW2; } while ( H2 > H ) { int halfH2 = H2 >> 1; float[,] temp = new float[W2,halfH2]; for ( int Y=0; Y < halfH2; Y++ ) for ( int X=0; X < W2; X++ ) temp[X,Y] = 0.5f * (source[X,2*Y+0] + source[X,2*Y+1]); source = temp; H2 = halfH2; } // Upscale then while ( W2 < W ) { int doubleW2 = W2 << 1; float[,] temp = new float[doubleW2,H2]; for ( int Y=0; Y < H2; Y++ ) for ( int X=0; X < W2; X++ ) { temp[2*X+0,Y] = source[X,Y]; temp[2*X+1,Y] = 0.5f * (source[X,Y] + source[Math.Min( W2-1, X+1 ),Y]); } source = temp; W2 = doubleW2; } while ( H2 < H ) { int doubleH2 = H2 << 1; float[,] temp = new float[W2,doubleH2]; for ( int Y=0; Y < H2; Y++ ) for ( int X=0; X < W2; X++ ) { temp[X,2*Y+0] = source[X,Y]; temp[X,2*Y+1] = 0.5f * (source[X,Y] + source[X,Math.Min( H2-1, Y+1 )]); } source = temp; H2 = doubleH2; } for ( int Y=0; Y < H; Y++ ) for ( int X=0; X < W; X++ ) diffuse.ContentXYZ[X,Y].w = source[X,Y]; } else { // Set gloss as alpha without re-scaling for ( int Y=0; Y < H; Y++ ) for ( int X=0; X < W; X++ ) { // diffuse.ContentXYZ[X,Y].w = gloss.ContentXYZ[X,Y].x; diffuse.ContentXYZ[X,Y].w = 0.3f * gloss.ContentXYZ[X,Y].x + 0.5f * gloss.ContentXYZ[X,Y].y + 0.2f * gloss.ContentXYZ[X,Y].z; } } } else { for ( int Y=0; Y < H; Y++ ) for ( int X=0; X < W; X++ ) diffuse.ContentXYZ[X,Y].w = 1.0f; } // Save diffuse as target diffuse.HasAlpha = gloss != null; diffuse.Save( targetFileName ); } // Save optimized filename + timestamps of source files m_diffuseFileName.Refresh(); if ( m_glossFileName != null ) m_glossFileName.Refresh(); m_optimizedDiffuseGlossFileName = targetFileName; m_diffuseTimeAtGeneration = m_diffuseFileName.LastWriteTime; m_glossTimeAtGeneration = m_glossFileName != null ? m_glossFileName.LastWriteTime : DateTime.MinValue; }
static void SaveTestsRGB() { ImageUtility.ColorProfile Profile_sRGB = new ImageUtility.ColorProfile( ImageUtility.ColorProfile.STANDARD_PROFILE.sRGB ); ImageUtility.ColorProfile Profile_Linear = new ImageUtility.ColorProfile( ImageUtility.ColorProfile.Chromaticities.sRGB, ImageUtility.ColorProfile.GAMMA_CURVE.STANDARD, 1.0f ); ImageUtility.Bitmap Gray_sRGB = new ImageUtility.Bitmap( 64, 64, Profile_sRGB ); ImageUtility.Bitmap Gray_Linear = new ImageUtility.Bitmap( 64, 64, Profile_Linear ); ImageUtility.Bitmap Gradient_sRGB = new ImageUtility.Bitmap( 128, 16, Profile_sRGB ); ImageUtility.Bitmap Gradient_Linear = new ImageUtility.Bitmap( 128, 16, Profile_Linear ); for ( int Y=0; Y < Gray_sRGB.Height; Y++ ) for ( int X=0; X < Gray_sRGB.Width; X++ ) { Gray_sRGB.ContentXYZ[X,Y] = Profile_Linear.RGB2XYZ( new ImageUtility.float4( 0.5f, 0.5f, 0.5f, 1.0f ) ); Gray_Linear.ContentXYZ[X,Y] = Profile_Linear.RGB2XYZ( new ImageUtility.float4( 0.5f, 0.5f, 0.5f, 1.0f ) ); } int W = Gradient_sRGB.Width; for ( int Y=0; Y < Gradient_sRGB.Height; Y++ ) for ( int X=0; X < Gradient_sRGB.Width; X++ ) { float C = (float) (X+0.5f) / W; Gradient_sRGB.ContentXYZ[X,Y] = Profile_Linear.RGB2XYZ( new ImageUtility.float4( C, C, C, 1.0f ) ); Gradient_Linear.ContentXYZ[X,Y] = Profile_Linear.RGB2XYZ( new ImageUtility.float4( C, C, C, 1.0f ) ); } Gray_sRGB.Save( new FileInfo( "./Gray128_sRGB.png" ) ); Gray_Linear.Save( new FileInfo( "./Gray128_Linear.png" ) ); Gradient_sRGB.Save( new FileInfo( "./Gradient_sRGB.png" ) ); Gradient_Linear.Save( new FileInfo( "./Gradient_Linear.png" ) ); }
/// <summary> /// Generates a (diffuse+gloss) texture from 2 distinct textures /// </summary> public void GenerateDiffuseGlossTexture() { if (m_diffuse == null) { throw new Exception("Invalid source diffuse image file!"); } if (!m_diffuse.m_fileName.Exists) { throw new Exception("Source diffuse image file \"" + m_diffuse.m_fileName.FullName + "\" does not exist on disk!"); } FileInfo targetFileName = GetDiffuseGlossTextureFileName(); using (ImageUtility.Bitmap diffuse = new ImageUtility.Bitmap(m_diffuse.m_fileName)) { int W = diffuse.Width; int H = diffuse.Height; ImageUtility.Bitmap gloss = null; if (m_gloss != null) { gloss = new ImageUtility.Bitmap(m_gloss.m_fileName); // int gW = gloss.Width; // int gH = gloss.Height; // for ( int Y=0; Y < gH; Y++ ) // for ( int X=0; X < gW; X++ ) { // gloss.ContentXYZ[X,Y].x = ImageUtility.ColorProfile.sRGB2Linear( gloss.ContentXYZ[X,Y].x ); // } } bool needsScale = false; if (gloss != null && (gloss.Width != W || gloss.Height != H)) { needsScale = true; } if (gloss != null) { if (needsScale) { // Set gloss as alpha with re-scaling int W2 = gloss.Width; int H2 = gloss.Height; float[,] source = new float[W2, H2]; for (int Y = 0; Y < H2; Y++) { for (int X = 0; X < W2; X++) { source[X, Y] = 0.3f * gloss.ContentXYZ[X, Y].x + 0.5f * gloss.ContentXYZ[X, Y].y + 0.2f * gloss.ContentXYZ[X, Y].z; } } // Downscale first while (W2 > W) { int halfW2 = W2 >> 1; float[,] temp = new float[halfW2, H2]; for (int Y = 0; Y < H2; Y++) { for (int X = 0; X < halfW2; X++) { temp[X, Y] = 0.5f * (source[2 * X + 0, Y] + source[2 * X + 1, Y]); } } source = temp; W2 = halfW2; } while (H2 > H) { int halfH2 = H2 >> 1; float[,] temp = new float[W2, halfH2]; for (int Y = 0; Y < halfH2; Y++) { for (int X = 0; X < W2; X++) { temp[X, Y] = 0.5f * (source[X, 2 * Y + 0] + source[X, 2 * Y + 1]); } } source = temp; H2 = halfH2; } // Upscale then while (W2 < W) { int doubleW2 = W2 << 1; float[,] temp = new float[doubleW2, H2]; for (int Y = 0; Y < H2; Y++) { for (int X = 0; X < W2; X++) { temp[2 * X + 0, Y] = source[X, Y]; temp[2 * X + 1, Y] = 0.5f * (source[X, Y] + source[Math.Min(W2 - 1, X + 1), Y]); } } source = temp; W2 = doubleW2; } while (H2 < H) { int doubleH2 = H2 << 1; float[,] temp = new float[W2, doubleH2]; for (int Y = 0; Y < H2; Y++) { for (int X = 0; X < W2; X++) { temp[X, 2 * Y + 0] = source[X, Y]; temp[X, 2 * Y + 1] = 0.5f * (source[X, Y] + source[X, Math.Min(H2 - 1, Y + 1)]); } } source = temp; H2 = doubleH2; } for (int Y = 0; Y < H; Y++) { for (int X = 0; X < W; X++) { diffuse.ContentXYZ[X, Y].w = source[X, Y]; } } } else { // Set gloss as alpha without re-scaling for (int Y = 0; Y < H; Y++) { for (int X = 0; X < W; X++) { // diffuse.ContentXYZ[X,Y].w = gloss.ContentXYZ[X,Y].x; diffuse.ContentXYZ[X, Y].w = 0.3f * gloss.ContentXYZ[X, Y].x + 0.5f * gloss.ContentXYZ[X, Y].y + 0.2f * gloss.ContentXYZ[X, Y].z; } } } } else { for (int Y = 0; Y < H; Y++) { for (int X = 0; X < W; X++) { diffuse.ContentXYZ[X, Y].w = 1.0f; } } } // Save diffuse as target diffuse.HasAlpha = gloss != null; diffuse.Save(targetFileName); } // Save optimized filename + timestamps of source files m_diffuseFileName.Refresh(); if (m_glossFileName != null) { m_glossFileName.Refresh(); } m_optimizedDiffuseGlossFileName = targetFileName; m_diffuseTimeAtGeneration = m_diffuseFileName.LastWriteTime; m_glossTimeAtGeneration = m_glossFileName != null ? m_glossFileName.LastWriteTime : DateTime.MinValue; }
/// <summary> /// Saves a texture to disk /// </summary> /// <param name="_Texture"></param> /// <param name="_FileName"></param> /// <param name="_FileType"></param> /// <param name="_Format"></param> private void SaveImage(ImageUtility.Bitmap _Texture, System.IO.FileInfo _FileName, ImageUtility.Bitmap.FILE_TYPE _FileType, ImageUtility.Bitmap.FORMAT_FLAGS _Format) { using (System.IO.FileStream S = _FileName.Create()) _Texture.Save(S, _FileType, _Format, null); }
/// <summary> /// Generates a (diffuse+gloss) texture from 2 distinct textures /// </summary> public void GenerateDiffuseGlossTexture() { if (m_diffuse == null) { throw new Exception("Invalid source diffuse image file!"); } if (!m_diffuse.m_fileName.Exists) { throw new Exception("Source diffuse image file \"" + m_diffuse.m_fileName.FullName + "\" does not exist on disk!"); } string targetFileNameString = TextureFileInfo.GetOptimizedDiffuseGlossNameFromDiffuseName(m_diffuse.m_fileName.FullName); FileInfo targetFileName = new FileInfo(targetFileNameString); using (ImageUtility.Bitmap diffuse = new ImageUtility.Bitmap(m_diffuse.m_fileName)) { int W = diffuse.Width; int H = diffuse.Height; ImageUtility.Bitmap gloss = null; if (m_gloss != null) { gloss = new ImageUtility.Bitmap(m_gloss.m_fileName); // int gW = gloss.Width; // int gH = gloss.Height; // for ( int Y=0; Y < gH; Y++ ) // for ( int X=0; X < gW; X++ ) { // gloss.ContentXYZ[X,Y].x = ImageUtility.ColorProfile.sRGB2Linear( gloss.ContentXYZ[X,Y].x ); // } } bool needsScale = false; if (gloss != null && (gloss.Width != W || gloss.Height != H)) { needsScale = true; } if (gloss != null) { if (needsScale) { // Set gloss as alpha with re-scaling float scaleX = (float)gloss.Width / W; float scaleY = (float)gloss.Height / H; for (int Y = 0; Y < H; Y++) { float Y2 = scaleY * Y; for (int X = 0; X < W; X++) { diffuse.ContentXYZ[X, Y].w = gloss.BilinearSample(scaleX * X, Y2).x; } } } else { // Set gloss as alpha without re-scaling for (int Y = 0; Y < H; Y++) { for (int X = 0; X < W; X++) { // diffuse.ContentXYZ[X,Y].w = gloss.ContentXYZ[X,Y].x; diffuse.ContentXYZ[X, Y].w = 0.3f * gloss.ContentXYZ[X, Y].x + 0.5f * gloss.ContentXYZ[X, Y].y + 0.2f * gloss.ContentXYZ[X, Y].z; } } } } else { for (int Y = 0; Y < H; Y++) { for (int X = 0; X < W; X++) { diffuse.ContentXYZ[X, Y].w = 1.0f; } } } // Save diffuse as target diffuse.HasAlpha = gloss != null; diffuse.Save(targetFileName); } // Save optimized filename + timestamps of source files m_diffuseFileName.Refresh(); if (m_glossFileName != null) { m_glossFileName.Refresh(); } m_optimizedDiffuseGlossFileName = targetFileName; m_diffuseTimeAtGeneration = m_diffuseFileName.LastWriteTime; m_glossTimeAtGeneration = m_glossFileName != null ? m_glossFileName.LastWriteTime : DateTime.MinValue; }