动画特效框架
来源:互联网 发布:梦里花落知多少2郭敬明 编辑:程序博客网 时间:2024/06/06 03:44
#pragma once
class HDCMemo
{
public:
HDCMemo(RECT rtImg);
virtual ~HDCMemo(void);
void Record(HDC hDC);
void Recover(HDC hDC);
RECT getSize();
private:
HANDLE m_hMutex;
RECT m_rtImg;
HBITMAP m_bmpMemo;
};
#pragma once
#include "../CE600.h"
#include "../HDCMemo.h"
class Cartoon
{
public:
bool Run(LPVOID pPar);
bool IsOver();
protected:
Cartoon(CDialog* pDlg, HDCMemo* pHDCMemo);
virtual ~Cartoon(void);
virtual void Render(LPVOID pPar) = 0;
CDialog *m_pDlg;
HDCMemo *m_pHDCMemo;
HANDLE m_hMutex;
ThreadEx* m_pThread;
HANDLE m_hClose;
LPVOID m_pRenderPar;
friend DWORD CartoonThread(LPVOID pThis);
};
#pragma once
#include "Cartoon.h"
class CartoonPiece: public Cartoon
{
public:
CartoonPiece(CDialog* pDlg, HDCMemo* pHDCMemo);
virtual ~CartoonPiece(void);
private:
virtual void Render(LPVOID pPar);
};
使用:
BOOL CCartoonDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CRect rtImg;
GetClientRect(rtImg);
m_pMemo = new HDCMemo(rtImg);
CDC* pDC = GetDC();
CDCBuf buf(pDC,&rtImg);
buf.fillRect(RGB(0,0,255));
m_pMemo->Record(buf);
m_pCartoon = new CartoonPiece(this,m_pMemo);
m_pCartoon->Run(NULL);
return TRUE; // return TRUE unless you set the focus to a control
}
void CCartoonPieceDlg::OnDestroy()
{
// TODO: Add your message handler code here
if( NULL != m_pCartoon)
delete m_pCartoon;
m_pCartoon = NULL;
if( NULL != m_pMemo)
delete m_pMemo;
m_pMemo = NULL;
CDialog::OnDestroy();
}
BOOL CCartoonPieceDlg::OnEraseBkgnd(CDC* pDC)
{
m_pMemo->Recover(*pDC);
return FALSE;
}
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
png格式的渲染速度较慢,画一张480*272的图要200毫秒左右,而人眼的辨别能力为100毫秒左右,故会出现反应延迟现象。而这个现象试图通过画取部份空间来解决并不现实。因为这样会导致两种渲染逻辑:1,如果是首次画,需全画。 2, 如果是补画,需重画部份空间。但是判断是首画还是补画会比较麻烦,因为触发画图函数的消息可以是用户触发的,也可以是由系统触发的(例如窗口被遮挡住等)。而要对所有的触发情况做标志,并针对标志做相应的全画和补画,不现实也不可靠。安全的方法可能还是得每次都全画,只是在全画的过程中想办法提高效率。 另还有一个渲染动画的问题一直也没有很好的解决,因为渲染过程中系统无法响应其它消息, 所以如果是一个动画,那么只有等动画执行完毕了。 虽然还可以用线程等方法,但是目前却没有很好的打包和设计模式来解决,导致明明是一个连续的动作,却要分割成一个个图画,然后再添加相关消息处理过程控制在程序里四处散放等,导致实现不影响用户动作的一个动画很麻烦。
解决方案:通过线程,计时器和备忘录模式(带互斥作用)解决。流程如下:
客户端:
动作线程:
{
服务器->开启刷新定时器。
While(X)
{
渲染。
备忘录记录记录(画面)。
}
服务器->关闭刷新定时器。
}
服务器端:
OnPaint()
{
画图(获得备忘录记录)。
}
备: 通过备忘录模式,使每次修改扩展渲染功能都不用去服务器的OnPaint功能里修改(画图一定要经过OnPaint才行,不然一些重画的情况时,画面会丢失)。通过线程,使动画过程不影响其它消息的响应。通过定时器来刷新使动画的渲染速度稳定。另,备忘录需带互斥功能,以防画面读写过程出错。
/********************************************************************
created: 2011/03/01
created: 1:3:2011 10:52
filename: g:/20110221文件整理/源码/小工具_实现代码(20110221版)/CE600/HDCMemo.h
file path: g:/20110221文件整理/源码/小工具_实现代码(20110221版)/CE600
file base: HDCMemo
file ext: h
author: Clark
purpose: 用于动画渲染的备忘录模式
*********************************************************************/
#include "StdAfx.h"
#include "HDCMemo.h"
HDCMemo::HDCMemo(RECT rtImg)
{
CopyRect(&m_rtImg,&rtImg);
HDC hDC = GetDC(NULL);
m_bmpMemo = CreateCompatibleBitmap(hDC,m_rtImg.right-m_rtImg.left, m_rtImg.bottom-m_rtImg.top);
ReleaseDC(NULL,hDC);
TCHAR szTemp[MAX_PATH];
_stprintf(szTemp,_T("MUTEX_FOR_HDCMEMO_%x"),this);
m_hMutex = CreateMutex(NULL,FALSE,szTemp);
}
HDCMemo::~HDCMemo(void)
{
DeleteObject(m_bmpMemo);
if( WAIT_OBJECT_0 == WaitForSingleObject(m_hMutex,5000))
{
ReleaseMutex(m_hMutex);
}
CloseHandle(m_hMutex);
}
void HDCMemo::Record(HDC hDC)
{
if( WAIT_OBJECT_0 == WaitForSingleObject(m_hMutex,INFINITE))
{
HDC dcBitmap = CreateCompatibleDC(hDC);
HGDIOBJ hOldBitmap = SelectObject(dcBitmap, m_bmpMemo);
BitBlt(dcBitmap,0,0,m_rtImg.right-m_rtImg.left, m_rtImg.bottom-m_rtImg.top,hDC,0,0,SRCCOPY);
SelectObject(dcBitmap, hOldBitmap);
DeleteDC(dcBitmap);
ReleaseMutex(m_hMutex);
}
}
void HDCMemo::Recover(HDC hDC)
{
if( WAIT_OBJECT_0 == WaitForSingleObject(m_hMutex,INFINITE))
{
HDC dcBitmap = CreateCompatibleDC(hDC);
HGDIOBJ hOldBitmap = SelectObject(dcBitmap,m_bmpMemo);
BitBlt(hDC,0,0,m_rtImg.right-m_rtImg.left, m_rtImg.bottom-m_rtImg.top,dcBitmap,0,0,SRCCOPY);
SelectObject(dcBitmap,hOldBitmap);
DeleteDC(dcBitmap);
ReleaseMutex(m_hMutex);
}
}
RECT HDCMemo::getSize()
{
return m_rtImg;
}
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
/********************************************************************
created: 2011/03/01
created: 1:3:2011 11:34
filename: g:/20110221文件整理/源码/小工具_实现代码(20110221版)/CE600/Cartoon.h
file path: g:/20110221文件整理/源码/小工具_实现代码(20110221版)/CE600
file base: Cartoon
file ext: h
author: Clark
purpose: 动画渲染
*********************************************************************/
#include "StdAfx.h"
#include "Cartoon.h"
DWORD CartoonThread(LPVOID pThis)
{
Cartoon* pCartoon = (Cartoon*)pThis;
pCartoon->Render(pCartoon->m_pRenderPar);
if( WAIT_OBJECT_0 == WaitForSingleObject(pCartoon->m_hMutex,INFINITE))
{
pCartoon->m_pThread = NULL;
ReleaseMutex(pCartoon->m_hMutex);
}
return 0;
}
Cartoon::Cartoon(CDialog* pDlg, HDCMemo* pHDCMemo):
m_pThread(NULL)
{
m_pDlg = pDlg;
m_pHDCMemo = pHDCMemo;
TCHAR szTemp[MAX_PATH];
_stprintf(szTemp,_T("MUTEX_FOR_CARTOON_%x"),this);
m_hMutex = CreateMutex(NULL,FALSE,szTemp);
}
Cartoon::~Cartoon(void)
{
if( NULL != m_pThread)
delete m_pThread;
m_pThread = NULL;
if( WAIT_OBJECT_0 == WaitForSingleObject(m_hMutex,5000))
{
ReleaseMutex(m_hMutex);
}
CloseHandle(m_hMutex);
}
bool Cartoon::Run(LPVOID pPar)
{
bool bSign = false;
if( WAIT_OBJECT_0 == WaitForSingleObject(m_hMutex,INFINITE))
{
if( NULL == m_pThread)
{
m_pRenderPar = pPar;
m_pThread = new ThreadEx(m_hClose,CartoonThread,this);
bSign = true;
}
ReleaseMutex(m_hMutex);
}
return bSign;
}
bool Cartoon::IsOver()
{
bool bSign = false;
if( WAIT_OBJECT_0 == WaitForSingleObject(m_hMutex,INFINITE))
{
if( NULL == m_pThread)
{
bSign = true;
}
ReleaseMutex(m_hMutex);
}
return bSign;
}
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
/********************************************************************
created: 2011/03/01
created: 1:3:2011 11:34
filename: g:/20110221文件整理/源码/小工具_实现代码(20110221版)/CE600/Cartoon.h
file path: g:/20110221文件整理/源码/小工具_实现代码(20110221版)/CE600
file base: Cartoon
file ext: h
author: Clark
purpose: 动画渲染
*********************************************************************/
#include "StdAfx.h"
#include "CartoonPiece.h"
#include "../CDCBuf.h"
CartoonPiece::CartoonPiece(CDialog* pDlg, HDCMemo* pHDCMemo):
Cartoon(pDlg,pHDCMemo)
{
NULL;
}
CartoonPiece::~CartoonPiece(void)
{
NULL;
}
void CartoonPiece::Render(LPVOID pPar)
{
CRect rtDlg;
m_pDlg->GetClientRect(rtDlg);
CDC* pDC = m_pDlg->GetDC();
CDCBuf buf(pDC,&rtDlg);
m_pDlg->ReleaseDC(pDC);
buf.SetAuto(false);
m_pMemo->Recover(buf);
const int iCount = 8;
const int iROWS = 4;
const int iLINES = 4;
const int iUW = rtDlg.Width()/iLINES+0.5;
const int iUH = rtDlg.Height()/iROWS+0.5;
const int iUW_L = iUW/iCount+0.5;
const int iUH_L = iUH/iCount+0.5;
int iPosX, iPosY, iW, iH;
iW = iH = 0;
for(int k=0; k<iCount; k++)
{
iPosX = iPosY = 0;
iW += iUW_L;
iH += iUH_L;
for(int i=0; i<=iROWS; i++)
{
iPosX = 0;
for(int j=0; j<=iLINES; j++)
{
CRect rtImg(iPosX,iPosY,iPosX+iW,iPosY+iH);
if( NULL == pPar)
buf.fillRect(RGB(0,255,0),&rtImg);
else
buf.drawBmp((CBitmap*)pPar,&rtImg,&rtImg);
iPosX += iUW;
}
iPosY += iUH;
}
m_pMemo->Record(buf);
m_pDlg->Invalidate();
Sleep(10);
}
if( NULL == pPar)
buf.fillRect(RGB(0,255,0),&rtDlg);
else
buf.drawBmp((CBitmap*)pPar,&rtDlg,&rtDlg);
m_pMemo->Record(buf);
m_pDlg->Invalidate();
}
- 动画特效框架
- Qt动画框架设计飞入-消失特效
- 用Qt动画框架设计飞入-消失特效
- paip.关于动画特效原理 html js 框架总结
- 带37种3D动画特效的跨浏览器CSS3动画框架
- 动画特效三:搜索动画
- 动画特效五:灌水动画
- 动画特效七:碰撞动画
- 动画特效八:渐变动画
- 动画特效之动画组
- 动画特效之转场动画
- 动画特效十七:粘性动画
- jQuery 中的动画特效
- jQuery制作动画特效
- activity 点击动画特效
- jQuery动画特效
- WPF 动画特效--翻牌
- Android 动画特效集合
- mysql load data infile
- Oracle SQL的硬解析和软解析
- 柱状图使用实例--设置柱子上是否显示数值及数值的显示位置
- 等死模式与穿越模式
- IP 存储网络
- 动画特效框架
- eCos GUI for Synthetic 的研究
- 微软拼音输入法团队博客搬家通知
- 用正则表达式去掉源代码行号
- 走进知酷网,全新的内容整合模式
- 怎样写好IT文章
- 聚集索引和非聚集索引
- 如何用Core Plot绘制柱状图
- 选ME525还是M9?热门智能手机对比导购