一些directdraw整合的画图类

来源:互联网 发布:软件测试工具 编辑:程序博客网 时间:2024/06/09 16:51
 
// Graphic.h: interface for the CGraphic class.////////////////////////////////////////////////////////////////////////#if !defined(AFX_GRAPHIC_H__AEDE17EF_1768_44AF_854B_EB2C98936FAB__INCLUDED_)#define AFX_GRAPHIC_H__AEDE17EF_1768_44AF_854B_EB2C98936FAB__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include "head.h"class CGraphic  {private:bool                    m_bfScreen;    // 是否全屏(在WIN32下通常都为全屏)DWORD                   m_dwHeight;    // 屏幕高DWORD                   m_dwWidth;     // 屏幕宽DWORD                   m_dwCDepth;    // 颜色深度(8位、16位、32位、64位,通常为32位)HWND                    m_hWnd;        // 窗口句柄LPDIRECTDRAW7           m_pDD7;        // DirectDraw对象LPDIRECTDRAWSURFACE7    m_pPSur;       // 前(页)缓冲LPDIRECTDRAWSURFACE7    m_pBBuf;       // 后(页)缓冲RECT                    m_bRect;RECT                    m_rcRect;DDCOLORKEY              m_key;         // 颜色键值LPDIRECTDRAWCLIPPER     lpDDclip;      // Directdraw剪切板(用途相当于把图纸上的没用的东西剪掉,留下我们要看的东西)POINT                   m_MPos;         //--光标的位置public:CGraphic();virtual ~CGraphic();    LPDIRECTDRAWSURFACE7 GetPBuffer(){return m_pPSur;} LPDIRECTDRAWSURFACE7 GetBBuffer(){return m_pBBuf;}//----------------------------------------------------------------------------------------//Name: InitDDraw 初始化离屏窗体//Desc: hWnd 当前窗口//      bfScreen 是否全屏//      Width 屏幕宽//      Height 屏幕高//      CDepth 颜色深度//----------------------------------------------------------------------------------------bool InitDDraw(HWND hWnd,bool bfScreen,DWORD Height,DWORD Width,DWORD CDepth);//----------------------------------------------------------------------------------------//Name: LoadToOffScreen 初始化离屏缓冲区(加载位图)//Desc: oBuffer为指向离屏缓冲区的指针   dwWidth 离屏缓存区的宽,   //      dwHeight离屏缓存区的高,         BitMapFile 位图源文件//      b_ColorKey  是否需要透明        color 透明色//----------------------------------------------------------------------------------------bool LoadToOffScreen(LPDIRECTDRAWSURFACE7& oBuffer,DWORD dwWidth,DWORD dwHeight,                  LPCSTR BitMapFile,bool b_ColorKey,DWORD color);//----------------------------------------------------------------------------------------//Name: BltBBuffer 画图//Desc: oBuffer 缓冲//      b_ColorKey 是否需要透明,   //      x  图片的X坐标//      y  图片的Y坐标//      ClipX  图片抠像X起点 //      ClipY  图片抠像Y起点//      ClipEndX 图片抠像X结束点//      CLipEndY 图片抠像Y结束点//----------------------------------------------------------------------------------------void BltBBuffer(LPDIRECTDRAWSURFACE7 oBuffer,bool b_ColorKey,int x ,int y,  int ClipX,    int ClipY,    int ClipEndX,     int CLipEndY);    // 翻页void Flip();// 清除当前图片资源(这样可以重新加载一个新的图片进来)void ClearBuffer(LPDIRECTDRAWSURFACE7& Buffer);// 文字输出void OutText(LPCSTR str, int x, int y,COLORREF color);// 设置鼠标区域(加载鼠标图片时可以使用)void SetMouseRect(RECT* m_rect, int scWidth, int scHeight, int msWidth, int msHeight);// 光标    /*void CopyToBuffer(LPDIRECTDRAWSURFACE7& SrcBuffer,LPDIRECTDRAWSURFACE7& DestBuffer,          bool b_ColorKey,int x,int y,RECT m_rect);void CopyToBuffer(LPDIRECTDRAWSURFACE7& SrcBuffer,LPDIRECTDRAWSURFACE7& DestBuffer,          bool b_ColorKey,float zoomX, float zoomY);*///void Flip(int x, int y, RECT m_rect);private://----------------------------------------------------------------------------------------//Name: InitOffScreen 初始化离屏缓冲区,类内部使用,LoadToOffScreen()函数调用,外部不需要//Desc: oBuffer为指向离屏缓冲区的指针   dwWidth 离屏缓存区的宽,   //      dwHeight离屏缓存区的高,         b_ColorKey 是否需要做透明//      color 透明色//----------------------------------------------------------------------------------------bool InitOffScreen(LPDIRECTDRAWSURFACE7& oBuffer,DWORD dwWidth,DWORD dwHeight,               bool b_ColorKey,DWORD color);// 设置透明的颜色值(内部调用)void DDColorKey(LPDIRECTDRAWSURFACE7 oBuffer,DWORD color);};#endif // !defined(AFX_GRAPHIC_H__AEDE17EF_1768_44AF_854B_EB2C98936FAB__INCLUDED_)
// Graphic.cpp: implementation of the CGraphic class.////////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "Graphic.h"//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////DDSURFACEDESC2desc;           // 剪裁属性(前页主绘属性)DDSCAPS2caps;// 剪裁属性(后页属性)CGraphic::CGraphic(){m_bfScreen   = true;m_dwWidth    = 1024;m_dwHeight   = 768;m_dwCDepth   = 32;m_hWnd       = NULL;m_pDD7       = NULL;m_pPSur      = NULL;m_pBBuf      = NULL;lpDDclip     = NULL;}CGraphic::~CGraphic(){SafeRelease(lpDDclip);//删除剪裁 }//----------------------------------------------------------------------------------------//Name: InitDDraw 初始化离屏窗体//Desc: hWnd 当前窗口//      bfScreen 是否全屏//      Width 屏幕宽//      Height 屏幕高//      CDepth 颜色深度//----------------------------------------------------------------------------------------bool CGraphic::InitDDraw(HWND hWnd,bool bfScreen,DWORD Width,DWORD Height,DWORD CDepth){m_hWnd= hWnd;//窗口句柄m_bfScreen= bfScreen;//是否全屏m_dwWidth= Width;//屏幕的宽m_dwHeight= Height;//屏幕的高m_dwCDepth= CDepth;//颜色深度    HRESULT      result;// 创建一个DirectDraw对象result = DirectDrawCreateEx(NULL,// 用当前的显示驱动 (VOID**)&m_pDD7,    // DirectDraw对象IID_IDirectDraw7,   // 使用版本7,目前Draw的最高版本吧NULL);// 其它参数,没有,默认为NULLif (result != DD_OK){MessageBox(NULL, "建立DirectDraw对象失败!", NULL, MB_OK);returnfalse;}if(m_bfScreen){// 设定程序协调层级//result = m_pDD7->SetCooperativeLevel(m_hWnd, DDSCL_NORMAL);  // 窗口模式,MFC中可使用,目前在WIN32还没有找到怎么使用它result = m_pDD7->SetCooperativeLevel(m_hWnd,                  // 当前窗口DDSCL_EXCLUSIVE           // 独占|DDSCL_FULLSCREEN);       // 全屏if(result != DD_OK){MessageBox(NULL, "设定程序协调层级失败!", NULL, MB_OK);returnfalse;}// 设定屏幕显示模式(此模式将把显示器的显示模式一起改变,当窗口关闭后,将被还原)result = m_pDD7->SetDisplayMode(m_dwWidth,                 // 宽m_dwHeight,                // 高m_dwCDepth,                // 颜色深度0, DDSDM_STANDARDVGAMODE);if(result != DD_OK){MessageBox(NULL, "设定屏幕显示模式失败!", NULL, MB_OK);returnfalse;}//创剪裁器(必须在设置完DirectDraw控制级后,创建主页面之前进行)result=m_pDD7->CreateClipper(NULL,&lpDDclip,NULL);   if(result != MB_OK){   return   FALSE;   }   lpDDclip->SetHWnd(0,m_hWnd);   // 设置剪裁窗口memset(&desc, 0, sizeof(desc)); desc.dwSize= sizeof(desc);// 剪裁区大小desc.dwFlags= DDSD_CAPS | DDSD_BACKBUFFERCOUNT;// 指定剪裁模式desc.dwBackBufferCount= 1;// 后(页)备缓冲区的个数,默认为1个desc.ddsCaps.dwCaps= DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX| DDSCAPS_FLIP;  // 指定剪裁方法        // 建立主绘图页(也就是前页)        result = m_pDD7->CreateSurface(&desc, &m_pPSur, NULL);                        if(result != DD_OK)       {MessageBox(NULL, "建立主绘图页失败!", NULL, MB_OK);returnfalse;}m_pPSur->SetClipper(lpDDclip);  //设置剪裁(开始剪裁)// 连接后缓冲区(连上后,就可以进行翻页了)caps.dwCaps = DDSCAPS_BACKBUFFER;result = m_pPSur->GetAttachedSurface(&caps, &m_pBBuf);if(result != DD_OK)                                     {MessageBox(NULL, "连接后缓冲区失败!", NULL, MB_OK);returnfalse;}}else{// 窗口模式忽略,在MFC中可使用,但MFC不稳定,不推荐使用result = m_pDD7->SetCooperativeLevel(m_hWnd, DDSCL_NORMAL); if(result != DD_OK){MessageBox(NULL, "设定程序协调层级失败!", NULL, MB_OK);}DDSURFACEDESC2 desc;memset(&desc,0,sizeof(desc));ZeroMemory(&desc,sizeof(desc));desc.dwSize= sizeof(desc);desc.dwFlags= DDSD_CAPS ;//desc.dwBackBufferCount= 1;desc.ddsCaps.dwCaps= DDSCAPS_PRIMARYSURFACE;result = m_pDD7->CreateSurface(&desc, &m_pPSur, NULL);if(result != DD_OK){MessageBox(NULL, "建立主绘图页失败!", NULL, MB_OK);returnfalse;}// 4.创建辅助图面memset(&desc,0,sizeof(desc));desc.dwSize=sizeof(desc);desc.dwFlags=DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH;desc.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN;desc.dwWidth =Width;desc.dwHeight=Height;result = m_pDD7->CreateSurface(&desc,&m_pBBuf,NULL);if (FAILED(result)){MessageBox(NULL, "创建辅助图面失败!", NULL, MB_OK);returnfalse;}// 3.创建裁剪IDirectDrawClipper *lpClipper=NULL;result = m_pDD7->CreateClipper(NULL,&lpClipper,NULL);if (FAILED(result)){MessageBox(NULL, "创建裁剪区域失败!", NULL, MB_OK);returnfalse;}result = lpClipper->SetHWnd(0,hWnd);if (FAILED(result)){MessageBox(NULL, "设置窗口裁剪区域失败!", NULL, MB_OK);returnfalse;}result = m_pPSur->SetClipper(lpClipper);if (FAILED(result)){MessageBox(NULL, "设置主图面的裁剪区域失败!", NULL, MB_OK);returnfalse;}lpClipper->Release();}return true;}bool CGraphic::InitOffScreen(LPDIRECTDRAWSURFACE7& oBuffer,DWORD dwWidth,DWORD dwHeight,                     bool b_ColorKey,DWORD color){HRESULT           result;memset(&desc,0,sizeof(desc));desc.dwSize= sizeof(desc);desc.dwFlags= DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; desc.ddsCaps.dwCaps= DDSCAPS_OFFSCREENPLAIN  | DDSCAPS_SYSTEMMEMORY ; desc.dwWidth= dwWidth; desc.dwHeight= dwHeight; result = m_pDD7->CreateSurface(&desc, &oBuffer, NULL); if(result != DD_OK ){MessageBox(NULL, "建立幕后暂存区失败!", NULL,MB_OK);returnfalse;}if(b_ColorKey){    DDColorKey(oBuffer,color);}return true;}bool CGraphic::LoadToOffScreen(LPDIRECTDRAWSURFACE7& oBuffer,DWORD dwWidth  ,DWORD dwHeight,                  LPCSTR BitMapFile,bool b_ColorKey,DWORD color){HDC    m_hdc;//一个显示设备句柄HDC    m_hdcImage;//一个显示设备句柄HBITMAP    m_hBmp;BITMAP    m_fBmp;DDSURFACEDESC2  ddsd;bool    b_result;HRESULT         result;  m_hBmp = (HBITMAP)::LoadImage(NULL, BitMapFile, IMAGE_BITMAP, NULL, NULL                                , LR_LOADFROMFILE|LR_CREATEDIBSECTION);  if(NULL == m_hBmp){MessageBox(NULL, "读取位图失败!", NULL, MB_OK);returnfalse;}GetObject(m_hBmp,sizeof(m_fBmp),&m_fBmp);//为图片分配内存空间dwWidth= (dwWidth  == 0 ? m_fBmp.bmWidth  : dwWidth);dwHeight= (dwHeight == 0 ? m_fBmp.bmHeight : dwHeight);b_result = InitOffScreen(oBuffer,dwWidth,dwHeight,true,color);if( !b_result)//判断创建是否成功{MessageBox(NULL, "创建离屏缓冲区失败!", NULL, MB_OK);returnfalse;}    m_hdcImage = ::CreateCompatibleDC(NULL);if (NULL == m_hdcImage)                 {MessageBox(NULL,"创建上下文设备出错!",NULL,MB_OK);returnfalse;}SelectObject(m_hdcImage, m_hBmp);//GetObject(m_hBmp, sizeof(m_fBmp), &m_fBmp);ddsd.dwSize = sizeof(ddsd);oBuffer->GetSurfaceDesc(&ddsd);oBuffer->GetDC(&m_hdc);result = oBuffer->GetDC(&m_hdc);if( result != NULL){StretchBlt(m_hdc,      0, 0,   ddsd.dwWidth,   ddsd.dwHeight,        m_hdcImage, 0, 0, m_fBmp.bmWidth, m_fBmp.bmHeight, SRCCOPY);oBuffer->ReleaseDC(m_hdc);}DeleteDC(m_hdcImage);//删除显示设备if( NULL == result)//判断是否加载成功{return false;}return true;}void CGraphic::BltBBuffer(LPDIRECTDRAWSURFACE7 oBuffer,bool b_ColorKey,int x, int y, int ClipX, int ClipY, int ClipEndX, int CLipEndY){m_bRect.left = ClipX;m_bRect.top = ClipY;m_bRect.right = ClipEndX;m_bRect.bottom = CLipEndY;int nx=x, ny=y;m_rcRect.left = x;m_rcRect.top = y ;m_rcRect.right = x + ClipEndX - ClipX;m_rcRect.bottom = y + CLipEndY - ClipY;    // 做相应地抠像,因为屏幕要移出去了。if(x < 0){m_bRect.left = m_bRect.left + abs(x);    m_rcRect.left = 0;nx = 0;}else if(x + (ClipEndX-ClipX) >= int(m_dwWidth)){m_bRect.right = m_bRect.right - (x + (ClipEndX-ClipX) - m_dwWidth);        m_rcRect.right = m_dwWidth;}if(y < 0){m_bRect.top = m_bRect.top + abs(y);m_rcRect.top = 0;ny = 0;}else if(y + (CLipEndY-ClipY) >= int(m_dwHeight)){m_bRect.bottom = m_bRect.bottom - (y + (CLipEndY-ClipY) - m_dwHeight);m_rcRect.bottom = m_dwHeight;}if(b_ColorKey){if(m_bfScreen)m_pBBuf->BltFast( nx, ny, oBuffer, &m_bRect, DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);elsem_pBBuf->Blt(&m_rcRect, oBuffer, &m_bRect, DDBLT_KEYSRC|DDBLT_WAIT|DDBLTFAST_SRCCOLORKEY, NULL);//(&rct, surface, NULL, DDBLT_WAIT, NULL));}else{if(m_bfScreen)m_pBBuf->BltFast( nx, ny, oBuffer, &m_bRect, DDBLTFAST_WAIT);elsem_pBBuf->Blt(&m_rcRect, oBuffer, &m_bRect, (DDBLT_WAIT | DDBLT_KEYSRC), NULL);}}/*void CGraphic::CopyToBuffer(LPDIRECTDRAWSURFACE7& SrcBuffer,LPDIRECTDRAWSURFACE7& DestBuffer,                                 bool b_ColorKey,int x,int y,RECT m_rect){m_bRect = m_rect;if(b_ColorKey){ DestBuffer->BltFast( x, y, SrcBuffer, &m_bRect,                   DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);}else{ DestBuffer->BltFast( x, y, SrcBuffer, &m_bRect, DDBLTFAST_WAIT);}}void CGraphic:: CopyToBuffer(LPDIRECTDRAWSURFACE7& SrcBuffer,LPDIRECTDRAWSURFACE7& DestBuffer,          bool b_ColorKey,float zoomX, float zoomY){HDC  m_hdc;HDC  m_hdcImage;int  width = 0, height = 0;    DDSURFACEDESC2  ddsd;    ddsd.dwSize = sizeof(ddsd);SrcBuffer->GetSurfaceDesc(&ddsd);width  =  ddsd.dwWidth;    height =  ddsd.dwHeight;DestBuffer->GetSurfaceDesc(&ddsd);SrcBuffer->GetDC(&m_hdc);DestBuffer->GetDC(&m_hdcImage);int iOldMode = SetStretchBltMode(m_hdcImage, COLORONCOLOR);     StretchBlt(m_hdcImage,0, 0, ddsd.dwWidth, ddsd.dwHeight,       m_hdc ,0, 0, width, height, SRCCOPY);SetStretchBltMode(m_hdcImage, iOldMode); DestBuffer->ReleaseDC(m_hdcImage);SrcBuffer->ReleaseDC(m_hdc);}*/void CGraphic::Flip(){   if(m_pPSur && m_pBBuf){if (m_pPSur->IsLost() == DDERR_SURFACELOST)//判断前页是否丢失{m_pPSur->Restore();//前页重绘}if (m_pBBuf->IsLost() == DDERR_SURFACELOST)//判断后页是否丢失{m_pBBuf->Restore();//后页重绘}}RECT rect;    GetWindowRect(m_hWnd, &rect);    m_pPSur->Blt(&rect,m_pBBuf,NULL,DDBLT_WAIT,NULL);//m_pPSur->Flip(NULL, DDFLIP_WAIT);}/*void CGraphic::Flip(int x,int y, RECT m_rect){if(m_pPSur && m_pBBuf){if (m_pPSur->IsLost() == DDERR_SURFACELOST)//判断前页是否丢失{m_pPSur->Restore();//前页重绘}if (m_pBBuf->IsLost() == DDERR_SURFACELOST)//判断后页是否丢失{m_pBBuf->Restore();//后页重绘}}m_pPSur->BltFast(x,y,m_pBBuf,&m_rect,DDBLTFAST_WAIT);}*///----------------------------------------------------------------------------------------//Name: DDColorKey 设置镂空的颜色键码//Desc: oBuffer 只是对那个缓冲区内进行镂空处理////----------------------------------------------------------------------------------------void CGraphic::DDColorKey(LPDIRECTDRAWSURFACE7 oBuffer,DWORD color){m_key.dwColorSpaceHighValue = color;m_key.dwColorSpaceLowValue  = color;oBuffer->SetColorKey(DDCKEY_SRCBLT, &m_key);}void CGraphic::ClearBuffer(LPDIRECTDRAWSURFACE7& Buffer){DDBLTFX ddBltFx;ddBltFx.dwSize=sizeof(DDBLTFX);ddBltFx.dwFillPixel=0;Buffer->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddBltFx);}//--鼠标拷贝判断void CGraphic::SetMouseRect(RECT* m_rect, int scWidth, int scHeight, int msWidth, int msHeight){int mouseX, mouseY;if(m_MPos.x > scWidth - msWidth)  //--若鼠标越界则只设置出现在屏幕的区域{mouseX = scWidth - m_MPos.x;}else                              //--否则就设置为传进来的图片区域大小{mouseX = msWidth;}if(m_MPos.y > scHeight - msHeight){mouseY = scHeight - m_MPos.y;}else{mouseY = msHeight;}SetRect(m_rect, 0, 0, mouseX, mouseY);}void CGraphic::OutText(LPCSTR str, int x, int y,COLORREF color){HDC hdc;m_pBBuf->GetDC(&hdc);SetTextColor(hdc, color);//文字颜色//SetBkColor(hdc, RGB(0, 0, 0));//背景颜色SetBkMode(hdc, TRANSPARENT);//背景透明TextOut(hdc, x, y, str, strlen(str));m_pBBuf->ReleaseDC(hdc);}

// GameTime.h: interface for the CGameTime class.////////////////////////////////////////////////////////////////////////#if !defined(AFX_GAMETIME_H__E21F4529_19F8_4F2E_8B0A_3BB627C8E0AE__INCLUDED_)#define AFX_GAMETIME_H__E21F4529_19F8_4F2E_8B0A_3BB627C8E0AE__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include "head.h"class CGameTime  {private:__int64    m_start;     //开始的时间__int64    m_end;       //结束的时间__int64    m_frequency; //计时器频 double    m_time;      //得到当前时间public:CGameTime();virtual ~CGameTime();double     GetTime();};#endif // !defined(AFX_GAMETIME_H__E21F4529_19F8_4F2E_8B0A_3BB627C8E0AE__INCLUDED_)

// GameTime.cpp: implementation of the CGameTime class.////////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "GameTime.h"//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////CGameTime::CGameTime(){QueryPerformanceFrequency((LARGE_INTEGER*)&m_frequency);}CGameTime::~CGameTime(){}double CGameTime::GetTime(){    QueryPerformanceCounter((LARGE_INTEGER*)&m_start);m_time = (double)(m_start) / (double)m_frequency; //将时间转为以秒为单位return m_time;}
#ifndef _HEADER#define _HEADER#include <windows.h>      //-- windows函数中的头文件#include <stdio.h>        //-- c 语言的头文件#include <ddraw.h>        //-- DirectDraw的函数需要的头文件//--对应函数调用所需要的静态连接库#pragma comment (lib,"ddraw.lib")#pragma comment (lib,"dxguid.lib")#pragma comment (lib,"winmm.lib")#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)#define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1) #define   SafeRelease(x)   if   (x)   {   x->Release();   x=NULL;   }   #define  WINDOWS_GAME_WIDTH  800#define  WINDOWS_GAME_HEIGHT  600#endif



原创粉丝点击