Jump to content

Headache for a plugin...


MadJik

Recommended Posts

Let's start slowly.

_________________________________________STEP 1

This first code will draw for each lines as many pixel (X axis) as the line number is (Y axis).

(read the code to understand):

void Render(Surface dst, Surface src, Rectangle rect) {
 PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds);
 Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
 ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
 ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor;

 for (int y = rect.Top; y < rect.Bottom; y++)   { 
   for (int x = rect.Left; x < rect.Right; x++)   {
     if (x    }
 }
}

Result: A triangle in the bottom-left corner filled with Primary Color.

_________________________________________STEP 2

Now I want each lines to have a random 'lenght' instead depending on y.

To do so I've added a random handler (based on PDNsrc,AddNoiseEffect.cs),

and used it to calculate m (to be between rect.left and rect.right):

[ThreadStatic]
private static Random threadRand = new Random();

void Render(Surface dst, Surface src, Rectangle rect) {
 PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds);
 Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
 ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
 ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor;
 if (threadRand == null)
 {
   threadRand = new Random(unchecked(System.Threading.Thread.CurrentThread.GetHashCode() ^ unchecked((int)DateTime.Now.Ticks)));
 }

 Random localRand = threadRand;

 for (int y = rect.Top; y < rect.Bottom; y++)   { 
   int m = localRand.Next(rect.Right - rect.Left) + rect.Left;    
   for (int x = rect.Left; x < rect.Right; x++)   {
     if (x<=m) dst[x,y] = PrimaryColor;
   }
 }
}

Result: Horizontal histogram with random values...

And it works well because it's in a way the renderer won't see any problem.

_________________________________________STEP 3

Now I want to define a ratio for the lenght of each line (m).

At the same time we could also add a random start position instead the left border.

To do so I've added a new variable (Codelab friendly) Amount1 (0 - 100, default 50),

and calculate a new random start position (n):

int Amount1=50;   //[0,100]% lenght ratio

[ThreadStatic]
private static Random threadRand = new Random();

void Render(Surface dst, Surface src, Rectangle rect) {
 float ratio = (float)Amount1 / 100.0f;  
 PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds);
 Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
 ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
 ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor;
 if (threadRand == null)
 {
   threadRand = new Random(unchecked(System.Threading.Thread.CurrentThread.GetHashCode() ^ unchecked((int)DateTime.Now.Ticks)));
 }

 Random localRand = threadRand;

 for (int y = rect.Top; y < rect.Bottom; y++)   { 
   int m = (int)(ratio * (float)(localRand.Next(rect.Right - rect.Left) + rect.Left));    
   int n = localRand.Next(m - rect.Left) + rect.Left;    
   for (int x = rect.Left; x < rect.Right; x++)   {
     if (x<=n) dst[x,y] = SecondaryColor;
     if ((x>n)&&(x<=m)) dst[x,y] = PrimaryColor;
   }
 }
}

Result: If you fill the image with white, and choose PrimaryColor = Red , SecondaryColor = Blackp, when you'll have horizontal histogram with bicolored bars.

__________________________________________________________________________________

_________________________________________HEADACHE STEP 1 !

Now I want to have the same effect verticaly!

...any suggestion ?

Warning: The code below doesn't work!

The renderer runs several threads with small

parts of the image (rect) and each thread seems

to be independant (no info from others threads).

int Amount1=50;   //[0,100]% lenght ratio

[ThreadStatic]
private static Random threadRand = new Random();

void Render(Surface dst, Surface src, Rectangle rect) {
 float ratio = (float)Amount1 / 100.0f;  
 PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds);
 Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
 ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
 ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor;
 if (threadRand == null)
 {
   threadRand = new Random(unchecked(System.Threading.Thread.CurrentThread.GetHashCode() ^ unchecked((int)DateTime.Now.Ticks)));
 }

 Random localRand = threadRand;

 for (int x = rect.Left; x < rect.Right; x++)   {
   int m = (int)(ratio * (float)(localRand.Next(rect.Bottom - rect.Top) + rect.Top));    
   int n = localRand.Next(Math.Abs(m - rect.Top)) + rect.Top;    
   for (int y = rect.Top; y < rect.Bottom; y++)   { 
     if (y<=n) dst[x,y] = SecondaryColor;
     if ((y>n)&&(y<=m)) dst[x,y] = PrimaryColor;
   }
 }
}

Result: All image is filled with SecondaryColor.

_________________________________________HEADACHE STEP 2 !

Let's say verticaly for the explanation, but it should also be horizontaly.

I want to place one pixel in the middle of the top border.

Then the plugin should read normally the source image and add more pixels in this way :

If the pixel above is On, then the Current Pixel should have Amount1% chance to be On.

If one of the pixel above and left or the pixel above and right is On, then the Current

Pixel should have Amount2% chance to be On.

pixels.jpg

no code...any suggestion ?

Expected result (made with Excel):

XLtree.png

_________________________________________CONCLUSION

I feel better now, because I already find some answers to my questions, while I was writing this post...

I've a lot of ideas that won't work if I can't find a solution for this. It's the case for my generator of Random Kaleidoscope.

The last example was a try for a grass/tree generator...

I will publish the code from Step 3 as a new plugin, I find some good stuff we could obtain with it...

And thank you to read this long post...

Link to comment
Share on other sites

Let's start slowly.

_________________________________________STEP 1

This first code will draw for each lines as many pixel (X axis) as the line number is (Y axis).

(read the code to understand):

void Render(Surface dst, Surface src, Rectangle rect) {
 PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds);
 Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
 ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
 ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor;

 for (int y = rect.Top; y < rect.Bottom; y++)   { 
   for (int x = rect.Left; x < rect.Right; x++)   {
     if (x    }
 }
}

Result: A triangle in the bottom-left corner filled with Primary Color.

_________________________________________STEP 2

Now I want each lines to have a random 'lenght' instead depending on y.

To do so I've added a random handler (based on PDNsrc,AddNoiseEffect.cs),

and used it to calculate m (to be between rect.left and rect.right):

[ThreadStatic]
private static Random threadRand = new Random();

void Render(Surface dst, Surface src, Rectangle rect) {
 PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds);
 Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
 ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
 ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor;
 if (threadRand == null)
 {
   threadRand = new Random(unchecked(System.Threading.Thread.CurrentThread.GetHashCode() ^ unchecked((int)DateTime.Now.Ticks)));
 }

 Random localRand = threadRand;

 for (int y = rect.Top; y < rect.Bottom; y++)   { 
   int m = localRand.Next(rect.Right - rect.Left) + rect.Left;    
   for (int x = rect.Left; x < rect.Right; x++)   {
     if (x<=m) dst[x,y] = PrimaryColor;
   }
 }
}

Result: Horizontal histogram with random values...

And it works well because it's in a way the renderer won't see any problem.

_________________________________________STEP 3

Now I want to define a ratio for the lenght of each line (m).

At the same time we could also add a random start position instead the left border.

To do so I've added a new variable (Codelab friendly) Amount1 (0 - 100, default 50),

and calculate a new random start position (n):

int Amount1=50;   //[0,100]% lenght ratio

[ThreadStatic]
private static Random threadRand = new Random();

void Render(Surface dst, Surface src, Rectangle rect) {
 float ratio = (float)Amount1 / 100.0f;  
 PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds);
 Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
 ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
 ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor;
 if (threadRand == null)
 {
   threadRand = new Random(unchecked(System.Threading.Thread.CurrentThread.GetHashCode() ^ unchecked((int)DateTime.Now.Ticks)));
 }

 Random localRand = threadRand;

 for (int y = rect.Top; y < rect.Bottom; y++)   { 
   int m = (int)(ratio * (float)(localRand.Next(rect.Right - rect.Left) + rect.Left));    
   int n = localRand.Next(m - rect.Left) + rect.Left;    
   for (int x = rect.Left; x < rect.Right; x++)   {
     if (x<=n) dst[x,y] = SecondaryColor;
     if ((x>n)&&(x<=m)) dst[x,y] = PrimaryColor;
   }
 }
}

Result: If you fill the image with white, and choose PrimaryColor = Red , SecondaryColor = Blackp, when you'll have horizontal histogram with bicolored bars.

__________________________________________________________________________________

_________________________________________HEADACHE STEP 1 !

Now I want to have the same effect verticaly!

...any suggestion ?

Warning: The code below doesn't work!

The renderer runs several threads with small

parts of the image (rect) and each thread seems

to be independant (no info from others threads).

int Amount1=50;   //[0,100]% lenght ratio

[ThreadStatic]
private static Random threadRand = new Random();

void Render(Surface dst, Surface src, Rectangle rect) {
 float ratio = (float)Amount1 / 100.0f;  
 PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds);
 Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
 ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
 ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor;
 if (threadRand == null)
 {
   threadRand = new Random(unchecked(System.Threading.Thread.CurrentThread.GetHashCode() ^ unchecked((int)DateTime.Now.Ticks)));
 }

 Random localRand = threadRand;

 for (int x = rect.Left; x < rect.Right; x++)   {
   int m = (int)(ratio * (float)(localRand.Next(rect.Bottom - rect.Top) + rect.Top));    
   int n = localRand.Next(Math.Abs(m - rect.Top)) + rect.Top;    
   for (int y = rect.Top; y < rect.Bottom; y++)   { 
     if (y<=n) dst[x,y] = SecondaryColor;
     if ((y>n)&&(y<=m)) dst[x,y] = PrimaryColor;
   }
 }
}

Result: All image is filled with SecondaryColor.

_________________________________________HEADACHE STEP 2 !

Let's say verticaly for the explanation, but it should also be horizontaly.

I want to place one pixel in the middle of the top border.

Then the plugin should read normally the source image and add more pixels in this way :

If the pixel above is On, then the Current Pixel should have Amount1% chance to be On.

If one of the pixel above and left or the pixel above and right is On, then the Current

Pixel should have Amount2% chance to be On.

pixels.jpg

no code...any suggestion ?

Expected result (made with Excel):

XLtree.png

_________________________________________CONCLUSION

I feel better now, because I already find some answers to my questions, while I was writing this post...

I've a lot of ideas that won't work if I can't find a solution for this. It's the case for my generator of Random Kaleidoscope.

The last example was a try for a grass/tree generator...

I will publish the code from Step 3 as a new plugin, I find some good stuff we could obtain with it...

And thank you to read this long post...

Link to comment
Share on other sites

HEADACHE STEP 1 !

Now I want to have the same effect verticaly!

...any suggestion ?

Warning: The code below doesn't work!

The renderer runs several threads with small

parts of the image (rect) and each thread seems

to be independant (no info from others threads).

int Amount1=50;   //[0,100]% lenght ratio

[ThreadStatic]
private static Random threadRand = new Random();

void Render(Surface dst, Surface src, Rectangle rect) {
 float ratio = (float)Amount1 / 100.0f;  
 PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds);
 Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
 ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
 ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor;
 if (threadRand == null)
 {
   threadRand = new Random(unchecked(System.Threading.Thread.CurrentThread.GetHashCode() ^ unchecked((int)DateTime.Now.Ticks)));
 }

 Random localRand = threadRand;

 for (int x = rect.Left; x < rect.Right; x++)   {
   int m = (int)(ratio * (float)(localRand.Next(rect.Bottom - rect.Top) + rect.Top));    
   int n = localRand.Next(Math.Abs(m - rect.Top)) + rect.Top;    
   for (int y = rect.Top; y < rect.Bottom; y++)   { 
     if (y<=n) dst[x,y] = SecondaryColor;
     if ((y>n)&&(y<=m)) dst[x,y] = PrimaryColor;
   }
 }
}

Result: All image is filled with SecondaryColor.

Moving from Horizontal to Vertical is not as easy as just changing Left and Right to Bottom and Top.

Paint.NET currently passes scanlines into the Render loop (and as Rick has said, this might not always be the case, so your Horizontal code could be wrong in the future). Since scanlines are going into your render loop, rect.Bottom - rect.Top [height] is going to be equal to 1. So far starters, use selection instead of rect when calculating the width and height of the total selection.

This does NOT solve how to draw vertically, since each pass into the render function will generate a new random number, but this should help you understand where you are going wrong and get back on track.

Link to comment
Share on other sites

HEADACHE STEP 1 !

Now I want to have the same effect verticaly!

...any suggestion ?

Warning: The code below doesn't work!

The renderer runs several threads with small

parts of the image (rect) and each thread seems

to be independant (no info from others threads).

int Amount1=50;   //[0,100]% lenght ratio

[ThreadStatic]
private static Random threadRand = new Random();

void Render(Surface dst, Surface src, Rectangle rect) {
 float ratio = (float)Amount1 / 100.0f;  
 PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds);
 Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
 ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
 ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor;
 if (threadRand == null)
 {
   threadRand = new Random(unchecked(System.Threading.Thread.CurrentThread.GetHashCode() ^ unchecked((int)DateTime.Now.Ticks)));
 }

 Random localRand = threadRand;

 for (int x = rect.Left; x < rect.Right; x++)   {
   int m = (int)(ratio * (float)(localRand.Next(rect.Bottom - rect.Top) + rect.Top));    
   int n = localRand.Next(Math.Abs(m - rect.Top)) + rect.Top;    
   for (int y = rect.Top; y < rect.Bottom; y++)   { 
     if (y<=n) dst[x,y] = SecondaryColor;
     if ((y>n)&&(y<=m)) dst[x,y] = PrimaryColor;
   }
 }
}

Result: All image is filled with SecondaryColor.

Moving from Horizontal to Vertical is not as easy as just changing Left and Right to Bottom and Top.

Paint.NET currently passes scanlines into the Render loop (and as Rick has said, this might not always be the case, so your Horizontal code could be wrong in the future). Since scanlines are going into your render loop, rect.Bottom - rect.Top [height] is going to be equal to 1. So far starters, use selection instead of rect when calculating the width and height of the total selection.

This does NOT solve how to draw vertically, since each pass into the render function will generate a new random number, but this should help you understand where you are going wrong and get back on track.

Link to comment
Share on other sites

Moving from Horizontal to Vertical is not as easy as just changing Left and Right to Bottom and Top.

Paint.NET currently passes scanlines into the Render loop (and as Rick has said, this might not always be the case, so your Horizontal code could be wrong in the future). Since scanlines are going into your render loop, rect.Bottom - rect.Top [height] is going to be equal to 1. So far starters, use selection instead of rect when calculating the width and height of the total selection.

This does NOT solve how to draw vertically, since each pass into the render function will generate a new random number, but this should help you understand where you are going wrong and get back on track.

That's what I was trying to tell. Thank you to give a better explanation for this problem...

So perhaps, Rick will tell more about future changes...with the hope we'll be able to do this as we want...

Link to comment
Share on other sites

Moving from Horizontal to Vertical is not as easy as just changing Left and Right to Bottom and Top.

Paint.NET currently passes scanlines into the Render loop (and as Rick has said, this might not always be the case, so your Horizontal code could be wrong in the future). Since scanlines are going into your render loop, rect.Bottom - rect.Top [height] is going to be equal to 1. So far starters, use selection instead of rect when calculating the width and height of the total selection.

This does NOT solve how to draw vertically, since each pass into the render function will generate a new random number, but this should help you understand where you are going wrong and get back on track.

That's what I was trying to tell. Thank you to give a better explanation for this problem...

So perhaps, Rick will tell more about future changes...with the hope we'll be able to do this as we want...

Link to comment
Share on other sites

Warning: The code below doesn't work!

The renderer runs several threads with small

parts of the image (rect) and each thread seems

to be independant (no info from others threads).

Precisely. You should not assume that your Render() method is called to render anything in any particular order. If it helps, pretend I'm going to be calling your Render() method once for each pixel, and in a completely randomized order.

Paint.NET currently passes scanlines into the Render loop (and as Rick has said, this might not always be the case, so your Horizontal code could be wrong in the future). Since scanlines are going into your render loop, rect.Bottom - rect.Top [height] is going to be equal to 1.

Rectangles are passed in. Depending on the size of your image, you may just get "scanlines" (1-height rectangles).

So perhaps, Rick will tell more about future changes...with the hope we'll be able to do this as we want...

No can do -- because I haven't written any changes yet!

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

Warning: The code below doesn't work!

The renderer runs several threads with small

parts of the image (rect) and each thread seems

to be independant (no info from others threads).

Precisely. You should not assume that your Render() method is called to render anything in any particular order. If it helps, pretend I'm going to be calling your Render() method once for each pixel, and in a completely randomized order.

Paint.NET currently passes scanlines into the Render loop (and as Rick has said, this might not always be the case, so your Horizontal code could be wrong in the future). Since scanlines are going into your render loop, rect.Bottom - rect.Top [height] is going to be equal to 1.

Rectangles are passed in. Depending on the size of your image, you may just get "scanlines" (1-height rectangles).

So perhaps, Rick will tell more about future changes...with the hope we'll be able to do this as we want...

No can do -- because I haven't written any changes yet!

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

Warning: The code below doesn't work!

The renderer runs several threads with small

parts of the image (rect) and each thread seems

to be independant (no info from others threads).

Precisely. You should not assume that your Render() method is called to render anything in any particular order. If it helps, pretend I'm going to be calling your Render() method once for each pixel, and in a completely randomized order.

...

It helps to be more clear about how it works. But it doesn't help me to create this plugin!

I tried with a table, expecting I could first fill it, then read it to update the image, but I can't isolate this routing in a pre-rendering stage! Meaning the subroutine (even if it uses selection instead rect) is ran at each render loop... If we could code some pre-rendering function, I actually don't know how, and so I miss this information.

Link to comment
Share on other sites

Warning: The code below doesn't work!

The renderer runs several threads with small

parts of the image (rect) and each thread seems

to be independant (no info from others threads).

Precisely. You should not assume that your Render() method is called to render anything in any particular order. If it helps, pretend I'm going to be calling your Render() method once for each pixel, and in a completely randomized order.

...

It helps to be more clear about how it works. But it doesn't help me to create this plugin!

I tried with a table, expecting I could first fill it, then read it to update the image, but I can't isolate this routing in a pre-rendering stage! Meaning the subroutine (even if it uses selection instead rect) is ran at each render loop... If we could code some pre-rendering function, I actually don't know how, and so I miss this information.

Link to comment
Share on other sites

Headache 1: Solved ?

int Amount1=80; //[0,100]% Length Ratio
int Amount2=5;   //[0,100]Bars Width (in px)

bool done = false;
int max = 999999;
int[] tbMax;
[ThreadStatic] 
private static Random threadRand = new Random(); 

void Render(Surface dst, Surface src, Rectangle rect)
{
 float ratio = (float)Amount1 / 100.0f;  
 PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds);
 Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();

 long CenterX = (long)(((selection.Right - selection.Left) / 2)+selection.Left);
 long CenterY = (long)(((selection.Bottom - selection.Top) / 2)+selection.Top);
 ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
 ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor;
 int BrushWidth = (int)EnvironmentParameters.BrushWidth;
 int x,y,m,r; 
 ColorBgra CurrentPixel;

 if (threadRand == null) 
   threadRand = new Random(unchecked(System.Threading.Thread.CurrentThread.GetHashCode() ^ unchecked((int)DateTime.Now.Ticks))); 
 Random localRand = threadRand; 

// Initialisation of the table :
// one cell per column, value to 0
 if (max == 999999) 
 { 
   max = (selection.Right - selection.Left);
   tbMax = new int[max];
   for (x = 0; x < max; x++) tbMax[x]=0;
 }

// Could I call this a pre-rendering loop?
// max = number of columns.
// As long as I haven't calculated each column I'm in this loop.
// I fill the table with a value.
// the value is the random max selected and memorized!
 if (!done)
 {
   r = 0;
   m = 0;
   y = 0; 
   { // 'for y' group (in fact y=0!)
     for (x = rect.Left; x < rect.Right; x++)
     {
       max-=1;
       if (max<=0) done=true;
       if (r<=0)
       {
         r=Amount2;
         m=(int)(ratio * (float)(localRand.Next(selection.Bottom - selection.Top) + selection.Top));
       }
       tbMax[x] = m;
       r-=1;
     }
   }
 }

// the table is filled. I can go on... 
 if (done)
 {
   for(y = rect.Top; y < rect.Bottom; y++)
   {
     for (x = rect.Left; x < rect.Right; x++)
     {
       if (selectionRegion.IsVisible(x, y))
       {
         CurrentPixel = src[x,y];
         if (y<=tbMax[x]) CurrentPixel = PrimaryColor;
         dst[x,y] = CurrentPixel;
       }
     }
   }
 }
}

Am I on the right way ?

Link to comment
Share on other sites

Headache 1: Solved ?

int Amount1=80; //[0,100]% Length Ratio
int Amount2=5;   //[0,100]Bars Width (in px)

bool done = false;
int max = 999999;
int[] tbMax;
[ThreadStatic] 
private static Random threadRand = new Random(); 

void Render(Surface dst, Surface src, Rectangle rect)
{
 float ratio = (float)Amount1 / 100.0f;  
 PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds);
 Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();

 long CenterX = (long)(((selection.Right - selection.Left) / 2)+selection.Left);
 long CenterY = (long)(((selection.Bottom - selection.Top) / 2)+selection.Top);
 ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
 ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor;
 int BrushWidth = (int)EnvironmentParameters.BrushWidth;
 int x,y,m,r; 
 ColorBgra CurrentPixel;

 if (threadRand == null) 
   threadRand = new Random(unchecked(System.Threading.Thread.CurrentThread.GetHashCode() ^ unchecked((int)DateTime.Now.Ticks))); 
 Random localRand = threadRand; 

// Initialisation of the table :
// one cell per column, value to 0
 if (max == 999999) 
 { 
   max = (selection.Right - selection.Left);
   tbMax = new int[max];
   for (x = 0; x < max; x++) tbMax[x]=0;
 }

// Could I call this a pre-rendering loop?
// max = number of columns.
// As long as I haven't calculated each column I'm in this loop.
// I fill the table with a value.
// the value is the random max selected and memorized!
 if (!done)
 {
   r = 0;
   m = 0;
   y = 0; 
   { // 'for y' group (in fact y=0!)
     for (x = rect.Left; x < rect.Right; x++)
     {
       max-=1;
       if (max<=0) done=true;
       if (r<=0)
       {
         r=Amount2;
         m=(int)(ratio * (float)(localRand.Next(selection.Bottom - selection.Top) + selection.Top));
       }
       tbMax[x] = m;
       r-=1;
     }
   }
 }

// the table is filled. I can go on... 
 if (done)
 {
   for(y = rect.Top; y < rect.Bottom; y++)
   {
     for (x = rect.Left; x < rect.Right; x++)
     {
       if (selectionRegion.IsVisible(x, y))
       {
         CurrentPixel = src[x,y];
         if (y<=tbMax[x]) CurrentPixel = PrimaryColor;
         dst[x,y] = CurrentPixel;
       }
     }
   }
 }
}

Am I on the right way ?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...