c# code to generate a custom texture

Previous post:
How to make circular progress bar

Let's see how to generate a custom texture.

Added : If you know python consider this.
https://gameenginebread.blogspot.com/2017/12/texture-generator-python-per-pixel-c.html

Step 1. Create C# Project.




Step 2. 

This form1 class code that create a new BMP with PerPixelAction function.



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TexGenTest
{
 public partial class Form1 : Form
 {
  public static double DegToRad = 0.0174533;
  public delegate Color PerPixelAction( int x, int y, Size ImageSize, Bitmap BitmapData, double Para1, double Para2, double Para3 );
  public Size MidSize = new Size( 128, 128 );

  public Form1()
  {
   InitializeComponent();

   CreateTexture_PPA( "F:\\RoundRectAngle_{0}_R{1}.bmp", MidSize, PPA_RoundRectAngle, 0.2 );
   CreateTexture_PPA( "F:\\Angle_Circle_{0}_Pos{1}x{2}.bmp", MidSize, PPA_AngleFrom, 0.5, 0.5 );
   CreateTexture_PPA( "F:\\Angle_Circle_{0}_Pos{1}x{2}.bmp", MidSize, PPA_AngleFrom, 0.3, 0.3 );
  }

  public Bitmap CreateTexture_PPA( string SavePath, Size ImageSize, PerPixelAction DelegateMethod, double Para1 = 0.0, double Para2 = 0.0, double Para3 = 0.0, string Command = "" )
  {
   Bitmap BitmapData = new Bitmap( ImageSize.Width, ImageSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb );

   for( int x = 0; x < ImageSize.Width; x++ )
   {
    for( int y = 0; y < ImageSize.Height; y++ )
    {
     BitmapData.SetPixel( x, y, DelegateMethod( x, y, ImageSize, BitmapData, Para1, Para2, Para3 ) );
    }
   }

   string TextureSize = string.Format( "{0}x{1}", ImageSize.Width, ImageSize.Height );

   BitmapData.Save( string.Format( SavePath, TextureSize, RD( Para1 ), RD( Para2 ), RD( Para3 ) ), System.Drawing.Imaging.ImageFormat.Bmp );

   return BitmapData;
  }

  // Remove dot.
  private double RD( double Value )
  {
   return Value < 1 ? Value * 100 : Value;
  }


  public static double FindAngle( double x, double y, Size ImageSize, double CenterX = 0.5, double CenterY = 0.5 )
  {
   double VX = (double)x / ImageSize.Width - CenterX;
   double VY = ( (double)y / ImageSize.Height - CenterY ) * -1;
   double VLen = Math.Sqrt( VX * VX + VY * VY );

   if( VLen <= 0.0 )
   {
    return -1; // Same Place.
   }

   VX = VX / VLen;
   VY = VY / VLen;

   double Dot = 0 * VX + 1 * VY;
   double Angle = Math.Acos( Dot );

   if( VX < 0.0 )
   {
    Angle = Math.PI + ( Math.PI - Angle );
   }

   return Angle;
  }

  public static void ConvertRadianTo2Byte( double Radian, ref int R, ref int G, ref int B )
  {
   B = 0;

   if( Radian < 0.0 )
   {
    R = 0;
    G = 0;
    return;
   }

   int Value = (int)( Radian / ( Math.PI * 2 ) * 65535 );
   Value = Math.Min( Value, 65535 );

   R = Value / 256;
   G = Value - ( R * 256 );
  }

  public static double Scale( double valueIn, double baseMin, double baseMax, double limitMin, double limitMax )
  {
   return ( ( limitMax - limitMin ) * ( valueIn - baseMin ) / ( baseMax - baseMin ) ) + limitMin;
  }

  public static Color ConvertRadianToRGB( double Radian )
  {
   int R = 0, G = 0, B = 0;
   ConvertRadianTo2Byte( Radian, ref R, ref G, ref B );

   return Color.FromArgb( R, G, B );
  }



  public static Color PPA_AngleFrom( int x, int y, Size ImageSize, Bitmap BitmapData, double CenterX, double CenterY, double Para3 )
  {
   double Angle = FindAngle( x, y, ImageSize, CenterX, CenterY );
   double Low = 0;
   double High = Math.PI * 2;

   if( CenterX == 0 )
   {
    High = Math.PI;
   }
   else if( CenterX >= ImageSize.Width )
   {
    Low = Math.PI;
   }

   if( CenterY == 0 )
   {
    Low = Math.Max( Math.PI * 0.5, Low );
    High = Math.Min( Math.PI * 2 * 0.75, High );
   }
   else if( CenterY >= ImageSize.Height )
   {
    // error;;;;;;;;;
    return Color.Red;
   }

   Angle = Scale( Angle, Low, High, 0, Math.PI * 2 );

   return ConvertRadianToRGB( Angle );
  }


  public static Color PPA_RoundRectAngle( int x, int y, Size ImageSize, Bitmap BitmapData, double RoundSize, double Para2, double Para3 )
  {
   double Angle = FindAngle( x, y, ImageSize );

   double Short = ImageSize.Width * RoundSize;
   double Long = ImageSize.Height - ImageSize.Height * RoundSize;

   if( x > Long && y < Short )
   {
    Angle = FindAngle( x, y, ImageSize, Long / ImageSize.Width, Short / ImageSize.Height );

    double Low = FindAngle( Long, 0, ImageSize );
    double High = FindAngle( ImageSize.Width, Short, ImageSize );
    Angle = Scale( Angle, 0, Math.PI * 0.5, Low, High );
   }
   else if( x > Long && y > Long )
   {
    Angle = FindAngle( x, y, ImageSize, Long / ImageSize.Width, Long / ImageSize.Height );

    double Low = FindAngle( ImageSize.Width, Long, ImageSize );
    double High = FindAngle( Long, ImageSize.Height, ImageSize );
    Angle = Scale( Angle, Math.PI * 0.5, Math.PI, Low, High );
   }
   else if( x < Short && y < Short )
   {
    Angle = FindAngle( x, y, ImageSize, Short / ImageSize.Width, Short / ImageSize.Height );

    double Low = FindAngle( 0, Short, ImageSize );
    double High = FindAngle( Short, 0, ImageSize );
    Angle = Scale( Angle, Math.PI * 1.5, Math.PI * 2, Low, High );
   }
   else if( x < Short && y > Long )
   {
    Angle = FindAngle( x, y, ImageSize, Short / ImageSize.Width, Long / ImageSize.Height );

    double Low = FindAngle( Short, ImageSize.Height, ImageSize );
    double High = FindAngle( 0, Long, ImageSize );
    Angle = Scale( Angle, Math.PI, Math.PI * 1.5, Low, High );
   }
   else
   {
    if( Angle <= 45 * DegToRad )
    {
     Angle = FindAngle( x, 0, ImageSize );
    }
    else if( Angle >= 45 * DegToRad && Angle <= 135 * DegToRad )
    {
     Angle = FindAngle( ImageSize.Width, y, ImageSize );
    }
    else if( Angle >= 135 * DegToRad && Angle <= 225 * DegToRad )
    {
     Angle = FindAngle( x, ImageSize.Height, ImageSize );
    }
    else if( Angle >= 225 * DegToRad && Angle <= 315 * DegToRad )
    {
     Angle = FindAngle( 0, y, ImageSize );
    }
    else
    {
     Angle = FindAngle( x, 0, ImageSize );
    }

    //resultImage.SetPixel( x, y, Color.FromArgb( 255, 0, 0 ) ); // debug.
   }

   return ConvertRadianToRGB( Angle );
  }
 }
}
Code highlight by http://hilite.me


Comments

Popular posts from this blog

Liquid material in a bottle

MatCap material

How to Make Circular Progress Bar(or Rounded Rectangle)