基于Dx11写一个自己的游戏引擎--5

使用d2d绘图

d2d初始化时,需要:

  1. ID2D1Factory*类型的对象,也就是D2D工厂接口,这个接口是所有D2D程序的起始点,几乎所有的D2D资源都是由这个接口创建;
  2. Render Target,在D2D中有多种类型的Render Target,这里我们选择ID2D1HwndRenderTarget类型,用来在窗口中进行渲染;
  3. Brush,用来绘制图形,这里选择固定颜色的画刷,即ID2D1SolidColorBrush。

注意头文件需要引入<d2d1.h>包含文件,并链接相关库。

//Direct2D 头文件
#include <wrl/client.h>
#include <d2d1.h>

//链接相关库

#pragma comment(lib,"d2d1.lib")

这里 <wrl/client.h> 的用处是引入微软自己提供的Comptr智能指针库,方便内存的管理,具体使用方式可以参考
DirectX11--ComPtr智能指针

这里用到的D2D资源文件全部在WindowsApp类中声明,如下:

    //声明d2d所需指针
    template <class T> 
    using ComPtr = Microsoft::WRL::ComPtr<T>;
	  
    ComPtr<ID2D1Factory>			m_pFactory;
    ComPtr<ID2D1HwndRenderTarget>	m_pRenderTarget;
    ComPtr<ID2D1SolidColorBrush>    m_pLightSlateGrayBrush;
    ComPtr<ID2D1SolidColorBrush>    m_pCornflowerBlueBrush;

在WindowsApp类中新建方法 InitDirect2D() 来初始化d2d,并在其中初始化d2d资源,最后通过Init()来调用此方法。
//初始化Direct2D所需资源
bool WindowsApp::InitDirect2D() { 
	HRESULT hr;
	
	
	//创建工厂
	//参数1 ,工厂类型,单线程or多线程  参数2 ,工厂地址
	hr=D2D1CreateFactory( D2D1_FACTORY_TYPE_SINGLE_THREADED, m_pFactory.GetAddressOf() );
	if (FAILED(hr)){
        MessageBox( 0, L"Create Factory Failed!", L"Error", 0 );
        return false;
	}

	//创建RenderTarget
	//参数1:属性,包括渲染模式,像素格式,DPI等。这里使用默认
    //参数2:Size
	//参数3:RenderTarget地址
	
	hr = m_pFactory->CreateHwndRenderTarget( D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties( m_hMainWnd, D2D1::SizeU( m_ClientWidth, m_ClientHeight ) ),
                                             m_pRenderTarget.GetAddressOf() );

	if (FAILED(hr)){
        MessageBox( 0, L"Create RenderTarget Failed!", L"Error", 0 );
        return false;
	}

	//创建两个笔刷

	hr = m_pRenderTarget->CreateSolidColorBrush( D2D1::ColorF( D2D1::ColorF::LightSlateGray ), m_pLightSlateGrayBrush.GetAddressOf() );

    hr = m_pRenderTarget->CreateSolidColorBrush( D2D1::ColorF( D2D1::ColorF::CornflowerBlue ), m_pCornflowerBlueBrush.GetAddressOf() );

	if ( FAILED( hr ) ) {
        MessageBox( 0, L"Create brush failed!", L"Error", 0 );
        return false;
    }


	return true;

}



在WindowsApp类中新建方法 DrawScene() 来使用创建的资源进行绘图,并在Run()中调用DrawScene();


 void WindowsApp::DrawScene() { 
	 HRESULT hr;
	 
	 m_pRenderTarget->BeginDraw();
	 
	 //设置背景颜色

	 m_pRenderTarget->Clear( D2D1::ColorF( D2D1::ColorF::White ) );



	 //绘制灰色背景

     int width = m_ClientWidth;
     int height = m_ClientHeight;

	 for ( int x = 0; x < width;x+=10 ) {
         m_pRenderTarget->DrawLine( D2D1::Point2F( static_cast<FLOAT>( x ), 0.0f ), D2D1::Point2F( static_cast<FLOAT>( x ), height ), m_pLightSlateGrayBrush.Get(), 0.5f );




	 }
     for ( int y = 0; y < height; y += 10 ) {
         m_pRenderTarget->DrawLine( D2D1::Point2F( 0.0f,static_cast < FLOAT > ( y ) ), D2D1::Point2F( width,static_cast<FLOAT>( y ) ), m_pLightSlateGrayBrush.Get(), 0.5f );
     }

	 //绘制两个矩形
   

         D2D1_RECT_F rectangle1 = D2D1::RectF(width / 2 - 50.0f, height / 2 - 50.0f,width / 2 + 50.0f, height / 2 + 50.0f  );
     D2D1_RECT_F rectangle2 = D2D1::RectF( width / 2 - 100.0f,height / 2 - 100.0f,width / 2 + 100.0f, height / 2 + 100.0f  );
     // draw a filled rectangle
     m_pRenderTarget->FillRectangle( &rectangle1, m_pLightSlateGrayBrush.Get() );
     // draw a outline only rectangle
     m_pRenderTarget->DrawRectangle( &rectangle2, m_pCornflowerBlueBrush.Get() );

     hr = m_pRenderTarget->EndDraw();
	
	 
	 // FinalizeDirect2D();

 }


Run():

//返回值为应用程序退出返回值
int WindowsApp::Run() {
    MSG msg = {0};


    while ( msg.message != WM_QUIT ) {

        if ( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) ) {
            //目前无用户输入,所以不需要Translate
            // TranslateMessage( &msg );

            DispatchMessage( &msg );

        } else {

            if ( !m_AppPaused ) {

                DrawScene();
            }
        }
    }

	//如果消息为退出,释放资源
    FinalizeDirect2D();

    return (int) msg.wParam;
}

用md中代码块的话不知道为什么代码排版很奇怪,源码地址

运行结果:




参考文章:

  1. 从零开始手敲次世代游戏引擎(九)
  2. DirectX11 With Windows SDK--01 DirectX11初始化
posted @ 2019-04-15 15:15  bCoherence  阅读(269)  评论(0编辑  收藏  举报