void VGraphicPath::SetPosBy(GReal inHoriz, GReal inVert)
{
#if !GRAPHIC_MIXED_GDIPLUS_D2D
	if (!VWinD2DGraphicContext::IsAvailable())
	{
#endif
		Gdiplus::Matrix matrix;
		matrix.Translate(inHoriz, inVert);
		fPath->Transform(&matrix);
#if !GRAPHIC_MIXED_GDIPLUS_D2D
	}
#endif

#if ENABLE_D2D
	if (VWinD2DGraphicContext::IsAvailable() && fPathD2D)
	{
		End();
		
		VAffineTransform mat;
		mat.SetTranslation( inHoriz, inVert);
		D2D1_MATRIX_3X2_F matNative;
		mat.ToNativeMatrix((D2D_MATRIX_REF)&matNative);

		ID2D1Geometry *sourcePath = fPathD2D;
		
		ID2D1TransformedGeometry *thisPath = NULL;
		VWinD2DGraphicContext::GetMutexFactory().Lock();
		bool ok = SUCCEEDED(VWinD2DGraphicContext::GetFactory()->CreateTransformedGeometry( sourcePath, &matNative, &thisPath));
		VWinD2DGraphicContext::GetMutexFactory().Unlock();
		xbox_assert(ok);
		if (ok)
		{
			fPathD2D = thisPath;
			sourcePath->Release();
		}
		else 
			return;
	}
#endif

	fPolygon.SetPosBy(inHoriz, inVert);

	if (fComputeBoundsAccurate)
	{
		VPoint translate( (SmallReal)inHoriz, (SmallReal)inVert);

		if (fPathMin != GP_BOUNDS_MIN_DEFAULT)
			fPathMin += translate;
		if (fPathMax != GP_BOUNDS_MAX_DEFAULT)
			fPathMax += translate;
	}
	_ComputeBounds();

	if (fCreateStorageForCrispEdges)
	{
		fDrawCmds.push_back( VGraphicPathDrawCmd( GPDCT_SET_POS_BY, inHoriz, inVert));
		fCurTransform.Translate( inHoriz, inVert, VAffineTransform::MatrixOrderAppend);
	}
}
void VRegion::Inset (GReal inHoriz, GReal inVert)
{
	if (fRegion == NULL)
		SetEmpty();
		
#if !USE_GDIPLUS

	GReal	dstRight = fBounds.GetRight() + inHoriz;
	GReal	dstLeft = fBounds.GetLeft() + inHoriz;
	GReal	dstTop = fBounds.GetTop() + inVert;
	GReal	dstBottom = fBounds.GetBottom() + inVert;
	
#if DEBUG_GDI_LIMITS
	assert(Abs(dstRight) <= kMAX_GDI_RGN_COORD);
	assert(Abs(dstLeft) <= kMIN_GDI_RGN_COORD);
	assert(Abs(dstTop) <= kMIN_GDI_RGN_COORD);
	assert(Abs(dstBottom) <= kMAX_GDI_RGN_COORD);
#endif
	
	// Make sure the region isn't too big for Win32
	if (dstRight > kMAX_GDI_RGN_COORD || dstLeft < kMIN_GDI_RGN_COORD
		|| dstBottom > kMAX_GDI_RGN_COORD || dstTop < kMIN_GDI_RGN_COORD) return;
		
	sLONG	rgnSize = ::GetRegionData(fRegion, sizeof(RGNDATA), 0);
	VHandle	vHandle = VMemory::NewHandle(rgnSize);
	VPtr	vPtr = VMemory::LockHandle(vHandle);
		
	// Create a translate matrix
	rgnSize = ::GetRegionData(fRegion, rgnSize, (RGNDATA*)vPtr);
	
	XFORM xForm;
	xForm.eM11 = inHoriz; 
    xForm.eM12 = 0.0;   
    xForm.eM21 = 0.0;   
    xForm.eM22 = inVert;
    xForm.eDx = 0.0;  
    xForm.eDy = 0.0;
    
	HRGN	tempRgn = ::ExtCreateRegion(&xForm, rgnSize, (RGNDATA*)vPtr);
	if (tempRgn != NULL)
	{
		_Release();
		fRegion = tempRgn;
	}
	
	VMemory::DisposeHandle(vHandle);
	
	_AdjustOrigin();
#else
	Gdiplus::Matrix mat;
	
	mat.Translate(inHoriz,inVert);
	mat.Scale((fBounds.GetWidth()-inHoriz)/(GReal)fBounds.GetWidth(),(fBounds.GetHeight()-inVert)/(GReal)fBounds.GetHeight());
	
	fRegion->Transform(&mat);
#endif

	_ComputeBounds();
}
HRESULT ParaEngine::CCCSFaceLoader::ComposeWithGDIPlus()
{
	HRESULT hr = S_OK;
#ifdef USE_DIRECTX_RENDERER
	// DO the texture composition here
	CGDIEngine* pEngine = CAsyncLoader::GetSingleton().GetGDIEngine();
	if (pEngine == NULL)
		return E_FAIL;
	pEngine->SetRenderTarget(pEngine->CreateGetRenderTargetBySize(CCharCustomizeSysSetting::FaceTexSize));
	pEngine->Begin();

	for (int i = 0; i<CFS_TOTAL_NUM; ++i)
	{
		const CharRegionCoords &coords = CCharCustomizeSysSetting::regions[CR_FACE_BASE + i];
		const FaceTextureComponent& component = m_layers[i];

		// load the component texture
		if (component.name.empty())
			continue;
		string componentfilename = component.name;

		AssetFileEntry* pEntry = CAssetManifest::GetSingleton().GetFile(componentfilename);
		if (pEntry)
			componentfilename = pEntry->GetLocalFileName();

		// compute the transform matrix
		Gdiplus::Matrix transformMatrix;
		// scale around the center
		float fScale = component.GetScaling();
		if (fabs(fScale)>0.01f)
		{
			transformMatrix.Scale(fScale + 1.f, fScale + 1.f);
		}

		// rotate around the center
		float fRotation = component.GetRotation();
		if (fabs(fRotation) > 0.01f)
		{
			transformMatrix.Rotate(fRotation);
		}

		// translation
		int x, y;
		component.GetPosition(&x, &y);
		transformMatrix.Translate(coords.xpos + (float)x, coords.ypos + (float)y);
		pEngine->SetTransform(&transformMatrix);

		Color color = component.GetColor();
		pEngine->DrawImage(pEngine->LoadTexture(componentfilename, component.name), (float)(-coords.xsize / 2), (float)(-coords.ysize / 2), (float)coords.xsize, (float)coords.ysize, color);

		// for eye and eye bow, there should be a mirrored image, around the center of the render target
		if (i == CFS_EYE || i == CFS_EYEBROW)
		{
			Gdiplus::Matrix reflectMat(-1.f, 0.f, 0.f, 1.f, CCharCustomizeSysSetting::FaceTexSize - (coords.xpos + (float)x) * 2, 0.f);
			transformMatrix.Multiply(&reflectMat);
			pEngine->SetTransform(&transformMatrix);
			pEngine->DrawImage(pEngine->LoadTexture(componentfilename, component.name), (float)(-coords.xsize / 2), (float)(-coords.ysize / 2), (float)coords.xsize, (float)coords.ysize);
		}
	}
	CParaFile::CreateDirectory(m_sFileName.c_str());
	hr = (pEngine->SaveRenderTarget(m_sFileName, CCharCustomizeSysSetting::FaceTexSize, CCharCustomizeSysSetting::FaceTexSize, false, 0)) ? S_OK : E_FAIL;
	pEngine->End();
#endif
	return hr;
}
Example #4
0
void CSkinUnitODL::DrawImage(Gdiplus::Graphics& gcDrawer, Gdiplus::GraphicsPath& gcPath, Gdiplus::PointF& ptOffset, Gdiplus::REAL fScale)
{
	if (m_imgSkin)
	{
		if (m_nWrapMode>=4)
		{
			//居中模式
			Gdiplus::RectF rtArea;
			gcPath.GetBounds(&rtArea);
			Gdiplus::GraphicsPath gcDrawPath;
			//图片中间X:(width-imagewidth )/2 + left;
			//Y: (height - imageheight)/2 +top;

			Gdiplus::REAL fX0 = (rtArea.Width - m_fSkinWidth-m_nGroutX) /2.0f + rtArea.X;
			Gdiplus::REAL fY0 = (rtArea.Height - m_fSkinHeight-m_nGroutY) /2.0f + rtArea.Y;
			Gdiplus::REAL fX1 = m_fSkinWidth + m_nGroutX+ fX0;
			Gdiplus::REAL fY1 = m_fSkinHeight +m_nGroutY+ fY0;
			std::vector<Gdiplus::PointF> arrPt;
			arrPt.emplace_back(fX0, fY0);
			arrPt.emplace_back(fX1, fY0);
			arrPt.emplace_back(fX1, fY1);
			arrPt.emplace_back(fX0, fY1);
			Gdiplus::Matrix mx;
			Gdiplus::PointF ptCenter=Gdiplus::PointF((fX1+fX0)/2.0f, (fY1+fY0)/2.0f);
			mx.RotateAt(m_fRotate, ptCenter);
			mx.TransformPoints(arrPt.data(), arrPt.size());
			gcDrawPath.AddPolygon(arrPt.data(),arrPt.size());
			//如果图片的path大于当前区域Path,则居中操作在区域内
			{
				BRepBuilderAPI_MakePolygon ply1;
				for (auto& ptPos:arrPt)
				{
					ply1.Add(gp_Pnt(ptPos.X, 0.0f, ptPos.Y));
				}
				ply1.Close();
				TopoDS_Face face1 = BRepBuilderAPI_MakeFace(ply1.Wire()).Face();
				std::vector<Gdiplus::PointF> arrPic;
				arrPic.resize(gcDrawPath.GetPointCount());
				gcPath.GetPathPoints(arrPic.data(), arrPic.size());

				BRepBuilderAPI_MakePolygon ply2;
				for (auto& ptPos:arrPic)
				{
					ply2.Add(gp_Pnt(ptPos.X, 0.0f, ptPos.Y));
				}
				ply2.Close();
				TopoDS_Face face2 = BRepBuilderAPI_MakeFace(ply2.Wire()).Face();

				BRepAlgoAPI_Common bc(face1, face2);
				auto face = bc.Shape();
				TopExp_Explorer expWire(face, TopAbs_WIRE);
				std::vector<Gdiplus::PointF> arrDraw;
				for ( BRepTools_WireExplorer expVertex(TopoDS::Wire(expWire.Current())); expVertex.More(); expVertex.Next() )
				{
					auto pnt = BRep_Tool::Pnt(expVertex.CurrentVertex());
					arrDraw.emplace_back(static_cast<Gdiplus::REAL>(pnt.X()), static_cast<Gdiplus::REAL>(pnt.Z()));
				}
				gcDrawPath.Reset();
				gcDrawPath.AddPolygon(arrDraw.data(), arrDraw.size());
			}

			Gdiplus::WrapMode wmMode=(Gdiplus::WrapMode)m_nWrapMode;
			if (std::fabs(m_fRotate)<0.001f)
			{
				Gdiplus::TextureBrush brush(m_imgSkin, wmMode);
				mx.Translate(fX0, fY0);
				brush.SetTransform(&mx);
				gcDrawer.FillPath(&brush, &gcDrawPath);
			}
			else
			{
				Gdiplus::TextureBrush brush(m_imgSkin, wmMode);
				mx.Translate(fX0, fY0);
				brush.SetTransform(&mx);
				gcDrawer.FillPath(&brush, &gcDrawPath);
			}
		}
		else
		{
			//铺满模式
			Gdiplus::WrapMode wmMode=(Gdiplus::WrapMode)m_nWrapMode;
			if (std::fabs(m_fRotate)<0.001f)
			{
				Gdiplus::TextureBrush brush(m_imgSkin, wmMode);
				brush.TranslateTransform(ptOffset.X, ptOffset.Y);
				gcDrawer.FillPath(&brush, &gcPath);
			}
			else
			{
				Gdiplus::TextureBrush brush(m_imgSkin, wmMode);
				brush.TranslateTransform(ptOffset.X, ptOffset.Y);
				brush.RotateTransform(m_fRotate);
				gcDrawer.FillPath(&brush, &gcPath);
			}
		}
		
	}
}