Skip to content

Unable to pass two objects to ImDrawList::AddCallback() #4770

Closed
@h4k1m0u

Description

@h4k1m0u

As a follow-up to #4748, I've managed to use a custom shader to set a rectangle to a different color as explained in the example shown in #4174. While doing this I've sent my shader class instance as a 2nd argument to ImDrawList::AddCallback() and it worked fine.

Now I also want to send the texture to the same method in order to modify it. However, when I combine the shader program instance and the texture either in the same struct or in an std::pair and set AddCallback's 2nd argument to a pointer to this structure, I get a segmentation fault. I verified inside the lambda function that neither the program nor the texture were set (their ids were random), which wasn't the case when only the program shader instance was sent to the lambda function (via AddCallback).

Anyone familiar with ImDrawList has an explanation for why only a single variable could be sent as AddCallback's first argument? or maybe I should proceed differently?

  auto callback_data = std::make_pair(&m_program, &m_texture);

  ImDrawList* draw_list = ImGui::GetWindowDrawList();
  draw_list->AddCallback([](const ImDrawList* parent_list, const ImDrawCmd* cmd) {
    // function pointer based on lambda fct cannot capture variables (passed as arg below)
    auto* callback_data = static_cast<std::pair<Program*, Texture2D*> *>(cmd->UserCallbackData);
    Program* program = callback_data->first;
    Texture2D* texture = callback_data->second;
    std::cout << "texture: " << callback_data->second->id << '\n';

    // projection matrix from viewport size (`GetDrawData()`: what to render)
    ImDrawData* draw_data = ImGui::GetDrawData();
    ImVec2 position = draw_data->DisplayPos;
    ImVec2 size = draw_data->DisplaySize;
    glm::mat4 projection2d = glm::ortho(0.0f, size.x, 0.0f, size.y);
    std::cout << "position: " << position.x << " " << position.y << '\n';
    std::cout << "size: " << size.x << " " << size.y << '\n';

    // pass shaders uniforms
    Uniforms uniforms = {
      {"ProjMtx", projection2d},
      {"texture", *texture}
    };
    program->use();
    program->set_uniforms(uniforms);
  }, &callback_data);
  // }, &m_program);

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions