• Tasks 2,3: when no update is observed, this is often due to leaving createObjects in the main loop
    and so re-initialize/overwrite correctly changed with the original hardcoded values.
    In the pick... function, consider updating Vertices (keeping the old value for restoration) and the buffer (VBO: bind, update, unbind).
    When the mouse is released, reverse.
  • By default webGL applies a color gradient at the boundary of large points. When you click near the boundary, a wrong color may be returned.


  • webGL The openGL example uses xpos, ypos as mouse coordinates. Confusingly, xpos, ypos in the webGL code are world coordinates. Rename them as world_x and world_y.

  • In openGL on high resolution devices such as a mac with Retina display, size of the buffer is automatically scaled (typically 2x). However, the mouse input coordinates are not scaled.
    The following code gives correct read pixel values on such devices.
    int bufferWidth; int bufferHeight; int currWidth; int currHeight;

    glfwGetFramebufferSize(window, & bufferWidth, & bufferHeight);
    glfwGetWindowSize(window, & currWidth, & currHeight);

    glReadPixels(xpos*(bufferWidth/currWidth), (currHeight - ypos)*(bufferHeight/currHeight), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);

  • The mac compiler is picky and expects a Vertex casting. Try inserting (Vertex) as in
    = (Vertex) {{ x, y, z, w},...

  • see glm::unProject which is slightly different from gluUnproject.

  • Always bind the buffer that you want to work on, before any buffer access. -- This avoid altering the wrong buffer.
    If you want to know more

  • Q: I selected the index correctly, saved the old color to be able to restore it and checked that I replaced the selected index color by white in Vertices. But colors do not update.
    A: The color information is now correct on the CPU and needs to be transmitted to the GPU via a buffer. As always the buffer needs to bound and updated before the rendering.

  • Orthogonal projection simplifies the picking. Use it. The picking pass and the visible display pass should use the same projection.

  • The shader code must know the size of any array sent to it.
    Think of a sender/receiver model for data transfer.
    Think of VBO as a parcel and VAO a letter that explains the contents of the parcel.
    uniform variables are shared by all instances of a vertexshader or fragmentshader

  • Make sure you have the proper logic:
    when your pointer is at the location that returns the (color=) index
    then you change the rgba of that index (but save the old one!)
    and, while the left_mouse_button is pressed,
    track the xpos, ypos of the pointer to update the xyzw of that index, too


  • Q: I have been messing around trying to get the callback function to work using "GLUT"
    A: Project 1A uses glfw, not glut and has already many working examples
    https://www.glfw.org/docs/3.3.2/input_guide.html#input_mouse_button

  • Q: how to get the world coordinates from the xpos,ypos
    See Remark in the project description right under the images.
    Maybe https://dondi.lmu.build/share/cg/unproject-explained.pdf (but that is already too much detail)

  • Q: when I add one point, index and color in the three arrays in the .cpp file, I do not get the number "4" returned when I click on the point
    A: constants are evil in programming.
    Fortunately, most of the Project 1A scaffold code avoids constants and therefore your scaffold code almost works when you make the obvious additions: remarkably you see the 5th point.
    Now you search where "4" occurs in the Project 1A files you downloaded.
    data[4] makes perfect sense (because is corresponds to a 2x2 picking footprint),
    vec4 should certainly not become vec5,
    ...
    good luck hunting! (Check the shaders, too)

  • Q: unproject flips the x-coordinate. Why?
    not 100% sure, but likely due to keeping a right hand coordinate system when interpreting depth
    (Justin: initOpenGL() creates the gViewMatrix with camera origin at (0, 0, -5) viewing the scene from behind the screen.
    glm::unProject expects input as "viewMatrix*modelMatrix"
    one could: multiply the view matrix with the modelMatrix for unprojection or replace -5 with 5 in the ViewMatrix initialization)
    (alternative) I think its because the viewpoint is from below rather than from above if I set the camera to glm::vec3(0, 0, 5) rather than glm::vec3(0, 0, -5) the x-coord is fixed
    yes, keeping the coord system right handed can be achieved by the x-flip or looking from the opposite z-direction.

  • Q: are random colors acceptable?
    A: yes

  • Q: ... submitting the modified source files. I am assuming only those files. Is that true?
    A: at most 5 files. If you only modified 2, submit 2.