7. dx3源程序
(1)dx3文件组成为:工程文件(dx3.bpr)、窗口文件(main.cpp)、头文件(main.h)、动画图形文件(spirit.bmp)。
(2)头文件main.h清单
#ifndef mainH
#define mainH
//-------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Dialogs.hpp>
#include "d:\dx6sdk\include\ddraw.h" //指定DirectDraw开发包的头文件
//-------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
(系统自动生成,省略)
private: // User declarations
LPDIRECTDRAW FAR lpDD; //DirectDarw指针
LPDIRECTDRAW2 FAR lpDD2; // DirectDarw2指针
DDSURFACEDESC ddsd;
LPDIRECTDRAWSURFACE FAR lpDDPrimary,lpDDOffScreen,lpDDSBack;
//主图面指针、后台图面指针、复杂后台切换图面指针
DDSCAPS ddscaps;
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//-------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//-------------------------------------------------------------------------#endif
(3)程序文件main.cpp
#include <vcl.h>
#pragma hdrstop
#include "main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner) {}
//释放DirectX对象,退出程序-----------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
if(lpDD2) lpDD2->Release();
}
//创建DirectX对象及设置显示方式-------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(!FAILED(DirectDrawCreate(NULL,&lpDD,NULL)))
{
if(!FAILED(lpDD->QueryInterface(IID_IDirectDraw2,(LPVOID *)&lpDD2)))
{
lpDD->Release();
if(!FAILED(lpDD2->SetCooperativeLevel(Handle,
DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN|DDSCL_NOWINDOWCHANGES)))
{
if(!FAILED(lpDD2->SetDisplayMode(800,600,8,0,0)))
{
Memo1->Lines->Text=Memo1->Lines->Text+"Create DirectDraw Object OK.\n";
Button1->Enabled=false;
Button2->Enabled=true;
return;
}
}
}
}
Memo1->Lines->Text=Memo1->Lines->Text+"Create DirectDraw Object Failed.\n";
}
//创建主图面及复合切换图面------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
ddsd.dwFlags=DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE
|DDSCAPS_FLIP
|DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount=1; //一个后台切换图面
if(FAILED(lpDD2->CreateSurface(&ddsd,&lpDDPrimary,NULL)))
Memo1->Lines->Text=Memo1->Lines->Text+"Create Priamry Complex Surface Failed.\n";
else
{
Memo1->Lines->Text=Memo1->Lines->Text+"Create Priamry Complex Surface OK.(BufferCount=1)\n";
Button2->Enabled=false;
Button3->Enabled=true;
}
}
//创建后台图面并装入图形--------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
HDC hdc,hdcImage;
HBITMAP hbm;
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
ddsd.dwFlags=DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH;
//动画图形文件包含12个100*312的图形,图面大小应正好保存所有图形
ddsd.dwWidth=400; //100点*4列
ddsd.dwHeight=312; //104点*3行
ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN;
if(FAILED(lpDD2->CreateSurface(&ddsd,&lpDDOffScreen,NULL)))
Memo1->Lines->Text=Memo1->Lines->Text+"Create OffScreen Surface Failed.\n";
else
{
Memo1->Lines->Text=Memo1->Lines->Text+"Create OffScreen Surface OK.\n";
if(FAILED(lpDDOffScreen->GetDC(&hdc)))
{
Memo1->Lines->Text=Memo1->Lines->Text+"Get DC of OffScreen Screen Surface Failed.\n";
return;
}
else
{
Memo1->Lines->Text=Memo1->Lines->Text+"Get DC of OffScreen Screen Surface OK.\n";
hbm=(HBITMAP)LoadImage(NULL,"spirit.bmp",IMAGE_BITMAP,400,312,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
hdcImage=CreateCompatibleDC(NULL);
SelectObject(hdcImage,hbm);
if(BitBlt(hdc,0,0,400,312,hdcImage,0,0,SRCCOPY)==FALSE)
Memo1->Lines->Text=Memo1->Lines->Text+"OffScreen Screen BitBlt Failed.\n";
else
Memo1->Lines->Text=Memo1->Lines->Text+"OffScreen Screen BitBlt OK.\n";
lpDDOffScreen->ReleaseDC(hdc);
}
if(hdcImage) DeleteDC(hdcImage);
if(hbm) DeleteObject(hbm);
Button3->Enabled=false;
Button4->Enabled=true;
}
}
//获得主图面后端缓冲区指针------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
ddscaps.dwCaps=DDSCAPS_BACKBUFFER;
if(FAILED(lpDDPrimary->GetAttachedSurface(&ddscaps,&lpDDSBack)))
{
Memo1->Lines->Text=Memo1->Lines->Text+"Get Pointer to Back Buffer Failed.\n";
}
else
{
Memo1->Lines->Text=Memo1->Lines->Text+"Get Pointer to Back Buffer OK.\n";
Button4->Enabled=false;
Button5->Enabled=true;
Button6->Enabled=true;
Button7->Enabled=true;
}
}
//主图面直接绘图动画------------------------------------------------------------
void __fastcall TForm1::Button5Click(TObject *Sender)
{
HDC hdcPrimary,hdcOffScreen;
WORD x=0,y=0;
lpDDPrimary->GetDC(&hdcPrimary);
lpDDOffScreen->GetDC(&hdcOffScreen);
for(int i=0;i<24;i++) //循环播放动画2遍
{
//将图形数据从hdcOffScreen直接位传送到主图面hdsPrimary
BitBlt(hdcPrimary,0,0,100,104,hdcOffScreen,x*100,y*104,SRCCOPY);
if(x<3) x++; else { x=0; y<2?y++:y=0; }
Sleep(150);
}
lpDDOffScreen->ReleaseDC(hdcOffScreen);
lpDDPrimary->ReleaseDC(hdcPrimary);
}
//利用后端缓冲实现动画----------------------------------------------------------
void __fastcall TForm1::Button6Click(TObject *Sender)
{
HDC hdcPrimary,hdcPrimaryBack,hdcOffScreen;
WORD x=0,y=0;
for(int i=0;i<24;i++)
{
lpDDPrimary->GetDC(&hdcPrimary); //主图面DC
lpDDOffScreen->GetDC(&hdcOffScreen); //后台图面DC
lpDDSBack->GetDC(&hdcPrimaryBack); //切换图面DC
//将主图面图形复制到切换图面作为背景
BitBlt(hdcPrimaryBack,0,0,800,600,hdcPrimary,0,0,SRCCOPY);
//将hdcOffScreen精灵动画帧位传送到切换图面(0,0)处
BitBlt(hdcPrimaryBack,0,0,100,104,hdcOffScreen,x*100,y*104,SRCCOPY);
//释放DC
lpDDPrimary->ReleaseDC(hdcPrimary);
lpDDOffScreen->ReleaseDC(hdcOffScreen);
lpDDSBack->ReleaseDC(hdcPrimaryBack);
//切换
lpDDPrimary->Flip(NULL,DDFLIP_WAIT);
if(x<3) x++; else { x=0; y<2?y++:y=0; }
}
}
//BltFast透明动画---------------------------------------------------------------
void __fastcall TForm1::Button7Click(TObject *Sender)
{
LPDIRECTDRAWSURFACE lpDDBuffer; //保存屏幕(主图面)图形以便恢复
RECT rect;
DDCOLORKEY ColorKey;
DDSURFACEDESC ddsd;
WORD x=0,y=0;
DWORD DrawX=0,dw;
HRESULT hre;
//创建保存屏幕图形的图面lpDDBuffer
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
ddsd.dwFlags=DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH;
ddsd.dwHeight=600;
ddsd.dwWidth=800;
ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN;
lpDD2->CreateSurface(&ddsd,&lpDDBuffer,NULL);
//保存主图面初始屏幕图形
lpDDBuffer->BltFast(0,0,lpDDPrimary,NULL,
DDBLTFAST_NOCOLORKEY|DDBLTFAST_WAIT);
//设置精灵图形绘画的透明颜色值
ddsd.dwSize=sizeof(ddsd);
while((hre=lpDDOffScreen->Lock(NULL,&ddsd,0,NULL))==
DDERR_WASSTILLDRAWING);
if(hre==DD_OK)
{
dw=*(DWORD *)ddsd.lpSurface; //取得DWORD类型后台表面(0,0)点颜色值
if (ddsd.ddpfPixelFormat.dwRGBBitCount < 32)
dw &=(1<<ddsd.ddpfPixelFormat.dwRGBBitCount)-1; // Mask it to bpp
lpDDOffScreen->Unlock(NULL);
}
ColorKey.dwColorSpaceLowValue=dw;
ColorKey.dwColorSpaceHighValue=dw;
Memo1->Lines->Text=Memo1->Lines->Text+"Color Key="+IntToStr(dw)+"\n";
if(FAILED(lpDDOffScreen->SetColorKey(DDCKEY_SRCBLT,&ColorKey)))
Memo1->Lines->Text=Memo1->Lines->Text+"Set Source Color Key Failed.\n";
else
Memo1->Lines->Text=Memo1->Lines->Text+"Set Source Color Key OK.\n";
//运行动画4次,使人物走动
for(int i=0;i<48;i++)
{
//在后台图面绘画已保存的背景
lpDDSBack->BltFast(0,0,lpDDBuffer,NULL,
DDBLTFAST_NOCOLORKEY|DDBLTFAST_WAIT);
rect.left=x*100; rect.top=y*104;
rect.right=(x+1)*100-1; rect.bottom=(y+1)*104-1;
//用透明方式绘画精灵的动画帧
lpDDSBack->BltFast(DrawX,0,lpDDOffScreen,&rect,
DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT);
DrawX+=4; //下一帧图形右移4个点
lpDDPrimary->Flip(NULL,DDFLIP_WAIT);
if(x<3) x++; else { x=0; y<2?y++:y=0; }
Sleep(150);
}
//动画播放完成后恢复已保存的原始屏幕内容
lpDDPrimary->BltFast(0,0,lpDDBuffer,NULL,
DDBLTFAST_NOCOLORKEY|DDBLTFAST_WAIT);
lpDDBuffer->Release();
}
|