你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 编程语言
在C++ Builder中进行DirectX编程(下)
 

7 dx3源程序

1dx3文件组成为:工程文件(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;

  //动画图形文件包含12100*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();

}

 

  推荐精品文章

·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089