/// <summary> /// Initializes a new instance of the <see cref="Polyline"/> class. /// </summary> /// <param name="">The .</param> RubyGM::Drawable::Polyline::Polyline(const PolylineStatus& ps) noexcept : Super(ps) { assert(m_pGiGeometry == nullptr); assert(ps.points && ps.count >= 2); this->filled_color.a = 0.f; // 初始化 ID2D1PathGeometry* path = nullptr; ID2D1GeometrySink* sink = nullptr; // 创建路径几何 auto hr = Bridge::CreatePathGeometry(path); // 打开路径记录 if (SUCCEEDED(hr)) { hr = path->Open(&sink); } // 填充路径 if (SUCCEEDED(hr)) { auto points = impl::d2d(ps.points); sink->BeginFigure(*points, D2D1_FIGURE_BEGIN_HOLLOW); sink->AddLines(points + 1, ps.count - 1); sink->EndFigure(D2D1_FIGURE_END_CLOSED); hr = sink->Close(); } // 错误代码 if (FAILED(hr)) Game::SetLastErrorCode(hr); RubyGM::SafeRelease(sink); // 数据转换 auto gi = static_cast<ID2D1Geometry*>(path); m_pGiGeometry = static_cast<IGMGeometry*>(gi); }
/// <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; }
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); }
// 创建路径几何 void ImageRenderer::MakePath() { SafeRelease(m_pNowPath); m_pd2dFactory->CreatePathGeometry(&m_pNowPath); if (m_pNowPath) { ID2D1GeometrySink* sink = nullptr; HRESULT hr = m_pNowPath->Open(&sink); if (SUCCEEDED(hr)) { sink->BeginFigure(points[0], D2D1_FIGURE_BEGIN_FILLED); sink->AddLines(points + 1, m_cPointCount); sink->EndFigure(D2D1_FIGURE_END_CLOSED); sink->Close(); } SafeRelease(sink); } }
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 STDMETHODCALLTYPE AddBeziers(CONST D2D1_BEZIER_SEGMENT *beziers, UINT beziersCount) { size_t quadIndex0 = m_Quads.size(); for( size_t i=0; i<beziersCount; ++i ) { Cubic c; c.p0 = m_Cursor; c.p1 = beziers[i].point1; c.p2 = beziers[i].point2; c.p3 = beziers[i].point3; m_Cursor = beziers[i].point3; c.FitQuads(m_FlatteningTolerance*m_FlatteningTolerance, m_Quads); } size_t quadIndex1 = m_Quads.size(); if( m_BaseSink ) { for( size_t i=quadIndex0; i<quadIndex1; i += 3 ) { D2D1_QUADRATIC_BEZIER_SEGMENT s; s.point1 = m_Quads[i+1]; s.point2 = m_Quads[i+2]; m_BaseSink->AddQuadraticBezier(&s); } } }
void STDMETHODCALLTYPE BeginFigure(D2D1_POINT_2F startPoint, D2D1_FIGURE_BEGIN figureBegin) { m_StartPoint = startPoint;//Bart: remember, may be needed when endfigure is drawn m_Cursor = startPoint; if( m_BaseSink ) m_BaseSink->BeginFigure(startPoint, figureBegin); }
void STDMETHODCALLTYPE EndFigure(D2D1_FIGURE_END figureEnd) { if( m_BaseSink ) m_BaseSink->EndFigure(figureEnd); if(figureEnd == D2D1_FIGURE_END_CLOSED) { m_Lines.push_back(m_Cursor); m_Lines.push_back(m_StartPoint); } }
HRESULT STDMETHODCALLTYPE Close() { HRESULT hr = S_OK; if( m_BaseSink ) { hr = m_BaseSink->Close(); } return hr; }
HRESULT Scene::CreateMouthGeometry() { HRESULT hr = S_OK; //mouth hr = m_pFactory->CreatePathGeometry(&m_pMouthGeometry); if (SUCCEEDED(hr)) { ID2D1GeometrySink *pSink = NULL; hr = m_pMouthGeometry->Open(&pSink); if (SUCCEEDED(hr)) { pSink->SetFillMode(D2D1_FILL_MODE_WINDING); pSink->BeginFigure( D2D1::Point2F(m_ellipse.point.x, m_ellipse.point.y), D2D1_FIGURE_BEGIN_FILLED ); D2D1_POINT_2F points[3] = { D2D1::Point2F(m_ellipse.point.x + m_ellipse.radiusX, m_ellipse.point.y - 10), D2D1::Point2F(m_ellipse.point.x + m_ellipse.radiusX, m_ellipse.point.y + 10), D2D1::Point2F(m_ellipse.point.x, m_ellipse.point.y), }; pSink->AddLines(points, ARRAYSIZE(points)); pSink->EndFigure(D2D1_FIGURE_END_CLOSED); } hr = pSink->Close(); SafeRelease(&pSink); return hr; } }
void GraphData(PlotData **data, ID2D1Factory *d2dFactory, ID2D1RenderTarget *target, ID2D1SolidColorBrush *brush, float xScale, float yScale) { int c = 0; while(*data) { brush->SetColor(Colors[c++]); ID2D1PathGeometry *path = NULL; if(SUCCEEDED(d2dFactory->CreatePathGeometry(&path))) { ID2D1GeometrySink *sink = NULL; if (SUCCEEDED(path->Open(&sink))) { PlotGraph(**data, sink, xScale, yScale); SUCCEEDED(sink->Close()); target->DrawGeometry(path, brush); SafeRelease(&sink); } SafeRelease(&path); } data++; } }
void STDMETHODCALLTYPE AddLines(CONST D2D1_POINT_2F *points, UINT pointsCount) { if( m_BaseSink ) m_BaseSink->AddLines(points, pointsCount); for( size_t i=0; i<pointsCount; ++i ) { m_Lines.push_back(m_Cursor); m_Lines.push_back(points[i]); m_Cursor = points[i]; } }
void VGraphicPath::Begin() { #if ENABLE_D2D //start to populate geometry if (fGeomSink) return; if (fPathD2D == NULL) return; ID2D1PathGeometry *thisPath = NULL; if (FAILED(fPathD2D->QueryInterface( __uuidof(ID2D1PathGeometry), (void **)&thisPath))) return; //no more a ID2D1PathGeometry so skip ID2D1GeometrySink *thisGeomSink; if (SUCCEEDED(thisPath->Open(&thisGeomSink))) { fGeomSink = thisGeomSink; thisGeomSink->SetFillMode( fFillMode == FILLRULE_EVENODD ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING); fFigureIsClosed = true; } thisPath->Release(); #endif }
Home::Home(float xPos, float yPos, ID2D1Factory *pID2D1Factory) : Actor(xPos, yPos) { r = 0.0f; g = 1.0f; b = 0.0f; a = 1.0f; HRESULT hr = pID2D1Factory->CreatePathGeometry(&pHomeGeometry); if (SUCCEEDED(hr)) { ID2D1GeometrySink *pSink = NULL; hr = pHomeGeometry->Open(&pSink); if (SUCCEEDED(hr)) { pSink->SetFillMode(D2D1_FILL_MODE_WINDING); pSink->BeginFigure( D2D1::Point2F(25, -25), D2D1_FIGURE_BEGIN_FILLED ); D2D1_POINT_2F points[] = { D2D1::Point2F(25, 25), D2D1::Point2F(-25, 25), D2D1::Point2F(-25, -25) }; pSink->AddLines(points, ARRAYSIZE(points)); pSink->EndFigure(D2D1_FIGURE_END_CLOSED); } hr = pSink->Close(); pSink->Release(); } D2D1_MATRIX_3X2_F mov; mov = D2D1::Matrix3x2F::Translation( D2D1::SizeF(x, y) ); D2D1_MATRIX_3X2_F transform = mov; hr = pID2D1Factory->CreateTransformedGeometry( pHomeGeometry, &transform, &pTransformed ); }
/// <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; }
HRESULT DemoApp::CreateDeviceIndependentResources() { HRESULT hr; ID2D1GeometrySink *pSink = NULL; // Create a Direct2D factory. hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pD2DFactory); if (SUCCEEDED(hr)) { // Create the path geometry. hr = m_pD2DFactory->CreatePathGeometry(&m_pPathGeometry); } if (SUCCEEDED(hr)) { // Write to the path geometry using the geometry sink. We are going to create a // spiral hr = m_pPathGeometry->Open(&pSink); } if (SUCCEEDED(hr)) { D2D1_POINT_2F currentLocation = {0, 0}; pSink->BeginFigure(currentLocation, D2D1_FIGURE_BEGIN_FILLED); D2D1_POINT_2F locDelta = {2, 2}; float radius = 3; for (UINT i = 0; i < 30; ++i) { currentLocation.x += radius * locDelta.x; currentLocation.y += radius * locDelta.y; pSink->AddArc( D2D1::ArcSegment( currentLocation, D2D1::SizeF(2*radius, 2*radius), // radiusx/y 0.0f, // rotation angle D2D1_SWEEP_DIRECTION_CLOCKWISE, D2D1_ARC_SIZE_SMALL ) ); locDelta = D2D1::Point2F(-locDelta.y, locDelta.x); radius += 3; } pSink->EndFigure(D2D1_FIGURE_END_OPEN); hr = pSink->Close(); } if (SUCCEEDED(hr)) { // Create the path geometry. hr = m_pD2DFactory->CreatePathGeometry(&m_pObjectGeometry); } if (SUCCEEDED(hr)) { // Write to the object geometry using the geometry sink. // We are going to create a simple triangle hr = m_pObjectGeometry->Open(&pSink); } if (SUCCEEDED(hr)) { pSink->BeginFigure( D2D1::Point2F(0.0f, 0.0f), D2D1_FIGURE_BEGIN_FILLED ); const D2D1_POINT_2F ptTriangle[] = {{-10.0f, -10.0f}, {-10.0f, 10.0f}, {0.0f, 0.0f}}; pSink->AddLines(ptTriangle, 3); pSink->EndFigure(D2D1_FIGURE_END_OPEN); hr = pSink->Close(); } SafeRelease(&pSink); return hr; }
// // 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; }
VOID CreateD2DResource(HWND hWnd) { // This function was called in the DrawRectangle function which in turn called to response the // WM_PAINT Message, to avoid creating resource every time, we test the pointer to g_pRenderTarget // If the resource already create, skip the function if (!g_pRenderTarget) { HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &g_pD2DFactory) ; if (FAILED(hr)) { MessageBox(hWnd, "Create D2D factory failed!", "Error", 0) ; return ; } // Obtain the size of the drawing area RECT rc ; GetClientRect(hWnd, &rc) ; // Create a Direct2D render target hr = g_pD2DFactory->CreateHwndRenderTarget( D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties( hWnd, D2D1::SizeU(rc.right - rc.left,rc.bottom - rc.top) ), &g_pRenderTarget ) ; if (FAILED(hr)) { MessageBox(hWnd, "Create render target failed!", "Error", 0) ; return ; } // Create a brush hr = g_pRenderTarget->CreateSolidColorBrush( D2D1::ColorF(D2D1::ColorF::Black), &g_pSceneBrush ) ; if (FAILED(hr)) { MessageBox(hWnd, "Create brush failed!", "Error", 0) ; return ; } // Create left mountain geometry hr = g_pD2DFactory->CreatePathGeometry(&g_pLeftMountainGeometry) ; if (SUCCEEDED(hr)) { ID2D1GeometrySink *pSink = NULL; hr = g_pLeftMountainGeometry->Open(&pSink); if (SUCCEEDED(hr)) { pSink->SetFillMode(D2D1_FILL_MODE_WINDING); pSink->BeginFigure( D2D1::Point2F(346,255), D2D1_FIGURE_BEGIN_FILLED ); D2D1_POINT_2F points[5] = { D2D1::Point2F(267, 177), D2D1::Point2F(236, 192), D2D1::Point2F(212, 160), D2D1::Point2F(156, 255), D2D1::Point2F(346, 255), }; pSink->AddLines(points, ARRAYSIZE(points)); pSink->EndFigure(D2D1_FIGURE_END_CLOSED); } pSink->Close() ; SAFE_RELEASE(pSink) ; } // Create right mountain geometry hr = g_pD2DFactory->CreatePathGeometry(&g_pRightMountainGeometry) ; if (SUCCEEDED(hr)) { ID2D1GeometrySink *pSink = NULL; hr = g_pRightMountainGeometry->Open(&pSink); if (SUCCEEDED(hr)) { pSink->SetFillMode(D2D1_FILL_MODE_WINDING); pSink->BeginFigure( D2D1::Point2F(575,263), D2D1_FIGURE_BEGIN_FILLED ); D2D1_POINT_2F points[] = { D2D1::Point2F(481, 146), D2D1::Point2F(449, 181), D2D1::Point2F(433, 159), D2D1::Point2F(401, 214), D2D1::Point2F(381, 199), D2D1::Point2F(323, 263), D2D1::Point2F(575, 263) }; pSink->AddLines(points, ARRAYSIZE(points)); pSink->EndFigure(D2D1_FIGURE_END_CLOSED); } hr = pSink->Close(); SAFE_RELEASE(pSink); } // Create sun geometry hr = g_pD2DFactory->CreatePathGeometry(&g_pSunGeometry) ; if (SUCCEEDED(hr)) { ID2D1GeometrySink *pSink = NULL; hr = g_pSunGeometry->Open(&pSink); if (SUCCEEDED(hr)) { pSink->SetFillMode(D2D1_FILL_MODE_WINDING); pSink->BeginFigure( D2D1::Point2F(270, 255), D2D1_FIGURE_BEGIN_FILLED ); pSink->AddArc( D2D1::ArcSegment( D2D1::Point2F(440, 255), // end point D2D1::SizeF(85, 85), 0.0f, // rotation angle D2D1_SWEEP_DIRECTION_CLOCKWISE, D2D1_ARC_SIZE_SMALL )); pSink->EndFigure(D2D1_FIGURE_END_CLOSED); pSink->BeginFigure( D2D1::Point2F(299, 182), D2D1_FIGURE_BEGIN_HOLLOW ); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(299, 182), D2D1::Point2F(294, 176), D2D1::Point2F(285, 178) )); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(276, 179), D2D1::Point2F(272, 173), D2D1::Point2F(272, 173) )); pSink->EndFigure(D2D1_FIGURE_END_OPEN); pSink->BeginFigure( D2D1::Point2F(354, 156), D2D1_FIGURE_BEGIN_HOLLOW ); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(354, 156), D2D1::Point2F(358, 149), D2D1::Point2F(354, 142) )); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(349, 134), D2D1::Point2F(354, 127), D2D1::Point2F(354, 127) )); pSink->EndFigure(D2D1_FIGURE_END_OPEN); pSink->BeginFigure( D2D1::Point2F(322,164), D2D1_FIGURE_BEGIN_HOLLOW ); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(322, 164), D2D1::Point2F(322, 156), D2D1::Point2F(314, 152) )); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(306, 149), D2D1::Point2F(305, 141), D2D1::Point2F(305, 141) )); pSink->EndFigure(D2D1_FIGURE_END_OPEN); pSink->BeginFigure( D2D1::Point2F(385, 164), D2D1_FIGURE_BEGIN_HOLLOW ); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(385,164), D2D1::Point2F(392,161), D2D1::Point2F(394,152) )); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(395,144), D2D1::Point2F(402,141), D2D1::Point2F(402,142) )); pSink->EndFigure(D2D1_FIGURE_END_OPEN); pSink->BeginFigure( D2D1::Point2F(408,182), D2D1_FIGURE_BEGIN_HOLLOW ); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(408,182), D2D1::Point2F(416,184), D2D1::Point2F(422,178) )); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(428,171), D2D1::Point2F(435,173), D2D1::Point2F(435,173) )); pSink->EndFigure(D2D1_FIGURE_END_OPEN); } hr = pSink->Close(); SAFE_RELEASE(pSink); } // Create river geometry hr = g_pD2DFactory->CreatePathGeometry(&g_pRiverGeometry) ; if (SUCCEEDED(hr)) { ID2D1GeometrySink *pSink = NULL; hr = g_pRiverGeometry->Open(&pSink); if (SUCCEEDED(hr)) { pSink->SetFillMode(D2D1_FILL_MODE_WINDING); pSink->BeginFigure( D2D1::Point2F(183, 392), D2D1_FIGURE_BEGIN_FILLED ); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(238, 284), D2D1::Point2F(472, 345), D2D1::Point2F(356, 303) )); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(237, 261), D2D1::Point2F(333, 256), D2D1::Point2F(333, 256) )); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(335, 257), D2D1::Point2F(241, 261), D2D1::Point2F(411, 306) )); pSink->AddBezier( D2D1::BezierSegment( D2D1::Point2F(574, 350), D2D1::Point2F(288, 324), D2D1::Point2F(296, 392) )); pSink->EndFigure(D2D1_FIGURE_END_OPEN); } pSink->Close() ; SAFE_RELEASE(pSink) ; } } }
/// <summary> /// IDWriteTextRenderer::DrawGlyphRun /// Draws glyphs /// </summary> HRESULT StateTextRender::DrawGlyphRun( LPVOID clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, DWRITE_MEASURING_MODE measuringMode, const DWRITE_GLYPH_RUN * glyphRun, const DWRITE_GLYPH_RUN_DESCRIPTION * glyphRunDescription, LPUNKNOWN clientDrawingEffect) { UNREFERENCED_PARAMETER(glyphRunDescription); UNREFERENCED_PARAMETER(clientDrawingEffect); HRESULT hr = S_OK; auto renderTarget = ((ID2D1RenderTarget*) clientDrawingContext); // Since the fill looks horrid anyways, only do this if we are // going to stroke, and fill using D2D's DrawGlyphRun if (mState->mStateSettings.fontStrokeWidth > 0.0f) { // Get our D2D factory ID2D1Factory *d2dFactory; renderTarget->GetFactory(&d2dFactory); // Create the path geometry. ID2D1PathGeometry *pPathGeometry = nullptr; hr = d2dFactory->CreatePathGeometry(&pPathGeometry); // Write to the path geometry using the geometry sink. ID2D1GeometrySink* sink = nullptr; if (SUCCEEDED(hr)) { hr = pPathGeometry->Open(&sink); } // Get the glyph run outline geometries back from DirectWrite and place them within the geometry sink. if (SUCCEEDED(hr)) { hr = glyphRun->fontFace->GetGlyphRunOutline( glyphRun->fontEmSize, glyphRun->glyphIndices, glyphRun->glyphAdvances, glyphRun->glyphOffsets, glyphRun->glyphCount, glyphRun->isSideways, glyphRun->bidiLevel % 2, sink ); } // Close the geometry sink if (SUCCEEDED(hr)) { hr = sink->Close(); } // Initialize a matrix to translate the origin of the glyph run. D2D1::Matrix3x2F const matrix = D2D1::Matrix3x2F( 1.0f, 0.0f, 0.0f, 1.0f, baselineOriginX, baselineOriginY ); // Create the transformed geometry ID2D1TransformedGeometry* pTransformedGeometry = nullptr; if (SUCCEEDED(hr)) { hr = d2dFactory->CreateTransformedGeometry( pPathGeometry, &matrix, &pTransformedGeometry ); } ID2D1StrokeStyle* strokeStyle = nullptr; if (SUCCEEDED(hr)) { d2dFactory->CreateStrokeStyle( D2D1::StrokeStyleProperties( D2D1_CAP_STYLE_FLAT, D2D1_CAP_STYLE_FLAT, D2D1_CAP_STYLE_SQUARE, D2D1_LINE_JOIN_BEVEL, 5.0f, D2D1_DASH_STYLE_SOLID, 0.0f ), nullptr, 0, &strokeStyle); } if (SUCCEEDED(hr)) { float strokeWidth = mState->mStateSettings.fontStrokeWidth; if (strokeWidth != 0.0f) { // Draw the outline of the glyph run renderTarget->DrawGeometry( pTransformedGeometry, mState->mBrushes[State::BrushType::TextStroke].brush, strokeWidth, strokeStyle ); } // Fill in the glyph run // This is so ugly... /*renderTarget->FillGeometry( pTransformedGeometry, mState->mBrushes[State::BrushType::Text].brush );*/ } SAFERELEASE(strokeStyle); SAFERELEASE(pPathGeometry); SAFERELEASE(sink); SAFERELEASE(pTransformedGeometry); d2dFactory->Release(); } // TODO::Figure out how to replicate the quality of D2Ds DrawGlyphRun! renderTarget->DrawGlyphRun(D2D1::Point2F(baselineOriginX, baselineOriginY), glyphRun, mState->mBrushes[State::BrushType::Text].brush, measuringMode); return hr; }
void STDMETHODCALLTYPE SetSegmentFlags(D2D1_PATH_SEGMENT vertexFlags) { if( m_BaseSink ) m_BaseSink->SetSegmentFlags(vertexFlags); }
void STDMETHODCALLTYPE SetFillMode(D2D1_FILL_MODE fillMode) { if( m_BaseSink ) m_BaseSink->SetFillMode(fillMode); }
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; }
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; }
/// <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; }
//----------------------------------------------------------------------------- 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; }
// 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; }
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; }