Jef Patat
February 23rd, 2006, 10:39 AM
Hi all,
I'm doing a design in which i use double buffering for flickerfree drawing.
I would like to use something i like to call triple buffering.
The background will always be the same, but is a grid so I have to draw it myself, it's not an image.
I would like to be able to only draw this background when a resize function is called.
So I created these two functions, in the main application the buffer is drawn in the onpaint.
public void Resize(int width, int height)
{
background = new Bitmap(width, height);
Graphics backgroundGraphic = null;
backgroundGraphic = Graphics.FromImage(background);
backgroundGraphic.Clear(Color.Blue);
//backgroundGraphic.DrawRectangle(new Pen(Color.Red, 1),0,0,200, 200);
DrawGrid(backgroundGraphic);
backgroundGraphic.Dispose();
}
public void Draw(Bitmap buffer)
{
int minimumPoint;
int maximumPoint;
if(buffer.Width != background.Width || buffer.Height != background.Height)
Resize(buffer.Width, buffer.Height);
Graphics g=null;
g=Graphics.FromImage(buffer);
g.Clear(backgroundColor);
//Resize(buffer.Width, buffer.Height);
g.DrawImage(background, 0, 0);
// Calculate the main drawing region
screenRectangle = g.VisibleClipBounds;
// Reduce the rectangle to accommodate the margins
screenRectangle.Inflate(new Size(-margin, -margin));
//DrawGrid(g);
RecalculatePrecissions(dataRectangle.Width, dataRectangle.Height);
DrawXAxis(g);
DrawYAxis(g);
DrawXLabel(g);
DrawYLabel(g);
clippedRectangle = screenRectangle;
clippedRectangle.Inflate(1, 1);
g.SetClip(clippedRectangle);
// Screen origin is top-left, so y-axis needs to be reversed
float yOffset = screenRectangle.Bottom + margin;
// Draw the data sets
for (int i = 0; i < studySets.Count; i ++)
{
Study study = (Study)studySets[i];
PointF[] vector = study.Vector;
Pen pen = study.StudyPen;
minimumPoint = 0;
maximumPoint = vector.Length-1;
while(vector[minimumPoint+1].X < dataRectangle.X)minimumPoint++;
while(vector[maximumPoint-1].X > (dataRectangle.X + dataRectangle.Width))maximumPoint--;
PointF from = Transform(dataRectangle, screenRectangle, vector[0]);
from.Y = yOffset - from.Y;
for (int j = minimumPoint; j < maximumPoint; j ++)
{
PointF to = Transform(dataRectangle, screenRectangle, vector[j]);
to.Y = yOffset - to.Y;
g.DrawLine(pen, from, to);
from = to;
}
}
// Release resources
g.Dispose();
}
The problem is this doesn't work and I don't see why. The result is that the background bitmap is drawn, i can see this because of it's color, but the lines drawn on this bitmap are gone, and some irrelevant dots appear, as if those lines are moved to a very small area.
If I uncomment the line
//Resize(buffer.Width, buffer.Height);
in the draw function then it does work, however, then this triple buffering idea is useless, how to get around this?
Kind regards, Jef
I'm doing a design in which i use double buffering for flickerfree drawing.
I would like to use something i like to call triple buffering.
The background will always be the same, but is a grid so I have to draw it myself, it's not an image.
I would like to be able to only draw this background when a resize function is called.
So I created these two functions, in the main application the buffer is drawn in the onpaint.
public void Resize(int width, int height)
{
background = new Bitmap(width, height);
Graphics backgroundGraphic = null;
backgroundGraphic = Graphics.FromImage(background);
backgroundGraphic.Clear(Color.Blue);
//backgroundGraphic.DrawRectangle(new Pen(Color.Red, 1),0,0,200, 200);
DrawGrid(backgroundGraphic);
backgroundGraphic.Dispose();
}
public void Draw(Bitmap buffer)
{
int minimumPoint;
int maximumPoint;
if(buffer.Width != background.Width || buffer.Height != background.Height)
Resize(buffer.Width, buffer.Height);
Graphics g=null;
g=Graphics.FromImage(buffer);
g.Clear(backgroundColor);
//Resize(buffer.Width, buffer.Height);
g.DrawImage(background, 0, 0);
// Calculate the main drawing region
screenRectangle = g.VisibleClipBounds;
// Reduce the rectangle to accommodate the margins
screenRectangle.Inflate(new Size(-margin, -margin));
//DrawGrid(g);
RecalculatePrecissions(dataRectangle.Width, dataRectangle.Height);
DrawXAxis(g);
DrawYAxis(g);
DrawXLabel(g);
DrawYLabel(g);
clippedRectangle = screenRectangle;
clippedRectangle.Inflate(1, 1);
g.SetClip(clippedRectangle);
// Screen origin is top-left, so y-axis needs to be reversed
float yOffset = screenRectangle.Bottom + margin;
// Draw the data sets
for (int i = 0; i < studySets.Count; i ++)
{
Study study = (Study)studySets[i];
PointF[] vector = study.Vector;
Pen pen = study.StudyPen;
minimumPoint = 0;
maximumPoint = vector.Length-1;
while(vector[minimumPoint+1].X < dataRectangle.X)minimumPoint++;
while(vector[maximumPoint-1].X > (dataRectangle.X + dataRectangle.Width))maximumPoint--;
PointF from = Transform(dataRectangle, screenRectangle, vector[0]);
from.Y = yOffset - from.Y;
for (int j = minimumPoint; j < maximumPoint; j ++)
{
PointF to = Transform(dataRectangle, screenRectangle, vector[j]);
to.Y = yOffset - to.Y;
g.DrawLine(pen, from, to);
from = to;
}
}
// Release resources
g.Dispose();
}
The problem is this doesn't work and I don't see why. The result is that the background bitmap is drawn, i can see this because of it's color, but the lines drawn on this bitmap are gone, and some irrelevant dots appear, as if those lines are moved to a very small area.
If I uncomment the line
//Resize(buffer.Width, buffer.Height);
in the draw function then it does work, however, then this triple buffering idea is useless, how to get around this?
Kind regards, Jef