简体   繁体   中英

Drag object based on mouse selection Opengl

What would I need to do in order to select an object with the mouse in OpenGL? I found something like selection buffer but I also read some where that it was depreciated. So I'm stuck and do not know what to look for. Also I'm using C++ do to do this.

For 2D, here's the code I have working -- you'll have to modify it a bit, but hopefully it will give you some ideas. This code gives you the world coordinates at "0 height" -- if something doesn't have 0 height, this may not select it properly depending on perspective.

// for the current mouse position on the screen, where does that correspond to in the world?
glm::vec2 World::world_position_for_mouse(const glm::vec2 mouse_position,
                                          const glm::mat4 projection_matrix,
                                          const glm::mat4 view_matrix) 
{
    int window_width;
    int window_height;
    this->graphics.get_window_dimensions(window_width, window_height);

    const int mouse_x = mouse_position[0];
    const int mouse_y = mouse_position[1];

    // normalize mouse position from window pixel space to between -1, 1
    GLfloat normalized_mouse_x =  (2.0f * mouse_x) / window_width - 1.0f;
    float normalized_mouse_y = 1.0f - (2.0f * mouse_y) / window_height;


    glm::vec3 normalized_mouse_vector = glm::vec3(normalized_mouse_x, normalized_mouse_y, 1.0f);

    glm::vec4 ray_clip = glm::vec4(normalized_mouse_vector.xy(), -1.0, 1.0);

    glm::vec4 ray_eye = glm::inverse(projection_matrix) * ray_clip;
    ray_eye = glm::vec4(ray_eye.xy(), -1.0, 0.0);

    glm::vec3 ray_world = (glm::inverse(view_matrix) * ray_eye).xyz();

    ray_world = glm::normalize(ray_world);

    float l = -(camera.z / ray_world.z);


    return {camera.x + l * ray_world.x, camera.y + l * ray_world.y};
}

To pan the world by the same "screen units" regardless of zoom, I use this code based on the results of the code above:

    float camera_motion = time.get_wall_clock_delta() * camera_motion_per_second;
    auto x1 = this->world_position_for_mouse(glm::vec2(1,0), this->cached_projection_matrix, this->cached_view_matrix).x;
    auto x2 = this->world_position_for_mouse(glm::vec2(0,0), this->cached_projection_matrix, this->cached_view_matrix).x;
    auto camera_change = (x1 - x2) * camera_motion;

where camera_motion is just a multiplier on how fast you want it to move combined with the time delta from the previous frame. Basically the further zoomed out you are, the faster this scrolls you per second. Whatever pixel is on the right edge of your window will take a constant time to get to the left edge regardless of zoom.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM