Просмотр сообщений
|
Страниц: [1]
|
1
|
Qt / OpenGL / Получение локальных координат объекта
|
: Октябрь 30, 2023, 13:19
|
Всем привет. Вопрос в следующем. Имеется некий 2д объект, он расположен в диапазоне координат -1 до 1. В мировом пространстве он также располагается в этих координатах, но z смещен на -3 единицы. Собственно инициализация матриц модели, вида и проекции: m_model.setToIdentity(); m_view.setToIdentity(); m_projection.setToIdentity();
m_model.translate({0.0, 0.0, -3.0}); m_projection.perspective(38.0, 1.0 * 640 / 480, 0.1, 100.0);
При щелчке по крайней правой границе моей окружности на экране я хочу получить ее координату, x = 1.0, так как r = 1.0. Пробовал несколько способов, дающих один и тот же результат, но не совсем правильный для меня. 1) Ray picking: QMatrix4x4 mat = m_view * m_projection * m_model; QMatrix4x4 invMat = mat. inverted() ; //расчет нормализованных координат х, y, где был клик float pt_x = (p.x()/640)*2.0f - 1.0f; float pt_y = -(p.y()/480)*2.0f + 1.0f;
QVector4D nearPlane(pt_x,pt_y, -1.0, 1.0); QVector4D farPlane(pt_x, pt_y, 1.0, 1.0); QVector4D nearRes = invMat * nearPlane; QVector4D farRes = invMat * farPlane; nearRes /= nearRes.w(); farRes /= farRes.w(); QVector3D direc = QVector3D(farRes - nearRes); //результирующий вектор direc.normalize();
2) Unproject QVector3D screenPos(p.x(),p.y(),1.0f); // p.x, p.y экранные координаты клика QVector3D vecUnproj = screenPos.unproject(m_view, m_projection,QRect(0,0, 640, 480)); vecUnproj.normalize();
Output: direc = QVector3D(0.314588, 0, -0.949228) unproject = QVector3D(0.314589, 0, -0.949228)
В итоге у результирующего вектора полученный x = 0,31 c копейками, а ожидалось что-то около 1.0. Понимаю, что похоже что-то не учитываю в преобразовании или не делаю еще какую то операцию. Надеюсь, подскажите правильный путь.
|
|
|
2
|
Qt / Вопросы новичков / Re: Зависание ui при обработке нажатия кнопки. Многопоточность.
|
: Декабрь 26, 2020, 15:24
|
Не увидел в вашей новой реализации вызова GetCycle, точнее этот вызов у вас закоменчен. А так не вызывайте значит отрисовку, до того момента, пока не получите сигнал о том, что GetCycle в другом потоке закончил свое выполнение.
Я смотрю вы вроде и сигнал в воркере добавили, только ни с чем его не связали. Также вы не должны вызывать тот же экземпляр Game, который в потоке крутится. Т.е. запустили в потоке выполняться Game, выполнился он, забились в нем нужные вам структуры - возвращаете его сигналом в MainWindow и уже только сейчас можете взять что либо из Game.
|
|
|
3
|
Qt / OpenGL / Re: QOpenGLWindow или QOpenGLWidget
|
: Ноябрь 13, 2020, 15:07
|
Прочел пост выше 3 раза - все равно ни хрена не понял как сообщить вершинному шейдеру, что нужно применять данные ему параметры только для конкретного набора вершин, а не для всех вершин в буфере? А для остальных что применять? Напр для первых 100 вертексов применить одну матрицу, для остальных - другую? Можно передать вертексам "флажки", напр если position.z == 1, значит делаем то-то, иначе.. и.т.п. Хорошее место position.w, в шейдере его прочитали и затем установили = 1 До этого момента примерно понятно ..а хотелось бы просто не рисовать второй раз набор индексов первого объекта. Точнее рисовать за один вызов glDrawElements(), но с применением своей матрицы трансформации для каждый фигуры.
Рисовать диапазон примитивов - последний параметр glDrawElements (смещение с которого начинать) Не нужно пытаться "свалить все в один объект", для этого должны быть веские основания. Если геометрия разная то для каждого должны быть свои буфера, избегать этого - себе дороже Немного сумбурно,извиняюсь Но Вы все верное поняли. Не совсем понял про position.w. Имеете в виду в моем коде? Так я ее не считываю, там же вектор из трех элементов в шейдер приходит. А так да, еще немного почитал, советуют, что если геометрия объектов будет постоянно меняться не зависимо друг от друга (а у меня так и задумывается), то лучше для таких динамических объектов применить отдельные буферы.
|
|
|
4
|
Qt / OpenGL / Re: QOpenGLWindow или QOpenGLWidget
|
: Ноябрь 13, 2020, 13:32
|
Снова здравствуйте. Понемножку продвигаюсь в изучении openGL, и назрел тут вопрос, буду благодарен, услышав ваше мнение. С рисованием одного 2d объекта, его перемещением и текстурированием вроде бы как ясно. Хочу добавить еще несколько аналогичных объектов. Видятся такие решения: 1) Под каждый новый объект создавать свой VAO, VBO, IBO и при отрисовке каждый раз биндить нужный набор и рисовать. 2) Этот 2й способ пробую реализовать пока с добавлением второй фигуры. Класть все в один набор VAO, VBO, IBO. При появлении нового объекта добавлять вершины в буферы и отрисовывать. Тут появляется непонятный для меня момент: как сообщить вершинному шейдеру, что нужно применять данные ему параметры только для конкретного набора вершин, а не для всех вершин в буфере? Поясню, что имею в виду. Есть объект, я его куда-то переместил, повернул, в общем его матрица трансофрмации поменялась. Затем я вызываю метод отрисовки, в котором говорю рисовать мое базовое количесво индексов умноженное на кол-во объектов. Результат получается не тот, который хотелось бы видеть. Помимо одного моего трансформированного объекта появляются теперь еще два, что и понятно, так как я помимо перерисовки первой фигуры нарисовал еще раз те же вершины плюс новые, но с применением другой матрицы трансформации, а хотелось бы просто не рисовать второй раз набор индексов первого объекта. Точнее рисовать за один вызов glDrawElements(), но с применением своей матрицы трансформации для каждый фигуры. Вот пока застрял здесь. oglwidget.cpp void OGLWidget::paintGL() { qDebug()<<"paint"; if (!m_funcs) return;
m_funcs->glClearColor(0.2f, 0.3f, 0.3f, 1.0f); m_funcs->glClear(GL_COLOR_BUFFER_BIT);
m_program->bind(); //texture m_funcs->glActiveTexture(GL_TEXTURE0); m_funcs->glBindTexture(GL_TEXTURE_2D, m_texture); m_program->setUniformValue("ourTexture", 0); //transform m_program->setUniformValue("transform",figure->GetTransform());
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); m_funcs->glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); if(countFigures>1)//отрисовываем еще одну фигуру { m_program->setUniformValue("transform",figure1->GetTransform()); m_funcs->glDrawElements(GL_TRIANGLES, 6*countFigures, GL_UNSIGNED_INT, 0); } m_program->release(); m_funcs->glBindTexture(GL_TEXTURE_2D, 0); m_vao.release(); }
vshader.vsh #version 330 core layout (location = 0) in vec3 position; layout (location = 1) in vec2 texCoord;
out vec2 TexCoord;
uniform mat4 transform;
void main() { gl_Position =transform * vec4(position.x, position.y, position.z, 1.0); TexCoord=vec2(texCoord.x,1.0 - texCoord.y); }
|
|
|
6
|
Qt / OpenGL / QOpenGLWindow или QOpenGLWidget
|
: Октябрь 26, 2020, 11:52
|
Всем доброго времени суток. Думаю сейчас над реализацией одной штуки и хотел спросить вашего совета. Делаю программу на виджетах, на форме необходимо отрисовывать некие движущиеся объекты и их траектории по поступающим извне координатам. Отрисовка на двухмерной плоскости. Период с которым поступает инфорамация (и, соотвественно, необходимо обновлять отрисовку через этот период) относительно небольшой - примерно 100-150 мс. Решил использовать для этих целей OpenGL. Понемногу разбираюсь и не могу пока решить, каким путем идти. Примеров вроде бы много, но все очень уж различаются. Подход с использованием glBegin-glEnd, как я понял - использовать не стоит. Думал пробовать с QOpenGLWidget, но примеров с ним маловато, много примеров с QOpenGLWindow. Плюс была здесь же эта темка http://www.prog.org.ru/topic_28826_0.html. В общем прошу вашего наставления какой путь тут лучше выбрать. Может быть имеется у кого пример наподобие QTшного hellogl2, только не трехмерный, в нем уж очень много вещей мне непонятных происходит
|
|
|
|
|