DirectX 直方图效果不会产生输出图像,局部边界矩形为 { 0, 0, 0, 0 }

问题描述 投票:0回答:1

我想演示直方图效果,但输出为空我尝试过软件类型和硬件类型渲染目标,但结果是相同的。如果需要的话,我还尝试确保效果的输入位图与垃圾箱的宽度相同。 EndDraw()后没有报hr错误。

直方图效果还需要其他东西吗?或者这段代码中有什么东西需要修复吗?

bool Display_Demo_Effect(ID2D1RenderTarget *arg_render_tgt, CLSID arg_clsid = CLSID_D2D1Histogram)
{
    // DBG_TRACKER_FUNCTION_NAME_T;

    if (!arg_render_tgt) { return false; }

    if (arg_clsid == CLSID_NULL) { return false; }

    CComPtr<ID2D1DeviceContext>      ccptr_dvctxt = nullptr;
    CComPtr<ID2D1BitmapRenderTarget> ccptr_bitmap_tgt = nullptr;
    CComPtr<ID2D1SolidColorBrush>    ccptr_brush_sc = nullptr;
    CComPtr<ID2D1Bitmap>             ccptr_bitmap = nullptr;
    CComPtr<ID2D1Effect>             ccptr_demo_effect = nullptr;

    HRESULT hr = S_OK;

    bool alt_bmp_method = false;

    arg_render_tgt->QueryInterface(&ccptr_dvctxt);

    if (!ccptr_dvctxt) { /* Error Message */ return false; }

    if (alt_bmp_method)
    {
        // Match the default bins count
        D2D1_SIZE_F des_sz_f = { 256.0f, 256.0f };

        D2D1_SIZE_U des_sz_u = { 256, 256 };

        hr = ccptr_dvctxt->CreateCompatibleRenderTarget(des_sz_f, des_sz_u, &ccptr_bitmap_tgt);
    }
    else
    {
        // Default creation method
        hr = ccptr_dvctxt->CreateCompatibleRenderTarget(&ccptr_bitmap_tgt);
    }

    if (FAILED(hr)) { /* Error Message */ return false; }

    D2D1_COLOR_F demo_colr = { 0.45f, 0.56f, 0.72f, 0.66f };
    
    D2D1_COLOR_F clr_colr  = { 0.5f, 0.5f, 0.5f, 1.0f };

    D2D1_ELLIPSE demo_ellipse = D2D1::Ellipse
    (
        D2D1::Point2F(128.0f, 128.0f),
        100.0f,
        100.0f
    );

    hr = ccptr_bitmap_tgt->CreateSolidColorBrush(demo_colr, &ccptr_brush_sc);

    if (FAILED(hr)) { /* Error Message */ return false; }

    // Draw an Ellipse on the bitmap
    ccptr_bitmap_tgt->BeginDraw();

    hr = ccptr_bitmap_tgt->Flush();
    
    ccptr_bitmap_tgt->Clear( {0.0f, 0.0f, 0.0f, 0.0f} );
    
    ccptr_bitmap_tgt->FillEllipse(&demo_ellipse, ccptr_brush_sc);
    
    hr = ccptr_bitmap_tgt->EndDraw();

    if (FAILED(hr)) { /* Error Message */ return false; }

    // Expose the bitmap
    ccptr_bitmap_tgt->GetBitmap(&ccptr_bitmap);

    if (FAILED(hr)) { /* Error Message */ return false; }

    hr = ccptr_dvctxt->CreateEffect(arg_clsid, &ccptr_demo_effect);

    if (FAILED(hr)) { /* Error Message */ return false; }
    
    // Configure the effect's input
    ccptr_demo_effect->SetInput(0, ccptr_bitmap);

    // Special considerations for Histogram
    if (arg_clsid == CLSID_D2D1Histogram)
    {
        UINT32 parm_bins = 256;

        ccptr_demo_effect->SetValue(D2D1_HISTOGRAM_PROP_NUM_BINS, parm_bins);

        ccptr_demo_effect->SetValue(D2D1_HISTOGRAM_PROP_CHANNEL_SELECT, D2D1_CHANNEL_SELECTOR_G);

        D2D1_RECT_F inp_local_rc = { 0.0f };
        D2D1_RECT_F out_local_rc = { 0.0f };

        D2D1_SIZE_F inp_sz = { 0.0f };
        D2D1_SIZE_F out_sz = { 0.0f };

        CComPtr<ID2D1Image>  ccptr_inp_image = nullptr;
        CComPtr<ID2D1Image>  ccptr_out_image = nullptr;

        ccptr_demo_effect->GetInput(0, &ccptr_inp_image);
        ccptr_demo_effect->GetOutput(&ccptr_out_image);
        
        // Display the input image local bounds
        if (ccptr_inp_image)
        {
            hr = ccptr_dvctxt->GetImageLocalBounds(ccptr_inp_image, &inp_local_rc);

            inp_sz = 
            { 
                fabsf(inp_local_rc.right  - inp_local_rc.left), 
                fabsf(inp_local_rc.bottom - inp_local_rc.top) 
            };

            // DisplayRC_Via_MsgBox(inp_local_rc);
            // DisplaySZ_Via_MsgBox(inp_sz);
        }

        if (ccptr_out_image)
        {
            hr = ccptr_dvctxt->GetImageLocalBounds(ccptr_out_image, &out_local_rc);

            out_sz =
            {
                fabsf(out_local_rc.right  - out_local_rc.left),
                fabsf(out_local_rc.bottom - out_local_rc.top)
            };

            // DisplayRC_Via_MsgBox(out_local_rc);
            // DisplaySZ_Via_MsgBox(out_sz);
        }
    }

    // Prove the dvctxt and input bitmap are valid
    ccptr_dvctxt->BeginDraw();
    hr = ccptr_dvctxt->Flush();
    ccptr_dvctxt->Clear(clr_colr);
    ccptr_dvctxt->DrawImage(ccptr_bitmap);
    hr = ccptr_dvctxt->EndDraw();

    if (FAILED(hr)) { /* Error Message */ return false; }

    Sleep(3000);

    // Display the Effect: nothing is drawn
    ccptr_dvctxt->BeginDraw();
    hr = ccptr_dvctxt->Flush();
    ccptr_dvctxt->Clear(clr_colr);
    ccptr_dvctxt->DrawImage(ccptr_demo_effect);
    hr = ccptr_dvctxt->EndDraw();

    // No failure even though nothing is displayed

    if (FAILED(hr)) { /* Error Message */ return false; }

    Sleep(3000);

    // Clear the window
    ccptr_dvctxt->BeginDraw();
    hr = ccptr_dvctxt->Flush();
    ccptr_dvctxt->Clear( {0.0f, 0.0f, 0.0f, 0.0f} );
    hr = ccptr_dvctxt->EndDraw();

    return true;
}

此代码适用于除直方图效果之外的单一输入效果。 ChatGPT 只是重复 MSDN 示例上的相同代码;但是它确实提到要在此处检查堆栈溢出。我无法使用谷歌搜索找到 CLSID_D2D1Histogram 的任何其他示例。我尝试确保渲染目标是硬件类型和功能级别 10 或软件类型,但结果是相同的;输出图像局部边界矩形为 {0} 并且不显示任何内容

c++ winapi histogram directx direct2d
1个回答
0
投票

Direct2D 直方图效果不输出任何图像,它构建一个浮点数数组,您可以从效果的D2D1_HISTOGRAM_PROP_HISTOGRAM_OUTPUT属性

获取该数组
d2dContext->CreateEffect(CLSID_D2D1Histogram, &histogramEffect);
histogramEffect->SetInputEffect(0, ... SomeInput ... );
d2dContext->BeginDraw();
d2dContext->DrawImage(histogramEffect.Get());
d2dContext->EndDraw();

// The histogram data is only available once the effect has been 'drawn'.
int histogramBinCount;
histogramEffect->GetValue(D2D1_HISTOGRAM_PROP_NUM_BINS, &histogramBinCount);

auto histogramData = new float[histogramBinCount];
histogramEffect->GetValue(D2D1_HISTOGRAM_PROP_HISTOGRAM_OUTPUT, 
                           reinterpret_cast<BYTE*>(histogramData), 
                           histogramBinCount * sizeof(float));
© www.soinside.com 2019 - 2024. All rights reserved.