soui4实现窗口3D旋转

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>();

2、布局中使用
soui4实现窗口3D旋转_第1张图片
3、调用

	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);
	}

你可能感兴趣的:(3d,c++,SOUI控件,windows,ui,算法)