Example #1
0
bool CDirectEngine::Init(const CEngine& aEngine, Vector2<unsigned int> aWindowSize, bool enableVSync, bool startInFullScreen)
{
    myEnableVSync = enableVSync;
    HRESULT result = S_OK;

    INFO_PRINT( "%s", "Starting engine" );

    myWindowSize = aWindowSize;
    DXGI_SWAP_CHAIN_DESC swapChainDescription;
    ZeroMemory( &swapChainDescription, sizeof( DXGI_SWAP_CHAIN_DESC ) );
    // fill the swap chain description struct
    swapChainDescription.BufferCount = 1;
    swapChainDescription.BufferDesc.Width = myWindowSize.x;
    swapChainDescription.BufferDesc.Height = myWindowSize.y;
    swapChainDescription.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;

    Vector2<int> numDenum;

	IDXGIAdapter* adapter = nullptr;
	if (CollectAdapters(aWindowSize, numDenum, adapter))
    {
        INFO_PRINT( "%s%s", "VSYNC Compatible: Yes, Enabled: ", myEnableVSync ? "Yes" : "No" );
    }

    swapChainDescription.BufferDesc.RefreshRate.Numerator = numDenum.x;
    swapChainDescription.BufferDesc.RefreshRate.Denominator = numDenum.y;

    swapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDescription.OutputWindow = aEngine.GetWindow().GetWindowHandle();
    swapChainDescription.SampleDesc.Count = 1;
	swapChainDescription.Windowed = !startInFullScreen;
    swapChainDescription.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
    swapChainDescription.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
    swapChainDescription.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
    swapChainDescription.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

    UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#if defined(_DEBUG)
#if defined(REPORT_DX_WARNIGNS)
	creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
#endif
    // create a device, device context and swap chain using the information in the scd struct
    INFO_PRINT( "%s", "Creating device" );
	D3D_FEATURE_LEVEL feat_level;
	result = D3D11CreateDeviceAndSwapChain(adapter,
		D3D_DRIVER_TYPE_UNKNOWN,
        NULL,
        creationFlags,
		supported_feature_levels,
		NUM_SUPPORTED_FEATURE_LEVELS,
        D3D11_SDK_VERSION,
        &swapChainDescription,
        &mySwapchain,
        &myDevice,
		&feat_level,
        &myDeviceContext );

#if defined(_DEBUG)
	if (FAILED(result))
	{
		D3D_FEATURE_LEVEL feat_level;
		ERROR_AUTO_PRINT("%s", "Device could not create itself in debug mode, trying without debug layer... If you have Win10, try this:  Settings panel -> System -> Apps & features -> Manage optional Features -> Add a feature -> Select ""Graphics Tools""");
		UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;

		INFO_PRINT("%s", "Creating device without debug layer");
		result = D3D11CreateDeviceAndSwapChain(adapter,
			D3D_DRIVER_TYPE_UNKNOWN,
			NULL,
			creationFlags,
			supported_feature_levels,
			NUM_SUPPORTED_FEATURE_LEVELS,
			D3D11_SDK_VERSION,
			&swapChainDescription,
			&mySwapchain,
			&myDevice,
			&feat_level,
			&myDeviceContext);
	}
#endif

	if (!myDeviceContext)
	{
		ERROR_AUTO_PRINT("%s", "Device context error, you might not have a DX11 supported grahics card");
		return false;
	}

	if (FAILED(result) || !mySwapchain || feat_level == D3D_FEATURE_LEVEL_10_0)
    {
        ERROR_AUTO_PRINT( "%s", "Device swap error, you might not have a DX11 supported grahics card" );
        return false;
    }

	SetDebugObjectName(myDeviceContext, "myDeviceContext");

    myD3dDebug = nullptr;
#ifdef _DEBUG
    if( SUCCEEDED( myDevice->QueryInterface( __uuidof( ID3D11Debug ), (void**)&myD3dDebug ) ) )
    {
        ID3D11InfoQueue *d3dInfoQueue = nullptr;
        if( SUCCEEDED( myD3dDebug->QueryInterface( __uuidof( ID3D11InfoQueue ), (void**)&d3dInfoQueue ) ) )
        {
            d3dInfoQueue->SetBreakOnSeverity( D3D11_MESSAGE_SEVERITY_CORRUPTION, true );
            d3dInfoQueue->SetBreakOnSeverity( D3D11_MESSAGE_SEVERITY_ERROR, false );

            D3D11_MESSAGE_ID hide[] =
            {
                D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS,
                // Add more message IDs here as needed
            };

            D3D11_INFO_QUEUE_FILTER filter;
            memset( &filter, 0, sizeof( filter ) );
            filter.DenyList.NumIDs = _countof( hide );
            filter.DenyList.pIDList = hide;
            d3dInfoQueue->AddStorageFilterEntries( &filter );
        }
    }
#endif

    // get the address of the back buffer
    ID3D11Texture2D *backBuffer = nullptr;
    result = mySwapchain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (LPVOID*)&backBuffer );
    INFO_PRINT( "%s", "Creating swapchain" );
    if( FAILED( result ) )
    {
        ERROR_AUTO_PRINT( "%s", "Get buffer error" );
        return false;
    }

    INFO_PRINT( "%s", "Swapchain created" );
    // use the back buffer address to create the render target
    result = myDevice->CreateRenderTargetView( backBuffer, NULL, &myBackbuffer );
    SetDebugObjectName( myBackbuffer, "myBackbuffer" );
    INFO_PRINT( "%s", "Creating RenderTargetView" );
    if( FAILED( result ) )
    {
        ERROR_AUTO_PRINT( "%s", "Render target view error" );
        return false;
    }
    backBuffer->Release();
    backBuffer = nullptr;

    //myRendertarget = aEngine.GetTextureManager().GetRendertarget(myWindowSize);

    D3D11_TEXTURE2D_DESC depthBufferDesc;
    // Initialize the description of the depth buffer.
    ZeroMemory( &depthBufferDesc, sizeof( depthBufferDesc ) );

    // Set up the description of the depth buffer.
    depthBufferDesc.Width = myWindowSize.x;
    depthBufferDesc.Height = myWindowSize.y;
    depthBufferDesc.MipLevels = 1;
    depthBufferDesc.ArraySize = 1;
	depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    depthBufferDesc.SampleDesc.Count = 1;
    depthBufferDesc.SampleDesc.Quality = 0;
    depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
    depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    depthBufferDesc.CPUAccessFlags = 0;
    depthBufferDesc.MiscFlags = 0;

    // Create the texture for the depth buffer using the filled out description.
    result = myDevice->CreateTexture2D( &depthBufferDesc, NULL, &myDepthStencilBuffer );
    INFO_PRINT( "%s", "Creating Texture2D" );
    if( FAILED( result ) )
    {
        ERROR_AUTO_PRINT( "%s", "Create tex2d error" );
        return false;
    }

    D3D11_DEPTH_STENCIL_DESC depthStencilDesc;

    // Initialize the description of the stencil state.
    ZeroMemory( &depthStencilDesc, sizeof( depthStencilDesc ) );

    // Set up the description of the stencil state.
    depthStencilDesc.DepthEnable = false;
    depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
    depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
    depthStencilDesc.StencilEnable = true;
    depthStencilDesc.StencilReadMask = 0xFF;
    depthStencilDesc.StencilWriteMask = 0xFF;
    depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
    depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
    depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
    depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
    depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
    depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
    depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
    depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

    // Create the depth stencil state.
    result = myDevice->CreateDepthStencilState( &depthStencilDesc, &myDepthStencilState );
    INFO_PRINT( "%s", "Creating DepthStencilState" );
    if( FAILED( result ) )
    {
        ERROR_AUTO_PRINT( "%s", "Depth stencil error" );
        return false;
    }

    myDeviceContext->OMSetDepthStencilState( myDepthStencilState, 1 );

    // Initialize the depth stencil view.
    D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
    ZeroMemory( &depthStencilViewDesc, sizeof( depthStencilViewDesc ) );

    // Set up the depth stencil view description.
	depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
    depthStencilViewDesc.Texture2D.MipSlice = 0;

    // Create the depth stencil view.
    result = myDevice->CreateDepthStencilView( myDepthStencilBuffer, &depthStencilViewDesc, &myDepthStencilView );
    INFO_PRINT( "%s", "Creating DepthStencilView" );
    if( FAILED( result ) )
    {
        ERROR_AUTO_PRINT( "%s", "depth stencil view error" );
        return false;
    }

    myDeviceContext->OMSetRenderTargets( 1, &myBackbuffer, myDepthStencilView );

    D3D11_RASTERIZER_DESC rasterDesc;
    // Setup the raster description which will determine how and what polygons will be drawn.
    rasterDesc.AntialiasedLineEnable = false;
	
    rasterDesc.CullMode = D3D11_CULL_NONE;
    rasterDesc.DepthBias = 0;
    rasterDesc.DepthBiasClamp = 0.0f;
    rasterDesc.DepthClipEnable = true;
    rasterDesc.FillMode = D3D11_FILL_SOLID;
    rasterDesc.FrontCounterClockwise = false;
    rasterDesc.MultisampleEnable = false;
    rasterDesc.ScissorEnable = false;
    rasterDesc.SlopeScaledDepthBias = 0.0f;

    // Create the rasterizer state from the description we just filled out.
    result = myDevice->CreateRasterizerState( &rasterDesc, &myRasterState );
    INFO_PRINT( "%s", "Creating RasterizerState" );
    if( FAILED( result ) )
    {
        ERROR_AUTO_PRINT( "%s", "Resterizer error" );
        return false;
    }

    myDeviceContext->RSSetState( myRasterState );

    D3D11_BLEND_DESC blendStateDescription;
    // Clear the blend state description.
    ZeroMemory( &blendStateDescription, sizeof( D3D11_BLEND_DESC ) );
    // Create an alpha enabled blend state description.
    blendStateDescription.RenderTarget[0].BlendEnable = TRUE;
    blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
    blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
    blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
    blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
    blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
    blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
    blendStateDescription.RenderTarget[0].RenderTargetWriteMask = 0x0f;
    result = myDevice->CreateBlendState( &blendStateDescription, &myAlphaEnableBlendingState );
    if( FAILED( result ) )
    {
        return false;
    }

    float blendFactor[4];

    // Setup the blend factor.
    blendFactor[0] = 0.0f;
    blendFactor[1] = 0.0f;
    blendFactor[2] = 0.0f;
    blendFactor[3] = 0.0f;

    // Turn on the alpha blending.
    myDeviceContext->OMSetBlendState( myAlphaEnableBlendingState, blendFactor, 0xffffffff );

	SetViewPort(0.0f, 0.0f, static_cast<float>(myWindowSize.x), static_cast<float>(myWindowSize.y));


    if( !CreateSampler() )
    {
        return false;
    }

    myTexturedQuadDrawer = new CTexturedQuadDrawer( this );
    myTexturedQuadDrawer->Init();

    myCustomShapeDrawer = new CCustomShapeDrawer( CEngine::GetInstance() );
    myCustomShapeDrawer->Init();

    myLineDrawer = new CLineDrawer( CEngine::GetInstance() );
    myLineDrawer->Init();

    myTexturedQuadBatchDrawer = new CTexturedQuadBatchDrawer( this );
    myTexturedQuadBatchDrawer->Init();

    INFO_PRINT( "%s", "All done, starting..." );
    return true;
}