Russian Qt Forum
Ноябрь 22, 2024, 03:49 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Работа с векторами и вертексными буферами  (Прочитано 4603 раз)
InquisitorAles
Гость
« : Сентябрь 27, 2017, 13:32 »

Приветствую. Я 3D-моделлер, изучал С#, и совсем недавно стал работать с Qt. Для одного старого проекта понадобилось сделать детализированную модель объекта и загрузить ее в opengl виджет. Сначала я хотел использовать Qt3D, но так как проект старый и делался на Qt4 то пришлось написать парсер obj файлов самому. Парсер работает, модель нормально загружается, однако теперь нужно вынести загрузку в отдельный класс и тут у меня возникли проблемы. Я с С++ и векторами в целом работал очень мало, и поэтому запихнул все в главный виджет и теперь не уверен, что нужно, а что не нужно переносить в отдельный класс.

1. В первую очередь, что делать с вертексным, индексным и текстурными буферами? Они у меня находятся в paintGL() в таком виде:
Код:
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    vertex_buffer.bind();
    index_buffer->bind();
    glVertexPointer(3,GL_FLOAT,sizeof(Point),0);
    glNormalPointer(GL_FLOAT,sizeof(Point),(void*)12);
    glTexCoordPointer(2,GL_FLOAT,sizeof(Point),(void*)24);

    glDrawElements(GL_TRIANGLES,faces_points_indices.count(),GLPointIdxType,0);
    index_buffer->release();
    vertex_buffer.release();

    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
    glPopMatrix();
initializeGL()
Код:
    if (vertex_buffer.create())
    {
        vertex_buffer.bind();
        vertex_buffer.setUsagePattern(QGLBuffer::StaticDraw);
        vertex_buffer.release();
    }
    else qDebug() << "Couldn't create vertex_buffer";

    index_buffer = new QGLBuffer(QGLBuffer::IndexBuffer);
    if (index_buffer&&(index_buffer->create()))
    {
        index_buffer->bind();
        index_buffer->setUsagePattern(QGLBuffer::StaticDraw);
        index_buffer->release();
    }
    else qDebug() << "Couldn't create index_buffer";
Как все задается в главном виджете:
Код:
typedef struct {
        QVector3D vertex;
        QVector3D normal;
        QVector2D texcoord;
    } Point;

    typedef unsigned int PointIdxType;
    const GLuint GLPointIdxType = GL_UNSIGNED_INT;

    typedef unsigned int FaceIdxType;

    QVector<QVector3D> vertices;
    QVector<QVector3D> face_normal;
    QVector<QVector2D> texcoords;
    QVector<Point> points;
    QHash<QString,PointIdxType> string_to_point_index;
    QVector<PointIdxType> faces_points_indices;
    QVector<QVector<FaceIdxType> > point_faces;

    QGLBuffer vertex_buffer;
    QGLBuffer *index_buffer;

Это работает если объект один, но что если объектов будет несколько? Постоянно включать и выключать glEnableClientState? И если переносить index_buffer в другой класс, как к нему потом обращаться? Делать указатель на указатель?

2. Для того чтобы улучшить код мне предложили вместо QVector использовать std::vector - но какая кардинальная разница между ними? Чем в данном варианте плох QVector?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Сентябрь 27, 2017, 14:13 »

Это работает если объект один, но что если объектов будет несколько? Постоянно включать и выключать glEnableClientState?
Да, у каждого объекта все буфера свои. С помощью VAO можно облегчить процесс переключения, но стоит ли заморачиваться ради экономии неск строк - дело Ваше. Расходов на переключения можно не опасаться т.к. передача данных на карту происходит при заполнении буферов

2. Для того чтобы улучшить код мне предложили вместо QVector использовать std::vector - но какая кардинальная разница между ними? Чем в данном варианте плох QVector?
Ничем, и принципиальной разницы никакой

Ну и уже неск лет glVertexPointer и.т.п. сдано в архив - принято использовать glVertexAttribPointer и шейдера. Если Вас это пока не волнует - ну и хорошо, но когда заволнует - лучше сразу соскочить на шейдера (больше возможностей)
Записан
InquisitorAles
Гость
« Ответ #2 : Сентябрь 27, 2017, 16:31 »

Да, у каждого объекта все буфера свои. С помощью VAO можно облегчить процесс переключения, но стоит ли заморачиваться ради экономии неск строк - дело Ваше. Расходов на переключения можно не опасаться т.к. передача данных на карту происходит при заполнении буферов
А что если количество загружаемых объектов изначально неизвестно? Я думаю, раз функцию просят перенести в отдельный класс, то каждый раз лезть в paintGL() явно никто не собирается.
Ничем, и принципиальной разницы никакой

Ну и уже неск лет glVertexPointer и.т.п. сдано в архив - принято использовать glVertexAttribPointer и шейдера. Если Вас это пока не волнует - ну и хорошо, но когда заволнует - лучше сразу соскочить на шейдера (больше возможностей)
Я бы с радостью пользовался всем самым новым, тем более что с помощью Qt3D можно было бы обойтись без написания собственного парсера, но так как проект старый и нужна совместимость с Qt4, то я уже боюсь использовать что-либо новое. Поэтому у меня QGLBuffer и QGLWidget, а не QOpenGLBuffer и QOpenGLWidget. Если б была возможность как-то перенести код на Qt5, то этих проблем вообще бы не было...
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Сентябрь 28, 2017, 11:51 »

А что если количество загружаемых объектов изначально неизвестно? Я думаю, раз функцию просят перенести в отдельный класс, то каждый раз лезть в paintGL() явно никто не собирается.
Есть класс "3D объект", буфера данных - его члены (или члены его членов). В paintGL известно какие объекты будут рисоваться

тем более что с помощью Qt3D можно было бы ...
Пока не видел человека который присел бы (плотно) на Qt3D. Слышал отрицательные отзывы (мол, все в багах), но неясно насколько им можно верить
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.045 секунд. Запросов: 23.