Russian Qt Forum

Qt => OpenGL => Тема начата: Kinley11 от Октябрь 26, 2020, 11:52



Название: QOpenGLWindow или QOpenGLWidget
Отправлено: Kinley11 от Октябрь 26, 2020, 11:52
Всем доброго времени суток. Думаю сейчас над реализацией одной штуки и хотел спросить вашего совета. Делаю программу на виджетах, на форме необходимо отрисовывать некие движущиеся объекты и их траектории по поступающим извне координатам.  Отрисовка на двухмерной плоскости. Период с которым поступает инфорамация (и, соотвественно, необходимо обновлять отрисовку через этот период) относительно небольшой - примерно 100-150 мс. Решил использовать для этих целей OpenGL. Понемногу разбираюсь и не могу пока решить, каким путем идти. Примеров вроде бы много, но все очень уж различаются. Подход с использованием glBegin-glEnd, как я понял - использовать не стоит. Думал пробовать с QOpenGLWidget, но примеров с ним маловато, много примеров с QOpenGLWindow. Плюс была здесь же эта темка http://www.prog.org.ru/topic_28826_0.html. В общем прошу вашего наставления какой путь тут лучше выбрать. Может быть имеется у кого пример наподобие QTшного hellogl2, только не трехмерный, в нем уж очень много вещей мне непонятных происходит :)


Название: Re: QOpenGLWindow или QOpenGLWidget
Отправлено: Авварон от Октябрь 26, 2020, 12:51
Время порекламировать мою репу=) https://github.com/ABBAPOH/learnopengl-qt

Читал статьи на Хабре, адаптировал примеры для классов Qt. Начинается всё с треугольника - куда уж проще=)


Название: Re: QOpenGLWindow или QOpenGLWidget
Отправлено: Авварон от Октябрь 26, 2020, 12:53
Разницы между Widget и Window почти нет, первый можно встраивать в другие виджеты, второй - нет. АПИ у них одинаковый.


Название: Re: QOpenGLWindow или QOpenGLWidget
Отправлено: Kinley11 от Октябрь 26, 2020, 12:59
Время порекламировать мою репу=) https://github.com/ABBAPOH/learnopengl-qt

Читал статьи на Хабре, адаптировал примеры для классов Qt. Начинается всё с треугольника - куда уж проще=)
Спасибо за ответ. Ваш репозиторий видел, буду внимательнее разбираться :)


Название: Re: QOpenGLWindow или QOpenGLWidget
Отправлено: Igors от Октябрь 26, 2020, 13:00
По поводу Window/Widget - в Вашем случае принципиальной разницы нет
Может быть имеется у кого пример наподобие QTшного hellogl2, только не трехмерный, в нем уж очень много вещей мне непонятных происходит :)
Да, "в первый раз" - действительно тяжело. Но какого-то "двумерного случая" не существует, и рисование на плоскости (вместо пространства) жизнь никак не облегчает. На плоскости - все то же самое только с одинаковой z координатой. Также тамошние шейдеры - довольно гнусная вещь, но лучше нырнуть в них сразу, это обойдется намного дешевле чем "потом переходить".

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


Название: Re: QOpenGLWindow или QOpenGLWidget
Отправлено: Авварон от Октябрь 26, 2020, 13:05
Вероятно/предполагаю Вас пугают матрицы - не переживайте, миллионы людей юзают их не понимая как они работают, просто используя готовые ф-ции, научиться этому несложно.

из курса линала помню только что-то вроде "строка на столбец"  :(


Название: Re: QOpenGLWindow или QOpenGLWidget
Отправлено: Igors от Октябрь 26, 2020, 13:19
из курса линала помню только что-то вроде "строка на столбец"  :(
Ну так уже неплохо! Математика утверждает что матрицы множатся "строка на столбец" - и только так. Но откуда берутся эти "строка" и "столбец" - математике совершенно все равно. Напр можно строки матрицы множить на вектор-столбец, а можно и вектор-строку на столбцы матрицы. И то и другое корректно (по крайней мере формально), но смысл/рез-т разный.

Начинается всё с треугольника - куда уж проще=)
Вот прямо сейчас занимаюсь треугольником :) Даны его 3 точки + конечно все необходимые матрицы/параметры. Требуется: для данной "линии" (координата y) определить какие пыксели экрана покрываются данным тр-ком. И как-то мне это не кажется "таким уж простым" :)


Название: Re: QOpenGLWindow или QOpenGLWidget
Отправлено: Kinley11 от Ноябрь 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);
}


Название: Re: QOpenGLWindow или QOpenGLWidget
Отправлено: Igors от Ноябрь 13, 2020, 14:24
Прочел пост выше 3 раза - все равно ни хрена не понял  :)

как сообщить вершинному шейдеру, что нужно применять данные ему параметры только для конкретного набора вершин, а не для всех вершин в буфере?
А для остальных что применять? Напр для первых 100 вертексов применить одну матрицу, для остальных - другую? Можно передать вертексам "флажки",  напр если position.z == 1, значит делаем то-то, иначе.. и.т.п. Хорошее место position.w, в шейдере его прочитали и затем установили   = 1

До этого момента примерно понятно
..а хотелось бы просто не рисовать второй раз набор индексов первого объекта. Точнее рисовать за один вызов glDrawElements(), но с применением своей матрицы трансформации для каждый фигуры.
??? Рисовать диапазон примитивов - последний параметр glDrawElements (смещение с которого начинать)

Не нужно пытаться "свалить все в один объект", для этого должны быть веские основания. Если геометрия разная то для каждого должны быть свои буфера, избегать этого - себе дороже


Название: Re: QOpenGLWindow или QOpenGLWidget
Отправлено: Kinley11 от Ноябрь 13, 2020, 15:07
Прочел пост выше 3 раза - все равно ни хрена не понял  :)

как сообщить вершинному шейдеру, что нужно применять данные ему параметры только для конкретного набора вершин, а не для всех вершин в буфере?
А для остальных что применять? Напр для первых 100 вертексов применить одну матрицу, для остальных - другую? Можно передать вертексам "флажки",  напр если position.z == 1, значит делаем то-то, иначе.. и.т.п. Хорошее место position.w, в шейдере его прочитали и затем установили   = 1

До этого момента примерно понятно
..а хотелось бы просто не рисовать второй раз набор индексов первого объекта. Точнее рисовать за один вызов glDrawElements(), но с применением своей матрицы трансформации для каждый фигуры.
??? Рисовать диапазон примитивов - последний параметр glDrawElements (смещение с которого начинать)

Не нужно пытаться "свалить все в один объект", для этого должны быть веские основания. Если геометрия разная то для каждого должны быть свои буфера, избегать этого - себе дороже
Немного сумбурно,извиняюсь :) Но Вы все верное поняли.
Не совсем понял про position.w. Имеете в виду в моем коде? Так я ее не считываю, там же вектор из трех элементов в шейдер приходит.
А так да, еще немного почитал, советуют, что если геометрия объектов будет постоянно меняться не зависимо друг от друга (а у меня так и задумывается), то лучше для таких динамических объектов применить отдельные буферы.


Название: Re: QOpenGLWindow или QOpenGLWidget
Отправлено: Igors от Ноябрь 13, 2020, 16:12
Не совсем понял про position.w. Имеете в виду в моем коде? Так я ее не считываю, там же вектор из трех элементов в шейдер приходит.
Просто удобное место для передачи данных (если они понадобятся). т.к. заводить новый атрибут - удовольствие дорогое, из обычно всего 16 (и так быстро кончаются)

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


Название: Re: QOpenGLWindow или QOpenGLWidget
Отправлено: Авварон от Ноябрь 13, 2020, 16:50
Прочел пост выше 3 раза - все равно ни хрена не понял  :)

добро пожаловать в клуб