Drawing point using mouse click function

I want to be able to display points on the position that I clicked on. However, I get the error saying “segmentation fault(core dumped)” when I click on the window…

Here’s how I setup my buffer and array

//Setup vertex data, buffers and attribute pointers
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * vertices.size(), vertices.data(), GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind

    glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs), remember: do NOT unbind the EBO, keep it bound to this VAO

This is the callback function:

void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
{
    if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE){

        //Prints the (x,y) coordinate of the clicked position
        double posX, posY;
        glfwGetCursorPos(window, &posX, &posY);
        std::cout << "(x,y) coordinates are: "<< posX << " " << posY << std::endl;

        //Generate 3D vector point
        int width, height;
		glfwGetWindowSize(window, &width, &height);
        float x = -1.0f + 2 * posX / width;
        float y = +1.0f - 2 * posY / height;
        glm::vec3 newPoint = glm::vec3(x, y, 1.0f);
        std::cout << "X: " << x << std::endl;
        std::cout << "Y: " << y << std::endl;
        //Store vector point into vector array
        vertices.push_back(newPoint);
        int verticeSize = vertices.size();
        std::cout << verticeSize << std::endl;
    }
}

And here’s my while loop that draws the point:

while (!glfwWindowShouldClose(window))
    {
        // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions
        glfwPollEvents();

        // Render
        // Clear the colorbuffer
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        //Draw points
        glUseProgram(shaderProgram);
        glBindVertexArray(VAO);
        glPointSize(10);
        glDrawArrays(GL_POINTS, 0, vertices.size());
        glBindVertexArray(0);

        // Swap the screen buffers
        glfwSwapBuffers(window);
    }

If anyone can point me out to the right direction…It’d be great :frowning: I spent like 8 hours on it and can’t seem to find what’s wrong… Although if I remove the VAO, the program works…it only draws one point at the origin…

And where is the segmentation fault (file, line, pointer which induce this) ?
Debug your program in order to know that.

Are you updating your VBO’s after adding the new point?
You give it a size of vertices.size(), but then later you push an additional point into the “vertices” vector thus changing its size

[QUOTE=Vorpcho;1286005]Are you updating your VBO’s after adding the new point?
You give it a size of vertices.size(), but then later you push an additional point into the “vertices” vector thus changing its size[/QUOTE]

Oh…I don’t think I did…I look into that :slight_smile:

[QUOTE=Silence;1285995]And where is the segmentation fault (file, line, pointer which induce this) ?
Debug your program in order to know that.[/QUOTE]

(gdb) run
Starting program: /home/andrew/C++/Assignment/main 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Starting GLFW context, OpenGL 3.3
(x,y) coordinates are: 462 358
X: 0.155
Y: 0.105
1

Program received signal SIGSEGV, Segmentation fault.
0x00000000400a1f7f in ?? ()

After spending several hours, I was able to compile and use gdb to have it show some information about the segmentation fault…but I still have no idea what is happening

[QUOTE=Chasiwpaw;1286009]

(gdb) run
Starting program: /home/andrew/C++/Assignment/main 
...
Program received signal SIGSEGV, Segmentation fault.
0x00000000400a1f7f in ?? ()

After spending several hours, I was able to compile and use gdb to have it show some information about the segmentation fault…but I still have no idea what is happening[/QUOTE]

Inside gdb, after you “run” your problem and it crashes, type “where”. That’ll give you a stack trace of where you are when your program crashes.

For more debug information in your stack trace, make sure you compile your program with the “-g” option fed to the compiler (gcc or g++).

It’s likely that there’s a memory problem in your application that you need to find. Running valgrind on your application may give you some clues as to what that is. After you’ve compiled your application with debug info (-g), run:


valgrind /home/andrew/C++/Assignment/main

This will emit a list of things you’re doing that look suspicious to valgrind (e.g. trying to free unallocated memory, trying to read past the end of an array, etc.) along with stack traces for each. For more information on valgrind, see:

I’ve tried to debug the segmentation fault with the command where and it displays this:


(gdb) where
#0  0x00000000400a1f7f in ?? ()
#1  0x00007ffff38a56e4 in ?? ()
   from /usr/lib/nvidia-367/libnvidia-glcore.so.367.57
#2  0x00007ffff38aa8f8 in ?? ()
   from /usr/lib/nvidia-367/libnvidia-glcore.so.367.57
#3  0x00007ffff3490a28 in ?? ()
   from /usr/lib/nvidia-367/libnvidia-glcore.so.367.57
#4  0x0000000000404f06 in main () at /home/andrew/C++/Assignment/main.cpp:155

I assume that it means that my error is at line 155, which is where I call the glDrawArrays

glDrawArrays(GL_POINTS, 0, vertices.size());

Does that mean it is related to the way I update my VBO just like Vorpcho has mentioned?

I’ve also checked with valgrind, but for some reason I cannot post the log here. It also mentions that the error is at line 155

What this nearly always indicates (a crash in a glDraw* call) is that you’ve asked OpenGL to go dereference a NULL (or bad pointer) somehow. Either through your vertex attribute bindings or your index list bindings. You’re using glDrawArrays, so there is no index list.

You can try to ensure that the problem is with your glDrawArrays call or something it has to reference like vertex arrays by (for testing only) putting a glFinish() right before your glDrawArrays(). If it still crashes in glDrawArrays(), then it problably is.

From what you’ve posted, the source of this bad pointer isn’t obvious. Try printing out the pointer value of vertices.data() before you call glBufferData(), and make sure it’s not NULL:


printf( "vertices.data() = %p
", vertices.data() );

You can use the code snippet I listed in this post to query your vertex attribute and index bindings right before your draw call to make sure they look reasonable.

Finally, are you sure that your shaderProgram is linked and set up properly? What happens if you change this to glUseProgram(0)?

If all else fails, post a short stand-alone test program that reproduces the problem, and you might get more feedback.

[QUOTE=Dark Photon;1286030]What this nearly always indicates (a crash in a glDraw* call) is that you’ve asked OpenGL to go dereference a NULL (or bad pointer) somehow. Either through your vertex attribute bindings or your index list bindings. You’re using glDrawArrays, so there is no index list.

You can try to ensure that the problem is with your glDrawArrays call or something it has to reference like vertex arrays by (for testing only) putting a glFinish() right before your glDrawArrays(). If it still crashes in glDrawArrays(), then it problably is.

From what you’ve posted, the source of this bad pointer isn’t obvious. Try printing out the pointer value of vertices.data() before you call glBufferData(), and make sure it’s not NULL:


printf( "vertices.data() = %p
", vertices.data() );

You can use the code snippet I listed in this post to query your vertex attribute and index bindings right before your draw call to make sure they look reasonable.

Finally, are you sure that your shaderProgram is linked and set up properly? What happens if you change this to glUseProgram(0)?

If all else fails, post a short stand-alone test program that reproduces the problem, and you might get more feedback.[/QUOTE]

Yeah…vertices.data() prints out as null. My vector only receive new data after I trigger a mouse-click callback…however I am not sure how to have my VBO draw only once the vector is not null…I have been searching for answers and it seems that I need to use glMapBuffer…let me know whether I’m going in the right direction and if not, what should I be looking for?

I’m not sure why you’d need to use glMapBuffer versus glBufferData to upload your data. I don’t think it makes any difference.

A suggestion: Have an “is populated” or “is valid” flag for your model. When you go to draw, if this is false, skip it. When you finally load the model in and create/populate the VBOs/VAO, then set “is populated” (or “is valid”) to true.

In fact, you could actually use the VAO (or VBO) handle as your “is valid” flag. When these are 0 (which are null handle values that won’t ever be returned by glGen{Buffers,Arrays}), then you can treat that as “is valid” == false.

[QUOTE=Dark Photon;1286039]I’m not sure why you’d need to use glMapBuffer versus glBufferData to upload your data. I don’t think it makes any difference.

A suggestion: Have an “is populated” or “is valid” flag for your model. When you go to draw, if this is false, skip it. When you finally load the model in and create/populate the VBOs/VAO, then set “is populated” (or “is valid”) to true.

In fact, you could actually use the VAO (or VBO) handle as your “is valid” flag. When these are 0 (which are null handle values that won’t ever be returned by glGen{Buffers,Arrays}), then you can treat that as “is valid” == false.[/QUOTE]

I’ve tried setting an if statement to make sure that whenever I call glDrawArrays, there’s atleast something inside the vertices. I am not sure what you meant by isPopulated/isValid statement for both the VBO/VAO. However, here’s my github link that has the code inside:

https://github.com/Chasiwpaw/OpenGL