Opengl: непредвиденное поведение при попытке нарисовать линию для визуализации приведения лучей мыши - PullRequest
0 голосов
/ 28 мая 2020

Я экспериментировал с преобразованием лучей, чтобы реализовать выбор мыши в моем приложении.
Я хотел буквально нарисовать линию, которая отбрасывается с экрана при щелчке мыши.
Вот что я сделал:

float xNormalised = ((float)200/w.getWidth())*2 -1;
float yNormalised = -(((float)300/w.getHeight())*2 -1);

glm::vec4 nearP = glm::vec4(xNormalised,yNormalised,-1,1);
glm::vec4 farP = glm::vec4(xNormalised,yNormalised,1,1);

Для простоты я жестко запрограммировал координаты мыши, из которых должен быть приведен луч, я сопоставляю их с нормализованными координатами устройства, а затем я создаю два вектора, представляющих две точки: точку, ближайшую к экрану, и самая дальняя точка на той же линии.

worldNear = getInversedPoint(nearP,proj, view);
worldFar = getInversedPoint(farP,proj, view);

Затем я вызываю эту функцию для каждой из точек, чтобы полностью изменить конвейер, чтобы получить их версию в мировом пространстве, вот что она делает:

glm::vec4 getInversedPoint(glm::vec4 point,glm::mat4& proj,glm::mat4 view){

    //glm::mat4 inv = inverse(proj*view);
    point = point*inverse(proj);
    auto v = vec4(point.x/point.w,point.y/point.w,point.z/point.w,1);
    //auto v = vec4(point.x/point.w,point.y/point.w,point.z/point.w,point.w);
    point = v*inverse(view);
    return vec4(point.x,point.y,point.z,point.w);
}

После этого я должен был получить две точки в мировом пространстве, если я не ошибся, поэтому я помещаю эти две точки в буфер и вызываю gldraw, чтобы нарисовать линию, соединяющую их.

Я ожидаю, что это будет красная точка в координатах, которые я поставил, потому что это прямая линия от точки щелчка до точки перед ней ... но я получаю странную линию подробнее или меньше в центре экрана, что не там, где я указал ..
Что я делаю не так?

enter image description here

Вы можете видеть красная линия в центре, рядом с боковым треугольником.
Мой вершинный шейдер:

#version 330 core

layout(location = 1)in vec4 pos;
uniform mat4 projectMat;
uniform mat4 viewMat;

void main(){
    gl_Position = pos;
} 

Я также попытался умножить точки на две матрицы, но это немного изменилось.

1 Ответ

1 голос
/ 28 мая 2020

Вы можете использовать glm :: unproject, чтобы получить дальние и ближние точки:

glm::vec3 near = glm::unProject(glm::vec3(mouseX, winSize.y - mouseY, 0), // the screen-space coordinate
                                camera.view,
                                camera.projection,
                                glm::vec4(0, 0, winSize)); // your viewport

glm::vec3 far = glm::unProject(glm::vec3(mouseX, winSize.y - mouseY, 0), // the screen-space coordinate
                               camera.view,
                               camera.projection,
                               glm::vec4(0, 0, winSize)); // your viewport

Вы также можете получить точку под мышью напрямую, прочитав фреймбуфер:

/** read depth buffer and get the point under the cursor **/
        float depth;
        glReadPixels(mouseX, winSize.y - mouseY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
        if (depth < 1.0)
            point_on_plane = glm::unProject(glm::vec3(mouseX, winSize.y - mouseY, depth), camera.view,
                                            camera.projection,
                                            glm::vec4(0, 0, winSize));

...