Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Box2d and opengl update is slow.



  • I have create a simple project and included the box2d library.
    could some one please tell me what i am doing wrong.
    the falling boxes seem to move very slowly.
    advice on how to implement the update function would be appreciated.
    thanks.

    @
    #ifndef GLWIDGET_H
    #define GLWIDGET_H

    #include <QGLWidget>
    #include <Box2D/Box2D.h>

    const int WIDTH = 640;
    const int HEIGHT = 480;
    const double FPS = 1.0/30.0;
    //const double M_PI = 3.1416;
    const float P2M = 20;
    const float M2P = 1/P2M;

    //! [0]
    class GLWidget : public QGLWidget
    {
    Q_OBJECT

    public:
    GLWidget(QWidget parent = 0);
    ~GLWidget();
    b2Body
    addrectangle(int x, int y,int w, int h, bool dyn);
    void drawSquare(b2Vec2* points,b2Vec2 center,float angle);
    QSize minimumSizeHint() const;
    QSize sizeHint() const;

    b2World *world;
    //! [0]
    

    //! [1]

    //! [2]
    protected:
    void initializeGL();
    void paintGL();
    void resizeGL(int width, int height);
    //! [2]

    //! [3]
    private:

    };
    //! [3]

    #endif
    @
    @

    #ifndef WINDOW_H
    #define WINDOW_H

    #include <QWidget>
    #include <Box2D/Box2D.h>

    QT_BEGIN_NAMESPACE
    class QSlider;
    QT_END_NAMESPACE
    //! [0]
    class GLWidget;

    class Window : public QWidget
    {
    Q_OBJECT

    public:
    Window();

    public slots:
    void updateworld();
    void animateworld();

    protected:
    void keyPressEvent(QKeyEvent *event);
    void mousePressEvent(QMouseEvent *event);

    private:
    QSlider *createSlider();

    GLWidget *glWidget;
    

    };
    //! [0]

    #endif
    @
    @

    #include <QtWidgets>
    #include <QtOpenGL>

    #include <math.h>

    #include "glwidget.h"

    #ifndef GL_MULTISAMPLE
    #define GL_MULTISAMPLE 0x809D
    #endif

    //! [0]
    GLWidget::GLWidget(QWidget *parent)
    : QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
    {

    }
    //! [0]

    //! [1]
    GLWidget::~GLWidget()
    {
    }
    //! [1]

    //! [2]
    QSize GLWidget::minimumSizeHint() const
    {
    return QSize(WIDTH, HEIGHT);
    }
    //! [2]

    //! [3]
    QSize GLWidget::sizeHint() const
    //! [3] //! [4]
    {
    return QSize(WIDTH, HEIGHT);
    }
    //! [4]

    //! [6]
    void GLWidget::initializeGL()
    {
    glMatrixMode(GL_PROJECTION);
    glOrtho(0,WIDTH,HEIGHT,0,-1,1);
    glMatrixMode(GL_MODELVIEW);
    glClearColor(0,0,0,1);

    // create world requires gravity
    //b2 vector x and y.
    world = new b2World(b2Vec2(0.0,9.81));
    
    // provide center point
    addrectangle(WIDTH/2,HEIGHT,WIDTH,30,false);
    

    }
    //! [6]

    //! [7]
    void GLWidget::paintGL()
    {
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();

    // temporary body
    b2Body* tmp = world->GetBodyList();
    b2Vec2 points[4];
    
    while(tmp)
    {
        for(int i=0;i<4;i++)
        {
            // get current vertex
            points[i]=((b2PolygonShape*)tmp->GetFixtureList()->GetShape())->GetVertex(i);
        }
    
        drawSquare(points,tmp->GetWorldCenter(),tmp->GetAngle());
        // go through the linked list
        tmp = tmp->GetNext();
        // time to update
    
    }
    

    }
    //! [7]

    //! [8]
    void GLWidget::resizeGL(int width, int height)
    {

    }
    //! [8]

    //! [10]
    b2Body* GLWidget::addrectangle(int x, int y,int w, int h, bool dyn=true)
    {
    // need to conver pixels to meter
    // create body definition
    b2BodyDef bodydef;
    bodydef.position.Set(xP2M,yP2M);

    if(dyn)
    {
        bodydef.type = b2_dynamicBody;
    }
    
    //create body after definition
    b2Body* body = world->CreateBody(&bodydef);
    
    // create shape
    b2PolygonShape shape;
    shape.SetAsBox(P2M*(w/2),P2M*(h/2));
    
    // create fixture definition
    b2FixtureDef fixturedef;
    
    //pass pointer
    fixturedef.shape = &shape;
    // defines mass
    fixturedef.density = 1.0;
    
    // pass pointer of fixture ref
    body->CreateFixture(&fixturedef);
    
    // body create fixture
    return body;
    

    }

    void GLWidget::drawSquare(b2Vec2* points,b2Vec2 center,float angle)
    {
    // need to convert back to pixels
    glColor3f(1,1,1);
    glPushMatrix();
    glTranslatef(center.xM2P,center.yM2P,0);
    glRotatef(angle180.0/M_PI,0,0,1);
    glBegin(GL_QUADS);
    for (int i=0; i < 4;i++)
    {
    glVertex2f(points[i].x
    M2P,points[i].y*M2P);
    }
    glEnd();
    glPopMatrix();
    }
    @

    @

    #include <QApplication>
    #include <QDesktopWidget>

    #include "window.h"

    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);
    Window window;
    window.resize(window.sizeHint());
    int desktopArea = QApplication::desktop()->width() *
    QApplication::desktop()->height();
    int widgetArea = window.width() * window.height();
    if (((float)widgetArea / (float)desktopArea) < 0.75f)
    window.show();
    else
    window.showMaximized();
    return app.exec();
    }
    @

    @

    #include <QtWidgets>
    #include <QTimer>

    #include "glwidget.h"
    #include "window.h"

    //! [0]
    Window::Window()
    {
    glWidget = new GLWidget;
    QTimer *timer = new QTimer(this);
    QTimer *animate = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(updateworld()));
    connect(animate, SIGNAL(timeout()),this, SLOT(animateworld()));
    animate->start(30);
    timer->start(1);
    //! [0]

    //! [1]
    QHBoxLayout *mainLayout = new QHBoxLayout;
    mainLayout->addWidget(glWidget);
    setLayout(mainLayout);
    setWindowTitle(tr("Hello GL"));

    }
    //! [1]

    void Window::keyPressEvent(QKeyEvent *e)
    {
    if (e->key() == Qt::Key_Escape)
    {
    close();
    }
    else if(e->key() ==Qt::Key_A)
    {
    glWidget->addrectangle(WIDTH/2,HEIGHT/2,20,20,true);
    }
    else
    QWidget::keyPressEvent(e);
    }

    void Window::mousePressEvent(QMouseEvent *event)
    {
    int dx = event->x();
    int dy = event->y();
    glWidget->addrectangle(dx,dy,20,20,true);

    }

    void Window::updateworld()
    {
    glWidget->world->Step(FPS,8,3);
    }

    void Window::animateworld()
    {
    glWidget->updateGL();
    }
    @


Log in to reply