mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-11 14:00:32 +08:00
1083 lines
27 KiB
C++
1083 lines
27 KiB
C++
#pragma once
|
||
|
||
#include <TemporaryCS.h>
|
||
#include <Gdiplus.h>
|
||
#include <TimeMeasurer.h>
|
||
|
||
#define INCLUDE_FAST_WINDOW
|
||
|
||
#include "DXINCLUDE.h"
|
||
|
||
#ifdef INCLUDE_FAST_WINDOW
|
||
|
||
namespace ImageRendering
|
||
{
|
||
class FastGridRender
|
||
{
|
||
public:
|
||
|
||
};
|
||
|
||
class FastRullersRender
|
||
{
|
||
public:
|
||
|
||
};
|
||
|
||
class CTextureBatch
|
||
{
|
||
public:
|
||
|
||
CTextureBatch ()
|
||
{
|
||
m_nCountX = 0;
|
||
m_nCountY = 0;
|
||
}
|
||
|
||
virtual ~CTextureBatch ()
|
||
{
|
||
Clear ();
|
||
}
|
||
|
||
|
||
inline void Create ( long CountX, long CountY, IDirect3DDevice9* pD3DDevice, long Size = 512 )
|
||
{
|
||
// Clear ();
|
||
|
||
m_nCountX = CountX;
|
||
m_nCountY = CountY;
|
||
m_nSize = Size;
|
||
|
||
long nMaxCount = m_nCountX * m_nCountY;
|
||
|
||
for ( long i = (long)m_Textures.GetCount (); i < nMaxCount; ++i )
|
||
{
|
||
IDirect3DTexture9* pTexture = NULL;
|
||
if ( FAILED ( pD3DDevice->CreateTexture ( Size, Size, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTexture, 0 ) ) )
|
||
{
|
||
Clear ();
|
||
}
|
||
|
||
m_Textures.Add ( pTexture );
|
||
}
|
||
|
||
return;
|
||
|
||
///*
|
||
|
||
for ( long i = 0; i < ( m_nCountX + 0 ) * ( m_nCountY + 0 ); ++i )
|
||
{
|
||
IDirect3DTexture9* pTexture = NULL;
|
||
if ( FAILED ( pD3DDevice->CreateTexture ( Size, Size, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTexture, 0 ) ) )
|
||
{
|
||
Clear ();
|
||
}
|
||
|
||
//D3DSURFACE_DESC Surface;
|
||
//if ( SUCCEEDED ( pTexture->GetLevelDesc ( 0, &Surface ) ) )
|
||
//{
|
||
// D3DLOCKED_RECT LockRect;
|
||
// if ( SUCCEEDED ( pTexture->LockRect ( 0, &LockRect, 0, 0 ) ) )
|
||
// {
|
||
// memset ( LockRect.pBits, 0x7F, Surface.Width * Surface.Height * 4 );
|
||
// pTexture->UnlockRect ( 0 );
|
||
// }
|
||
//}
|
||
|
||
m_Textures.Add ( pTexture );
|
||
}
|
||
|
||
//*/
|
||
}
|
||
|
||
inline void Clear ()
|
||
{
|
||
for ( long i = 0; i < m_nCountX * m_nCountY; ++i )
|
||
{
|
||
m_Textures [i]->Release ();
|
||
}
|
||
|
||
m_Textures.RemoveAll ();
|
||
|
||
m_nCountX = 0;
|
||
m_nCountY = 0;
|
||
}
|
||
|
||
inline void SetImage ( long IndX, long IndY, const BYTE* pImage, long ImageW, long ImagH, long OffSetX, long OffSetY, long OffSetW = 0, long OffSetH = 0 )
|
||
{
|
||
IDirect3DTexture9* pTexture = m_Textures.GetAt ( IndY * ( m_nCountX )+ IndX );
|
||
|
||
D3DSURFACE_DESC Surface;
|
||
if ( SUCCEEDED ( pTexture->GetLevelDesc ( 0, &Surface ) ) )
|
||
{
|
||
D3DLOCKED_RECT LockRect;
|
||
if ( SUCCEEDED ( pTexture->LockRect ( 0, &LockRect, 0, 0 ) ) )
|
||
{
|
||
DWORD* pPixel = (DWORD*)LockRect.pBits;
|
||
DWORD* pSource = (DWORD*)pImage;
|
||
|
||
memset ( pPixel, 0, Surface.Width * Surface.Height * 4 );
|
||
|
||
DWORD CopyBytes = __min ( OffSetW * 4, (long)(Surface.Width * 4) );
|
||
DWORD CopyLines = __min ( OffSetH, (long)(Surface.Height) );
|
||
|
||
for ( DWORD i = 0; i < CopyLines; ++i )
|
||
{
|
||
memcpy ( &pPixel [ i * Surface.Width ], &pSource [ ( i + OffSetY ) * ImageW + OffSetX ], CopyBytes );
|
||
}
|
||
|
||
pTexture->UnlockRect ( 0 );
|
||
}
|
||
}
|
||
}
|
||
|
||
IDirect3DTexture9* GetTexture ( long IndX, long IndY )
|
||
{
|
||
return m_Textures.GetAt ( IndY * ( m_nCountX )+ IndX );
|
||
}
|
||
|
||
private:
|
||
|
||
CAtlArray <IDirect3DTexture9*> m_Textures;
|
||
|
||
long m_nCountX;
|
||
long m_nCountY;
|
||
|
||
long m_nSize;
|
||
};
|
||
|
||
}
|
||
|
||
namespace ImageRendering
|
||
{
|
||
class FrameFastWindow
|
||
{
|
||
class CChessBrush
|
||
{
|
||
public:
|
||
|
||
CChessBrush ()
|
||
{
|
||
m_pBrush = NULL;
|
||
|
||
m_nDarkColor = 0xFFCCCCCC;
|
||
m_nLightColor = 0xFFFFFFFF;
|
||
m_nSizesCell = 16;
|
||
|
||
CreateBrush ();
|
||
}
|
||
|
||
~CChessBrush ()
|
||
{
|
||
Clear ();
|
||
}
|
||
|
||
|
||
|
||
inline void OnPaint ( Gdiplus::Graphics* pGraphics, Gdiplus::Rect rc )
|
||
{
|
||
rc.Width = ( (long)rc.Width / 2 ) * 2;
|
||
rc.Height = ( (long)rc.Height / 2 ) * 2;
|
||
|
||
if ( NULL != m_pBrush )
|
||
{
|
||
pGraphics->FillRectangle ( m_pBrush, rc );
|
||
}
|
||
else
|
||
{
|
||
pGraphics->FillRectangle ( new HatchBrush ( Gdiplus::HatchStyleLargeCheckerBoard, Gdiplus::Color ( m_nLightColor ),
|
||
Gdiplus::Color ( m_nDarkColor ) ), rc );
|
||
}
|
||
}
|
||
|
||
inline DWORD GetDarkColor () { return m_nDarkColor; }
|
||
inline DWORD GetLightColor () { return m_nLightColor; }
|
||
inline DWORD GetSizesCell () { return m_nSizesCell; }
|
||
inline void SetDarkColor ( DWORD Value ) { m_nDarkColor = Value; Clear (); CreateBrush (); }
|
||
inline void SetLightColor ( DWORD Value ) { m_nLightColor = Value; Clear (); CreateBrush (); }
|
||
inline void SetSizesCell ( DWORD Value ) { m_nSizesCell = Value; Clear (); CreateBrush (); }
|
||
|
||
private:
|
||
|
||
inline void Clear ()
|
||
{
|
||
if ( NULL != m_pBrush )
|
||
{
|
||
delete m_pBrush;
|
||
m_pBrush = NULL;
|
||
}
|
||
}
|
||
|
||
inline void CreateBrush ()
|
||
{
|
||
Gdiplus::Bitmap oBitmap ( m_nSizesCell * 2, m_nSizesCell * 2, PixelFormat32bppRGB );
|
||
|
||
if ( Gdiplus::Ok == oBitmap.GetLastStatus() )
|
||
{
|
||
Gdiplus::Graphics oGraphics ( &oBitmap );
|
||
if ( Gdiplus::Ok == oGraphics.GetLastStatus() )
|
||
{
|
||
Gdiplus::REAL fWidthCell = (Gdiplus::REAL)m_nSizesCell;
|
||
|
||
oGraphics.FillRectangle ( new SolidBrush ( Color ( m_nDarkColor ) ), Gdiplus::RectF ( 0.0f, 0.0f, fWidthCell, fWidthCell ) );
|
||
oGraphics.FillRectangle ( new SolidBrush ( Color ( m_nDarkColor ) ), Gdiplus::RectF ( fWidthCell, fWidthCell, fWidthCell, fWidthCell ) );
|
||
oGraphics.FillRectangle ( new SolidBrush ( Color ( m_nLightColor ) ), Gdiplus::RectF ( 0.0f, fWidthCell, fWidthCell, fWidthCell ) );
|
||
oGraphics.FillRectangle ( new SolidBrush ( Color ( m_nLightColor ) ), Gdiplus::RectF ( fWidthCell, 0.0f, fWidthCell, fWidthCell ) );
|
||
|
||
if ( Gdiplus::Ok == oGraphics.GetLastStatus() )
|
||
{
|
||
if ( Gdiplus::Ok == oBitmap.GetLastStatus() )
|
||
{
|
||
m_pBrush = new Gdiplus::TextureBrush ( &oBitmap );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private:
|
||
|
||
Gdiplus::TextureBrush* m_pBrush;
|
||
|
||
DWORD m_nDarkColor;
|
||
DWORD m_nLightColor;
|
||
DWORD m_nSizesCell;
|
||
};
|
||
|
||
public:
|
||
|
||
FrameFastWindow ()
|
||
{
|
||
m_nIsInitialized = -1;
|
||
m_nIsTexturesComplete = false;
|
||
|
||
m_nBackClearColor = 0xFFD0D0D0;
|
||
m_bEnableAlphaLayer = true;
|
||
|
||
m_pD3D = NULL;
|
||
m_pD3DDevice = NULL;
|
||
|
||
m_nZoom = 1.0f;
|
||
m_nZoomSmooth = 1.0f;
|
||
|
||
m_nCenterX = 1.0f;
|
||
m_nCenterY = 1.0f;
|
||
|
||
m_nWindowWidth = -1;
|
||
m_nWindowHeight = -1;
|
||
|
||
m_pTexureChess = NULL;
|
||
|
||
m_hWnd = NULL;
|
||
m_pSurface = NULL;
|
||
|
||
m_pImage = NULL;
|
||
m_nWidth = 0;
|
||
m_nHeight = 0;
|
||
|
||
m_bUpdateTexture = false;
|
||
m_nScale = 1.0;
|
||
|
||
m_nAsyncUpdateRender = 0;
|
||
|
||
m_nBatchSize = 256;
|
||
|
||
m_bZoomToWindow = false;
|
||
|
||
m_hThread = NULL;
|
||
|
||
InitializeCriticalSection ( &m_BlockingCS );
|
||
}
|
||
|
||
virtual ~FrameFastWindow ()
|
||
{
|
||
Clear ();
|
||
|
||
DeleteCriticalSection ( &m_BlockingCS );
|
||
}
|
||
|
||
inline bool Create ( HWND hWnd )
|
||
{
|
||
if ( 1 == m_nIsInitialized && m_hWnd == hWnd )
|
||
return true;
|
||
|
||
InterlockedExchange ( &m_nSetImageBlock, 1L );
|
||
|
||
Clear ();
|
||
|
||
m_hWnd = hWnd;
|
||
m_HDC = GetDC ( m_hWnd );
|
||
|
||
if ( NULL == ( m_pD3D = Direct3DCreate9 ( D3D_SDK_VERSION ) ) )
|
||
{
|
||
m_nIsInitialized = -1;
|
||
|
||
Clear ();
|
||
|
||
return false;
|
||
}
|
||
|
||
D3DPRESENT_PARAMETERS d3dpp;
|
||
ZeroMemory ( &d3dpp, sizeof ( d3dpp ) );
|
||
|
||
d3dpp.hDeviceWindow = m_hWnd;
|
||
d3dpp.FullScreen_RefreshRateInHz= 0;
|
||
d3dpp.BackBufferCount = 1;
|
||
d3dpp.Windowed = TRUE;
|
||
d3dpp.SwapEffect = D3DSWAPEFFECT_COPY; // D3DSWAPEFFECT_DISCARD;
|
||
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; // D3DFMT_UNKNOWN;
|
||
d3dpp.EnableAutoDepthStencil = TRUE;
|
||
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
|
||
d3dpp.Windowed = TRUE;
|
||
//d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||
d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
|
||
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||
d3dpp.PresentationInterval = 0;
|
||
|
||
D3DCAPS9 d3dCaps;
|
||
if ( FAILED ( m_pD3D->GetDeviceCaps ( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps ) ) )
|
||
{
|
||
m_nIsInitialized = -1;
|
||
|
||
Clear ();
|
||
|
||
return false;
|
||
}
|
||
|
||
DWORD dwBehaviorFlags = 0;
|
||
|
||
if ( d3dCaps.VertexProcessingCaps != 0 )
|
||
{
|
||
dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
|
||
}
|
||
else
|
||
{
|
||
dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
|
||
|
||
m_nIsInitialized = -1;
|
||
|
||
Clear ();
|
||
|
||
return false;
|
||
}
|
||
|
||
// Create the D3DDevice
|
||
if ( FAILED ( m_pD3D->CreateDevice ( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd, dwBehaviorFlags | D3DCREATE_MULTITHREADED, &d3dpp, &m_pD3DDevice ) ) )
|
||
{
|
||
m_nIsInitialized = -1;
|
||
|
||
Clear ();
|
||
|
||
return false;
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
||
m_pD3DDevice->SetRenderState ( D3DRS_LIGHTING, FALSE );
|
||
m_pD3DDevice->SetRenderState ( D3DRS_CULLMODE, D3DCULL_NONE );
|
||
m_pD3DDevice->SetRenderState ( D3DRS_ZENABLE, D3DZB_FALSE );
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
m_pD3DDevice->SetSamplerState ( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT );
|
||
m_pD3DDevice->SetSamplerState ( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
|
||
m_pD3DDevice->SetSamplerState ( 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT );
|
||
|
||
SetFiltering ( 3 );
|
||
|
||
m_nIsInitialized = 1;
|
||
|
||
if ( FAILED ( m_pD3DDevice->CreateTexture ( 256, 256, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_pTexureChess, 0 ) ) )
|
||
{
|
||
m_nIsInitialized = -1;
|
||
|
||
Clear ();
|
||
|
||
return false;
|
||
}
|
||
|
||
D3DSURFACE_DESC d3dsd;
|
||
m_pTexureChess->GetLevelDesc ( 0, &d3dsd );
|
||
|
||
D3DLOCKED_RECT Rect;
|
||
if ( SUCCEEDED ( m_pTexureChess->LockRect ( 0, &Rect, 0, 0 ) ) )
|
||
{
|
||
DWORD* pPixel = (DWORD*)Rect.pBits;
|
||
|
||
CChessBrush ChessBrush;
|
||
|
||
Gdiplus::Bitmap oBitmap ( d3dsd.Width, d3dsd.Height, 4 * d3dsd.Width, PixelFormat32bppARGB, (BYTE*)Rect.pBits );
|
||
Gdiplus::Graphics oGraphic ( &oBitmap );
|
||
ChessBrush.OnPaint ( &oGraphic, Gdiplus::Rect ( 0, 0, d3dsd.Width, d3dsd.Height ) );
|
||
|
||
m_pTexureChess->UnlockRect ( 0 );
|
||
}
|
||
|
||
|
||
if ( m_pImage && m_nWidth > 1 && m_nHeight > 1 )
|
||
{
|
||
SetImage ( m_pImage, m_nWidth, m_nHeight, m_nScale );
|
||
}
|
||
|
||
InterlockedExchange ( &m_nAsyncUpdateRender, 0L );
|
||
InterlockedExchange ( &m_nSetImageBlock, 0L );
|
||
InterlockedExchange ( &m_nSetEnableRender, 0L );
|
||
|
||
m_nZoomSmooth = m_nZoom;
|
||
|
||
unsigned int nThreadID = 0;
|
||
m_hThread = (HANDLE) _beginthreadex ( 0, 0, &FrameFastWindow::AsyncRender, (void*)this, 0, &nThreadID );
|
||
SetThreadPriority ( m_hThread, THREAD_PRIORITY_LOWEST );
|
||
|
||
m_oTimer.Reset ();
|
||
|
||
return true;
|
||
}
|
||
|
||
inline void Clear ()
|
||
{
|
||
if ( NULL == m_hThread || -1 == m_nIsInitialized )
|
||
return;
|
||
|
||
m_nAsyncUpdateRender = 1;
|
||
|
||
WaitForSingleObject ( m_hThread, INFINITE );
|
||
|
||
m_oTextureBatch.Clear ();
|
||
|
||
if ( NULL != m_pTexureChess )
|
||
{
|
||
m_pTexureChess->Release ();
|
||
m_pTexureChess = NULL;
|
||
}
|
||
|
||
if ( NULL != m_pD3D )
|
||
{
|
||
m_pD3D->Release ();
|
||
m_pD3D = NULL;
|
||
}
|
||
|
||
if ( NULL != m_pD3DDevice )
|
||
{
|
||
m_pD3DDevice->Release ();
|
||
m_pD3DDevice = NULL;
|
||
}
|
||
|
||
ReleaseDC ( m_hWnd, m_HDC );
|
||
}
|
||
|
||
inline void ClearImage ( )
|
||
{
|
||
CTemporaryCS TemporaryCS ( &m_BlockingCS );
|
||
|
||
m_oTextureBatch.Clear ();
|
||
}
|
||
|
||
inline bool Update ( )
|
||
{
|
||
CTemporaryCS TemporaryCS ( &m_BlockingCS );
|
||
|
||
typedef D3DXVECTOR2 float2;
|
||
|
||
if ( m_pD3DDevice )
|
||
{
|
||
RECT m_RECT;
|
||
GetWindowRect ( m_hWnd, &m_RECT );
|
||
|
||
int nWindowWidth = abs ( m_RECT.right - m_RECT.left );
|
||
int nWindowHeight = abs ( m_RECT.bottom - m_RECT.top );
|
||
|
||
m_pD3DDevice->Clear ( 0, NULL, D3DCLEAR_TARGET /*| D3DCLEAR_ZBUFFER*/, m_nBackClearColor, 1.0f, 0 );
|
||
m_pD3DDevice->BeginScene();
|
||
|
||
if ( false == m_bUpdateTexture )
|
||
{
|
||
if ( m_pImage && m_nWidth > 1 && m_nHeight > 1 )
|
||
{
|
||
if ( TRUE ) // update zoom
|
||
{
|
||
if ( abs ( m_nZoom - m_nZoomSmooth ) < 0.0025f )
|
||
m_nZoomSmooth = m_nZoom;
|
||
|
||
if ( m_nZoom > m_nZoomSmooth )
|
||
{
|
||
m_nZoomSmooth += m_oTimer.GetTimeInterval() * 5.0f * abs ( m_nZoom - m_nZoomSmooth );
|
||
if ( m_nZoom < m_nZoomSmooth )
|
||
{
|
||
m_nZoomSmooth = m_nZoom;
|
||
}
|
||
}
|
||
if ( m_nZoom < m_nZoomSmooth )
|
||
{
|
||
m_nZoomSmooth -= m_oTimer.GetTimeInterval() * 5.0f * abs ( m_nZoom - m_nZoomSmooth );
|
||
if ( m_nZoom > m_nZoomSmooth )
|
||
{
|
||
m_nZoomSmooth = m_nZoom;
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
|
||
m_pD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR );
|
||
m_pD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR );
|
||
|
||
DrawColorQuad ( D3DXVECTOR2 ( 0.0f, 0.0f ), D3DXVECTOR2 ( (float)m_nWindowWidth, (float)m_nWindowHeight ),
|
||
0xFFEFEFEF, 0xFFCFCFCF, 0xFFAFAFAF, 0xFF9F9F9F );
|
||
|
||
*/
|
||
|
||
if ( m_bEnableAlphaLayer )
|
||
{
|
||
/*
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
float ChessLeft = 0.0f;
|
||
float ChessTop = 0.0f;
|
||
|
||
float ChessRight = nWindowWidth * 2;
|
||
float ChessBottom = nWindowHeight * 2;
|
||
*/
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
float ChessLeft = __max ( (float) nWindowWidth * 0.5f - m_nCenterX * m_nZoomSmooth, 0.0f );
|
||
float ChessTop = __max ( (float) nWindowHeight * 0.5f - m_nCenterY * m_nZoomSmooth, 0.0f );
|
||
|
||
float ChessRight = __min ( (float) nWindowWidth * 0.5f - m_nCenterX * m_nZoomSmooth + (float)m_nChessWidth * m_nZoomSmooth * m_nScale, (float) nWindowWidth );
|
||
float ChessBottom = __min ( (float) nWindowHeight * 0.5f - m_nCenterY * m_nZoomSmooth + (float)m_nChessHeight * m_nZoomSmooth * m_nScale, (float) nWindowHeight );
|
||
|
||
m_pD3DDevice->SetTextureStageState ( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
|
||
m_pD3DDevice->SetRenderState ( D3DRS_ALPHABLENDENABLE, TRUE );
|
||
|
||
m_pD3DDevice->SetSamplerState ( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP );
|
||
m_pD3DDevice->SetSamplerState ( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP );
|
||
m_pD3DDevice->SetSamplerState ( 0, D3DSAMP_ADDRESSW, D3DTADDRESS_WRAP );
|
||
|
||
SetFiltering ( 1 );
|
||
|
||
m_pD3DDevice->SetTexture ( 0, m_pTexureChess );
|
||
|
||
DrawTextureQuad ( D3DXVECTOR2 ( ChessLeft, ChessTop ), D3DXVECTOR2 ( ChessRight, ChessBottom ),
|
||
D3DXVECTOR2 ( 0.0f, 0.0f ), D3DXVECTOR2 ( ( ChessRight - ChessLeft ) / 256.0f, ( ChessBottom - ChessTop ) / 256.0f ) );
|
||
}
|
||
|
||
m_pD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
|
||
m_pD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
|
||
|
||
//Gdiplus::RectF ZonePaint = RectF ( ChessLeft, ChessTop, ChessRight - ChessLeft, ChessBottom - ChessTop );
|
||
|
||
double OffSetX = (float)m_nBatchSize * m_nZoomSmooth * m_nScale;
|
||
double OffSetY = (float)m_nBatchSize * m_nZoomSmooth * m_nScale;
|
||
|
||
//D3DXMATRIX ScaleMatrix;
|
||
//D3DXMatrixIdentity ( &ScaleMatrix );
|
||
//D3DXMatrixScaling ( &ScaleMatrix, m_nZoomSmooth, m_nZoomSmooth, m_nZoomSmooth );
|
||
|
||
//m_pD3DDevice->SetTransform ( D3DTS_VIEW, &ScaleMatrix );
|
||
|
||
m_pD3DDevice->SetSamplerState ( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR );
|
||
m_pD3DDevice->SetSamplerState ( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR );
|
||
m_pD3DDevice->SetSamplerState ( 0, D3DSAMP_ADDRESSW, D3DTADDRESS_MIRROR );
|
||
|
||
int FilteringImage = 2;
|
||
|
||
SetFiltering ( FilteringImage );
|
||
|
||
if ( 2 == FilteringImage || 1 == FilteringImage )
|
||
{
|
||
for ( int j = 0; j < m_nBatchesH; ++j )
|
||
{
|
||
for ( int i = 0; i < m_nBatchesW; ++i )
|
||
{
|
||
float2 v1 = float2 ( (float)(nWindowWidth * 0.5 - m_nCenterX * m_nZoomSmooth + OffSetX * ( i )),
|
||
(float)(nWindowHeight * 0.5 - m_nCenterY * m_nZoomSmooth + OffSetY * ( j )) );
|
||
float2 v2 = float2 ( (float)(nWindowWidth * 0.5 - m_nCenterX * m_nZoomSmooth + OffSetX * ( i + 1 )),
|
||
(float)(nWindowHeight * 0.5 - m_nCenterY * m_nZoomSmooth + OffSetY * ( j + 1 ) ));
|
||
|
||
D3DXVECTOR2 Tx01 = D3DXVECTOR2
|
||
(
|
||
0.0f,
|
||
0.0f
|
||
);
|
||
|
||
D3DXVECTOR2 Tx02 = D3DXVECTOR2
|
||
(
|
||
1.0f,
|
||
1.0f
|
||
);
|
||
|
||
//v1.x = (int)v1.x;
|
||
//v1.y = (int)v1.y;
|
||
//v2.x = (int)v2.x;
|
||
//v2.y = (int)v2.y;
|
||
|
||
//v1.x -= 0.5f;
|
||
//v1.y -= 0.5f;
|
||
//v2.x += 0.5f;
|
||
//v2.y += 0.5f;
|
||
|
||
//Gdiplus::RectF ZoneCur = RectF ( v1.x, v1.y, v2.x - v1.x, v1.y - v2.y );
|
||
//if ( ZonePaint.IntersectsWith ( ZoneCur ) )
|
||
{
|
||
m_pD3DDevice->SetTexture ( 0, m_oTextureBatch.GetTexture ( i, j ) );
|
||
DrawTextureQuad ( v1, v2, Tx01, Tx02 );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
m_pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
|
||
}
|
||
}
|
||
|
||
m_pD3DDevice->EndScene();
|
||
|
||
RECT SourceRect;
|
||
|
||
LONG OffSet = 0;// 16;
|
||
|
||
SourceRect.left = 0;//OffSet;
|
||
SourceRect.top = 0;//OffSet;
|
||
SourceRect.right = m_nWindowWidth;// - OffSet-1; // 1600;
|
||
SourceRect.bottom = m_nWindowHeight;// - OffSet-1; // 1200;
|
||
|
||
RECT DestRect;
|
||
|
||
DestRect.left = 0;//OffSet;
|
||
DestRect.top = 0;//OffSet;
|
||
DestRect.right = m_nWindowWidth;// - OffSet-1; // 1600;
|
||
DestRect.bottom = m_nWindowHeight;// - OffSet-1; // 1200;
|
||
|
||
//
|
||
|
||
m_pD3DDevice->Present ( &SourceRect, &DestRect, NULL, NULL );
|
||
}
|
||
|
||
m_oTimer.Reset ();
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
inline bool SetImage ( const BYTE* pImage, int Width, int Height, float Scale )
|
||
{
|
||
if ( NULL == pImage || Width < 1 || Height < 1 )
|
||
return false;
|
||
|
||
InterlockedExchange ( &m_nSetImageBlock, 1L );
|
||
|
||
CTemporaryCS TemporaryCS ( &m_BlockingCS );
|
||
|
||
if ( 1 != m_nIsInitialized )
|
||
{
|
||
return false;
|
||
}
|
||
|
||
m_nZoomSmooth = m_nZoom;
|
||
|
||
m_bUpdateTexture = true;
|
||
|
||
m_nChessWidth = (float)Width;
|
||
m_nChessHeight = (float)Height;
|
||
|
||
m_pImage = pImage;
|
||
m_nWidth = Width;
|
||
m_nHeight = Height;
|
||
m_nScale = Scale;
|
||
|
||
m_nBatchesW = m_nWidth / m_nBatchSize;
|
||
m_nBatchesH = m_nHeight / m_nBatchSize;
|
||
|
||
if ( m_nWidth < m_nBatchSize )
|
||
{
|
||
++m_nBatchesW;
|
||
}
|
||
else
|
||
{
|
||
if ( 0.0 != floor ( (double)m_nWidth / (double)m_nBatchSize ) )
|
||
++m_nBatchesW;
|
||
}
|
||
|
||
if ( m_nHeight < m_nBatchSize )
|
||
{
|
||
++m_nBatchesH;
|
||
}
|
||
else
|
||
{
|
||
if ( 0.0 != floor ( (double)m_nHeight / (double)m_nBatchSize ) )
|
||
++m_nBatchesH;
|
||
}
|
||
|
||
m_oTextureBatch.Create ( m_nBatchesW, m_nBatchesH, m_pD3DDevice, m_nBatchSize );
|
||
|
||
// inline void SetImage ( long IndX, long IndY, BYTE* pImage, long ImageW, long ImagH, long OffSetX, long OffSetY, long OffSetW = 0, long OffSetH = 0 )
|
||
|
||
for ( int j = 0; j < m_nBatchesH; ++j )
|
||
{
|
||
for ( int i = 0; i < m_nBatchesW; ++i )
|
||
{
|
||
long OffSetW = m_nBatchSize;
|
||
if ( ( i + 1 ) * m_nBatchSize > m_nWidth )
|
||
{
|
||
OffSetW = m_nBatchSize - ( ( i + 1 ) * m_nBatchSize - m_nWidth );
|
||
}
|
||
|
||
long OffSetH = m_nBatchSize;
|
||
if ( ( j + 1 ) * m_nBatchSize > m_nHeight )
|
||
{
|
||
OffSetH = m_nBatchSize - ( ( j + 1 ) * m_nBatchSize - m_nHeight );
|
||
}
|
||
|
||
m_oTextureBatch.SetImage ( i, j, pImage, m_nWidth, m_nHeight, m_nBatchSize * i, m_nBatchSize * j, OffSetW, OffSetH );
|
||
}
|
||
}
|
||
|
||
m_bUpdateTexture = false;
|
||
|
||
InterlockedExchange ( &m_nSetImageBlock, 0L );
|
||
|
||
return true;
|
||
}
|
||
|
||
inline void SetZoom ( float Zoom, bool ZoomForce = false )
|
||
{
|
||
m_nZoom = Zoom;
|
||
|
||
if ( ZoomForce )
|
||
{
|
||
m_nZoomSmooth = m_nZoom;
|
||
}
|
||
}
|
||
|
||
inline void SetCenterX ( float X )
|
||
{
|
||
m_nCenterX = X;
|
||
}
|
||
|
||
inline void SetCenterY ( float Y )
|
||
{
|
||
m_nCenterY = Y;
|
||
}
|
||
|
||
inline void SetBackClearColor ( DWORD Color )
|
||
{
|
||
m_nBackClearColor = Color;
|
||
}
|
||
inline void SetEnableAlphaLayer ( bool Enable )
|
||
{
|
||
m_bEnableAlphaLayer = Enable;
|
||
}
|
||
|
||
inline void SetFiltering ( int Filtering )
|
||
{
|
||
//D3DTEXF_NONE = 0, // filtering disabled (valid for mip filter only)
|
||
//D3DTEXF_POINT = 1, // nearest
|
||
//D3DTEXF_LINEAR = 2, // linear interpolation
|
||
//D3DTEXF_ANISOTROPIC = 3, // anisotropic
|
||
//D3DTEXF_PYRAMIDALQUAD = 6, // 4-sample tent
|
||
//D3DTEXF_GAUSSIANQUAD = 7, // 4-sample gaussian
|
||
//D3DTEXF_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
|
||
|
||
if ( NULL != m_pD3DDevice )
|
||
{
|
||
m_pD3DDevice->SetSamplerState ( 0, D3DSAMP_MINFILTER, (D3DTEXTUREFILTERTYPE)Filtering );
|
||
m_pD3DDevice->SetSamplerState ( 0, D3DSAMP_MAGFILTER, (D3DTEXTUREFILTERTYPE)Filtering );
|
||
m_pD3DDevice->SetSamplerState ( 0, D3DSAMP_MIPFILTER, (D3DTEXTUREFILTERTYPE)Filtering );
|
||
}
|
||
}
|
||
|
||
inline void SetEnableRender ( bool Enable )
|
||
{
|
||
CTemporaryCS TemporaryCS ( &m_BlockingCS );
|
||
|
||
if ( Enable )
|
||
{
|
||
InterlockedExchange ( &m_nSetEnableRender, 1L );
|
||
}
|
||
else
|
||
{
|
||
InterlockedExchange ( &m_nSetEnableRender, 0L );
|
||
//Clear ();
|
||
//m_oTextureBatch.Clear ();
|
||
}
|
||
}
|
||
|
||
inline long IsInitialized ()
|
||
{
|
||
return m_nIsInitialized;
|
||
}
|
||
inline bool IsEnable ()
|
||
{
|
||
if ( 1 == m_nIsInitialized )
|
||
{
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
inline bool Reset ()
|
||
{
|
||
CTemporaryCS TemporaryCS ( &m_BlockingCS );
|
||
|
||
if ( 1 == m_nIsInitialized )
|
||
{
|
||
RECT m_RECT;
|
||
GetWindowRect ( m_hWnd, &m_RECT );
|
||
|
||
int nWindowWidth = abs ( m_RECT.right - m_RECT.left );
|
||
int nWindowHeight = abs ( m_RECT.bottom - m_RECT.top );
|
||
|
||
if ( nWindowWidth > m_nWindowWidth || nWindowHeight > m_nWindowHeight )
|
||
{
|
||
m_nWindowWidth = nWindowWidth;
|
||
m_nWindowHeight = nWindowHeight;
|
||
|
||
D3DPRESENT_PARAMETERS d3dpp;
|
||
ZeroMemory ( &d3dpp, sizeof ( d3dpp ) );
|
||
//d3dpp.Windowed = TRUE;
|
||
//d3dpp.SwapEffect = D3DSWAPEFFECT_COPY; //D3DSWAPEFFECT_DISCARD;
|
||
//d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
|
||
//d3dpp.EnableAutoDepthStencil = TRUE;
|
||
//d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
|
||
//d3dpp.hDeviceWindow = m_hWnd;
|
||
|
||
d3dpp.hDeviceWindow = m_hWnd;
|
||
d3dpp.FullScreen_RefreshRateInHz= 0;
|
||
d3dpp.BackBufferCount = 1;
|
||
d3dpp.Windowed = TRUE;
|
||
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;// D3DSWAPEFFECT_COPY; // D3DSWAPEFFECT_DISCARD;
|
||
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; // D3DFMT_UNKNOWN;
|
||
d3dpp.EnableAutoDepthStencil = TRUE;
|
||
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
|
||
d3dpp.Windowed = TRUE;
|
||
//d3dpp.PresentationInterval = 0;
|
||
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||
d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
|
||
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||
|
||
LONG WindowStyle = GetWindowLongW ( m_hWnd, GWL_STYLE );
|
||
if ( WindowStyle & WS_POPUP )
|
||
{
|
||
d3dpp.Windowed = FALSE;
|
||
}
|
||
|
||
if ( FAILED ( IDirect3DDevice9_Reset ( m_pD3DDevice, &d3dpp ) ) )
|
||
{
|
||
return false;
|
||
}
|
||
|
||
// Create OffScreen Surface
|
||
|
||
RELEASEINTERFACE ( m_pSurface );
|
||
if ( FAILED ( m_pD3DDevice->CreateOffscreenPlainSurface ( m_nWindowWidth, m_nWindowHeight, D3DFMT_X8R8G8B8,
|
||
//D3DPOOL_SCRATCH
|
||
D3DPOOL_SYSTEMMEM,
|
||
&m_pSurface, NULL ) ) )
|
||
{
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
|
||
inline void SetZoomToWindow ( bool Value )
|
||
{
|
||
m_bZoomToWindow = Value;
|
||
}
|
||
|
||
|
||
private:
|
||
|
||
inline void DrawTextureQuad ( D3DXVECTOR2 Vertex1, D3DXVECTOR2 Vertex2, D3DXVECTOR2 TecCoord1, D3DXVECTOR2 TecCoord2 )
|
||
{
|
||
struct VFTexturePoint2D
|
||
{
|
||
float m_VertexX;
|
||
float m_VertexY;
|
||
float m_VertexZ;
|
||
float m_VertexW;
|
||
|
||
float m_Tex0;
|
||
float m_Tex1;
|
||
};
|
||
|
||
m_pD3DDevice->SetFVF ( D3DFVF_XYZRHW | D3DFVF_TEX1 );
|
||
|
||
VFTexturePoint2D Vertexes[4];
|
||
|
||
Vertexes[0].m_VertexX = Vertex1.x;
|
||
Vertexes[0].m_VertexY = Vertex1.y;
|
||
Vertexes[0].m_VertexZ = 0.0f;
|
||
Vertexes[0].m_VertexW = 1.0f;
|
||
|
||
Vertexes[1].m_VertexX = Vertex2.x;
|
||
Vertexes[1].m_VertexY = Vertex1.y;
|
||
Vertexes[1].m_VertexZ = 0.0f;
|
||
Vertexes[1].m_VertexW = 1.0f;
|
||
|
||
Vertexes[2].m_VertexX = Vertex2.x;
|
||
Vertexes[2].m_VertexY = Vertex2.y;
|
||
Vertexes[2].m_VertexZ = 0.0f;
|
||
Vertexes[2].m_VertexW = 1.0f;
|
||
|
||
Vertexes[3].m_VertexX = Vertex1.x;
|
||
Vertexes[3].m_VertexY = Vertex2.y;
|
||
Vertexes[3].m_VertexZ = 0.0f;
|
||
Vertexes[3].m_VertexW = 1.0f;
|
||
|
||
Vertexes[0].m_Tex0 = TecCoord1.x;
|
||
Vertexes[0].m_Tex1 = TecCoord1.y;
|
||
|
||
Vertexes[1].m_Tex0 = TecCoord2.x;
|
||
Vertexes[1].m_Tex1 = TecCoord1.y;
|
||
|
||
Vertexes[2].m_Tex0 = TecCoord2.x;
|
||
Vertexes[2].m_Tex1 = TecCoord2.y;
|
||
|
||
Vertexes[3].m_Tex0 = TecCoord1.x;
|
||
Vertexes[3].m_Tex1 = TecCoord2.y;
|
||
|
||
m_pD3DDevice->DrawPrimitiveUP ( D3DPT_TRIANGLEFAN, 2, Vertexes, sizeof(VFTexturePoint2D) );
|
||
}
|
||
|
||
inline void DrawColorQuad ( D3DXVECTOR2 Vertex1, D3DXVECTOR2 Vertex2, DWORD Color01, DWORD Color02, DWORD Color03, DWORD Color04 )
|
||
{
|
||
struct VFColorPoint2D
|
||
{
|
||
float m_VertexX;
|
||
float m_VertexY;
|
||
float m_VertexZ;
|
||
float m_VertexW;
|
||
|
||
unsigned long m_Color;
|
||
};
|
||
|
||
m_pD3DDevice->SetFVF ( D3DFVF_XYZRHW | D3DFVF_DIFFUSE );
|
||
|
||
VFColorPoint2D Vertexes[4];
|
||
|
||
Vertexes[0].m_VertexX = Vertex1.x;
|
||
Vertexes[0].m_VertexY = Vertex1.y;
|
||
Vertexes[0].m_VertexZ = 0.0f;
|
||
Vertexes[0].m_VertexW = 1.0f;
|
||
|
||
Vertexes[1].m_VertexX = Vertex2.x;
|
||
Vertexes[1].m_VertexY = Vertex1.y;
|
||
Vertexes[1].m_VertexZ = 0.0f;
|
||
Vertexes[1].m_VertexW = 1.0f;
|
||
|
||
Vertexes[2].m_VertexX = Vertex2.x;
|
||
Vertexes[2].m_VertexY = Vertex2.y;
|
||
Vertexes[2].m_VertexZ = 0.0f;
|
||
Vertexes[2].m_VertexW = 1.0f;
|
||
|
||
Vertexes[3].m_VertexX = Vertex1.x;
|
||
Vertexes[3].m_VertexY = Vertex2.y;
|
||
Vertexes[3].m_VertexZ = 0.0f;
|
||
Vertexes[3].m_VertexW = 1.0f;
|
||
|
||
Vertexes[0].m_Color = Color01;
|
||
Vertexes[1].m_Color = Color02;
|
||
Vertexes[2].m_Color = Color03;
|
||
Vertexes[3].m_Color = Color04;
|
||
|
||
m_pD3DDevice->DrawPrimitiveUP ( D3DPT_TRIANGLEFAN, 2, Vertexes, sizeof(VFColorPoint2D) );
|
||
}
|
||
|
||
|
||
static unsigned int __stdcall AsyncRender ( void* pArguments )
|
||
{
|
||
#ifdef _DEBUG
|
||
ATLTRACE (_T("START ASYNC RENDER\n"));
|
||
#endif
|
||
FrameFastWindow* pFrameFastWindow = static_cast<FrameFastWindow*> ( pArguments );
|
||
if ( NULL != pFrameFastWindow )
|
||
{
|
||
while ( true )
|
||
{
|
||
Sleep ( 1 );
|
||
|
||
if ( pFrameFastWindow->m_nAsyncUpdateRender )
|
||
{
|
||
#ifdef _DEBUG
|
||
ATLTRACE (_T("STOP ASYNC RENDER\n"));
|
||
#endif
|
||
return 0;
|
||
}
|
||
|
||
if ( FALSE == pFrameFastWindow->m_nSetImageBlock && TRUE == pFrameFastWindow->m_nSetEnableRender )
|
||
{
|
||
//if ( false == pFrameFastWindow->m_bZoomToWindow )
|
||
pFrameFastWindow->Update ();
|
||
}
|
||
else
|
||
{
|
||
//Sleep ( 10 );
|
||
}
|
||
}
|
||
}
|
||
|
||
#ifdef _DEBUG
|
||
ATLTRACE (_T("STOP ASYNC RENDER\n"));
|
||
#endif
|
||
return 0;
|
||
}
|
||
|
||
public:
|
||
|
||
long m_nIsInitialized;
|
||
bool m_bIsEnabled;
|
||
bool m_nIsTexturesComplete;
|
||
|
||
DWORD m_nBackClearColor;
|
||
bool m_bEnableAlphaLayer;
|
||
|
||
IDirect3D9* m_pD3D;
|
||
IDirect3DDevice9* m_pD3DDevice;
|
||
|
||
long m_nAsyncUpdateRender;
|
||
long m_nSetImageBlock;
|
||
long m_nSetEnableRender;
|
||
|
||
const BYTE* m_pImage;
|
||
int m_nWidth;
|
||
int m_nHeight;
|
||
|
||
IDirect3DTexture9* m_pTexureChess;
|
||
float m_nChessWidth;
|
||
float m_nChessHeight;
|
||
|
||
CTextureBatch m_oTextureBatch;
|
||
long m_nBatchSize;
|
||
long m_nBatchesW;
|
||
long m_nBatchesH;
|
||
|
||
IDirect3DSurface9* m_pSurface;
|
||
|
||
int m_nWindowWidth;
|
||
int m_nWindowHeight;
|
||
|
||
long m_bUpdateTexture;
|
||
float m_nScale;
|
||
|
||
float m_nZoom;
|
||
float m_nCenterX;
|
||
float m_nCenterY;
|
||
bool m_bZoomToWindow;
|
||
|
||
HWND m_hWnd;
|
||
HDC m_HDC;
|
||
HANDLE m_hThread;
|
||
CRITICAL_SECTION m_BlockingCS;
|
||
|
||
// SMOOTH
|
||
|
||
float m_nZoomSmooth;
|
||
|
||
CTimeMeasurer m_oTimer;
|
||
};
|
||
}
|
||
|
||
#endif |