Координаты не спроецированной мыши находятся в диапазоне 0-1

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

Это даст мне значение между 0 & 1 для каждой оси.

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

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

  • Я рисую треугольники с вершинами не ограничены 0-1, скорее они являются координатами типа (0,100,0), (100,100,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();

}

Где as, 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

Решение

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

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

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

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

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

0

Другие решения

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

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

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

  • Использование GLM для хранения всех моих матриц
  • выполнение вычислений самостоятельно (матрица обратного просмотра * матрица обратной модели * матрица обратной проекции) * вектор, содержащий NDC преобразованные координаты пространства экрана (диапазон от -1 до 1: x или y, разделенные на ширину или высоту, * 2 — 1), что также имеет az -1 или 1 для дальних или ближних плоскостей и aw 1.
  • Разделите результат на четвертое место вектора.

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

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

0

По вопросам рекламы [email protected]