Results 1 to 19 of 19

Thread: What is the fastest way to draw a circle ?

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jan 2007
    Posts
    45
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: What is the fastest way to draw a circle ?

    Quote Originally Posted by Gopala Krishna View Post
    Removing QApplication:: processEvents improved FPS by 10 on mys system. I don't think you need to call that since you are not using an infinite loop.
    Yes, removing it improves performance, but for some strange reason without it MyGraphicsItem:aint() is called only once per two frames !

  2. #2
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: What is the fastest way to draw a circle ?

    I guess Wysota is correct in recommending item caching in pixmap. Actually i tried andreas's new item caching patch with your program and with some modifications to your program i could get ~30 FPS. With processEvents i could get ~20FPS.

    Here are the changes i made
    • Firstly i applied the patch specified
    • Changed update mode to FullViewportMode
    • Removed scaling
    • Enabled item's dynamic cache(available only through patch)


    Qt Code:
    1. #include <QtGui>
    2. #include <QtCore>
    3.  
    4. const int N = 1000;
    5. const int S = 500;
    6. const int DT = 10;
    7. const double R = 7;
    8.  
    9. class MyGraphicsItem: public QGraphicsItem
    10. {
    11. public:
    12. MyGraphicsItem(): _vel((double(qrand())/RAND_MAX-0.5)*S/10,(double(qrand())/RAND_MAX-0.5)*S/10),
    13. _rect(-R,-R,2*R,2*R), _color(QColor::fromRgba(qrand())) {
    14.  
    15. setPos(double(qrand())/RAND_MAX*S,double(qrand())/RAND_MAX*S);
    16. }
    17. void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
    18. painter->setRenderHint(QPainter::Antialiasing, true);
    19. painter->setPen(Qt::NoPen);
    20. painter->setBrush(_color);
    21. painter->drawEllipse(_rect);
    22. }
    23. QRectF boundingRect() const { return _rect; }
    24. void step() {
    25. setPos(pos() + (_vel*double(DT)/1000));
    26. if(pos().x() < 0 || pos().x() > S) _vel.setX(-_vel.x());
    27. if(pos().y() < 0 || pos().y() > S) _vel.setY(-_vel.y());
    28. }
    29.  
    30. protected:
    31. QPointF _vel;
    32. QRectF _rect;
    33. QColor _color;
    34. };
    35.  
    36. class MyGraphicsScene: public QGraphicsScene
    37. {
    38. public:
    39. MyGraphicsScene(): _startTime(QTime::currentTime()), _framesCount(0) {
    40. setItemIndexMethod(NoIndex);
    41. for(int i=0; i<N; ++i) {
    42. MyGraphicsItem *it = new MyGraphicsItem();
    43. addItem(it);
    44. it->setCacheMode(QGraphicsItem::DynamicCache);
    45. }
    46. startTimer(0);
    47. }
    48.  
    49. protected:
    50. void timerEvent(QTimerEvent* event) {
    51. foreach(QGraphicsItem *item, items()) {
    52. static_cast<MyGraphicsItem*>(item)->step();
    53. }
    54.  
    55. QApplication::processEvents();
    56. ++_framesCount;
    57. if(_framesCount == 50) {
    58. qDebug() << "FPS:" << double(_framesCount) / _startTime.msecsTo(QTime::currentTime()) * 1000;
    59. _startTime = QTime::currentTime();
    60. _framesCount = 0;
    61. }
    62. }
    63. QTime _startTime;
    64. int _framesCount;
    65. };
    66.  
    67. int main(int argc, char *argv[])
    68. {
    69. QApplication app(argc, argv);
    70.  
    71. MyGraphicsScene scene;
    72. QGraphicsView view(&scene);
    73. view.setOptimizationFlags(QGraphicsView::DontClipPainter);
    74. view.setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
    75. view.resize(S,S);
    76.  
    77. view.show();
    78. return app.exec();
    79. }
    To copy to clipboard, switch view to plain text mode 

    EDIT: Forgot to inform you about my hardware. I have descent hardware with 1 GB ram, 3 GHz processor and an ATI Radeon XPress 200m card.
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  3. The following user says thank you to Gopala Krishna for this useful post:

    Vladimir (6th September 2007)

  4. #3
    Join Date
    Jan 2007
    Posts
    45
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: What is the fastest way to draw a circle ?

    Quote Originally Posted by Gopala Krishna View Post
    I guess Wysota is correct in recommending item caching in pixmap. Actually i tried andreas's new item caching patch with your program and with some modifications to your program i could get ~30 FPS. With processEvents i could get ~20FPS.
    Thanks for the advice ! But when using QPixmap I'm getting very noticeable jitter when particle moves because QPixmap can only be drawn at integer position. Are this problem fixed with the patch you mentioned ?

  5. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,371
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: What is the fastest way to draw a circle ?

    Quote Originally Posted by Vladimir View Post
    So I'll probably stick with using GL. But what if user has not OpenGL (I've tried to run my program in Xephyr and got just error messages). Are there any ways to check it at runtime ?
    QGLFormat::hasOpenGL()
    QGLFormat::sampleBuffers()

    Quote Originally Posted by Vladimir View Post
    Thanks for the advice ! But when using QPixmap I'm getting very noticeable jitter when particle moves because QPixmap can only be drawn at integer position. Are this problem fixed with the patch you mentioned ?
    You can speed up pixmap scaling by tweaking transformation modes from smooth to fast. You can improve quality by doing the opposite thing. You'll always have aliasing when using pixmaps, because they are pixel based (using smooth transform mode will reduce the effect). But if you use GL pixel buffers and render the circle to texture, you should avoid any artifacts at all. Should be very simple in your case.

  6. The following user says thank you to wysota for this useful post:

    Vladimir (6th September 2007)

  7. #5
    Join Date
    Jan 2007
    Posts
    45
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: What is the fastest way to draw a circle ?

    Quote Originally Posted by wysota View Post
    QGLFormat::hasOpenGL()
    QGLFormat::sampleBuffers()
    Thanks !

    Quote Originally Posted by wysota View Post
    You can speed up pixmap scaling by tweaking transformation modes from smooth to fast. You can improve quality by doing the opposite thing.
    I still can't figure out how to do it. I can draw into QPixmap with antialiasing but the problem is that when I'm calling QPainter::drawPixmap (even without any transformations) the pixmap is always painted starting from some pixel on the screen, for example when position of the item is (15.4,19.7) it will still be drawn at position (15,20). When items are slowly moving it gives the impression that the movement is shaky.

  8. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,371
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: What is the fastest way to draw a circle ?

    Well... you can't draw in the middle of a pixel. If you scale up the painter, the precision should increase.

  9. #7
    Join Date
    Jan 2007
    Posts
    45
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: What is the fastest way to draw a circle ?

    Quote Originally Posted by wysota View Post
    Well... you can't draw in the middle of a pixel. If you scale up the painter, the precision should increase.
    I could suppose that QT can resample my pixmap using algorithm similar to one using for resizing...

    Anyway, for now I've decided to use OpenGL which should be available in 90% cases with fallback to slow software rendering in other cases. On old machines without OpenGL even QPixmap approach can be too slow so I'll probably provide advances options to draw particles as points instead of circles.

  10. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,371
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: What is the fastest way to draw a circle ?

    Here is something to play with. Some parts of the code are commented and uncommenting some of them might change the behavior a bit.

    The most important part is the one that makes sure the animation is "lag-undependent" - items will move properly regardless of the number of frames the hardware can handle.
    Attached Files Attached Files

  11. #9
    Join Date
    Jan 2007
    Posts
    45
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: What is the fastest way to draw a circle ?

    Quote Originally Posted by wysota View Post
    Here is something to play with. Some parts of the code are commented and uncommenting some of them might change the behavior a bit.

    The most important part is the one that makes sure the animation is "lag-undependent" - items will move properly regardless of the number of frames the hardware can handle.
    Thanks ! GL version gives 25fps for me. In my case position calculation is more complicated: each frame is calculated in separate thread and calculation sometimes can be long. However frame time is adjustable so I'll try to follow your ideas and adjust it when rendering takes more time than calculations.

  12. #10
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: What is the fastest way to draw a circle ?

    Quote Originally Posted by Vladimir View Post
    Thanks for the advice ! But when using QPixmap I'm getting very noticeable jitter when particle moves because QPixmap can only be drawn at integer position. Are this problem fixed with the patch you mentioned ?
    By jitter you mean shaky movement right ? I did get them when using the caching mechanism. But anyway I think pixmap can be drawn in real positions too -
    void QPainter::drawPixmap ( const QRectF & target, const QPixmap & pixmap, const QRectF & source )
    I found this prototype in assistant.

    With both caching and gl i could get 20 FPS. (your card is better than mine )
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  13. #11
    Join Date
    Jan 2007
    Posts
    45
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: What is the fastest way to draw a circle ?

    Quote Originally Posted by Gopala Krishna View Post
    I found this prototype in assistant.
    I've tried this but it still gives the same result.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.