/// <summary> /// Create gauge (with position cloud) used to display sound source angle. /// </summary> /// <returns>S_OK on success, otherwise failure code.</returns> HRESULT AudioPanel::CreateSourceGauge() { HRESULT hr = m_pD2DFactory->CreatePathGeometry(&m_pSourceGauge); // Create gauge background shape if (SUCCEEDED(hr)) { ID2D1GeometrySink *pGeometrySink = NULL; hr = m_pSourceGauge->Open(&pGeometrySink); if (SUCCEEDED(hr)) { pGeometrySink->BeginFigure(D2D1::Point2F(0.1270f,0.3021f), D2D1_FIGURE_BEGIN_FILLED); pGeometrySink->AddLine(D2D1::Point2F(0.1503f,0.2832f)); pGeometrySink->AddArc(D2D1::ArcSegment(D2D1::Point2F(0.8497f,0.2832f), D2D1::SizeF(0.45f,0.45f), 102, D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, D2D1_ARC_SIZE_SMALL)); pGeometrySink->AddLine(D2D1::Point2F(0.8730f,0.3021f)); pGeometrySink->AddArc(D2D1::ArcSegment(D2D1::Point2F(0.1270f,0.3021f), D2D1::SizeF(0.48f,0.48f), 102, D2D1_SWEEP_DIRECTION_CLOCKWISE, D2D1_ARC_SIZE_SMALL)); pGeometrySink->EndFigure(D2D1_FIGURE_END_CLOSED); hr = pGeometrySink->Close(); // Create gauge background brush if (SUCCEEDED(hr)) { hr = CreateSourceGaugeFill(0.1f); } } SafeRelease(pGeometrySink); } return hr; }
/// <summary> /// Create gauge (with needle) used to display beam angle. /// </summary> /// <returns>S_OK on success, otherwise failure code.</returns> HRESULT AudioPanel::CreateBeamGauge() { HRESULT hr = m_pD2DFactory->CreatePathGeometry(&m_pBeamGauge); // Create gauge background shape if (SUCCEEDED(hr)) { ID2D1GeometrySink *pGeometrySink = NULL; hr = m_pBeamGauge->Open(&pGeometrySink); if (SUCCEEDED(hr)) { pGeometrySink->BeginFigure(D2D1::Point2F(0.1503f,0.2832f), D2D1_FIGURE_BEGIN_FILLED); pGeometrySink->AddLine(D2D1::Point2F(0.228f,0.2203f)); pGeometrySink->AddArc(D2D1::ArcSegment(D2D1::Point2F(0.772f,0.2203f), D2D1::SizeF(0.35f,0.35f), 102, D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, D2D1_ARC_SIZE_SMALL)); pGeometrySink->AddLine(D2D1::Point2F(0.8497f,0.2832f)); pGeometrySink->AddArc(D2D1::ArcSegment(D2D1::Point2F(0.1503f,0.2832f), D2D1::SizeF(0.45f,0.45f), 102, D2D1_SWEEP_DIRECTION_CLOCKWISE, D2D1_ARC_SIZE_SMALL)); pGeometrySink->EndFigure(D2D1_FIGURE_END_CLOSED); hr = pGeometrySink->Close(); // Create gauge background brush if (SUCCEEDED(hr)) { ID2D1GradientStopCollection *pGradientStops = NULL; D2D1_GRADIENT_STOP gradientStops[4]; gradientStops[0].color = D2D1::ColorF(D2D1::ColorF::LightGray, 1); gradientStops[0].position = 0.0f; gradientStops[1].color = D2D1::ColorF(D2D1::ColorF::LightGray, 1); gradientStops[1].position = 0.34f; gradientStops[2].color = D2D1::ColorF(D2D1::ColorF::WhiteSmoke, 1); gradientStops[2].position = 0.37f; gradientStops[3].color = D2D1::ColorF(D2D1::ColorF::WhiteSmoke, 1); gradientStops[3].position = 1.0f; hr = m_pRenderTarget->CreateGradientStopCollection( gradientStops, 4, &pGradientStops ); if (SUCCEEDED(hr)) { hr = m_pRenderTarget->CreateRadialGradientBrush(D2D1::RadialGradientBrushProperties(D2D1::Point2F(0.5f,0.0f), D2D1::Point2F(0.0f,0.0f), 1.0f, 1.0f), pGradientStops, &m_pBeamGaugeFill); if (SUCCEEDED(hr)) { // Create gauge needle shape and fill brush hr = CreateBeamGaugeNeedle(); } } SafeRelease(pGradientStops); } } SafeRelease(pGeometrySink); } return hr; }
/// <summary> /// Create gauge needle used to display beam angle. /// </summary> /// <returns>S_OK on success, otherwise failure code.</returns> HRESULT AudioPanel::CreateBeamGaugeNeedle() { HRESULT hr = m_pD2DFactory->CreatePathGeometry(&m_pBeamNeedle); // Create gauge needle shape if (SUCCEEDED(hr)) { ID2D1GeometrySink *pGeometrySink = NULL; hr = m_pBeamNeedle->Open(&pGeometrySink); if (SUCCEEDED(hr)) { pGeometrySink->BeginFigure(D2D1::Point2F(0.495f,0.35f), D2D1_FIGURE_BEGIN_FILLED); pGeometrySink->AddLine(D2D1::Point2F(0.505f,0.35f)); pGeometrySink->AddLine(D2D1::Point2F(0.5f,0.44f)); pGeometrySink->EndFigure(D2D1_FIGURE_END_CLOSED); hr = pGeometrySink->Close(); // Create gauge needle brush if (SUCCEEDED(hr)) { ID2D1GradientStopCollection *pGradientStops = NULL; D2D1_GRADIENT_STOP gradientStops[4]; gradientStops[0].color = D2D1::ColorF(D2D1::ColorF::LightGray, 1); gradientStops[0].position = 0.0f; gradientStops[1].color = D2D1::ColorF(D2D1::ColorF::LightGray, 1); gradientStops[1].position = 0.35f; gradientStops[2].color = D2D1::ColorF(D2D1::ColorF::BlueViolet, 1); gradientStops[2].position = 0.395f; gradientStops[3].color = D2D1::ColorF(D2D1::ColorF::BlueViolet, 1); gradientStops[3].position = 1.0f; hr = m_pRenderTarget->CreateGradientStopCollection( gradientStops, 4, &pGradientStops ); if (SUCCEEDED(hr)) { hr = m_pRenderTarget->CreateLinearGradientBrush(D2D1::LinearGradientBrushProperties(D2D1::Point2F(0.5f,0.0f), D2D1::Point2F(0.5f,1.0f)), pGradientStops, &m_pBeamNeedleFill); } SafeRelease(pGradientStops); } } SafeRelease(pGeometrySink); } return hr; }
RenderableGrid::RenderableGrid(Direct2D1& _d2d1, IJSON& _parameters) : Renderable(_d2d1, _parameters), m_geometry(NULL), m_tgeometry(NULL) { IJSON& params = *_parameters[L"parameters"]; D2D1_SIZE_F size, steps; size.width = (*params[L"size"])[0]->AsNumber(); size.height = (*params[L"size"])[1]->AsNumber(); steps.width = (*params[L"steps"])[0]->AsNumber(); steps.height = (*params[L"steps"])[1]->AsNumber(); if (SUCCEEDED(this->m_d2d1.D2D1().CreatePathGeometry(&this->m_geometry))) { ID2D1GeometrySink *pSink = NULL; if (SUCCEEDED(this->m_geometry->Open(&pSink))) { D2D1_POINT_2F p1, p2; pSink->SetFillMode(D2D1_FILL_MODE_WINDING); p1.y = -size.height / 2.0f; p2.y = size.height / 2.0f; for (float x = -size.width / 2.0f ; (size.width / 2.0f) >= x ; x += steps.width) { p1.x = x; p2.x = x; pSink->BeginFigure(p1, D2D1_FIGURE_BEGIN_HOLLOW); pSink->AddLine(p2); pSink->EndFigure(D2D1_FIGURE_END_OPEN); } p1.x = -size.width / 2.0f; p2.x = size.width / 2.0f; for (float y = -size.height / 2.0f ; (size.height / 2.0f) >= y ; y += steps.height) { p1.y = y; p2.y = y; pSink->BeginFigure(p1, D2D1_FIGURE_BEGIN_HOLLOW); pSink->AddLine(p2); pSink->EndFigure(D2D1_FIGURE_END_OPEN); } pSink->Close(); pSink->Release(); } } }
void Renderer::FillPolygon(Vector2D * points, int size, bool close) { if (size < 3) return; HRESULT hr; ID2D1PathGeometry* pGeometry = nullptr; hr = GRAPHICSDEVICEMANAGER->GetGraphics()->GetD2DFactory()->CreatePathGeometry(&pGeometry); if (FAILED(hr)) { SafeRelease(pGeometry); //Logger::Log(_T("Failed to create path geometry"), LOGTYPE_WARNING, false); return; } //Write to the path geometry using the geometry sink ID2D1GeometrySink* pGeometrySink = nullptr; hr = pGeometry->Open(&pGeometrySink); if (FAILED(hr)) { SafeRelease(pGeometrySink); SafeRelease(pGeometry); //Logger::Log(_T("Failed to create geometry sink"), LOGTYPE_WARNING, false); return; } if (SUCCEEDED(hr)) { pGeometrySink->BeginFigure(D2D1::Point2((FLOAT)points[0].x, (FLOAT)points[0].y), D2D1_FIGURE_BEGIN_FILLED); for (int i = 1; i < size; ++i) pGeometrySink->AddLine(D2D1::Point2F((FLOAT)points[i].x, (FLOAT)points[i].y)); pGeometrySink->EndFigure(D2D1_FIGURE_END_CLOSED); hr = pGeometrySink->Close(); SafeRelease(pGeometrySink); } if (SUCCEEDED(hr)) { GRAPHICSDEVICEMANAGER->GetGraphics()->GetRenderTarget()->FillGeometry(pGeometry, GRAPHICSDEVICEMANAGER->GetGraphics()->GetColorBrush()); SafeRelease(pGeometry); return; } SafeRelease(pGeometry); }
/// <summary> /// Create outline that frames both gauges and energy display into a cohesive panel. /// </summary> /// <returns>S_OK on success, otherwise failure code.</returns> HRESULT AudioPanel::CreatePanelOutline() { HRESULT hr = m_pD2DFactory->CreatePathGeometry(&m_pPanelOutline); // Create panel outline path if (SUCCEEDED(hr)) { ID2D1GeometrySink *pGeometrySink = NULL; hr = m_pPanelOutline->Open(&pGeometrySink); if (SUCCEEDED(hr)) { /// Draw left wave display frame pGeometrySink->BeginFigure(D2D1::Point2F(0.15f,0.0353f), D2D1_FIGURE_BEGIN_FILLED); pGeometrySink->AddLine(D2D1::Point2F(0.13f,0.0353f)); pGeometrySink->AddLine(D2D1::Point2F(0.13f,0.2203f)); pGeometrySink->AddLine(D2D1::Point2F(0.2280f,0.2203f)); // Draw gauge outline pGeometrySink->AddLine(D2D1::Point2F(0.1270f,0.3021f)); pGeometrySink->AddArc(D2D1::ArcSegment(D2D1::Point2F(0.8730f,0.3021f), D2D1::SizeF(0.48f,0.48f), 102, D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, D2D1_ARC_SIZE_SMALL)); pGeometrySink->AddLine(D2D1::Point2F(0.7720f,0.2203f)); pGeometrySink->AddArc(D2D1::ArcSegment(D2D1::Point2F(0.2280f,0.2203f), D2D1::SizeF(0.35f,0.35f), 102, D2D1_SWEEP_DIRECTION_CLOCKWISE, D2D1_ARC_SIZE_SMALL)); // Reposition geometry without drawing pGeometrySink->SetSegmentFlags(D2D1_PATH_SEGMENT_FORCE_UNSTROKED); pGeometrySink->AddLine(D2D1::Point2F(0.7720f,0.2203f)); pGeometrySink->SetSegmentFlags(D2D1_PATH_SEGMENT_NONE); // Draw right wave display frame pGeometrySink->AddLine(D2D1::Point2F(0.87f,0.2203f)); pGeometrySink->AddLine(D2D1::Point2F(0.87f,0.0353f)); pGeometrySink->AddLine(D2D1::Point2F(0.85f,0.0353f)); pGeometrySink->EndFigure(D2D1_FIGURE_END_OPEN); hr = pGeometrySink->Close(); // Create panel outline brush if (SUCCEEDED(hr)) { hr = m_pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::LightGray), &m_pPanelOutlineStroke); } } SafeRelease(pGeometrySink); } return hr; }
HRESULT SaveToImageFile() { HRESULT hr = S_OK; // // Create Factories // IWICImagingFactory *pWICFactory = NULL; ID2D1Factory *pD2DFactory = NULL; IDWriteFactory *pDWriteFactory = NULL; IWICBitmap *pWICBitmap = NULL; ID2D1RenderTarget *pRT = NULL; IDWriteTextFormat *pTextFormat = NULL; ID2D1PathGeometry *pPathGeometry = NULL; ID2D1GeometrySink *pSink = NULL; ID2D1GradientStopCollection *pGradientStops = NULL; ID2D1LinearGradientBrush *pLGBrush = NULL; ID2D1SolidColorBrush *pBlackBrush = NULL; IWICBitmapEncoder *pEncoder = NULL; IWICBitmapFrameEncode *pFrameEncode = NULL; IWICStream *pStream = NULL; hr = CoCreateInstance( CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, reinterpret_cast<void **>(&pWICFactory) ); if (SUCCEEDED(hr)) { hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory); } if (SUCCEEDED(hr)) { hr = DWriteCreateFactory( DWRITE_FACTORY_TYPE_SHARED, __uuidof(pDWriteFactory), reinterpret_cast<IUnknown **>(&pDWriteFactory) ); } // // Create IWICBitmap and RT // static const UINT sc_bitmapWidth = 640; static const UINT sc_bitmapHeight = 480; if (SUCCEEDED(hr)) { hr = pWICFactory->CreateBitmap( sc_bitmapWidth, sc_bitmapHeight, GUID_WICPixelFormat32bppBGR, WICBitmapCacheOnLoad, &pWICBitmap ); } if (SUCCEEDED(hr)) { hr = pD2DFactory->CreateWicBitmapRenderTarget( pWICBitmap, D2D1::RenderTargetProperties(), &pRT ); } if (SUCCEEDED(hr)) { // // Create text format // static const WCHAR sc_fontName[] = L"Calibri"; static const FLOAT sc_fontSize = 50; hr = pDWriteFactory->CreateTextFormat( sc_fontName, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, sc_fontSize, L"", //locale &pTextFormat ); } if (SUCCEEDED(hr)) { pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER); pTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER); // // Create a path geometry representing an hour glass // hr = pD2DFactory->CreatePathGeometry(&pPathGeometry); } if (SUCCEEDED(hr)) { hr = pPathGeometry->Open(&pSink); } if (SUCCEEDED(hr)) { pSink->SetFillMode(D2D1_FILL_MODE_ALTERNATE); pSink->BeginFigure( D2D1::Point2F(0, 0), D2D1_FIGURE_BEGIN_FILLED ); pSink->AddLine(D2D1::Point2F(200, 0)); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(150, 50), D2D1::Point2F(150, 150), D2D1::Point2F(200, 200)) ); pSink->AddLine(D2D1::Point2F(0, 200)); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(50, 150), D2D1::Point2F(50, 50), D2D1::Point2F(0, 0)) ); pSink->EndFigure(D2D1_FIGURE_END_CLOSED); hr = pSink->Close(); } if (SUCCEEDED(hr)) { // // Create a linear-gradient brush // static const D2D1_GRADIENT_STOP stops[] = { { 0.f, { 0.f, 1.f, 1.f, 1.f } }, { 1.f, { 0.f, 0.f, 1.f, 1.f } }, }; hr = pRT->CreateGradientStopCollection( stops, ARRAYSIZE(stops), &pGradientStops ); } if (SUCCEEDED(hr)) { hr = pRT->CreateLinearGradientBrush( D2D1::LinearGradientBrushProperties( D2D1::Point2F(100, 0), D2D1::Point2F(100, 200)), D2D1::BrushProperties(), pGradientStops, &pLGBrush ); } if (SUCCEEDED(hr)) { hr = pRT->CreateSolidColorBrush( D2D1::ColorF(D2D1::ColorF::Black), &pBlackBrush ); } if (SUCCEEDED(hr)) { // // Render into the bitmap // pRT->BeginDraw(); pRT->Clear(D2D1::ColorF(D2D1::ColorF::White)); D2D1_SIZE_F rtSize = pRT->GetSize(); // Set the world transform to a 45 degree rotation at the center of the render target // and write "Hello, World". pRT->SetTransform( D2D1::Matrix3x2F::Rotation( 45, D2D1::Point2F( rtSize.width / 2, rtSize.height / 2)) ); static const WCHAR sc_helloWorld[] = L"Hello, World!"; pRT->DrawText( sc_helloWorld, ARRAYSIZE(sc_helloWorld) - 1, pTextFormat, D2D1::RectF(0, 0, rtSize.width, rtSize.height), pBlackBrush); // // Reset back to the identity transform // pRT->SetTransform(D2D1::Matrix3x2F::Translation(0, rtSize.height - 200)); pRT->FillGeometry(pPathGeometry, pLGBrush); pRT->SetTransform(D2D1::Matrix3x2F::Translation(rtSize.width - 200, 0)); pRT->FillGeometry(pPathGeometry, pLGBrush); hr = pRT->EndDraw(); } if (SUCCEEDED(hr)) { // // Save image to file // hr = pWICFactory->CreateStream(&pStream); } WICPixelFormatGUID format = GUID_WICPixelFormatDontCare; if (SUCCEEDED(hr)) { static const WCHAR filename[] = L"output.png"; hr = pStream->InitializeFromFilename(filename, GENERIC_WRITE); } if (SUCCEEDED(hr)) { hr = pWICFactory->CreateEncoder(GUID_ContainerFormatPng, NULL, &pEncoder); } if (SUCCEEDED(hr)) { hr = pEncoder->Initialize(pStream, WICBitmapEncoderNoCache); } if (SUCCEEDED(hr)) { hr = pEncoder->CreateNewFrame(&pFrameEncode, NULL); } if (SUCCEEDED(hr)) { hr = pFrameEncode->Initialize(NULL); } if (SUCCEEDED(hr)) { hr = pFrameEncode->SetSize(sc_bitmapWidth, sc_bitmapHeight); } if (SUCCEEDED(hr)) { hr = pFrameEncode->SetPixelFormat(&format); } if (SUCCEEDED(hr)) { hr = pFrameEncode->WriteSource(pWICBitmap, NULL); } if (SUCCEEDED(hr)) { hr = pFrameEncode->Commit(); } if (SUCCEEDED(hr)) { hr = pEncoder->Commit(); } SafeRelease(&pWICFactory); SafeRelease(&pD2DFactory); SafeRelease(&pDWriteFactory); SafeRelease(&pWICBitmap); SafeRelease(&pRT); SafeRelease(&pTextFormat); SafeRelease(&pPathGeometry); SafeRelease(&pSink); SafeRelease(&pGradientStops); SafeRelease(&pLGBrush); SafeRelease(&pBlackBrush); SafeRelease(&pEncoder); SafeRelease(&pFrameEncode); SafeRelease(&pStream); return hr; }
// Create device-independent resources HRESULT DemoApp::CreateDeviceIndependentResources() { static const WCHAR msc_fontName[] = L"Verdana"; static const FLOAT msc_fontSize = 50; HRESULT hr; ID2D1GeometrySink *pSink = NULL; // Create a Direct2D factory hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pD2DFactory); if (SUCCEEDED(hr)) { // Create WIC factory hr = CoCreateInstance( CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, reinterpret_cast<void **>(&m_pWICFactory)); } if (SUCCEEDED(hr)) { // Create a DirectWrite factory hr = DWriteCreateFactory( DWRITE_FACTORY_TYPE_SHARED, __uuidof(m_pDWriteFactory), reinterpret_cast<IUnknown **>(&m_pDWriteFactory)); } if (SUCCEEDED(hr)) { // Create a DirectWrite text format object hr = m_pDWriteFactory->CreateTextFormat( msc_fontName, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, msc_fontSize, L"", &m_pTextFormat); } if (SUCCEEDED(hr)) { // center the text horizontally and vertically m_pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER); m_pTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER); // Create a path geometry hr = m_pD2DFactory->CreatePathGeometry(&m_pPathGeometry); } if (SUCCEEDED(hr)) { // Use the geometry sink to write to the path geometry hr = m_pPathGeometry->Open(&pSink); } if (SUCCEEDED(hr)) { pSink->SetFillMode(D2D1_FILL_MODE_ALTERNATE); pSink->BeginFigure(D2D1::Point2F(0, 0), D2D1_FIGURE_BEGIN_FILLED); pSink->AddLine(D2D1::Point2F(200, 0)); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(150, 50), D2D1::Point2F(150, 150), D2D1::Point2F(200, 200))); pSink->AddLine(D2D1::Point2F(0, 200)); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(50, 150), D2D1::Point2F(50, 50), D2D1::Point2F(0, 0))); pSink->EndFigure(D2D1_FIGURE_END_CLOSED); hr = pSink->Close(); } SafeRelease(&pSink); return hr; }
//----------------------------------------------------------------------------- ID2D1PathGeometry* D2DGraphicsPath::getPath (int32_t fillMode) { if (path == 0 || fillMode != currentPathFillMode) { dirty (); if (!SUCCEEDED (getD2DFactory ()->CreatePathGeometry (&path))) return 0; if (fillMode == -1) fillMode = 0; currentPathFillMode = fillMode; ID2D1GeometrySink* sink = 0; if (!SUCCEEDED (path->Open (&sink))) { path->Release (); path = 0; return 0; } sink->SetFillMode ((D2D1_FILL_MODE)fillMode); bool figureOpen = false; CPoint lastPos; for (ElementList::const_iterator it = elements.begin (); it != elements.end (); it++) { Element e = (*it); switch (e.type) { case Element::kArc: { bool clockwise = e.instruction.arc.clockwise; double startAngle = e.instruction.arc.startAngle; double endAngle = e.instruction.arc.endAngle; CRect o_r (e.instruction.arc.rect.left, e.instruction.arc.rect.top, e.instruction.arc.rect.right, e.instruction.arc.rect.bottom); CRect r (o_r); o_r.originize (); CPoint center = o_r.getCenter (); CPoint start; start.x = r.left + center.x + center.x * cos (radians (startAngle)); start.y = r.top + center.y + center.y * sin (radians (startAngle)); if (!figureOpen) { sink->BeginFigure (makeD2DPoint (start), D2D1_FIGURE_BEGIN_FILLED); figureOpen = true; } else if (lastPos != start) { sink->AddLine (makeD2DPoint (start)); } double sweepangle = endAngle - startAngle; if (clockwise) { // sweepangle positive while (sweepangle < 0.0) sweepangle += 360.0; while (sweepangle > 360.0) sweepangle -= 360.0; } else { // sweepangle negative while (sweepangle > 0.0) sweepangle -= 360.0; while (sweepangle < -360.0) sweepangle += 360.0; } CPoint endPoint; endPoint.x = r.left + center.x + center.x * cos (radians (endAngle)); endPoint.y = r.top + center.y + center.y * sin (radians (endAngle)); D2D1_ARC_SEGMENT arc; arc.size = makeD2DSize (r.getWidth ()/2., r.getHeight ()/2.); arc.rotationAngle = 0; arc.sweepDirection = clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE; arc.point = makeD2DPoint (endPoint); arc.arcSize = fabs(sweepangle) <= 180. ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE; sink->AddArc (arc); lastPos = endPoint; break; } case Element::kEllipse: { CRect r (e.instruction.rect.left, e.instruction.rect.top, e.instruction.rect.right, e.instruction.rect.bottom); CPoint top (r.getTopLeft ()); top.x += r.getWidth () / 2.; CPoint bottom (r.getBottomLeft ()); bottom.x += r.getWidth () / 2.; if (figureOpen && lastPos != CPoint (e.instruction.rect.left, e.instruction.rect.top)) { sink->EndFigure (D2D1_FIGURE_END_OPEN); figureOpen = false; } if (!figureOpen) { sink->BeginFigure (makeD2DPoint (top), D2D1_FIGURE_BEGIN_FILLED); figureOpen = true; } D2D1_ARC_SEGMENT arc = D2D1::ArcSegment (makeD2DPoint (bottom), D2D1::SizeF ((FLOAT)r.getWidth ()/2.f, (FLOAT)r.getHeight ()/2.f), 180.f, D2D1_SWEEP_DIRECTION_CLOCKWISE, D2D1_ARC_SIZE_SMALL); sink->AddArc (arc); arc.point = makeD2DPoint (top); sink->AddArc (arc); lastPos = top; break; } case Element::kRect: { D2D1_POINT_2F points[4] = { {(FLOAT)e.instruction.rect.right, (FLOAT)e.instruction.rect.top}, {(FLOAT)e.instruction.rect.right, (FLOAT)e.instruction.rect.bottom}, {(FLOAT)e.instruction.rect.left, (FLOAT)e.instruction.rect.bottom}, {(FLOAT)e.instruction.rect.left, (FLOAT)e.instruction.rect.top} }; if (figureOpen && lastPos != CPoint (e.instruction.rect.left, e.instruction.rect.top)) { sink->EndFigure (D2D1_FIGURE_END_OPEN); figureOpen = false; } if (figureOpen == false) { sink->BeginFigure (points[3], D2D1_FIGURE_BEGIN_FILLED); figureOpen = true; } sink->AddLine (points[0]); sink->AddLine (points[1]); sink->AddLine (points[2]); sink->AddLine (points[3]); lastPos = CPoint (e.instruction.rect.left, e.instruction.rect.top); break; } case Element::kLine: { if (figureOpen) { D2D1_POINT_2F end = {(FLOAT)e.instruction.point.x, (FLOAT)e.instruction.point.y}; sink->AddLine (end); lastPos = CPoint (e.instruction.point.x, e.instruction.point.y); } break; } case Element::kBezierCurve: { if (figureOpen) { D2D1_POINT_2F control1 = {(FLOAT)e.instruction.curve.control1.x, (FLOAT)e.instruction.curve.control1.y}; D2D1_POINT_2F control2 = {(FLOAT)e.instruction.curve.control2.x, (FLOAT)e.instruction.curve.control2.y}; D2D1_POINT_2F end = {(FLOAT)e.instruction.curve.end.x, (FLOAT)e.instruction.curve.end.y}; D2D1_BEZIER_SEGMENT bezier = D2D1::BezierSegment (control1, control2, end); sink->AddBezier (bezier); lastPos = CPoint (e.instruction.curve.end.x, e.instruction.curve.end.y); } break; } case Element::kBeginSubpath: { if (figureOpen) sink->EndFigure (D2D1_FIGURE_END_OPEN); D2D1_POINT_2F start = {(FLOAT)e.instruction.point.x, (FLOAT)e.instruction.point.y}; sink->BeginFigure (start, D2D1_FIGURE_BEGIN_FILLED); figureOpen = true; lastPos = CPoint (e.instruction.point.x, e.instruction.point.y); break; } case Element::kCloseSubpath: { if (figureOpen) { sink->EndFigure (D2D1_FIGURE_END_CLOSED); figureOpen = false; } break; } } } if (figureOpen) sink->EndFigure (D2D1_FIGURE_END_OPEN); HRESULT res = sink->Close (); if (!SUCCEEDED (res)) { path->Release (); path = 0; } sink->Release (); } return path; }
// // Generates new graph geometry, which may change every frame. // HRESULT D3D12MemoryManagement::GenerateMemoryGraphGeometry(const RectF& Bounds, UINT GraphSizeMB, ID2D1PathGeometry** ppPathGeometry) { HRESULT hr; ID2D1PathGeometry* pPathGeometry = nullptr; ID2D1GeometrySink* pGeometrySink = nullptr; hr = m_pD2DFactory->CreatePathGeometry(&pPathGeometry); if (FAILED(hr)) { LOG_WARNING("Failed to create path geometry, hr=0x%.8x"); goto cleanup; } hr = pPathGeometry->Open(&pGeometrySink); if (FAILED(hr)) { LOG_WARNING("Failed to open path geometry sink, hr=0x%.8x"); goto cleanup; } { float GraphHeightPadded = GRAPH_HEIGHT * GRAPH_HEIGHT_RATIO / 100; float XStep = GRAPH_WIDTH / GRAPH_SEGMENTS; D2D1_POINT_2F Point; Point.x = Bounds.Left; Point.y = Bounds.Bottom; pGeometrySink->BeginFigure(Point, D2D1_FIGURE_BEGIN_FILLED); for (UINT i = 0; i < NUM_GRAPH_POINTS; ++i) { UINT32 GraphPoint = (i + m_CurrentGraphPoint) % NUM_GRAPH_POINTS; Point.y = Bounds.Bottom - (m_GraphPoints[GraphPoint] / 1024 / 1024) / (float)GraphSizeMB * GraphHeightPadded; pGeometrySink->AddLine(Point); Point.x += XStep; } Point.x = Bounds.Right; Point.y = Bounds.Bottom; pGeometrySink->AddLine(Point); pGeometrySink->EndFigure(D2D1_FIGURE_END_CLOSED); } hr = pGeometrySink->Close(); if (FAILED(hr)) { LOG_ERROR("Failed to close path geometry sink, hr=0x%.8x", hr); goto cleanup; } pGeometrySink->Release(); *ppPathGeometry = pPathGeometry; return S_OK; cleanup: SafeRelease(pGeometrySink); SafeRelease(pPathGeometry); return hr; }
HRESULT DemoApp::CreateDeviceIndependentResources() { static const WCHAR msc_fontName[] = L"Verdana"; //사용할 폰트 이름 static const FLOAT msc_fontSize = 20; //폰트 크기 HRESULT hr = S_OK; ID2D1GeometrySink *pSink = NULL; // Create a Direct2D factory. hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pD2DFactory); if (SUCCEEDED(hr)) { // Create WIC factory. hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_pWICFactory)); } if (SUCCEEDED(hr)) { // Create a DirectWrite factory. hr = DWriteCreateFactory( DWRITE_FACTORY_TYPE_SHARED, __uuidof(m_pDWriteFactory), reinterpret_cast<IUnknown **>(&m_pDWriteFactory) ); } if (SUCCEEDED(hr)) { // Create a DirectWrite text format object. hr = m_pDWriteFactory->CreateTextFormat( msc_fontName, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, msc_fontSize, L"", //locale &m_pTextFormat ); } if (SUCCEEDED(hr)) // 바퀴벌레 기하 { hr = m_pD2DFactory->CreateEllipseGeometry(D2D1::Ellipse(D2D1::Point2F(0,0), 10, 5),&m_pWheel); } if (SUCCEEDED(hr)) // 칼날 반원 기하 { hr = m_pD2DFactory->CreatePathGeometry(&m_pPathGeometry); if (SUCCEEDED(hr)) { // Write to the path geometry using the geometry sink. hr = m_pPathGeometry->Open(&pSink); if (SUCCEEDED(hr)) { pSink->BeginFigure( D2D1::Point2F(200 , 100), // 200 ,100 D2D1_FIGURE_BEGIN_FILLED ); pSink->AddBezier(D2D1::BezierSegment( D2D1::Point2F(220, 300), D2D1::Point2F(380, -100) , D2D1::Point2F(400, 100) ) ); // 220, 300 380 -100 400 100 pSink->EndFigure(D2D1_FIGURE_END_CLOSED); hr = pSink->Close(); } SafeRelease(&pSink); } } if (SUCCEEDED(hr)) // 바퀴 경로 기하 { hr = m_pD2DFactory->CreatePathGeometry(&m_wheelPath); if (SUCCEEDED(hr)) { // Write to the path geometry using the geometry sink. hr = m_wheelPath->Open(&pSink); if (SUCCEEDED(hr)) { pSink->BeginFigure(D2D1::Point2F(200,0),D2D1_FIGURE_BEGIN_FILLED); pSink->AddBezier(D2D1::BezierSegment( D2D1::Point2F(250,-50),D2D1::Point2F(80,-80),D2D1::Point2F(0,-50))); pSink->AddBezier(D2D1::BezierSegment( D2D1::Point2F(-50,-10),D2D1::Point2F(-180,-80),D2D1::Point2F(-200,0))); pSink->AddBezier(D2D1::BezierSegment( D2D1::Point2F(-230,60),D2D1::Point2F(-80,70),D2D1::Point2F(0,50))); pSink->AddBezier(D2D1::BezierSegment( D2D1::Point2F(50,10),D2D1::Point2F(180,80),D2D1::Point2F(200,0))); pSink->EndFigure(D2D1_FIGURE_END_CLOSED); hr = pSink->Close(); } SafeRelease(&pSink); } } if (SUCCEEDED(hr)) // 파리 경로 기하 { hr = m_pD2DFactory->CreatePathGeometry(&m_flyPath); if (SUCCEEDED(hr)) { // Write to the path geometry using the geometry sink. hr = m_flyPath->Open(&pSink); if (SUCCEEDED(hr)) { pSink->BeginFigure(D2D1::Point2F(200,0),D2D1_FIGURE_BEGIN_FILLED); pSink->AddBezier(D2D1::BezierSegment( D2D1::Point2F(250,-50),D2D1::Point2F(80,-80),D2D1::Point2F(-100,-50))); pSink->AddBezier(D2D1::BezierSegment( D2D1::Point2F(-50,-10),D2D1::Point2F(-180,-80),D2D1::Point2F(-100,0))); pSink->AddBezier(D2D1::BezierSegment( D2D1::Point2F(-230,60),D2D1::Point2F(-80,70),D2D1::Point2F(50,50))); pSink->AddBezier(D2D1::BezierSegment( D2D1::Point2F(50,10),D2D1::Point2F(180,80),D2D1::Point2F(300,60))); pSink->EndFigure(D2D1_FIGURE_END_CLOSED); hr = pSink->Close(); } SafeRelease(&pSink); } } if(SUCCEEDED(hr)) //파리 몸통 기하 { hr = m_pD2DFactory->CreateEllipseGeometry( D2D1::Ellipse(D2D1::Point2F(0,0), 20, 10), &m_pFlyGeometry); } if(SUCCEEDED(hr)) //파리 오른쪽 눈알 기하 { hr = m_pD2DFactory->CreateEllipseGeometry( D2D1::Ellipse(D2D1::Point2F(20,-5), 5, 5), &m_pRightEyeGeometry); } if(SUCCEEDED(hr)) //파리 왼쪽 눈알 기하 { hr = m_pD2DFactory->CreateEllipseGeometry( D2D1::Ellipse(D2D1::Point2F(20,5), 5, 5), &m_pLeftEyeGeometry); } if(SUCCEEDED(hr)) //파리 날개 가운데 기하 { hr = m_pD2DFactory->CreatePathGeometry(&m_pMiddleWingGeometry); if(SUCCEEDED(hr)) { ID2D1GeometrySink *pSink = NULL; hr = m_pMiddleWingGeometry->Open(&pSink); if (SUCCEEDED(hr)) { pSink->SetFillMode(D2D1_FILL_MODE_WINDING); pSink->BeginFigure( D2D1::Point2F(10, -9), D2D1_FIGURE_BEGIN_FILLED ); pSink->AddLine(D2D1::Point2F(10, -15)); pSink->AddArc(D2D1::ArcSegment(D2D1::Point2F(-10,-15),D2D1::SizeF(10,5),0, D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE,D2D1_ARC_SIZE_SMALL)); pSink->AddLine(D2D1::Point2F(-10, -9)); pSink->AddLine(D2D1::Point2F(-10, 9)); pSink->AddLine(D2D1::Point2F(-10, 15)); pSink->AddArc(D2D1::ArcSegment(D2D1::Point2F(10,15),D2D1::SizeF(10,5),0, D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE,D2D1_ARC_SIZE_SMALL)); pSink->EndFigure(D2D1_FIGURE_END_CLOSED); } hr = pSink->Close(); SafeRelease(&pSink); } } if(SUCCEEDED(hr)) //파리 날개 위쪽 기하 { hr = m_pD2DFactory->CreatePathGeometry(&m_pUpWingGeometry); if(SUCCEEDED(hr)) { ID2D1GeometrySink *pSink = NULL; hr = m_pUpWingGeometry->Open(&pSink); if (SUCCEEDED(hr)) { pSink->SetFillMode(D2D1_FILL_MODE_WINDING); pSink->BeginFigure( D2D1::Point2F(10, -9), D2D1_FIGURE_BEGIN_FILLED ); pSink->AddLine(D2D1::Point2F(10, -15)); pSink->AddArc(D2D1::ArcSegment(D2D1::Point2F(-10,-15),D2D1::SizeF(10,5),45, D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE,D2D1_ARC_SIZE_SMALL)); pSink->AddLine(D2D1::Point2F(-10, -9)); pSink->AddLine(D2D1::Point2F(-10, 9)); pSink->AddLine(D2D1::Point2F(-10, 15)); pSink->AddArc(D2D1::ArcSegment(D2D1::Point2F(10,15),D2D1::SizeF(10,5),-45, D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE,D2D1_ARC_SIZE_SMALL)); pSink->EndFigure(D2D1_FIGURE_END_CLOSED); } hr = pSink->Close(); SafeRelease(&pSink); } } if(SUCCEEDED(hr)) //파리 날개 아래쪽 기하 { hr = m_pD2DFactory->CreatePathGeometry(&m_pDownWingGeometry); if(SUCCEEDED(hr)) { ID2D1GeometrySink *pSink = NULL; hr = m_pDownWingGeometry->Open(&pSink); if (SUCCEEDED(hr)) { pSink->SetFillMode(D2D1_FILL_MODE_WINDING); pSink->BeginFigure( D2D1::Point2F(10, -9), D2D1_FIGURE_BEGIN_FILLED ); pSink->AddLine(D2D1::Point2F(10, -15)); pSink->AddArc(D2D1::ArcSegment(D2D1::Point2F(-10,-15),D2D1::SizeF(10,5),-45, D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE,D2D1_ARC_SIZE_SMALL)); pSink->AddLine(D2D1::Point2F(-10, -9)); pSink->AddLine(D2D1::Point2F(-10, 9)); pSink->AddLine(D2D1::Point2F(-10, 15)); pSink->AddArc(D2D1::ArcSegment(D2D1::Point2F(10,15),D2D1::SizeF(10,5),45, D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE,D2D1_ARC_SIZE_SMALL)); pSink->EndFigure(D2D1_FIGURE_END_CLOSED); } hr = pSink->Close(); SafeRelease(&pSink); } } m_pWingGeometry[0] = m_pMiddleWingGeometry; //중간위치의 날개 m_pWingGeometry[1] = m_pUpWingGeometry; //위쪽 위치의 날개 m_pWingGeometry[2] = m_pMiddleWingGeometry; //중간위치의 날개 m_pWingGeometry[3] = m_pDownWingGeometry; //아래쪽 위치의 날개 return hr; }
int _tmain(int argc, _TCHAR* argv[]) { HRESULT hr = S_OK; // Create a Direct2D factory. CHECKHR(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &g_pD2DFactory)); // Create a DirectWrite factory. CHECKHR(DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&g_pDWriteFactory))); // Create a WIC factory IWICImagingFactory* pWICFactory = NULL; CHECKHR(CoInitialize(nullptr)); CHECKHR(CoCreateInstance(CLSID_WICImagingFactory1, nullptr, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&pWICFactory)); // Create an IWICBitmap and RT IWICBitmap* pWICBitmap = NULL; static const UINT sc_bitmapWidth = 640; static const UINT sc_bitmapHeight = 480; CHECKHR(pWICFactory->CreateBitmap(sc_bitmapWidth, sc_bitmapHeight, GUID_WICPixelFormat32bppBGR, WICBitmapCacheOnLoad, &pWICBitmap)); // Set the render target type to D2D1_RENDER_TARGET_TYPE_DEFAULT to use software rendering. CHECKHR(g_pD2DFactory->CreateWicBitmapRenderTarget( pWICBitmap, D2D1::RenderTargetProperties(), &g_pRenderTarget)); // Create text format and a path geometry representing an hour glass. IDWriteTextFormat* pTextFormat = NULL; static const WCHAR sc_fontName[] = L"Calibri"; static const FLOAT sc_fontSize = 50; CHECKHR(g_pDWriteFactory->CreateTextFormat( sc_fontName, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, sc_fontSize, L"", //locale &pTextFormat )); CHECKHR(pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER)); CHECKHR(pTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER)); // Create a path geometry ID2D1PathGeometry* pPathGeometry = NULL; ID2D1GeometrySink* pSink = NULL; CHECKHR(g_pD2DFactory->CreatePathGeometry(&pPathGeometry)); CHECKHR(pPathGeometry->Open(&pSink)); pSink->SetFillMode(D2D1_FILL_MODE_ALTERNATE); pSink->BeginFigure( D2D1::Point2F(0, 0), D2D1_FIGURE_BEGIN_FILLED ); pSink->AddLine(D2D1::Point2F(200, 0)); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(150, 50), D2D1::Point2F(150, 150), D2D1::Point2F(200, 200)) ); pSink->AddLine(D2D1::Point2F(0, 200)); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(50, 150), D2D1::Point2F(50, 50), D2D1::Point2F(0, 0)) ); pSink->EndFigure(D2D1_FIGURE_END_CLOSED); CHECKHR(pSink->Close()); // Create GradientStopCollection ID2D1GradientStopCollection *pGradientStops = NULL; static const D2D1_GRADIENT_STOP stops[] = { { 0.f, { 0.f, 1.f, 1.f, 1.f } }, { 1.f, { 0.f, 0.f, 1.f, 1.f } }, }; CHECKHR(g_pRenderTarget->CreateGradientStopCollection( stops, ARRAYSIZE(stops), &pGradientStops )); ID2D1LinearGradientBrush* pLGBrush = NULL; ID2D1SolidColorBrush* pBlackBrush = NULL; CHECKHR(g_pRenderTarget->CreateLinearGradientBrush( D2D1::LinearGradientBrushProperties( D2D1::Point2F(100, 0), D2D1::Point2F(100, 200)), D2D1::BrushProperties(), pGradientStops, &pLGBrush )); CHECKHR(g_pRenderTarget->CreateSolidColorBrush( D2D1::ColorF(D2D1::ColorF::Black), &pBlackBrush )); // Render into the bitmap. g_pRenderTarget->BeginDraw(); g_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White)); D2D1_SIZE_F rtSize = g_pRenderTarget->GetSize(); // Set the world transform to a 45 degree rotation at the center of the render target // and write "Hello, World". g_pRenderTarget->SetTransform( D2D1::Matrix3x2F::Rotation( 45, D2D1::Point2F( rtSize.width / 2, rtSize.height / 2)) ); static const WCHAR sc_helloWorld[] = L"Hello, World!"; g_pRenderTarget->DrawText( sc_helloWorld, ARRAYSIZE(sc_helloWorld) - 1, pTextFormat, D2D1::RectF(0, 0, rtSize.width, rtSize.height), pBlackBrush); // Reset back to the identity transform. g_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Translation(0, rtSize.height - 200)); g_pRenderTarget->FillGeometry(pPathGeometry, pLGBrush); g_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Translation(rtSize.width - 200, 0)); g_pRenderTarget->FillGeometry(pPathGeometry, pLGBrush); CHECKHR(g_pRenderTarget->EndDraw()); // Save the image to a file. IWICStream* pStream = NULL; CHECKHR(pWICFactory->CreateStream(&pStream)); // Use InitializeFromFilename to write to a file. If there is need to write inside the memory, use InitializeFromMemory. static const WCHAR filename[] = L"output.png"; CHECKHR(pStream->InitializeFromFilename(filename, GENERIC_WRITE)); IWICBitmapEncoder* pEncoder = NULL; CHECKHR(pWICFactory->CreateEncoder(GUID_ContainerFormatPng, NULL, &pEncoder)); CHECKHR(pEncoder->Initialize(pStream, WICBitmapEncoderNoCache)); IWICBitmapFrameEncode* pFrameEncode = NULL; CHECKHR(pEncoder->CreateNewFrame(&pFrameEncode, NULL)); // Use IWICBitmapFrameEncode to encode the bitmap into the picture format you want. CHECKHR(pFrameEncode->Initialize(NULL)); CHECKHR(pFrameEncode->SetSize(sc_bitmapWidth, sc_bitmapHeight)); WICPixelFormatGUID format = GUID_WICPixelFormatDontCare; CHECKHR(pFrameEncode->SetPixelFormat(&format)); CHECKHR(pFrameEncode->WriteSource(pWICBitmap, NULL)); CHECKHR(pFrameEncode->Commit()); CHECKHR(pEncoder->Commit()); return 0; }
HRESULT DemoApp::CreateGeometries() { HRESULT hr = S_OK; if (!m_pGeometry) { IGeometryRealizationFactory *pRealizationFactory = NULL; IGeometryRealization *pRealization = NULL; ID2D1TransformedGeometry *pGeometry = NULL; ID2D1PathGeometry *pPathGeometry = NULL; ID2D1GeometrySink *pSink = NULL; float squareWidth = 0.9f * sc_boardWidth / m_numSquares; // Create the path geometry. hr = m_pD2DFactory->CreatePathGeometry(&pPathGeometry); if (SUCCEEDED(hr)) { // Write to the path geometry using the geometry sink to // create an hour glass shape. hr = pPathGeometry->Open(&pSink); } if (SUCCEEDED(hr)) { pSink->SetFillMode(D2D1_FILL_MODE_ALTERNATE); pSink->BeginFigure( D2D1::Point2F(0, 0), D2D1_FIGURE_BEGIN_FILLED ); pSink->AddLine(D2D1::Point2F(1.0f, 0)); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(0.75f, 0.25f), D2D1::Point2F(0.75f, 0.75f), D2D1::Point2F(1.0f, 1.0f)) ); pSink->AddLine(D2D1::Point2F(0, 1.0f)); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(0.25f, 0.75f), D2D1::Point2F(0.25f, 0.25f), D2D1::Point2F(0, 0)) ); pSink->EndFigure(D2D1_FIGURE_END_CLOSED); hr = pSink->Close(); } if (SUCCEEDED(hr)) { D2D1_MATRIX_3X2_F scale = D2D1::Matrix3x2F::Scale(squareWidth, squareWidth); D2D1_MATRIX_3X2_F translation = D2D1::Matrix3x2F::Translation(-squareWidth / 2, -squareWidth / 2); hr = m_pD2DFactory->CreateTransformedGeometry( pPathGeometry, scale * translation, &pGeometry ); } if (SUCCEEDED(hr)) { // Transfer the reference. m_pGeometry = pGeometry; pGeometry = NULL; } SafeRelease(&pRealizationFactory); SafeRelease(&pRealization); SafeRelease(&pGeometry); SafeRelease(&pPathGeometry); SafeRelease(&pSink); } return hr; }