Beispiel #1
0
/// <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;
}
Beispiel #4
0
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);
}
Beispiel #5
0
//  创建路径几何
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();
		}
	}
}
Beispiel #7
0
    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);
            }
        }
    }
Beispiel #8
0
    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);
    }
Beispiel #9
0
    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);
		}
    }
Beispiel #10
0
    HRESULT STDMETHODCALLTYPE Close()
    {
        HRESULT hr = S_OK;

        if( m_BaseSink )
        {
            hr = m_BaseSink->Close();
        }

        return hr;
    }
Beispiel #11
0
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;
	}
}
Beispiel #12
0
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++;
	}
}
Beispiel #13
0
    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
}
Beispiel #15
0
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;
}
Beispiel #19
0
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) ;
		}
	}
}
Beispiel #20
0
/// <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;
}
Beispiel #21
0
 void STDMETHODCALLTYPE SetSegmentFlags(D2D1_PATH_SEGMENT vertexFlags)
 {
     if( m_BaseSink )
         m_BaseSink->SetSegmentFlags(vertexFlags);
 }
Beispiel #22
0
 void STDMETHODCALLTYPE SetFillMode(D2D1_FILL_MODE fillMode) 
 {
     if( m_BaseSink )
         m_BaseSink->SetFillMode(fillMode);
 }
Beispiel #23
0
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;
}
Beispiel #27
0
//-----------------------------------------------------------------------------
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;
}
Beispiel #29
0
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;
}