双缓冲绘图问题,我用了双缓冲,并且 InvalidateRect(NULL,FALSE),OnEraseBkgnd()返回true,闪烁为什么还是存在?

golduty2 2009-06-25 01:10:53
先上代码
void Draw(CDC *p,double house[28][4],int Color,int DispAxis)
{
double x0,y0,z0,x1,y1,z1,x2,y2,z2,x3,y3,z3;
int nface=0;



CDC MemDC; //首先定义一个显示设备对象
CBitmap MemBitmap;//定义一个位图对象
//HWND hwndIE = FindWindow(CMy3D_ShowDlg,NULL);

//随后建立与屏幕显示兼容的内存显示设备
MemDC.CreateCompatibleDC(NULL);

//这时还不能绘图,因为没有地方画 ^_^
//下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小
CRect rect;
GetClientRect(AfxGetMainWnd()->m_hWnd,&rect);
MemBitmap.CreateCompatibleBitmap(p,rect.Width(),rect.Height());

//将位图选入到内存显示设备中
//只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);

//先用背景色将位图清除干净,这里我用的是黑色作为背景
MemDC.FillSolidRect(0,0,rect.Width(),rect.Height(),BLACK);


CPen pen(PS_SOLID,1,Color);
CBrush brush(MYCOLOR);
MemDC.SelectObject(pen);
MemDC.SelectObject(brush);

for(nface=0;nface<6;nface++)
{
MemDC.BeginPath();

x0=house[nface*4][0];
y0=house[nface*4][1];
z0=house[nface*4][2];
x1=house[nface*4+1][0];
y1=house[nface*4+1][1];
z1=house[nface*4+1][2];
x2=house[nface*4+2][0];
y2=house[nface*4+2][1];
z2=house[nface*4+2][2];
x3=house[nface*4+3][0];
y3=house[nface*4+3][1];
z3=house[nface*4+3][2];



moveto2(&MemDC,house[nface*4][0],house[nface*4][1],house[nface*4][2]);
lineto2(&MemDC,house[nface*4+1][0],house[nface*4+1][1],house[nface*4+1][2]);
lineto2(&MemDC,house[nface*4+2][0],house[nface*4+2][1],house[nface*4+2][2]);
lineto2(&MemDC,house[nface*4+3][0],house[nface*4+3][1],house[nface*4+3][2]);
lineto2(&MemDC,house[nface*4][0],house[nface*4][1],house[nface*4][2]);

MemDC.EndPath();
MemDC.FillPath();

}
//将内存中的图拷贝到屏幕上进行显示
p->BitBlt(0,0,rect.Width(),rect.Height(),&MemDC,0,0,SRCCOPY);
//绘图完成后的清理
MemBitmap.DeleteObject();
MemDC.DeleteDC();


首先一个奇怪的地方就是红色部分网上都是只有一个参数,但是我必须要两个参数,非要我给个窗口句柄,我只好这样写了,也不知道对不对,不过图是画出来了的,说明应该是对的,但是只要我一拖动(其他地方有相应的处理拖动的函数,都是来调用draw的),还是在狂闪烁,完全没变化,大家帮忙看看吧,到底是咋回事啊。在线等啊,整了两天了!
希望大家帮助!!!谢谢!!!!
...全文
213 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
golduty2 2009-06-25
  • 打赏
  • 举报
回复
太谢谢大家了!! 我犯了一个很低级的错误!!

我在窗体的onpaint中填充了一次背景色!!! 导致了无论我在算法中怎么双缓冲 一直都会闪烁! 因为onpaint里就有一次填充! 它是罪魁祸首!!


还是很感谢大家 这个事情错在我 那段代码没给出来 不然大家都看出来了就 我太笨了~ 呵呵


分给大家,谢谢大家!!
fengrx 2009-06-25
  • 打赏
  • 举报
回复
将InvalidateRect(NULL,false);的调用的地方直接修改成Draw的调用。
NTooL 2009-06-25
  • 打赏
  • 举报
回复
你可以在鼠标移动时不重绘,鼠标抬起时重绘,或者在鼠标按下并拖动时开个定时器,100ms刷一次,鼠标抬起时关掉定时器。
fandh 2009-06-25
  • 打赏
  • 举报
回复 1
OnMouseMove(UINT nFlags, CPoint point)中不停的调用InvalidateRect,肯定会闪烁的!
这时候,不要调用InvalidateRect ,建议先在内存中画好,然后贴图!
NTooL 2009-06-25
  • 打赏
  • 举报
回复


BOOL CTtDlg::OnEraseBkgnd(CDC * pDC)
{
return TRUE;
}

背景去掉了吗?加上这两句试试 ON_WM_ERASEBKGND() 填到消息映射里
golduty2 2009-06-25
  • 打赏
  • 举报
回复
Rotate处理的是拖动的如果是图像中的坐标轴时图像的变换
Move处理的是整体图像拖动的变换

做这两个都还是会闪烁
golduty2 2009-06-25
  • 打赏
  • 举报
回复
Rotate函数也是自己写的 也是改变house的一些数值,只是在变换三维坐标
golduty2 2009-06-25
  • 打赏
  • 举报
回复
好的 拖动处理的贴出来


void CMy3D_ShowDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
// & bit-and
// && logical-and
if(nFlags & MK_LBUTTON && RotateMode!=ROTATE_N)
{
if(oldPoint.x<point.x)
Rotate(house,-R_STEP,RotateMode);
else
Rotate(house,R_STEP,RotateMode);
InvalidateRect(NULL,false);
}
else if(nFlags & MK_LBUTTON && flag == 1)
{
if(oldPoint.x!=point.x||oldPoint.y!=point.y)
{
Move(house,point.x-oldPoint.x,oldPoint.y-point.y,0);
InvalidateRect(NULL,false);
}
InvalidateRect(NULL,false);

}
oldPoint=point;
CDialog::OnMouseMove(nFlags, point);
}



这里是拖动处理的,其中的move函数是自己写的,也贴出来


void Move(double house[28][4],double x,double y,double z)
{
double SMatrix[4][4];
ResetMatrix(SMatrix);
SMatrix[3][0]=x;
SMatrix[3][1]=y;
SMatrix[3][2]=z;
MultiMatrix((double*)house,SMatrix,28,4);
}


这是一个调用矩阵乘法做三维变换的函数,具体的乘法就是一个算法,就是改变了house【28】【4】的点的值,然后InvalidateRect(NULL,false);的时候,传给第一个贴出来的draw的参数就变了,于是图像位置就变了。大体就是这样 帮我看下吧 谢了!!!
Ryanwen 2009-06-25
  • 打赏
  • 举报
回复
1个参数,2个参数,这个无所谓,一个是调用CWnd成员函数,一个调用SDK函数,效果没区别

这段代码的双缓冲看不出什么问题,拖动刷新部分是怎么做的?
skyxie 2009-06-25
  • 打赏
  • 举报
回复
1个参数,2个参数,效果都是一样的...
问题应该在拖动处理的地方...你把那里的代码贴出来看看
skyxie 2009-06-25
  • 打赏
  • 举报
回复
你如果写 this->GetClientRect(&rect);就只需要一个参数了~ 你那样,调用到了SDK的函数了.
golduty2 2009-06-25
  • 打赏
  • 举报
回复
GetClientRect(AfxGetMainWnd()->m_hWnd,&rect);
这里我想设成红色的,没成功,晕。。。。

急等 谢谢大家了

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧