#include "StdAfx.h" #include "VirtualGlassMap.h" #include "CHImageControls/CHImageProcess.h" #include "CHCommonClasses/MacroFile.h" #include #define Rounding(x, dig) (floor((x) * pow(10,dig) + 0.5) / pow(10,dig)) #define M_PI 3.14159265358979323846 #define ToRadian(degree) ( (degree) * (M_PI/180.0) ) #define ToDegree(radian) ( (radian) * (180.0/M_PI) ) #define SafeRelease(T) if(T){T->Release(); T = 0; } #define SafeDelete(T) if(T){delete T; T = 0; } CVirtualGlassMap::CVirtualGlassMap(void) { Reset(); InitializeCriticalSection(&m_csImageData); OleInitialize(NULL); HRESULT hr = S_OK; // create wic factory hr = ::CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_pWICFactory)); if (hr!=S_OK) { } // create d2d factory hr = ::D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pD2DFactory); if (hr!=S_OK) { } m_pWicBitmap = nullptr; m_pRenderTarget = nullptr; } CVirtualGlassMap::~CVirtualGlassMap(void) { Reset(); SafeRelease(m_pRenderTarget); SafeRelease(m_pWicBitmap); SafeRelease(m_pD2DFactory); SafeRelease(m_pWICFactory); DeleteCriticalSection(&m_csImageData); } void CVirtualGlassMap::Reset() { m_ImageInfo.Reset(); m_MotorInfo.Reset(); m_GlassInfo.Reset(); m_CurGlassInfo.Reset(); m_nCurMotorDir = -1; m_CurGlassInfo.nCutDir = -1; m_vecGlassObject.clear(); if (LoadGlassMap(_T("TestGlassInfo.vmf"))) { return; } CVirtualGlassObject object; object.nObjectType = VGOT_Align; object.nDrawType = VODT_Polygon; object.nBrushColor = MakeColor(255,50,200,50); object.nPenColor = MakeColor(255,0,0,0); object.dPenSize = 0.005; object.dSizeX = 0.9; object.dSizeY = 0.9; double dDistX = 10.0; double dDistY = 10.0; double dBlockSizeX = object.dSizeX / 3.0; double dBlockSizeY = object.dSizeY / 3.0; // cross mark object.vecPolygon.push_back(SDoublePos(dBlockSizeX, 0.00)); object.vecPolygon.push_back(SDoublePos(dBlockSizeX*2, 0.00)); object.vecPolygon.push_back(SDoublePos(dBlockSizeX*2, dBlockSizeY)); object.vecPolygon.push_back(SDoublePos(dBlockSizeX*3, dBlockSizeY)); object.vecPolygon.push_back(SDoublePos(dBlockSizeX*3, dBlockSizeY*2)); object.vecPolygon.push_back(SDoublePos(dBlockSizeX*2, dBlockSizeY*2)); object.vecPolygon.push_back(SDoublePos(dBlockSizeX*2, dBlockSizeY*3)); object.vecPolygon.push_back(SDoublePos(dBlockSizeX, dBlockSizeY*3)); object.vecPolygon.push_back(SDoublePos(dBlockSizeX, dBlockSizeY*2)); object.vecPolygon.push_back(SDoublePos(0.00, dBlockSizeY*2)); object.vecPolygon.push_back(SDoublePos(0.00, dBlockSizeY)); object.vecPolygon.push_back(SDoublePos(dBlockSizeX, dBlockSizeY)); double dMaskSizeX = 800; double dMaskSizeY = 600; double dMaskStartX = 0; double dMaskStartY = 0; // 1 object.dPosX = dMaskStartX + dDistX - (object.dSizeX/2.0); object.dPosY = dMaskStartY + dDistY - (object.dSizeY/2.0); m_vecGlassObject.push_back(object); // 2 object.dPosX = dMaskStartX + dMaskSizeX - dDistX - (object.dSizeX/2.0); object.dPosY = dMaskStartY + dDistY - (object.dSizeY/2.0); m_vecGlassObject.push_back(object); // 3 object.dPosX = dMaskStartX + dDistX - (object.dSizeX/2.0); object.dPosY = dMaskStartY + dMaskSizeY - dDistY - (object.dSizeY/2.0); m_vecGlassObject.push_back(object); // 4 object.dPosX = dMaskStartX + dMaskSizeX - dDistX - (object.dSizeX/2.0); object.dPosY = dMaskStartY + dMaskSizeY - dDistY - (object.dSizeY/2.0); m_vecGlassObject.push_back(object); dMaskStartX = 800; dMaskStartY = 0; // 1 object.dPosX = dMaskStartX + dDistX - (object.dSizeX/2.0); object.dPosY = dMaskStartY + dDistY - (object.dSizeY/2.0); m_vecGlassObject.push_back(object); // 2 object.dPosX = dMaskStartX + dMaskSizeX - dDistX - (object.dSizeX/2.0); object.dPosY = dMaskStartY + dDistY - (object.dSizeY/2.0); m_vecGlassObject.push_back(object); // 3 object.dPosX = dMaskStartX + dDistX - (object.dSizeX/2.0); object.dPosY = dMaskStartY + dMaskSizeY - dDistY - (object.dSizeY/2.0); m_vecGlassObject.push_back(object); // 4 object.dPosX = dMaskStartX + dMaskSizeX - dDistX - (object.dSizeX/2.0); object.dPosY = dMaskStartY + dMaskSizeY - dDistY - (object.dSizeY/2.0); m_vecGlassObject.push_back(object); dMaskStartX = 0; dMaskStartY = 600; // 1 object.dPosX = dMaskStartX + dDistX - (object.dSizeX/2.0); object.dPosY = dMaskStartY + dDistY - (object.dSizeY/2.0); m_vecGlassObject.push_back(object); // 2 object.dPosX = dMaskStartX + dMaskSizeX - dDistX - (object.dSizeX/2.0); object.dPosY = dMaskStartY + dDistY - (object.dSizeY/2.0); m_vecGlassObject.push_back(object); // 3 object.dPosX = dMaskStartX + dDistX - (object.dSizeX/2.0); object.dPosY = dMaskStartY + dMaskSizeY - dDistY - (object.dSizeY/2.0); m_vecGlassObject.push_back(object); // 4 object.dPosX = dMaskStartX + dMaskSizeX - dDistX - (object.dSizeX/2.0); object.dPosY = dMaskStartY + dMaskSizeY - dDistY - (object.dSizeY/2.0); m_vecGlassObject.push_back(object); dMaskStartX = 800; dMaskStartY = 600; // 1 object.dPosX = dMaskStartX + dDistX - (object.dSizeX/2.0); object.dPosY = dMaskStartY + dDistY - (object.dSizeY/2.0); m_vecGlassObject.push_back(object); // 2 object.dPosX = dMaskStartX + dMaskSizeX - dDistX - (object.dSizeX/2.0); object.dPosY = dMaskStartY + dDistY - (object.dSizeY/2.0); m_vecGlassObject.push_back(object); // 3 object.dPosX = dMaskStartX + dDistX - (object.dSizeX/2.0); object.dPosY = dMaskStartY + dMaskSizeY - dDistY - (object.dSizeY/2.0); m_vecGlassObject.push_back(object); // 4 object.dPosX = dMaskStartX + dMaskSizeX - dDistX - (object.dSizeX/2.0); object.dPosY = dMaskStartY + dMaskSizeY - dDistY - (object.dSizeY/2.0); m_vecGlassObject.push_back(object); // active object.nObjectType = VGOT_Active; object.nDrawType = VODT_Rectangle; object.nBrushColor = MakeColor(255,200,200,50); object.nPenColor = MakeColor(255,0,0,0); object.dPenSize = 0.005; object.vecPolygon.clear(); object.dPosX = 40.0; object.dPosY = 40.0; object.dSizeX = 720; object.dSizeY = 520; m_vecGlassObject.push_back(object); object.dPosX = 840.0; object.dPosY = 40.0; m_vecGlassObject.push_back(object); object.dPosX = 40.0; object.dPosY = 640.0; m_vecGlassObject.push_back(object); object.dPosX = 840.0; object.dPosY = 640.0; m_vecGlassObject.push_back(object); // top pad object.nObjectType = VGOT_Pad; object.nDrawType = VODT_Rectangle; object.nBrushColor = MakeColor(255,100,100,100); object.nPenColor = MakeColor(255,0,0,0); object.dPenSize = 0.005; object.dPosX = 20.0; object.dPosY = 20.0; object.dSizeX = 760.0; object.dSizeY = 20.0; m_vecGlassObject.push_back(object); object.dPosX = 820.0; object.dPosY = 20.0; m_vecGlassObject.push_back(object); object.dPosX = 20.0; object.dPosY = 620.0; m_vecGlassObject.push_back(object); object.dPosX = 820.0; object.dPosY = 620.0; m_vecGlassObject.push_back(object); // bottom pad object.nBrushColor = MakeColor(255,50,100,100); object.dPosX = 20.0; object.dPosY = 560.0; object.dSizeX = 760.0; object.dSizeY = 20.0; m_vecGlassObject.push_back(object); object.dPosX = 820.0; object.dPosY = 560.0; m_vecGlassObject.push_back(object); object.dPosX = 20.0; object.dPosY = 1160.0; m_vecGlassObject.push_back(object); object.dPosX = 820.0; object.dPosY = 1160.0; m_vecGlassObject.push_back(object); // left pad object.nBrushColor = MakeColor(255,50,200,100); object.dPosX = 20.0; object.dPosY = 40.0; object.dSizeX = 20.0; object.dSizeY = 520.0; m_vecGlassObject.push_back(object); object.dPosX = 820.0; object.dPosY = 40.0; m_vecGlassObject.push_back(object); object.dPosX = 20.0; object.dPosY = 640.0; m_vecGlassObject.push_back(object); object.dPosX = 820.0; object.dPosY = 640.0; m_vecGlassObject.push_back(object); // right pad object.nBrushColor = MakeColor(255,100,50,200); object.dPosX = 760.0; object.dPosY = 40.0; object.dSizeX = 20.0; object.dSizeY = 520.0; m_vecGlassObject.push_back(object); object.dPosX = 1560.0; object.dPosY = 40.0; m_vecGlassObject.push_back(object); object.dPosX = 760.0; object.dPosY = 640.0; m_vecGlassObject.push_back(object); object.dPosX = 1560.0; object.dPosY = 640.0; m_vecGlassObject.push_back(object); SaveGlassMap(_T("TestGlassInfo.vmf")); } void CVirtualGlassMap::SetGlassTilt(double dDx, double dDy, double dAngle) { if (m_GlassTilt.dDx==dDx && m_GlassTilt.dDy==dDy && m_GlassTilt.dAngle==dAngle) return; m_GlassTilt.dDx = dDx; m_GlassTilt.dDy = dDy; m_GlassTilt.dAngle = dAngle; m_bGlassTilt = true; } void CVirtualGlassMap::SetGlassTilt(const CVirtualGlassTilt& glassTilt) { if (m_GlassTilt.dDx==glassTilt.dDx && m_GlassTilt.dDy==glassTilt.dDy && m_GlassTilt.dAngle==glassTilt.dAngle) return; m_GlassTilt = glassTilt; m_bGlassTilt = true; } void CVirtualGlassMap::SetMotorOriginDir(int nDir) { m_MotorInfo.nOriginDir = nDir; } void CVirtualGlassMap::SetGlassOriginDir(int nDir) { m_GlassInfo.nOriginDir = nDir; } BOOL CVirtualGlassMap::LoadGlassMap(const CString& strFilename) { CMacroFile file; if (file.Read(strFilename)==FALSE) return FALSE; // motor info file.GetItem(_T("MOTOR_INFO_INDEX"), m_MotorInfo.nIndex, 0); file.GetItem(_T("MOTOR_INFO_NAME"), m_MotorInfo.strName, _T("Motor")); file.GetItem(_T("MOTOR_INFO_PENCOLOR"), m_MotorInfo.nPenColor, MakeColor(255,0,0,0)); file.GetItem(_T("MOTOR_INFO_BRUSHCOLOR"), m_MotorInfo.nBrushColor, MakeColor(255,50,0,50)); file.GetItem(_T("MOTOR_INFO_PENSIZE"), m_MotorInfo.dPenSize, 0.01); file.GetItem(_T("MOTOR_INFO_PENOPACITY"), m_MotorInfo.dPenOpacity, 1.0); file.GetItem(_T("MOTOR_INFO_BRUSHOPACITY"), m_MotorInfo.dBrushOpacity, 1.0); file.GetItem(_T("MOTOR_INFO_ORIGINDIR"), m_MotorInfo.nOriginDir, VODT_LeftTop); file.GetItem(_T("MOTOR_INFO_RANGEMINX"), m_MotorInfo.dPosX, 0.0); file.GetItem(_T("MOTOR_INFO_RANGEMAXX"), m_MotorInfo.dSizeX, 0.0); file.GetItem(_T("MOTOR_INFO_RANGEMINY"), m_MotorInfo.dPosY, 1800.0); file.GetItem(_T("MOTOR_INFO_RANGEMAXY"), m_MotorInfo.dSizeY, 1400.0); // glass info file.GetItem(_T("GLASS_INFO_INDEX"), m_GlassInfo.nIndex, 0); file.GetItem(_T("GLASS_INFO_NAME"), m_GlassInfo.strName, _T("Galass")); file.GetItem(_T("GLASS_INFO_PENCOLOR"), m_GlassInfo.nPenColor, MakeColor(255,100,100,100)); file.GetItem(_T("GLASS_INFO_BRUSHCOLOR"), m_GlassInfo.nBrushColor, MakeColor(255,0,200,200)); file.GetItem(_T("GLASS_INFO_PENSIZE"), m_GlassInfo.dPenSize, 0.01); file.GetItem(_T("GLASS_INFO_PENOPACITY"), m_GlassInfo.dPenOpacity, 1.0); file.GetItem(_T("GLASS_INFO_BRUSHOPACITY"), m_GlassInfo.dBrushOpacity, 1.0); file.GetItem(_T("GLASS_INFO_ORIGINDIR"), m_GlassInfo.nOriginDir, VODT_LeftTop); file.GetItem(_T("GLASS_INFO_CUTDIR"), m_GlassInfo.nCutDir, VODT_LeftTop); file.GetItem(_T("GLASS_INFO_CUT_SIZE"), m_GlassInfo.dCutSize, 5.0); file.GetItem(_T("GLASS_INFO_NOCUT_SIZE"), m_GlassInfo.dNoCutSize, 1.0); file.GetItem(_T("GLASS_INFO_POSX"), m_GlassInfo.dPosX, 100.0); file.GetItem(_T("GLASS_INFO_POSY"), m_GlassInfo.dPosY, 100.0); file.GetItem(_T("GLASS_INFO_SIZEX"), m_GlassInfo.dSizeX, 1600.0); file.GetItem(_T("GLASS_INFO_SIZEY"), m_GlassInfo.dSizeY, 1200.0); // glass object int nValue = 0; file.GetItem(_T("GLASS_OBJECT_COUNT"), nValue, 0); CString strValue = _T(""); CVirtualGlassObject object; SDoublePos position; for (int nIdx=0; nIdxGetSize(&nWidth, &nHeight); if (hr!=S_OK) return FALSE; // for 4 channels image if (m_ImageInfo.nFrameChannels==4 && pImageData) { WICRect rect; rect.X = 0; rect.Y = 0; rect.Width = nWidth; rect.Height = nHeight; hr = m_pWicBitmap->CopyPixels(&rect, nWidth*m_ImageInfo.nFrameChannels, nWidth*nHeight*m_ImageInfo.nFrameChannels, pImageData); if (hr==S_OK) return TRUE; return FALSE; } GUID pixelFormat = GUID_WICPixelFormat32bppBGRA; switch(m_ImageInfo.nFrameChannels) { case 1: pixelFormat = GUID_WICPixelFormat8bppGray; break; // case 3: // pixelFormat = GUID_WICPixelFormat24bppBGR; // break; default: return FALSE; } IWICFormatConverter * pFormatConverter = NULL; hr = m_pWICFactory->CreateFormatConverter(&pFormatConverter); if (hr!=S_OK) return FALSE; hr = pFormatConverter->Initialize( m_pWicBitmap, // Input source to convert pixelFormat, // Destination pixel format WICBitmapDitherTypeNone, // Specified dither pattern NULL, // Specify a particular palette 0.f, // Alpha threshold WICBitmapPaletteTypeCustom // Palette translation type ); if (hr!=S_OK) return FALSE; WICRect rect; rect.X = 0; rect.Y = 0; rect.Width = nWidth; rect.Height = nHeight; hr = pFormatConverter->CopyPixels(&rect, nWidth*m_ImageInfo.nFrameChannels, nWidth*nHeight*m_ImageInfo.nFrameChannels, pImageData); SafeRelease(pFormatConverter); if (hr==S_OK) return TRUE; return FALSE; } BOOL CVirtualGlassMap::GetImageData( const CVirtualImageInfo& imageInfo, BYTE *pImageData) { if (pImageData==NULL) return FALSE; EnterCriticalSection(&m_csImageData); if (m_pWicBitmap && (m_ImageInfo==imageInfo) && !m_bGlassTilt) { BOOL bResult = GetImageDataFromWicBitmap(pImageData); LeaveCriticalSection(&m_csImageData); return bResult; } m_bGlassTilt = false; if (MakeWicImage(imageInfo)) { BOOL bResult = GetImageDataFromWicBitmap(pImageData); LeaveCriticalSection(&m_csImageData); return bResult; } LeaveCriticalSection(&m_csImageData); return FALSE; } BOOL CVirtualGlassMap::GetImageData( const CVirtualImageInfo& imageInfo, CCHImageData* pImageData ) { if (pImageData==NULL) return FALSE; if (pImageData->CreateImage(imageInfo.nFrameWidth, imageInfo.nFrameHeight, 8, imageInfo.nFrameChannels)==FALSE) { return FALSE; } int nStep = pImageData->GetWidthStep(); EnterCriticalSection(&m_csImageData); if (m_pWicBitmap && (m_ImageInfo==imageInfo) && !m_bGlassTilt) { BOOL bResult = GetImageDataFromWicBitmap((BYTE*)pImageData->GetImageBuffer()); LeaveCriticalSection(&m_csImageData); return bResult; } m_bGlassTilt = false; if (MakeWicImage(imageInfo)) { BOOL bResult = GetImageDataFromWicBitmap((BYTE*)pImageData->GetImageBuffer()); LeaveCriticalSection(&m_csImageData); return bResult; } LeaveCriticalSection(&m_csImageData); return FALSE; } BOOL CVirtualGlassMap::MakeWicImage( const CVirtualImageInfo& imageInfo) { if (m_pD2DFactory==NULL || m_pWICFactory==NULL) return FALSE; if (imageInfo.dPixelSizeX<=0.0 || imageInfo.dPixelSizeY<=0.0) return FALSE; if (imageInfo.nFrameWidth<1 || imageInfo.nFrameHeight<1) return FALSE; SafeRelease(m_pWicBitmap); SafeRelease(m_pRenderTarget); HRESULT hr = S_OK; int nFrameWidth = (imageInfo.nFrameWidth * imageInfo.nFrameChannels) % 4; if (nFrameWidth!=0) { nFrameWidth = imageInfo.nFrameWidth + (4-(imageInfo.nFrameWidth%4)); } else { nFrameWidth = imageInfo.nFrameWidth; } // create wic bitmap hr = m_pWICFactory->CreateBitmap(nFrameWidth, imageInfo.nFrameHeight, GUID_WICPixelFormat32bppBGR, WICBitmapCacheOnLoad, &m_pWicBitmap); if (hr!=S_OK) { return FALSE; } // create render target hr = m_pD2DFactory->CreateWicBitmapRenderTarget(m_pWicBitmap, D2D1::RenderTargetProperties(), &m_pRenderTarget); if (hr!=S_OK) { SafeRelease(m_pWicBitmap); return FALSE; } // cal fov double dFrameWidth = (nFrameWidth * imageInfo.dPixelSizeX) / 1000.0; // um double dFrameHeight = (imageInfo.nFrameHeight * imageInfo.dPixelSizeY) / 1000.0; // um // cal fov rect D2D1_RECT_F rtFovRect = D2D1::RectF(FLOAT(imageInfo.dCenterX-(dFrameWidth/2.0)), FLOAT(imageInfo.dCenterY-(dFrameHeight/2.0)), FLOAT(imageInfo.dCenterX+(dFrameWidth/2.0)), FLOAT(imageInfo.dCenterY+(dFrameHeight/2.0)) ); // cal scale double dMotorScaleX = 1.0; double dMotorScaleY = 1.0; double dMotorTransX = 0.0; double dMotorTransY = 0.0; // set translate switch(m_MotorInfo.nOriginDir) { case VODT_LeftTop: dMotorScaleX = (1.0 / imageInfo.dPixelSizeX) * 1000.0; dMotorScaleY = (1.0 / imageInfo.dPixelSizeY) * 1000.0; dMotorTransX = -(imageInfo.dCenterX - (dFrameWidth / 2)); dMotorTransY = -(imageInfo.dCenterY - (dFrameHeight / 2)); break; case VODT_RightTop: dMotorScaleX = -(1.0 / imageInfo.dPixelSizeX) * 1000.0; dMotorScaleY = (1.0 / imageInfo.dPixelSizeY) * 1000.0; dMotorTransX = -(imageInfo.dCenterX + (dFrameWidth / 2)); dMotorTransY = -(imageInfo.dCenterY - (dFrameHeight / 2)); break; case VODT_LeftBottom: dMotorScaleX = (1.0 / imageInfo.dPixelSizeX) * 1000.0; dMotorScaleY = -(1.0 / imageInfo.dPixelSizeY) * 1000.0; dMotorTransX = -(imageInfo.dCenterX - (dFrameWidth / 2)); dMotorTransY = -(imageInfo.dCenterY + (dFrameHeight / 2)); break; case VODT_RightBottom: dMotorScaleX = -(1.0 / imageInfo.dPixelSizeX) * 1000.0; dMotorScaleY = -(1.0 / imageInfo.dPixelSizeY) * 1000.0; dMotorTransX = -(imageInfo.dCenterX + (dFrameWidth / 2)); dMotorTransY = -(imageInfo.dCenterY + (dFrameHeight / 2)); break; default: return FALSE; } // set anti alias mode if (m_pRenderTarget->GetAntialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED) { m_pRenderTarget->SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); } m_pRenderTarget->BeginDraw(); // translation & scale transform D2D1_MATRIX_3X2_F matTranslation = D2D1::Matrix3x2F::Translation(FLOAT(dMotorTransX), FLOAT(dMotorTransY)); D2D1_MATRIX_3X2_F matScale = D2D1::Matrix3x2F::Scale(FLOAT(dMotorScaleX), FLOAT(dMotorScaleY), D2D1::Point2F(0.0f, 0.0f)); D2D1_MATRIX_3X2_F matTandS = matTranslation * matScale; m_pRenderTarget->SetTransform(matTandS); // draw motor DrawMotor(m_pRenderTarget, rtFovRect); // glass tilt D2D1_MATRIX_3X2_F matGlassRotation = D2D1::Matrix3x2F::Rotation(FLOAT(m_GlassTilt.dAngle), D2D1::Point2F(FLOAT(m_GlassInfo.dPosX), FLOAT(m_GlassInfo.dPosY))); D2D1_MATRIX_3X2_F matGlassTranslation = D2D1::Matrix3x2F::Translation(FLOAT(dMotorTransX+m_GlassTilt.dDx), FLOAT(dMotorTransY+m_GlassTilt.dDy)); D2D1_MATRIX_3X2_F matRandTandS = matGlassRotation * matGlassTranslation * matScale; m_pRenderTarget->SetTransform(matRandTandS); // draw glass DrawGlass(m_pRenderTarget, rtFovRect); // draw glass object DrawGalssObject(m_pRenderTarget, rtFovRect); m_pRenderTarget->EndDraw(); // save current image info m_ImageInfo = imageInfo; return TRUE; } const CVirtualGlassObject* CVirtualGlassMap::GetGlassObject(int nIndex) const { if (nIndex<0 || nIndex>=(int)m_vecGlassObject.size()) return NULL; return &m_vecGlassObject[nIndex]; } CVirtualGlassObject* CVirtualGlassMap::GetGlassObject(int nIndex) { if (nIndex<0 || nIndex>=(int)m_vecGlassObject.size()) return NULL; return &m_vecGlassObject[nIndex]; } void CVirtualGlassMap::AddGlassObject(const CVirtualGlassObject& glassObject) { m_vecGlassObject.push_back(glassObject); } void CVirtualGlassMap::DrawMotor( ID2D1RenderTarget* pRenderTarget, const D2D1_RECT_F& rtRect ) { D2D1_RECT_F rtMotor = D2D1::RectF(FLOAT(m_MotorInfo.Left()), FLOAT(m_MotorInfo.Top()), FLOAT(m_MotorInfo.Right()), FLOAT(m_MotorInfo.Bottom()) ); if (IntersectsWith(rtRect, rtMotor)==FALSE) return; ID2D1SolidColorBrush *pPen = NULL; HRESULT hr = pRenderTarget->CreateSolidColorBrush( D2D1::ColorF(D2D1::ColorF(m_MotorInfo.nPenColor, FLOAT(m_MotorInfo.dPenOpacity))), &pPen ); ID2D1SolidColorBrush *pBrush = NULL; hr = pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF(m_MotorInfo.nBrushColor, FLOAT(m_MotorInfo.dBrushOpacity))),&pBrush); pRenderTarget->FillRectangle(rtMotor, pBrush); pRenderTarget->DrawRectangle(rtMotor, pPen, FLOAT(m_MotorInfo.dPenSize)); SafeRelease(pPen); SafeRelease(pBrush); } int GetDirX(int nDir1, int nDir2) { if ( (nDir1==VODT_LeftTop) || (nDir1==VODT_LeftBottom) ) { if ( (nDir2==VODT_LeftTop) || (nDir2==VODT_LeftBottom) ) { return 1; } return 0; } if ( (nDir2==VODT_RightTop) || (nDir2==VODT_RightBottom) ) { return 1; } return 0; } int GetDirY(int nDir1, int nDir2) { if ( (nDir1==VODT_LeftTop) || (nDir1==VODT_RightTop) ) { if ( (nDir2==VODT_LeftTop) || (nDir2==VODT_RightTop) ) { return 1; } return 0; } if ( (nDir2==VODT_LeftBottom) || (nDir2==VODT_RightBottom) ) { return 1; } return 0; } void CVirtualGlassMap::CalculateGlassPos( int nMotorDir, const CVirtualGlassInfo& glassInfo ) { int nDir = GetDirX(nMotorDir, glassInfo.nCutDir) << 1; nDir += GetDirY(nMotorDir, glassInfo.nCutDir); switch(nDir) { case 3: // x°°Àº¹æÇâ, y°°Àº¹æÇâ { // 0 m_ptPosition[0].x = FLOAT(m_GlassInfo.Left()+m_GlassInfo.dCutSize); m_ptPosition[0].y = FLOAT(m_GlassInfo.Top()); //1 m_ptPosition[1].x = FLOAT(m_GlassInfo.Right()-m_GlassInfo.dNoCutSize); m_ptPosition[1].y = FLOAT(m_GlassInfo.Top()); //2 m_ptPosition[2].x = FLOAT(m_GlassInfo.Right()); m_ptPosition[2].y = FLOAT(m_GlassInfo.Top()+m_GlassInfo.dNoCutSize); //3 m_ptPosition[3].x = FLOAT(m_GlassInfo.Right()); m_ptPosition[3].y = FLOAT(m_GlassInfo.Bottom()-m_GlassInfo.dNoCutSize); //4 m_ptPosition[4].x = FLOAT(m_GlassInfo.Right()-m_GlassInfo.dNoCutSize); m_ptPosition[4].y = FLOAT(m_GlassInfo.Bottom()); //5 m_ptPosition[5].x = FLOAT(m_GlassInfo.Left()+m_GlassInfo.dNoCutSize); m_ptPosition[5].y = FLOAT(m_GlassInfo.Bottom()); //6 m_ptPosition[6].x = FLOAT(m_GlassInfo.Left()); m_ptPosition[6].y = FLOAT(m_GlassInfo.Bottom()-m_GlassInfo.dNoCutSize); //7 m_ptPosition[7].x = FLOAT(m_GlassInfo.Left()); m_ptPosition[7].y = FLOAT(m_GlassInfo.Top()+m_GlassInfo.dCutSize); } break; case 2:// x°°Àº¹æÇâ, y¹Ý´ë¹æÇâ { // 0 m_ptPosition[0].x = FLOAT(m_GlassInfo.Left()+m_GlassInfo.dNoCutSize); m_ptPosition[0].y = FLOAT(m_GlassInfo.Top()); //1 m_ptPosition[1].x = FLOAT(m_GlassInfo.Right()-m_GlassInfo.dNoCutSize); m_ptPosition[1].y = FLOAT(m_GlassInfo.Top()); //2 m_ptPosition[2].x = FLOAT(m_GlassInfo.Right()); m_ptPosition[2].y = FLOAT(m_GlassInfo.Top()+m_GlassInfo.dNoCutSize); //3 m_ptPosition[3].x = FLOAT(m_GlassInfo.Right()); m_ptPosition[3].y = FLOAT(m_GlassInfo.Bottom()-m_GlassInfo.dNoCutSize); //4 m_ptPosition[4].x = FLOAT(m_GlassInfo.Right()-m_GlassInfo.dNoCutSize); m_ptPosition[4].y = FLOAT(m_GlassInfo.Bottom()); //5 m_ptPosition[5].x = FLOAT(m_GlassInfo.Left()+m_GlassInfo.dCutSize); m_ptPosition[5].y = FLOAT(m_GlassInfo.Bottom()); //6 m_ptPosition[6].x = FLOAT(m_GlassInfo.Left()); m_ptPosition[6].y = FLOAT(m_GlassInfo.Bottom()-m_GlassInfo.dCutSize); //7 m_ptPosition[7].x = FLOAT(m_GlassInfo.Left()); m_ptPosition[7].y = FLOAT(m_GlassInfo.Top()+m_GlassInfo.dNoCutSize); } break; case 1:// x¹Ý´ë¹æÇâ, y°°Àº¹æÇâ { // 0 m_ptPosition[0].x = FLOAT(m_GlassInfo.Left()+m_GlassInfo.dNoCutSize); m_ptPosition[0].y = FLOAT(m_GlassInfo.Top()); //1 m_ptPosition[1].x = FLOAT(m_GlassInfo.Right()-m_GlassInfo.dCutSize); m_ptPosition[1].y = FLOAT(m_GlassInfo.Top()); //2 m_ptPosition[2].x = FLOAT(m_GlassInfo.Right()); m_ptPosition[2].y = FLOAT(m_GlassInfo.Top()+m_GlassInfo.dCutSize); //3 m_ptPosition[3].x = FLOAT(m_GlassInfo.Right()); m_ptPosition[3].y = FLOAT(m_GlassInfo.Bottom()-m_GlassInfo.dNoCutSize); //4 m_ptPosition[4].x = FLOAT(m_GlassInfo.Right()-m_GlassInfo.dNoCutSize); m_ptPosition[4].y = FLOAT(m_GlassInfo.Bottom()); //5 m_ptPosition[5].x = FLOAT(m_GlassInfo.Left()+m_GlassInfo.dNoCutSize); m_ptPosition[5].y = FLOAT(m_GlassInfo.Bottom()); //6 m_ptPosition[6].x = FLOAT(m_GlassInfo.Left()); m_ptPosition[6].y = FLOAT(m_GlassInfo.Bottom()-m_GlassInfo.dNoCutSize); //7 m_ptPosition[7].x = FLOAT(m_GlassInfo.Left()); m_ptPosition[7].y = FLOAT(m_GlassInfo.Top()+m_GlassInfo.dNoCutSize); } break; case 0:// x¹Ý´ë¹æÇâ, y¹Ý´ë¹æÇâ { // 0 m_ptPosition[0].x = FLOAT(m_GlassInfo.Left()+m_GlassInfo.dNoCutSize); m_ptPosition[0].y = FLOAT(m_GlassInfo.Top()); //1 m_ptPosition[1].x = FLOAT(m_GlassInfo.Right()-m_GlassInfo.dNoCutSize); m_ptPosition[1].y = FLOAT(m_GlassInfo.Top()); //2 m_ptPosition[2].x = FLOAT(m_GlassInfo.Right()); m_ptPosition[2].y = FLOAT(m_GlassInfo.Top()+m_GlassInfo.dNoCutSize); //3 m_ptPosition[3].x = FLOAT(m_GlassInfo.Right()); m_ptPosition[3].y = FLOAT(m_GlassInfo.Bottom()-m_GlassInfo.dCutSize); //4 m_ptPosition[4].x = FLOAT(m_GlassInfo.Right()-m_GlassInfo.dCutSize); m_ptPosition[4].y = FLOAT(m_GlassInfo.Bottom()); //5 m_ptPosition[5].x = FLOAT(m_GlassInfo.Left()+m_GlassInfo.dNoCutSize); m_ptPosition[5].y = FLOAT(m_GlassInfo.Bottom()); //6 m_ptPosition[6].x = FLOAT(m_GlassInfo.Left()); m_ptPosition[6].y = FLOAT(m_GlassInfo.Bottom()-m_GlassInfo.dNoCutSize); //7 m_ptPosition[7].x = FLOAT(m_GlassInfo.Left()); m_ptPosition[7].y = FLOAT(m_GlassInfo.Top()+m_GlassInfo.dNoCutSize); } break; } } void CVirtualGlassMap::DrawGlass( ID2D1RenderTarget* pRenderTarget, const D2D1_RECT_F& rtRect ) { D2D1_RECT_F rtGlass = D2D1::RectF( FLOAT(m_GlassInfo.Left()), FLOAT(m_GlassInfo.Top()), FLOAT(m_GlassInfo.Right()), FLOAT(m_GlassInfo.Bottom()) ); if (IntersectsWith(rtRect, rtGlass)==FALSE) return; ID2D1SolidColorBrush *pPen = NULL; HRESULT hr = pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF(m_GlassInfo.nPenColor, FLOAT(m_GlassInfo.dPenOpacity))),&pPen); ID2D1SolidColorBrush *pBrush = NULL; hr = pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF(m_GlassInfo.nBrushColor, FLOAT(m_GlassInfo.dBrushOpacity))),&pBrush); // cal glass positionm_ if (!(m_CurGlassInfo==m_GlassInfo) || !(m_nCurMotorDir==m_MotorInfo.nOriginDir)) { CalculateGlassPos(m_MotorInfo.nOriginDir, m_GlassInfo); m_nCurMotorDir = m_MotorInfo.nOriginDir; m_CurGlassInfo = m_GlassInfo; } ID2D1PathGeometry* pPathGeometry = nullptr; m_pD2DFactory->CreatePathGeometry(&pPathGeometry); if (pPathGeometry) { ID2D1GeometrySink* pGeometrySink = nullptr; pPathGeometry->Open(&pGeometrySink); if (pGeometrySink) { // Use D2D1_FIGURE_BEGIN_FILLED for filled D2D1_FIGURE_BEGIN fg = D2D1_FIGURE_BEGIN_FILLED; D2D1_FIGURE_END fe = D2D1_FIGURE_END_CLOSED; pGeometrySink->BeginFigure(m_ptPosition[0], fg); for (int nIdx=1; nIdxAddLine(m_ptPosition[nIdx]); } pGeometrySink->EndFigure(fe); pGeometrySink->Close(); SafeRelease(pGeometrySink); } pRenderTarget->FillGeometry(pPathGeometry, pBrush); pRenderTarget->DrawGeometry(pPathGeometry, pPen, FLOAT(m_GlassInfo.dPenSize)); SafeRelease(pPathGeometry); } SafeRelease(pPen); SafeRelease(pBrush); } void CVirtualGlassMap::DrawGalssObject( ID2D1RenderTarget* pRenderTarget, const D2D1_RECT_F& rtRect ) { D2D1_POINT_2F glassPoint = D2D1::Point2F( FLOAT(m_GlassInfo.dPosX), FLOAT(m_GlassInfo.dPosX) ); for (VectorVirtualGlassObjectIt it=m_vecGlassObject.begin(); it!=m_vecGlassObject.end(); it++) { DrawGalssObject(pRenderTarget, *it, rtRect, glassPoint); } } void CVirtualGlassMap::DrawGalssObject( ID2D1RenderTarget* pRenderTarget, const CVirtualGlassObject& object, const D2D1_RECT_F& rtRect, const D2D1_POINT_2F& ptPoint ) { D2D1_RECT_F rect = D2D1::RectF( FLOAT(ptPoint.x+object.Left()), FLOAT(ptPoint.y+object.Top()), FLOAT(ptPoint.x+object.Right()), FLOAT(ptPoint.y+object.Bottom()) ); if (IntersectsWith(rtRect, rect)==FALSE) return; ID2D1SolidColorBrush *pPen = NULL; HRESULT hr = pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF(object.nPenColor, FLOAT(object.dPenOpacity))),&pPen); ID2D1SolidColorBrush *pBrush = NULL; hr = pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF(object.nBrushColor, FLOAT(object.dBrushOpacity))),&pBrush); switch(object.nDrawType) { case VODT_Rectangle: { pRenderTarget->FillRectangle(rect, pBrush); pRenderTarget->DrawRectangle(rect, pPen, FLOAT(object.dPenSize)); } break; case VODT_Ellipse: { D2D1_ELLIPSE ellipse; ellipse.radiusX = FLOAT(object.dSizeX/2.0); ellipse.radiusY = FLOAT(object.dSizeY/2.0); ellipse.point = D2D1::Point2F(FLOAT(ptPoint.x+object.dPosX+ellipse.radiusX), FLOAT(ptPoint.y+object.dPosY+ellipse.radiusY)); pRenderTarget->FillEllipse(ellipse, pBrush); pRenderTarget->DrawEllipse(ellipse, pPen, FLOAT(object.dPenSize)); } break; case VODT_Polygon: { D2D1_POINT_2F rectStart = D2D1::Point2F(FLOAT(ptPoint.x+object.dPosX), FLOAT(ptPoint.y+object.dPosY)); ID2D1PathGeometry* pPathGeometry = nullptr; m_pD2DFactory->CreatePathGeometry(&pPathGeometry); if (pPathGeometry) { ID2D1GeometrySink* pGeometrySink = nullptr; pPathGeometry->Open(&pGeometrySink); if (pGeometrySink) { D2D1_POINT_2F fb; fb.x = FLOAT(object.vecPolygon[0].dPosX) + rectStart.x; fb.y = FLOAT(object.vecPolygon[0].dPosY) + rectStart.y; // Use D2D1_FIGURE_BEGIN_FILLED for filled D2D1_FIGURE_BEGIN fg = D2D1_FIGURE_BEGIN_FILLED; D2D1_FIGURE_END fe = D2D1_FIGURE_END_CLOSED; pGeometrySink->BeginFigure(fb, fg); int nCount = (int)object.vecPolygon.size(); for (int nIdx=1; nIdxAddLine(fu); } pGeometrySink->EndFigure(fe); pGeometrySink->Close(); SafeRelease(pGeometrySink); } pRenderTarget->FillGeometry(pPathGeometry, pBrush); pRenderTarget->DrawGeometry(pPathGeometry, pPen, FLOAT(object.dPenSize)); SafeRelease(pPathGeometry); } } break; } SafeRelease(pPen); SafeRelease(pBrush); }