2015-02-11 3 views
0

Я пытаюсь создать луч из моего местоположения мыши в 3D-пространство, и, видимо, для этого мне нужно «UnProject()».Непроектированные координаты мыши находятся между 0-1

Выполнение этого даст мне значение от 0 & 1 для каждой оси.

Этот не может быть прав для рисования «Луч» или линии из окна просмотра, не так ли? Все это, в основном, зависит от моей мыши от размера видового экрана.

Если это на самом деле правильно, то я не понимаю следующее:

  • рисую треугольники, которые имеют вершины, которые не затрудненной от 0-1, а они являются координатами, как (0,100,0), (100,000,0), (100,0,0), И эти ничьи отлично выглядят
  • Но также, рисуя вершины, которые непроектированы из координат моей мыши как линии/точки также отлично рисуют хорошо.
  • Как я мог бы сравнить мои координаты мыши с координатами моих объектов?

Если это действительно так, то что может вызвать такую ​​ошибку? Я попытался непроектировать вершины моего собственного объекта, и они не ограничены 0-1. Я не знаю, совместим ли я с моими проекциями, когда рендеринг совместим с gluUnproject. Я просто делаю это так, как эти учебники здесь показать его (около дна): http://qt-project.org/wiki/Developer-Guides#28810c65dd0f273a567b83a48839d275

Это способ, которым я пытаюсь получить мою мышь координаты:

GLdouble modelViewMatrix[16]; 
GLdouble projectionMatrix[16]; 
GLint viewport[4]; 
GLfloat winX, winY, winZ; 
glGetDoublev(GL_MODELVIEW_MATRIX, modelViewMatrix); 
glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix); 
glGetIntegerv(GL_VIEWPORT, viewport); 

winX = (float)x; 
winY = (float)viewport[3] - (float)y; 
glReadPixels(winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ); 

GLdouble nearPlaneLocation[3]; 
gluUnProject(winX, winY, 0, modelViewMatrix, projectionMatrix, 
      viewport, &nearPlaneLocation[0], &nearPlaneLocation[1], 
     &nearPlaneLocation[2]); 

GLdouble farPlaneLocation[3]; 
gluUnProject(winX, winY, 1, modelViewMatrix, projectionMatrix, 
      viewport, &farPlaneLocation[0], &farPlaneLocation[1], 
     &farPlaneLocation[2]); 

QVector3D nearP = QVector3D(nearPlaneLocation[0], nearPlaneLocation[1], 
     nearPlaneLocation[2]); 
QVector3D farP = QVector3D(farPlaneLocation[0], farPlaneLocation[1], 
     farPlaneLocation[2]); 

Возможно, мои фактические прогнозы выключены?

void oglWidget::paintGL() 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    QMatrix4x4 mMatrix; 
    QMatrix4x4 vMatrix; 

    QMatrix4x4 cameraTransformation; 
    cameraTransformation.rotate(alpha, 0, 1, 0); 
    cameraTransformation.rotate(beta, 1, 0, 0); 

    QVector3D cameraPosition = cameraTransformation * QVector3D(camX, camY, distance); 
    QVector3D cameraUpDirection = cameraTransformation * QVector3D(0, 1, 0); 
    vMatrix.lookAt(cameraPosition, QVector3D(camX, camY, 0), cameraUpDirection); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    gluLookAt(cameraPosition.x(), cameraPosition.y(), cameraPosition.z(), camX, camY, 0, cameraUpDirection.x(), cameraUpDirection.y(), cameraUpDirection.z()); 
    shaderProgram.bind(); 
    shaderProgram.setUniformValue("mvpMatrix", pMatrix * vMatrix * mMatrix); 
    shaderProgram.setUniformValue("texture", 0); 


    for (int x = 0; x < tileCount; x++) 
    { 
     shaderProgram.setAttributeArray("vertex", tiles[x]->vertices.constData()); 
     shaderProgram.enableAttributeArray("vertex"); 
     shaderProgram.setAttributeArray("textureCoordinate", textureCoordinates.constData()); 
     shaderProgram.enableAttributeArray("textureCoordinate"); 

     //Triangle Drawing 
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tiles[x]->image.width(), tiles[x]->image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tiles[x]->image.bits()); 
     glDrawArrays(GL_TRIANGLES, 0, tiles[x]->vertices.size()); 
    }  

    shaderProgram.release(); 

} 

Где, как, pMatrix является матрица 4х4, контролируется во время изменения размера событий, как:

pMatrix.setToIdentity(); 
pMatrix.perspective(fov, (float) width/(float) height, 0.001, 10000); 
glViewport(0, 0, width, height); 

и моей вершинных шейдеров устанавливается следующим образом:

uniform mat4 mvpMatrix; 

in vec4 vertex; 
in vec2 textureCoordinate; 

out vec2 varyingTextureCoordinate; 

void main(void) 
{ 
    varyingTextureCoordinate = textureCoordinate; 
    gl_Position = mvpMatrix * vertex; 
} 
+0

Для чего вы используете этот луч? Вы уже прочитали буфер глубины назад (это хранит окно-пространство Z), поэтому вы можете UnProject координаты вашей мыши и получить точную позицию в пространстве объектов. –

+0

пересечение линии/треугольника. Точки моего луча, по-видимому, лежат на экране, так как возвращаемые значения находятся между 0-1 (например, 0,003x, -0,5y, 0z). У моих объектов, с другой стороны, есть вершины, которые не ограничены этим. – Yattabyte

+0

Координаты в диапазоне [0-1] действительно не описывают пространство экрана (это пространство координат, где 1 единица равна размеру 1 пиксель). Не часто вы рисуете в окне просмотра 1x1;) Эти координаты больше соответствуют линиям координат нормализованных устройств (которые имеют диапазон [-1,1]). Это говорит мне о том, что вы неправильно применяете преобразование видового экрана, но я не знаю, почему. –

ответ

0

Часть моей проблемы здесь плохо описывала ее. Я случайно оставил остаточный код из-за отчаянного тестирования, в результате чего были обнаружены фрагменты функций «read Pixel» и связанных с ними глупостей, которые не были полезны для решения проблемы.

Остальная часть моей проблемы возникла из-за несогласованных типов данных для матриц и пытается вытащить матрицы из OpenGL, когда они никогда не хранили их в первую очередь.

Проблема была решена путем:

  • Using GLM to hold all my matrices
  • выполняя расчеты себя (обратная матрица вид * инверсная модель матрицы * обратная матрица проекции) * векторный холдинг НДЦ преобразован экран пространственные координаты (диапазон от -1 до 1: x или y, деленное на ширину или высоту, * 2 - 1), которое также имеет az -1 или 1 для дальних или ближайших плоскостей, а aw равно 1.
  • Разделить результат на четвертое место вектор.

Я до сих пор не знаю, почему непроект не работает для меня, так как я получил неправильные результаты с GLU, а также функцию unproject GLM, но это вручную работало для меня.

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

0

glReadPixels принимает целые числа (x и y), и вы, кажется, не используете winZ по какой-либо причине в gluUnProject.

Попробуйте так:

gluUnProject(winX, winY, winZ, glView, glProjection, viewport, &posX, &posY, &posZ); 

Кроме того, если вы хотите, чтобы остановить луч, когда он встречает что-то в буфер глубины, то не очистить буфер глубины после рендеринга. Если вы сделаете glClear (GL_DEPTH_BUFFER_BIT), луч должен зайти так далеко, как вы установили в своей проекционной матрице.

Я также не знаю, почему вам нужно позвонить ему более одного раза. Последние три поплавка будут целевым вектором, и вы можете просто использовать положение вашей камеры в качестве источника луча (в зависимости от того, что вы делаете).

+0

2 глубины (и 2 непроекта) связаны с тем, что я должен (как изображали другие методы) получить 2 точки в пространстве на ближней и дальней плоскости проекции, чтобы провести линию между ними, которая тогда используется для пересечения линии/треугольника («Выбор луча») – Yattabyte

+0

Но вы не используете результат (float) из glReadPixels. – Rebirth