画图时,如何解决闪烁的问题?
rt 问题点数:20、回复次数:6Top
1 楼rongh(topone)回复于 2003-08-04 18:53:32 得分 10
用双缓冲。Top
2 楼ljzcom()回复于 2003-08-04 19:15:29 得分 0
可以给个具体的例子吗?Top
3 楼GZCompiler(编译器)回复于 2003-08-04 20:04:50 得分 0
搜一下吧,这方面的帖子挺多的。充分利用资源。Top
4 楼warmchang(风滑过的痕迹)回复于 2003-08-04 20:31:40 得分 10
使用双缓冲,在内存里面画完了以后在BitBlt出去。Top
5 楼smartax(招聘实习女友)回复于 2003-08-04 20:40:13 得分 0
或是用DIRECTDRAW,建立个主页面后一个后台缓存,然后不停交替换页,实现无闪烁动画~~
#include <windows.h>
#include <ddraw.h>
#include <math.h> //为后面调用一些数学函数做准备
#include "ddutil.h"
LPDIRECTDRAW7 lpDD; // DirectDraw对象的指针
LPDIRECTDRAWSURFACE7 lpDDSPrimary; // DirectDraw主页面的指针
LPDIRECTDRAWSURFACE7 lpDDSBuffer; // DirectDraw后台缓存的指针
LPDIRECTDRAWSURFACE7 lpDDSBack; // 存放背景图的页面的指针
HWND hwnd;
WNDCLASS wc;
static BOOL InitWindow( HINSTANCE hInstance, int nCmdShow );
LRESULT CALLBACK WinProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);
void InitDDraw( );
void Refresh( );
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
InitWindow(hInstance,nCmdShow);
InitDDraw();
while(1)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message==WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
Refresh();
}
}
return msg.wParam;
}
static BOOL InitWindow( HINSTANCE hInstance, int nCmdShow )
{
WNDCLASS wc;
wc.style = NULL;
wc.lpfnWndProc = (WNDPROC)WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "YXBCZN_CHAPTER_IV";
RegisterClass(&wc);
hwnd = CreateWindow("YXBCZN_CHAPTER_IV",
"DirectDraw DEMO",
WS_POPUP|WS_MAXIMIZE,0,0,
GetSystemMetrics( SM_CXSCREEN ),
GetSystemMetrics( SM_CYSCREEN ),
NULL,NULL,hInstance,NULL);
if( !hwnd ) return FALSE;
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
return TRUE;
}
LRESULT CALLBACK WinProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case WM_SETCURSOR:
SetCursor(NULL);
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
void InitDDraw( )
{
DDSURFACEDESC2 ddsd; // DirectDraw的页面描述
DirectDrawCreateEx (NULL, (void **)&lpDD, IID_IDirectDraw7, NULL); //创建DirectDraw对象
lpDD->SetCooperativeLevel(hwnd,DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN); //设置DirectDraw控制级
lpDD->SetDisplayMode( 800, 600, 32, 0, DDSDM_STANDARDVGAMODE ); //设置显示模式
//开始创建主页面,先清空页面描述
memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
//填充页面描述
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT; //有后台缓存
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount = 1; //一个后台缓存
lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL ); //创建主页面
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; //这是后台缓存
lpDDSPrimary->GetAttachedSurface( &ddsd.ddsCaps, &lpDDSBuffer ); //创建后台缓存
//下面的语句会将lpDDSPrimary和lpDDSBuffer全部涂上黑色,在5.1节会介绍
DDBLTFX ddBltFx;
ddBltFx.dwSize=sizeof(DDBLTFX);
ddBltFx.dwFillColor=RGB(0,0,0); //要填充的颜色
lpDDSPrimary->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddBltFx);
lpDDSBuffer->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddBltFx);
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; //这是离屏页面
ddsd.dwHeight = 16; //高
ddsd.dwWidth = 16; //宽
lpDD->CreateSurface( &ddsd, &lpDDSBack, NULL ); //创建放背景图的页面
DDReLoadBitmap(lpDDSBack,"Ball.BMP");
DDSetColorKey(lpDDSBack,RGB(255,255,255));
}
void Refresh()
{
static float x=0,y=0; //存储小球的位置
x+=(cos(y/13)-sin(y/37)); y-=(sin(x/41)+cos(x/29)); //计算小球的新位置
//你可以随便修改这里的公式
//把小球放到新位置上
lpDDSBuffer->BltFast(350+x/4,580+y/4,lpDDSBack,NULL,DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT);
lpDDSPrimary->Flip(NULL,DDFLIP_WAIT);//翻页,完成刷新
}Top
6 楼jvcit(々燕归来々)回复于 2003-08-04 20:40:26 得分 0
www.vckbase.com 上有Top




