OpenGL / GLUT - рисование на объекте - PullRequest
0 голосов
/ 28 декабря 2011

Я импортирую объектный файл, скажем, это самолет, например. Я хочу иметь возможность рисовать на самолете, и я просто не могу понять, как это делается. Узнать координаты x и y щелчка мыши довольно просто, но как насчет координаты z? Я должен быть в состоянии сделать какую-то трассировку лучей, которая испускает луч и сообщает мне, как только он достигает объекта. Я пытаюсь узнать координату z щелчка, который находится на объекте. В моем пространстве нет других объектов, это хорошее предположение.

Ответы [ 2 ]

1 голос
/ 28 декабря 2011

Получение XYZ точки под мышью очень просто. Вам не нужно приводить лучи, вам просто нужно извлечь значение глубины из кадрового буфера под вашим курсором, а затем выполнить gluUnProject.

Если вы хотите рисовать на объектах, вы, вероятно, захотите изменить текстуру, а не геометрию, поэтому вам нужны в основном координаты UV, а не XYZ. Если ваш объект нарисован с использованием одной текстуры, тогда я предлагаю использовать MRT (несколько целей рендеринга) и записывать UV-координаты для каждого пикселя во внеэкранный буфер во время рендеринга вашей сцены, чтобы вы могли легко их прочитать.


Отвечая на ваши дальнейшие запросы:

Я хочу нарисовать линию на объекте, поэтому я хочу получить несколько XYZ и соединить их вместе. Я хочу нарисовать линии перед объектом, но очень и очень близко к нему, как будто он на нем (или на самом деле на нем, в зависимости от того, что возможно).

Если вы хотите нарисовать «на» объекте, то вы, вероятно, натолкнетесь на z-fight (два фрагмента, имеющие ~ одинаковые значения глубины, что приведет к артефактам unool.

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

Как извлечь значение глубины из кадрового буфера?

Попробуйте glReadPixels с format = GL_DEPTH_COMPONENT.

2 - Как мне изменить текстуру?

Просто glTexImage* или glTexSubImage*.

Кроме того, техника рендеринга MRT звучит очень сложно, и я не очень разбираюсь в этом.

Вам не нужно быть экспертом :), сама MRT не сложна (она разбивается на вывод значений цвета в буфер экрана и любых других значений в буфер вне экрана одновременно). Я не реализовал это до сих пор, но должно быть действительно легко, как только вы поймете шейдеры и объекты кадрового буфера (что вы должны определенно сделать как можно скорее, поскольку именно так вы получаете большую часть OpenGL! Если бы я проводил классы OpenGL, шейдеры были бы вторым уроком ).

1 голос
/ 28 декабря 2011

Погуглив немного, дала мне такие приятные советы:

Некоторое время назад я использовал их (почти все) для создания своего приложения. По некоторым причинам у меня нет этого приложения сейчас, но я могу показать вам, как мой код получает 3D-вектор точки выбора за 2 .. 3 часа =)

Если вы хотите реализовать «рисование на объекте», я предлагаю вам найти координаты UV (текстуры) точки выбора, а затем выполнить некоторые операции рисования на текстуре объекта.

UPADTE: моя реализация функции комплектования

sf::Vector3f ScreenToSpace(int x, int y)
{
    GLint viewport[4];
    GLdouble modelview[16];
    GLdouble projection[16];
    GLfloat winX, winY, winZ;
    GLdouble posX, posY, posZ;

    glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
    glGetDoublev(GL_PROJECTION_MATRIX, projection);
    glGetIntegerv(GL_VIEWPORT, viewport);

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

    gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);

    return sf::Vector3f((float) posX, (float) posY, (float) posZ);
}

Здесь sf :: Vector3f - это просто SFML Vector класс.

...