我的目标是将使用Graphics对象的方法绘制的可视元素移动到没有闪烁或伪像的Form上(在.NET 3.5中)。我可以通过使用自动双缓冲(将Form的DoubleBuffered属性设置为true)或自己实现后缓冲来成功实现无闪烁运动。然而,我正在努力找到一种方法来使用任何一种方法,而没有明显可见的工件显示。
使用自动双缓冲时,页面撕裂效果很明显。看起来后退缓冲区正在缓慢地,逐渐地从上到下复制到表单中,多达三次刷新我的60Hz LCD。
当我自己实现双缓冲时(详见代码块),看起来后面的缓冲区被快速复制到表单中,不会发生页面撕裂。然而,有时会出现另一种类型的工件下面的代码,允许您使用箭头键在表单上左右移动白色背景上的蓝色矩形,应该将效果重现为一系列水平白色条带,有时会出现在矩形的左右边缘就像它被移动一样。
public partial class Form1 : Form {
int x;
Bitmap buffer;
public Form1() {
InitializeComponent();
buffer = new Bitmap(Width, Height);
}
private void Form1_Paint(object sender, PaintEventArgs e) {
Graphics g = Graphics.FromImage(buffer);
g.Clear(Color.FromArgb(255, 255, 255));
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.FillRectangle(Brushes.Blue, x, 0, 100, 500);
e.Graphics.DrawImageUnscaled(buffer, 0, 0);
}
protected override void OnPaintBackground(PaintEventArgs pevent) {
//Don't allow the background to paint
}
private void Form1_KeyDown(object sender, KeyEventArgs e) {
const int scrollSpeed = 20;
if(e.KeyData == Keys.Left) {
x -= scrollSpeed;
Refresh();
}
else {
if(e.KeyData == Keys.Right) {
x += scrollSpeed;
Refresh();
}
}
}
}
if(其他人能够重现效果){
我做错了什么,也许会引发一些问题
在绘画代码中的种类条件或是
这只是我必须运行的运行时行为
和谁一起生活?
}
否则{
它可能是我的显示卡或一个特殊的
有问题的显示驱动程序?
}
答案 0 :(得分:1)
重要的是要知道加速2D操作的图形卡通常会加速GDI,而不是GDI +。我认为使用GDI位图并使用GDI方法(例如通过p / invoke)直接绘制它会使事情变得更快。
答案 1 :(得分:1)
每当我完成双缓冲时,我确保在Paint事件中没有渲染代码;事件中唯一的代码是从缓冲区复制到屏幕。
尝试将渲染代码移动到自己的函数中,然后使区域无效(在本例中为表单):
RenderScene()
Invalidate()
看看是否有帮助。为了更好地衡量,请覆盖OnResize以调整缓冲区的大小。
答案 2 :(得分:0)
当按下按键并释放时,对我来说实际上看起来“很好”(但是如果你按下按键,会有一点点撕裂,在下一步行动中自行解决)。
我使用的是ATI x1300和Intel e6400。也许处理速度或视频卡是一个问题?
编辑:上面说的是,我会同意其他人的说法,如果你正在寻找快速的话,说GDI +不是要走的路。 DirectX或使用Windows API可能是最佳选择。
答案 3 :(得分:0)
除了过度使用Invalidate
所说的内容之外,你也不需要使用抗锯齿来填充没有应用变换的矩形。