DirectX 11 ClearRenderTargetView Полноэкранная проблема - PullRequest
0 голосов
/ 28 ноября 2018

У меня есть приложение DirectX 11, которое отображает кадры, полученные из SDK.Моя функция clear_screen не работает (застревает в последнем кадре), когда полноэкранный режим включен путем вызова swapchain_->SetFullscreenState(TRUE, dxgi_output) после того, как я создал swapchain_.

Вот моя функция render_frame.Он вызывается в отдельном потоке, который выполняет функцию play_loop до вызова функции stop.

HRESULT xpreview::render_frame(xframe_ptr_t frame)
{
    HRESULT hr = S_OK;
    rendered_frame_count_++;

    dev_ctx_->UpdateSubresource(texture_input_, 0, nullptr, frame->buffer(), width_ * 2, 0);

    hr = vid_ctx_->VideoProcessorBlt(vid_proc_, vid_proc_output_view_, 0, 1, &stream_data_);
    if (FAILED(hr))
    {
        return hr;
    }

    if (overlay_enabled_)
    {
        text_overlay_.draw();
    }

    hr = swapchain_->Present(DXGI_SWAP_EFFECT_DISCARD, DXGI_PRESENT_DO_NOT_WAIT);

    if (overlay_enabled_)
    {
        update_overlays();
    }

    return hr;
}

void xpreview::play_loop()
{
    while (rendering_)
    {
        xframe_ptr_t frame;

        {
            std::lock_guard<std::mutex> lg(mutex_);

            if(!frame_queue_.empty())
            {
                frame = frame_queue_.front();
                frame_queue_.pop_front();
            }
        }

        if (frame_queue_.size() < queue_limit_)
        {
            wait_for_frames_.notify_one();
        }

        if (frame)
        {
            decode_drop_count_ += frame->drop_count();
            overlay_time_ += frame->additional();

            // Wait until it is time to render
            int64_t wait_time = render_start_time_ + frame->timestamp() - clock_.now();
            if (wait_time > 0)
            {
                LARGE_INTEGER li_wait_time;
                li_wait_time.QuadPart = -1 * wait_time;

                if (SetWaitableTimer(timer_, &li_wait_time, 0, nullptr, nullptr, FALSE))
                {
                    WaitForSingleObject(timer_, INFINITE);
                }
            }
            else if (drop_ && (wait_time < -100000))
            {
                dropped_frame_count_++;
                continue;
            }

            render_frame(frame);
        }
    }
}

Вот моя clear_screen функция.Я вызываю его в своей функции stop, и функция stop вызывается, когда в мой экземпляр класса не добавляются новые кадры.

void clear_screen()
{
    float bg[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
    dev_ctx_->ClearRenderTargetView(render_target_, bg);
    swapchain_->Present(DXGI_SWAP_EFFECT_DISCARD, DXGI_PRESENT_DO_NOT_WAIT);
}


void xpreview::stop()
{
    if (!rendering_)
    {
        return;
    }

    accept_frames_ = false;
    rendering_ = false;

    if (play_thread_.joinable())
    {
        play_thread_.join();
    }

    {
        std::lock_guard<std::mutex> lg(mutex_);
        frame_queue_.clear();
    }

    clear_screen();
}

Кроме того, я использую библиотеку DirectXTk для наложения некоторого текста поверхкадры.Когда я включаю оверлей, clear_screen работает неожиданно.Эта библиотека исправляет некоторые вещи, которые я неправильно установил раньше?Я использую код ниже, чтобы нарисовать строку;

void text_overlay::draw()
{
    sprite_batch_->Begin();

    DirectX::SimpleMath::Vector2 origin = sprite_font_->MeasureString(text_.c_str());
    origin.x = 0;
    origin.y = 0;
    sprite_font_->DrawString(sprite_batch_.get(), text_.c_str(), font_pos_, DirectX::Colors::Yellow, 0.f, origin);

    sprite_batch_->End();
}
...