基于鼠标选择拖动对象Opengl [英] Drag object based on mouse selection Opengl

查看:145
本文介绍了基于鼠标选择拖动对象Opengl的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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.

推荐答案

对于2D,这里是我工作的代码 - 必须修改它一点,但希望它会给你一些想法。这个代码给你世界坐标为0 height - 如果某个东西的高度不为0,根据视角不能正确选择它。

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;

其中 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.

这篇关于基于鼠标选择拖动对象Opengl的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆