Nelarius / imnodes

A small, dependency-free node editor for dear imgui
MIT License
1.97k stars 241 forks source link

Link isn't showing. #132

Open Wynter-del opened 2 years ago

Wynter-del commented 2 years ago

I've followed the brief tour for ImNodes and tried to get the node links showing up but no matter what I do nothing works. I've tried debugging the code as much as I can and the link pair does get put into memory, but for whatever reason no curve appears between the two nodes.

I'm struggling to understand what is going wrong here. My code is essentially a copy+paste from the readme file, so I'd expect it to work by default. If anyone knows what the problem is it'd be a huge help.

Here is what I have: `

        ImGui::Begin("Graph");

    ImNodes::BeginNodeEditor();

    const int inputNode_id = 0;
    const int inputNode_attrib_id = 1;
    const int outputNode_id = 2;
    const int outputNode_attrib_id = 3;

    ImNodes::BeginNode(inputNode_id);
    ImNodes::BeginInputAttribute(inputNode_attrib_id);
    ImGui::Text("pin");
    ImNodes::EndInputAttribute();
    ImNodes::EndNode();

    ImNodes::BeginNode(outputNode_id);
    ImNodes::BeginOutputAttribute(outputNode_attrib_id);
    ImGui::Text("pin");
    ImNodes::EndOutputAttribute();
    ImNodes::EndNode();

    ImNodes::EndNodeEditor();

    std::vector<std::pair<int, int>> links;
    for (int i = 0; i < links.size(); ++i)
    {
        const std::pair<int, int> p = links[i];
        ImNodes::Link(i, p.first, p.second);
    }

    int start_attr, end_attr;
    if (ImNodes::IsLinkCreated(&start_attr, &end_attr))
    {
        links.push_back(std::make_pair(start_attr, end_attr));
    }

    ImGui::End();

`

brukted commented 2 years ago

You are calling ImNodes::Link(...) after ImNodes::EndNodeEditor()

Wynter-del commented 2 years ago

I've tried putting ImNodes::Link before EndNodeEditor, and that still does not work. I've tried various orders of some of the lines to see what might work and I've not come across anything that is correct.

brukted commented 2 years ago

If std::vector<std::pair<int, int>> links; is inside your draw function it should be static otherwise the link would be drawn for only one frame.

Wynter-del commented 2 years ago

I don't get what's going wrong here. When I click and drag from a node, the bezier is rendered from the point to my mouse but the moment I drag to the other point and let go the line stops being rendered (the two "int start_attr, end_attr" values update to have the correct value for each node Id). I know in the examples that SDL is being used and I'm using GLFW+OpenGl, I can't imagine that is causing problems but I want to point it out just encase.

I really just want to get this up and running as fast as possible as ImNodes seems extremely promising and useful for my project over some of the other node based extensions for ImGui.

Here's my entire main while loop for context: The rest of the code outside this loop is purely done to set up ImGui+GLFW/OpenGl to render out to the GPU, so besides from the basic ImNodes::CreateContext(); ImNodes::DestroyContext(); lines I don't touch ImNodes other than inside the main loop.

while (!glfwWindowShouldClose(window)) {
//I'm using a namespace for "std" and "ImGui"

ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
NewFrame();

glUseProgram(shaderProgram);
glBindVertexArray(VAO);

Begin("Graph");

ImNodes::BeginNodeEditor();

const int inputNode_id = 0;
const int inputNode_attrib_id = 1;
const int outputNode_id = 2;
const int outputNode_attrib_id = 3;

ImNodes::BeginNode(inputNode_id);
ImNodes::BeginInputAttribute(inputNode_attrib_id);
Text("pin");
ImNodes::EndInputAttribute();
ImNodes::EndNode();

ImNodes::BeginNode(outputNode_id);
ImNodes::BeginOutputAttribute(outputNode_attrib_id);
Text("pin");
ImNodes::EndOutputAttribute();
ImNodes::EndNode();

vector<pair<int, int>> links; 
for (int i = 0; i < links.size(); ++i) {
    const pair<int, int> p = links[i];
    ImNodes::Link(i, p.first, p.second);
    }

ImNodes::EndNodeEditor();

int start_attr, end_attr;
if (ImNodes::IsLinkCreated(&start_attr, &end_attr)) {
    links.push_back(std::make_pair(start_attr, end_attr));
    }

End();

glUseProgram(shaderProgram);

Render();
ImGui_ImplOpenGL3_RenderDrawData(GetDrawData());

glfwSwapBuffers(window);
glfwPollEvents();
}
Green-Sky commented 2 years ago

If std::vector<std::pair<int, int>> links; is inside your draw function it should be static otherwise the link would be drawn for only one frame.

I will reword this for you @Wynter-del. The vector of links is RECREATED each frame, empty. Then you render the links, which are ofc none, since the vector just got created (still empty). The vector is destroyed at the end of the loop iteration. The Solution is simple, just move the links vector outside of the loop. :+1: