PDA

View Full Version : Drawing point using mouse click function



Chasiwpaw
02-18-2017, 06:10 PM
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 :( 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...

Silence
02-19-2017, 03:47 AM
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...

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

Vorpcho
02-19-2017, 11:56 AM
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

Chasiwpaw
02-19-2017, 12:00 PM
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

Oh....I don't think I did...I look into that :)

Chasiwpaw
02-19-2017, 06:37 PM
And where is the segmentation fault (file, line, pointer which induce this) ?
Debug your program in order to know that.


(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

Dark Photon
02-20-2017, 04:53 AM
(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

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:

* http://valgrind.org/docs/manual/mc-manual.html

Chasiwpaw
02-20-2017, 11:27 AM
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?

Chasiwpaw
02-20-2017, 11:36 AM
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

Dark Photon
02-20-2017, 04:15 PM
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\n", vertices.data() );


You can use the code snippet I listed in this post (https://www.opengl.org/discussion_boards/showthread.php/199027-Difficulties-rendering-a-3D-mesh?p=1284723&viewfull=1#post1284723) 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.

Chasiwpaw
02-20-2017, 08:07 PM
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\n", vertices.data() );


You can use the code snippet I listed in this post (https://www.opengl.org/discussion_boards/showthread.php/199027-Difficulties-rendering-a-3D-mesh?p=1284723&viewfull=1#post1284723) 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.

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?

Dark Photon
02-21-2017, 05:09 AM
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.

Chasiwpaw
02-21-2017, 08:30 PM
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.

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