Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I render a large number of waveforms drawn using ImGui's drawList only once and then use it as a cached image for display to reduce drawing resource usage? Should I use a texture with DirectX 11 and Win32, or save it as an image? #7893

Closed
Caesar454905970 opened this issue Aug 16, 2024 · 2 comments

Comments

@Caesar454905970
Copy link

Version/Branch of Dear ImGui:

Version 1.91.0

Back-ends:

imgui_impl_dx11.h+ imgui_impl_win32.cpp

Compiler, OS:

win10+dx11+win32

Full config/build information:

No response

Details:

How can I render a large number of waveforms drawn using ImGui's drawList only once and then use it as a cached image for display to reduce drawing resource usage? Should I use a texture with DirectX 11 and Win32, or save it as an image?

Screenshots/Video:

image

Minimal, Complete and Verifiable Example code:

void RenderEcgines(ImDrawList* drawList, ImVec2 windowPos, const std::vector<std::vector>& tmp_list) {
// 常量定义
constexpr double baselineOffset = 100.0;
constexpr double leadOffset = 75.0;
constexpr float lineThickness = 1.0f;
constexpr ImU32 lineColor = IM_COL32(0, 0, 0, 255); // 黑色
const double y_Translate_item = baselineOffset + InputScalar_y_line_offect;

// 计算各导联的基线平移距离
std::vector<double> leadTranslates(12);
for (int i = 0; i < 12; ++i) {
    leadTranslates[i] = leadOffset + i * y_Translate_item;
}
// 增益因子
double m_x_line_standard_gain = 1;
double m_y_line_standard_gain = 1;
// 增益因子
const double xGain = 0.25 * m_x_line_standard_gain;
const double yGain = (-1) * m_y_line_standard_gain * InputScalar_y_line_standard_gain;

// 计算窗口的高度的一部分
const float windowHeight = ImGui::GetWindowSize().y;

for (size_t i = 0; i < tmp_list.size() - 1; ++i) {
    double x1 = i * xGain;
    double x2 = (i + 1) * xGain;

    // 绘制12导联
    for (int lead = 0; lead < 12; ++lead) {
        double y1 = tmp_list[i][lead] * yGain + leadTranslates[lead];
        double y2 = tmp_list[i + 1][lead] * yGain + leadTranslates[lead];

        drawList->AddLine(
                ImVec2(static_cast<float>(x1) + windowPos.x, static_cast<float>(y1) + windowPos.y),
                ImVec2(static_cast<float>(x2) + windowPos.x, static_cast<float>(y2) + windowPos.y),
                lineColor, lineThickness);
    }

    // 绘制时间轴
    if ((i + SliderInt_model) % 500 == 0) {
        std::size_t timestamp = (i + SliderInt_model) * 2;
        std::string timestampText = convertFromTimestamp_hh_mm_ss(timestamp);

        ImFont* font = ImGui::GetFont();
        ImVec2 textSize = font->CalcTextSizeA(font->FontSize, FLT_MAX, 0.0f, timestampText.c_str());

        float lineX = static_cast<float>(x1) + windowPos.x;

        drawList->AddLine(
                ImVec2(lineX, windowPos.y + windowHeight - 5 - textSize.y),
                ImVec2(lineX, windowPos.y + windowHeight),
                lineColor, 1.0f);

        float textX = lineX - textSize.x / 2.0f;
        float textY = windowPos.y + windowHeight - 20 - textSize.y;

        drawList->AddText(ImVec2(textX + 5, textY), lineColor, timestampText.c_str());
    }
}

isSliderChanged = false;

}

@Caesar454905970
Copy link
Author

i can't save drawList to dx11 Texture

this is my test code:
//2. 渲染波形到纹理
void RenderEcginesToTexture(ImDrawList* drawList, const ImVec2& windowPos, const std::vector<std::vector>& tmp_list) {
if (!pWaveRenderTargetView) {
spdlog::error("Render target view is null.");
return;
}

g_pd3dDeviceContext->OMSetRenderTargets(1, &pWaveRenderTargetView, nullptr);

float clearColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
g_pd3dDeviceContext->ClearRenderTargetView(pWaveRenderTargetView, clearColor);

// Render ECG waveforms
RenderEcgines(drawList, windowPos, tmp_list);

// Reset render target
g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, nullptr);

// Save the texture to file
SaveTextureToFile(pWaveTexture, "waveform.png");

}

@ocornut
Copy link
Owner

ocornut commented Aug 16, 2024

Render to texture is going to be specific to your engine and backend.

This page has links about DX11 render to texture:
https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples

If you want to use ImDrawList you will need to likely create your own ImDrawData, or create another Dear ImGui Context and capture its render. See #6406 #6892 #1878 for further references.

Also see #2948 and specifically #2948 (comment) which implements the the second approach and for OpenGL.

i can't save drawList to dx11 Texture

At this point we cannot be debugging your engine/rendering code. It is frequent in graphics programming to run into issue.
Maybe RenderDoc can help you debug something.

@ocornut ocornut closed this as completed Aug 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants