• 6186阅读
  • 0回复

[转载]OpenGL in Qt 5.1 – Part 3 [复制链接]

上一主题 下一主题
离线XChinux
 

只看楼主 倒序阅读 楼主  发表于: 2013-03-21
关键词: Qt5OpenGL
原文见:http://www.kdab.com/opengl-in-qt-5-1-part-3/?utm_source=rss&utm_medium=rss&utm_campaign=opengl-in-qt-5-1-part-3



OpenGL in Qt 5.1 – Part 3


Published: March 18, 2013 by Sean Harmer




This article continues our series on what is new in Qt 5.1 withrespect to OpenGL. If you haven’t already seen them, you may beinterested in reading Part 1 and Part 2.

Timer Queries


OpenGL on the desktop exposes a very useful tool in the shape of timer query objects. These can be used to record the amount of time taken by the GPUto process sequences of commands. If we couple this with the usual CPUprofiling techniques then we can get a very complete understanding ofthe bottlenecks in our rendering code.One obvious place that could take advantage of this is the Qt Quick 2renderer. Although the Qt Quick 2 renderer does have options to enabletimings of various stages of rendering, this only tells us half of thestory. Namely, the CPU half. Using OpenGL timer queries would allow usto fill in the gap and gain an understanding of how the GPU isperforming.
Another common use for OpenGL timer queries is to provide feedback toadaptive rendering routines in order to maintain more consistent framerates. For example, if we instrument our rendering function and find atruntime that our application is rendering too slowly, we can perhapsincrease the frame rate by using less complex shaders or by using lowerresolution meshes etc. Conversely, if we find that we have GPU cycles tospare then we could improve rendering quality by perhaps using higherlevels of tessellation.Qt 5.1 will make such tasks much easier with the introduction of two new classes developed by KDAB engineers: QOpenGLTimerQuery and QOpenGLTimeMonitor. The QOpenGLTimerQueryclass is a simple wrapper around a single OpenGL timer query object andcan be used if you wish to have total control. It is expected that QOpenGLTimeMonitorwill be the more commonly used class as this is a wrapper around asequence of timer query objects and makes it trivial to measure the GPUtime of the various stages of our rendering functions:

  1. void Scene::initialize()
  2. {
  3.     // Create a timer query object
  4.     m_timeMonitor = new QOpenGLTimeMonitor( this );
  5.     m_timeMonitor->setSampleCount( 5 );
  6.     if ( !m_timeMonitor->create() )
  7.         qWarning() << "Failed to create timer query object";
  8.     // Generate some names for the various stages of rendering
  9.     m_renderStages << "Clear Buffer" << "VAO Binding"
  10.                    << "Shader Program Binding" << "Drawing";
  11. }
  12. void Scene::render()
  13. {
  14.     // Start the timer query
  15.     m_timeMonitor->recordSample();
  16.     // Do some rendering
  17.     m_funcs->glClear( GL_COLOR_BUFFER_BIT );
  18.     m_timeMonitor->recordSample();
  19.     m_vao.bind();
  20.     m_timeMonitor->recordSample();
  21.     m_shaderProgram.bind();
  22.     m_timeMonitor->recordSample();
  23.     m_funcs->glDrawArrays( GL_TRIANGLES, 0, 3 );
  24.     // End the timer query
  25.     m_timeMonitor->recordSample();
  26.     // Block until the results are available
  27.     QVector<GLuint64> timeSamples = m_timeMonitor->waitForSamples();
  28.     qDebug() << "timeSamples =" << timeSamples;
  29.     QVector<GLuint64> intervals = m_timeMonitor->waitForIntervals();
  30.     for ( int i = 0; i <= intervals.count(); ++i )
  31.         qDebug() << i << m_renderStages.at( i )
  32.                  << double( intervals.at( i ) ) / 1.0e6 << "msecs";
  33.     // Clear the query results ready for the next frame
  34.     m_timeMonitor->reset();
  35. }


This is obviously a trivial example but gives an idea of the usage.Note that the timer intervals and timestamps are recorded innanoseconds. Sample output from this is:

timeSamples = QVector(5850713788736, 5850713794176, 5850713794848, 5850713795552, 5850713801952)
0 "Clear Buffer" 0.00544 msecs
1 "VAO Binding" 0.000672 msecs
2 "Shader Program Binding" 0.000704 msecs
3 "Drawing" 0.0064 msecs

So here we see in this trivial example (which just draws a singlelarge triangle) that the GPU is using only a fraction of a millisecond.This means that we could easily ask the GPU to do more work per-frame(as we would certainly hope!).There is much more to say about the nuances of using timer queries but we’ll leave that to a future more in-depth article.


二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
快速回复
限100 字节
 
上一个 下一个