3D旋转
//
// 参考自:
// File Name: Dui3DView.h
// Description: SImg3DView
// Creator: ZhangZhiBin
//
#pragma once
#include "image3d/3dTransform.h"
class CTurn3DCtrl : public SWindow
{
DEF_SOBJECT(SWindow, L"turn3d")
public:
CTurn3DCtrl(void);
~CTurn3DCtrl(void);
protected:
void OnTimer(char idEvent);
void OnPaint(IRenderTarget* pRT);
protected:
SOUI_MSG_MAP_BEGIN()
MSG_WM_PAINT_EX(OnPaint)
MSG_WM_TIMER_EX(OnTimer)
SOUI_MSG_MAP_END()
SOUI_ATTRS_BEGIN()
ATTR_INT(L"zStep", m_nZStep, FALSE)
ATTR_INT(L"yStep", m_nYStep, FALSE)
SOUI_ATTRS_END()
private:
int m_nZStep; //z轴的每一步距离
int m_nYStep; //每次动画绕Y轴旋转m_nYStep角度
BOOL m_bTurn2Front; //翻转方向
int m_nFrameIndex; //翻转到第几帧
BOOL m_bTurning; //正在翻转
IMAGE3D::PARAM3DTRANSFORM m_3dparam;
CAutoRefPtr<IBitmap> m_bmpBefore;
CAutoRefPtr<IBitmap> m_bmpAfter;
CAutoRefPtr<IBitmap> m_bmpTrans;
public:
BOOL Turn(SWindow* pStart, SWindow* pEnd, BOOL bTurn2Front = TRUE);
};
#include "stdafx.h"
#include "CTurn3DCtrl.h"
CTurn3DCtrl::CTurn3DCtrl()
: m_bTurn2Front(FALSE)
, m_nZStep(50)
, m_nYStep(10)
, m_bTurning(FALSE)
{
m_bVisible = FALSE;
memset(&m_3dparam, 0, sizeof(m_3dparam));
}
CTurn3DCtrl::~CTurn3DCtrl()
{
}
void CTurn3DCtrl::OnTimer(char idEvent)
{
int n = m_bTurn2Front ? -1 : 1;
int nMaxBeforeFrame, nMaxAfterFrame;
nMaxBeforeFrame = 90 / m_nYStep;
nMaxAfterFrame = 180 / m_nYStep;
if (m_nFrameIndex >= nMaxAfterFrame)
{//turn over finished
KillTimer(idEvent);
GetWindow(GSW_PREVSIBLING)->SetVisible(TRUE, FALSE);
SetVisible(FALSE, TRUE);//隐藏窗口
m_bTurning = FALSE;
m_bmpBefore = NULL;
m_bmpAfter = NULL;
m_bmpTrans = NULL;
//旋转完成,通过事件通知上层
return;
}
CAutoRefPtr<IBitmap> pBmp;
if (m_nFrameIndex <= nMaxBeforeFrame)
{
m_3dparam.nOffsetZ = m_nZStep * m_nFrameIndex;
m_3dparam.nRotateY = n * m_nYStep * m_nFrameIndex;
pBmp = m_bmpBefore;
}
else// if(m_nFrameIndex < nMaxAfterFrame)
{
m_3dparam.nOffsetZ = m_nZStep * (nMaxAfterFrame - m_nFrameIndex);
m_3dparam.nRotateY = n * m_nYStep * (m_nFrameIndex - nMaxAfterFrame);
pBmp = m_bmpAfter;
}
//render transform image
IMAGE3D::C3DTransform image3d;
SIZE szImg = pBmp->Size();
pBmp->LockPixelBits();
LPVOID pBitSrc = pBmp->GetPixelBits();
m_bmpTrans->LockPixelBits();
LPVOID pBitDst = m_bmpTrans->GetPixelBits();
image3d.SetImage((LPBYTE)pBitSrc, (LPBYTE)pBitDst, szImg.cx, szImg.cy, 32);
image3d.Render(m_3dparam);
pBmp->UnlockPixelBits(pBitSrc);
m_bmpTrans->UnlockPixelBits(pBitDst);
m_nFrameIndex++;
Invalidate();
}
void CTurn3DCtrl::OnPaint(IRenderTarget* pRT)
{
pRT->SetAntiAlias(TRUE);
CRect rcWnd;
GetWindowRect(&rcWnd);
pRT->DrawBitmap(&rcWnd, m_bmpTrans, 0, 0);
}
BOOL CTurn3DCtrl::Turn(SWindow* pStart, SWindow* pEnd, BOOL bTurn2Front /* = TRUE */)
{
SASSERT(pEnd && pStart);
if (m_bTurning) return FALSE;
CRect rcClient = GetWindowRect();
//复制正面窗体的图像
SWindow* pFrmWnd = GetWindow(GSW_PREVSIBLING);
if (!pFrmWnd) return FALSE;
CAutoRefPtr<IRenderTarget> pRT;
GETRENDERFACTORY->CreateRenderTarget(&pRT, rcClient.Width(), rcClient.Height());
pStart->SetVisible(TRUE, FALSE);
pEnd->SetVisible(FALSE, FALSE);
//渲染窗口变化前状态
pRT->ClearRect(&rcClient, 0);
pFrmWnd->RedrawRegion(pRT, NULL);
CAutoRefPtr<IRenderTarget> pRTCopy1;
GETRENDERFACTORY->CreateRenderTarget(&pRTCopy1, rcClient.Width(), rcClient.Height());
pRTCopy1->BitBlt(CRect(CPoint(0, 0), rcClient.Size()), pRT, rcClient.left, rcClient.top, SRCCOPY);
m_bmpBefore = (IBitmap*)pRTCopy1->GetCurrentObject(OT_BITMAP);
//渲染窗口变化后状态
pStart->SetVisible(FALSE, FALSE);
pEnd->SetVisible(TRUE, FALSE);
pRT->ClearRect(&rcClient, 0);
pFrmWnd->RedrawRegion(pRT, NULL);
CAutoRefPtr<IRenderTarget> pRTCopy2;
GETRENDERFACTORY->CreateRenderTarget(&pRTCopy2, rcClient.Width(), rcClient.Height());
pRTCopy2->BitBlt(CRect(CPoint(0, 0), rcClient.Size()), pRT, rcClient.left, rcClient.top, SRCCOPY);
m_bmpAfter = (IBitmap*)pRTCopy2->GetCurrentObject(OT_BITMAP);
//先把FrameWindow HIDE
pFrmWnd->SetVisible(FALSE, FALSE);
GETRENDERFACTORY->CreateBitmap(&m_bmpTrans);
CAutoRefPtr<IBitmap> bmp = (IBitmap*)pRT->GetCurrentObject(OT_BITMAP);
bmp->LockPixelBits();
m_bmpTrans->Init(rcClient.Width(), rcClient.Height(), bmp->GetPixelBits());
bmp->UnlockPixelBits(bmp->GetPixelBits());
//让窗口可见
SetVisible(TRUE, TRUE);
m_3dparam.nOffsetZ = m_nZStep;
m_3dparam.nRotateY = -10;
m_nFrameIndex = 0;
m_bTurn2Front = bTurn2Front;
m_bTurning = TRUE;
SetTimer(1, 20);
OnTimer(1);
return TRUE;
}
使用:
1、注册
m_theApp->RegisterWindowClass<CTurn3DCtrl>();
SWindow* pWindow1 = FindChildByName2<SWindow>(L"test_window1");
SWindow* pWindow2 = FindChildByName2<SWindow>(L"test_window2");
CTurn3DCtrl* pTurn3d = FindChildByName2<CTurn3DCtrl>(L"turn3d");
if (pTurn3d)
{
//
pTurn3d->Turn(pWindow1, pWindow2, TRUE);
}