SlideShare a Scribd company logo
1 of 53
Download to read offline
Convert your Legacy OpenGL
Code to Modern OpenGL with
Qt
Dr. Roland Krause
Integrated Computer Solutions
Abstract
OpenGL is a powerful, low level graphics toolkit with a steep learning curve that
allows access to accelerated GPU hardware. Using OpenGL developers achieve
high-fidelity, animated graphics ubiquitous in games, screen productions and
scientific software. Due to OpenGL’s native C-language API large scale,
professional software development endeavors wanting to utilize the advantages of
direct and accelerated graphics quickly become expensive and hard to maintain.
This presentation gives a comprehensive overview of the many aspects of
OpenGL development where Qt provides advanced interfaces that let the
developer focus on the tasks at hand instead of dealing with repetitive and error-
prone, platform dependent issues. From handling of Window related tasks,
providing type-safe data-structures for Vertex Array Objects to managing Shader
Programs, dealing with Textures, Frame Buffer Objects all the way to support for
Debugging and Profiling of OpenGL Applications we show solutions to the most
common issues any OpenGL program has to address.
We are able to demonstrate why Qt is the best C++ framework for development of
modern OpenGL based graphics applications.
Modern OpenGL with Qt
● OpenGL is an Application Programming Interface (API) for
Rendering Graphics in 2D and 3D
○ Widely used in CAD, Virtual Reality, Scientific Visualization, Information
Visualization, Flight Simulation, and Video Games.
○ Over 500 commands in Version 4.3
○ Managed by the non-profit technology consortium Khronos Group.
● Designed as a Streamlined, Hardware Independent
Interface
○ To be efficient usually implemented on graphics hardware (GPU)
○ Independent of Operating System or Windowing System, Cross-platform
○ No functions for windowing tasks, managing state, user input, 3D models
or reading image files
That’s where Qt comes into play!
In the Olden Days...
● Glut (or SDL) was the way to platform
independent code
○ For platform dependent code there are WGL, AGL,
GLX
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(resize);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
A simple Triangle in Fixed Pipeline OpenGL
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_SMOOTH);
}
void triangle(void)
{
glBegin (GL_TRIANGLES);
glColor3f (1.0, 0.0, 0.0);
glVertex2f (5.0, 5.0);
glColor3f (0.0, 1.0, 0.0);
glVertex2f (25.0, 5.0);
glColor3f (0.0, 0.0, 1.0);
glVertex2f (5.0, 25.0);
glEnd();
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
triangle ();
glFlush ();
}
Render a Scene with Modern OpenGL
1. Create OpenGL Context and Window
2. Create and Manage the OpenGL Scene
○ Create Geometry
■ Store Geometry in Vertex Buffer Objects (VBOs)
■ Manage VBOs using Vertex Array Objects (VAOs)
○ Compile and Link Shaders into Shader Programs
○ Configure the Rendering Pipeline
○ Set Attribute Arrays, Uniforms, Textures, etc…
3. Render the Scene using OpenGL Primitives
Integration of OpenGL with Qt
● There are several possibilities when
integrating OpenGL Rendering with Qt
1. Native OpenGL rendering
using QWindow and QOpenGLContext
2. QOpenGLWindow
○ Wrapper for QWindow that hides complexity
○ Can be OpenGL Canvas with QPainter syntax
3. QOpenGLWidget
○ QWidget based applications
4. QQuickFramebufferObject
○ new since Qt-5.4
5. Rendering into the SceneGraph
6. Custom QQuickItem
7
Create OpenGL Context and Window
● Since Qt 5 the class QWindow represents a
window in the underlying windowing system
○ In Qt 4, QWidget had both Window and Widget
functionality
○ In Qt 5, QWindow is part of the gui module, QWidget is
in a separate and now optional module (widgets)
○ Applications will typically use QWidget or QQuickView
to create user interfaces
● It is possible to render directly to a
QWindow with a QOpenGLContext
● QWindow can be embedded in a QWidget
8
QOpenGLWindow
● Convenience subclass of QWindow to perform
OpenGL painting
○ Enhanced QWindow that allows easily creating
windows that perform OpenGL rendering
○ API compatible with QOpenGLWidget and similar to
the legacy QGLWidget.
○ No dependency on widgets module and better
performance.
○ Optionally backed by a framebuffer object
○ Default behavior (and thus performance) is equivalent
to QWindow.
9
Using QOpenGLWindow
● Subclass QOpenGLWindow and reimplement
the following virtual functions:
○ initializeGL() to perform OpenGL resource initialization
○ resizeGL() to set up the transformation matrices and
other window size dependent resources
○ paintGL() to issue OpenGL commands or draw using
QPainter
● To schedule a repaint, call update()
○ Note that this will not immediately result in a call to
paintGL().
○ This is a slot so it can be connected to a QTimer::
timeout() signal to perform animation.
10
Simple Triangle in Modern OpenGL
void OpenGLScene::initialize() {...}
void OpenGLScene::createBuffers() {...}
void OpenGLScene::setupVertexArrayState() {...}
void OpenGLScene::paint()
{
glClear( GL_COLOR_BUFFER_BIT );
if(!m_shaderProgram.isLinked()) return;
m_shaderProgram.bind();
m_vao.bind();
m_shaderProgram.setUniformValue("MVP", m_projection);
glDrawArrays(GL_TRIANGLES, 0, 3);
m_shaderProgram.release();
}
void OpenGLScene::resize(int w, int h) {...}
void OpenGLScene::createShaderProgram() {...}
let’s look closer at the code ...
QOpenGLWindow using QPainter
● QOpenGLWindow inherits
QPaintDeviceWindow
● Allows opening a painter on itself and perform
QPainter-based drawing:
void paintGL() {
QOpenGLFunctions *f = context()->functions();
f->glClear(GL_COLOR_BIT | GL_DEPTH_BUFFER_BIT);
// issue some native OpenGL commands
QPainter p(this);
// draw using QPainter
// animate continuously: schedule an update
update();
}
12
Example: QOpenGLWindow-QPainter
13
● State machine that stores all data related to
the OpenGL rendering state
○ Most OpenGL functions set or retrieve some state
○ Creating a window and an OpenGL context is not part
of the OpenGL specification
● QOpenGLContext represents a native
OpenGL context
○ Enables OpenGL rendering on a QSurface.
○ Context allow to share resources with other contexts
with setShareContext()
OpenGL Context
14
QOpenGLContext
To create:
● Create a QSurfaceFormat object
○ Set desired OpenGL version and profile
● Create the QOpenGLContext
○ Set the context format using the QSurfaceFormat
object
● Finally call QOpenGLContext::create()
○ Use return value or isValid() to check if the context was
successfully initialized
● Before using any OpenGL QOpenGLContext
must be made current against a surface
○ QOpenGLContext::makeCurrent(QSurface*)
15
● When OpenGL rendering is done
○ Call swapBuffers() to swap the front and back buffers
of the surface at the end of the update function
○ Newly rendered content becomes visible
○ QOpenGLContext requires to call makeCurrent() again
before starting rendering a new frame, after calling
swapBuffers()
● QOpenGLWindow takes care of all of it!
● Use QOpenGLContext::format() to retrieve info
on the context
○ Returns a QSurfaceFormat
○ OpenGL version, profile, etc...
QOpenGLContext
16
Converting Legacy Qt OpenGL Code
● When porting code from Qt4 to Qt5 we find
that QGLWidget is marked obsolete
● The replacement, QOpenGLWidget, has the
same familiar API but works differently
Qt4 Legacy Classes Qt5 Modern OpenGL Classes
QGLWidget QOpenGLWidget
QGLFormat QSurfaceFormat
QGLContext QOpenGLContext
QOpenGLWidget
● Can be used on Embedded Systems with eglfs
and wayland plugins
● Uses same technology as QQuickWidget
○ Unlike QGLWidget it is not a native window
● On desktop platforms, OpenGL 3.x and 4.x,
including core profiles, are fully supported
○ QGLWidget forced the usage of legacy, incomplete
utility classes like QGLFormat and QGLContext
○ QOpenGLWidget uses the modern equivalents from
the QtGui module: QSurfaceFormat, QOpenGLContext
QOpenGLWidget Example
Important Differences
QGLWidget vs QOpenGLWidget
● QOpenGLWidget always renders offscreen, using
framebuffer objects.
● QGLWidget on the other hand uses a native window and
surface.
○ Depending on platform native child widgets may have various limitations
(e.g. eglfs)
○ QOpenGLWidget avoids this by not creating a separate native window.
● Behavior of QOpenGLWidget is very similar to
QOpenGLWindow
○ Update behavior can be set to PartialUpdateBlit or PartialUpdateBlend.
○ Contents are preserved between paintGL() calls so that incremental
rendering is possible.
QOpenGLWidget Hints
● When rendering everything in the view on every paint call:
○ Important to call glClear() as early as possible in paintGL().
○ Mobile GPUs can optimize reloads of the tile buffer.
○ Omitting the clear call can lead to significant performance drops
● Avoid calling winId() on a QOpenGLWidget.
○ This function triggers the creation of a native window, resulting in reduced
performance and possibly rendering glitches.
● Putting other Widgets underneath and making the
QOpenGLWidget transparent will not show as expected:
○ Widgets underneath will not be visible because QOpenGLWidget is
drawn before all other non-OpenGL widgets.
○ Having widgets on top of the QOpenGLWidget, will function as expected.
● Alternative with Limitations is QOpenGLWindow with
QWidget::createWindowContainer()
Qt’s OpenGL Support
● QOpenGLFunctions are convenience classes
● Simplify writing of OpenGL code
● Hide complexities of extension handling
● Hide differences between OpenGL ES 2 and
desktop OpenGL
○ Allow the use of OpenGL ES 2 functions on Desktop
OpenGL
○ No need to manually resolve OpenGL function pointers
○ Allowing cross-platform development of applications
targeting mobile or embedded devices
22
QAbstractOpenGLFunctions
● Family of classes that expose all functions for
a given OpenGL version and profile
○ OpenGL implementations on different platforms are
able to link to a variable number of OpenGL functions
depending upon the OpenGL ABI on that platform
○ On many platforms most functions must be resolved at
runtime, Options are:
■ Work with raw function pointers:
QOpenGLContext::getProcAddress()
■ Use QOpenGLFunctions and only expose those
functions common to OpenGL ES 2 and desktop
OpenGL
23
QAbstractOpenGLFunctions (cont.)
● Provides better support for newer versions of
OpenGL (especially 3.0 and higher)
● Ease development of desktop applications
relying on modern, desktop-only OpenGL
features
● QOpenGLFunctions_X_Y_PROFILE
○ Core and Compatibility Profiles
○ Expose every core OpenGL function by way of a
corresponding member function
○ Class for every valid combination of OpenGL version
and profile following the naming convention:
QOpenGLFunctions_<MAJOR VERSION>_<MINOR VERSION>[_PROFILE]
24
● Ensure QOpenGLContext is current before
using it
● Call
QOpenGLFunctions_X_Y_PROFILE::initializeOpenGLFunctions()
once before using it to resolve function
pointers
Using QOpenGLFunctions_X_Y_PROFILE
25
Qt’s OpenGL Support
● Classes that wrap native OpenGL Resources
○ QOpenGLBuffer, QOpenGLFramebufferObject
QOpenGLShaderProgram, OpenGLTexture,
QOpenGLVertexArrayObject
● Qt GUI Module Contains
○ QMatrix4x4, QVector4D and QQuaternion
○ Support common mathematical operations for 3D
graphics
● Miscellaneous
○ Debugging, QOpenGLDebugLogger
○ Timing, QOpenGLTimeMonitor, QOpenGLTimerQuery
26
QOpenGLDebugLogger
QOpenGLDebugMessage
QOpenGLTimeMonitor
QOpenGLTimerQuery
QOpenGLPaintDevice
QOpenGLTexture (Qt 5.3)
QOpenGLWidget(Qt 5.4)
QOpenGLWindow(Qt 5.4)
QOpenGLContext
QOpenGLContextGroup
QOpenGLVersionProfile
QOpenGLFunctions*
QOpenGLVertexArrayObject
QOpenGLBuffer
QOpenGLShader
QOpenGLShaderProgram
QOpenGLFrameBufferObject
QOpenGLFrameBufferObjectFormat
Qt 5 and OpenGL Classes
27
● Small program that runs on the GPU
● Ran as part of the OpenGL pipeline
● Programmable
● Coded in GLSL (OpenGL Shading Language)
● Makes rendering infinitely flexible
What is a Shader?
28
Simplified Pipeline
29
Shaders
● Two kinds of shaders:
○ Shaders that deal with Vertices, i.E:
Vertex, Tessellation and Geometry shaders determine
where on the screen a primitive is.
○ Fragment Shader uses that information to determine
what color that fragment will be.
● Must have a version identifier at top of file
● Must have a main() function
● Each shader is compiled, then they are linked
together to make a shader program
● Input/output interfaces must match, and are
checked at link time
30
● Vertex Shader
○ Executed once for every vertex
○ Input: Content of Vertex Buffer Arrays and Uniforms
○ Output: Vertex position
● Fragment Shader
○ Executed once for every fragment
○ Input: Result of Rasterization after Vertex Shader
○ Output: Candidate pixel color (aka Fragment)
Shader Basics
31
● Preparing Shaders
○ Compile vertex shader
○ Compile fragment shader
○ Configure attribute locations before linking
○ Link both shaders into a shader program
● Preparing shaders with Qt vs pure OpenGL
○ Much less code
○ Less error prone
Prepare Shaders
32
Example: Use Qt to Create Shader Program
void OpenGLScene::createShaderProgram()
{
QByteArray version=OpenGLCheck::getShaderVersionString()+"n";
QFile vtFile(":/vertex.vsh");
vtFile.open((QIODevice::ReadOnly | QIODevice::Text));
QFile fsFile (":/fragment.fsh");
fsFile.open((QIODevice::ReadOnly | QIODevice::Text));
if (!m_shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex,version+vtFile.readAll())) {
qWarning() << "Error in vertex shader:" << m_shaderProgram.log();
exit(1);
}
if (!m_shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment,version+fsFile.readAll())) {
qWarning() << "Error in fragment shader:" << m_shaderProgram.log();
exit(1);
}
#if defined ICS_OPENGL_ES2==1
m_shaderProgram.bindAttributeLocation("vertexPosition", 0);
m_shaderProgram.bindAttributeLocation("vertexColor", 1);
#endif
if ( !m_shaderProgram.link() ) {
qDebug() << "Error linking shader program:" << m_shaderProgram.log();
exit(1);
}
}
● Create buffer object
● Bind the buffer, making it the active buffer
● Copy the data to the buffer
// Triangle vertices
float vertices[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 0.6f, 0.0f
};
// Create a static buffer for vertex data
m_vertexBuffer.create();
// Set usage pattern to Static Draw, (the data won't change)
m_vertexBuffer.setUsagePattern( QOpenGLBuffer::StaticDraw );
// Bind the buffer to the current OpenGL context
m_vertexBuffer.bind();
// Copy the data to the buffer
m_vertexBuffer.allocate( vertices, 3 * 3 * sizeof( float ) );
Creating a VBO
34
Vertex Attributes
● We have the data (in VBOs)
● We have the shaders compiled
● How do we map the data to the shader
attributes?
In OpenGL-ES, after compiling shaders and
before linking:
m_shaderProgram.bindAttributeLocation("vertexPosition", 0);
This assigns the attribute vertexPosition the
first location (0)
35
Mapping Attribute Data in Shaders
● When using Desktop OpenGL (version 3.2 and
higher) locations are set in the shaders:
#if __VERSION__ > 320
layout(location = 0) in vec3 vertexPosition;
layout(location = 1) in vec3 vertexColor;
out vec3 color;
#else
attribute vec3 vertexPosition;
attribute vec3 vertexColor;
varying lowp vec3 color;
#endif
● VBO data is mapped to shader attribute
locations
m_shaderProgram.bind();
m_vertexBuffer.bind();
int vertexLocation = m_shaderProgram.attributeLocation("vertexPosition");
m_shaderProgram.setAttributeBuffer(
vertexLocation, // layout location
GL_FLOAT, // data's type
0, // Offset to data in buffer
3); // number of components (3 for x,y,z)
○ Bind the shader program
○ Bind the VBO containing the attribute data
○ Enable the desired vertex attribute array location
○ Set the attribute buffer to desired attribute location, set
number of components and stride
○ Supports VBOs with interleaved data
Vertex Attribute Arrays
37
Defining Uniform Values in Qt
● Yep, It is that simple! OpenGLShaderProgram
has a myriad ways to do it, e.g.: m_shaderProgram.
bind();
// Get the location of uniform value "uni" in the shader.
int uniLocation = m_shaderProgram.uniformLocation("uni");
// Then update the value m_shaderProgram.
setUniformValue(uniLocation,uniValue);
// Or in one step m_shaderProgram.setUniformValue
("uni",0.8f,0.5f,0.5f);
● If the value changes during an animation this
code would go in the updateGL function
● If it is static it could go into initializeGL after the
shader program has been linked and bound
38
Deprecated OpenGL Matrix Stack
● OpenGL Desktop version < 3 used to have
“built in” matrix stacks and related functionality
for dealing with transformations and
projections
○ glRotate*, glTranslate*, glScale*
○ glMatrixMode(), glPushMatrix(), glPopMatrix()
○ glLoadIdentity()
○ glFrustum(), gluPerspective(...), gluLookAt(..)
● All of these are now deprecated and
should/can no longer be used
39
● Fortunately, it is very easy to achieve the
same functionality with more flexibility using Qt
● There are functions to:
○ Create or set a matrix to the identity matrix
■ Identity matrix is a diagonal matrix with all elements
being 1. When multiplied with a vector the result will
be the same vector.
○ Translate, Scale, Rotate
○ Create a (view) matrix representing a “camera”
○ Create perspective or orthographic projection matrix
● And then one can use QStack, QVector, QList
and gain ultimate flexibility
Matrices, Qt to the Rescue
40
● Contains convenient functions for handling
Model, View, and Projection Matrices
○ QMatrix4x4::translate()
○ QMatrix4x4::scale()
○ QMatrix4x4::rotate()
○ QMatrix4x4::lookAt()
○ QMatrix4x4::perspective()
○ QMatrix4x4::ortho()
QMatrix4x4
41
Example from porting our Glut Application
void resize (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
if (w <= h)
gluOrtho2D (0.0, 30.0, 0.0, 30.0 * (GLfloat) h/(GLfloat) w);
else
gluOrtho2D (0.0, 30.0 * (GLfloat) w/(GLfloat) h, 0.0, 30.0);
glMatrixMode(GL_MODELVIEW);
}
● Set the current MatrixMode such that subsequent matrix
operations apply to the projection matrix stack
● Load the Identity Matrix and then apply an orthogonal
projection transformation
● Set the current MatrixMode back to the model-view stack
class OpenGLScene : public QOpenGLFunctions
{
...
QMatrix4x4 m_projection;
...
void OpenGLScene::resize(int w, int h)
{
glViewport( 0, 0, w, h );
float a = (float)w/(float)h;
float l=30.0;
m_projection.setToIdentity();
if (w<=h)
m_projection.ortho(0,l,0,l/a, -1.0, 1.0f);
else
m_projection.ortho(0,l*a,0,l, -1.0, 1.0f);
}
void OpenGLScene::paint()
{
...
// Set MVP uniform to projection matrix
// since modelview is identity
m_shaderProgram.setUniformValue("MVP", m_projection);
...
Equivalent in Modern OpenGL with Qt
Vertex Shader Code:
attribute vec3 vertexPosition;
void main()
{
...
// Calculate the vertex position
gl_Position = MVP*vec4(vertexPosition, 1.0 );
...
}
● Qt- 5.2 introduces QOpenGLTexture to encapsulate an
OpenGL texture object
○ Makes it easy to work with OpenGL textures
○ Simplifies dealing with dependencies upon the capabilities of an OpenGL
implementation
● Typical usage pattern for QOpenGLTexture is
○ Instantiate the object specifying the texture target type
○ Set properties that affect storage requirements e.g. storage format,
dimensions
○ Allocate server-side storage
○ Optionally upload pixel data
○ Optionally set any additional properties e.g. filtering and border options
○ Render with texture or render to texture
○ In the common case of simply using a QImage as the source of texture
pixel data most of the above steps are performed automatically.
QOpenGLTexture
44
● Qt simplifies the process with:
○ QOpenGLFramebufferObject class
▪ Represents OpenGL FBO
▪ By default creates 2D texture for rendering target
▪ Function to return the OpenGL texture id
● Can be used for texture rendering
▪ Function to return rendered scene as a QImage
○ QOpenGLFramebufferObjectFormat()
▪ Specify format and attachments of FBO
Qt Support for FBO
45
Qt and OpenGL Extensions
● A list of all OpenGL extensions supported by the current
context can be retrieved with a call to
QSet<QByteArray> QOpenGLContext::​ extensions() const
The context or a sharing context must be current.
● Resolve the entry points if the extension introduces a new
API: QOpenGLContext::getProcAddress().
● QtOpenGLExtensions module contains a class for every
OpenGL extension in the Khronos registry that introduces
new API.
46
OpenGL Debugging with Qt
● OpenGL programming can be error prone
○ Black screen syndrom. There is no indication what is going on?
○ To be sure that no errors are being returned from OpenGL
implementation check glGetError after every API call
○ OpenGL errors stack up so need to use this in a loop.
○ Additional information e.g. performance issues, warnings about using
deprecated APIs are not reported through the ordinary OpenGL error
reporting mechanisms
● QOpenGLDebugLogger enables logging of OpenGL
debugging messages
○ Provides access to the OpenGL debug log if OpenGL implementation
supports it (by exposing the GL_KHR_debug extension)
○ Messages from the OpenGL server will either be logged in an internal
OpenGL log or passed in "real-time", i.e. as they're generated from
OpenGL, to listeners
47
OpenGL Debugging with Qt
● Creating an OpenGL Debug Context
○ OpenGL implementations are allowed not to create any debug output at
all, unless the OpenGL context is a debug context
○ Set QSurfaceFormat::DebugContext format option on the
QSurfaceFormat used to create the QOpenGLContext object:
format.setOption(QSurfaceFormat::DebugContext);
● Creating and Initializing a QOpenGLDebugLogger
○ QOpenGLDebugLogger is a simple QObject-derived class
○ Create an instance and initialize it before usage by calling
initialize() with a current OpenGL context:
QOpenGLContext *ctx = QOpenGLContext::currentContext();
QOpenGLDebugLogger *logger = new QOpenGLDebugLogger(this);
logger->initialize();
○ Note that GL_KHR_debug extension must be available in the context in
order to access the messages logged by OpenGL
○ You can check the presence of this extension by calling:
ctx->hasExtension(QByteArrayLiteral("GL_KHR_debug")) 48
Qt OpenGL Debug Messages
● Reading the Internal OpenGL Debug Log
○ Messages stored in the internal log of debug messages can be retrieved
by using the loggedMessages() function
QList<QOpenGLDebugMessage> messages = logger->loggedMessages();
foreach (const QOpenGLDebugMessage &message, messages)
qDebug() << message;
○ Internal log has limited size; Older messages will get discarded to make
room for new incoming messages
● Real-time logging of messages
○ Receive a stream of debug messages from the OpenGL server as they
are generated by the implementation
○ Connect a slot to the messageLogged() signal, and start logging by
calling startLogging():
connect(logger, &QOpenGLDebugLogger::messageLogged, receiver,
&LogHandler::handleLoggedMessage);
logger->startLogging();
● Similarly, logging can be disabled at any time by calling the stopLogging()
function.
49
● Measure GPU execution time of OpenGL calls
● Use to profile an application’s rendering
performance
● Timed results in nanoseconds
● Create and set number of samples that will be
taken, e.g:
m_timeMonitor = new QOpenGLTimeMonitor(this);
m_timeMonitor->setSampleCount(3);
if (!m_timeMonitor->create())
...Handle error
QOpenGLTimeMonitor
50
● QOpenGLTimeMonitor::recordSample() to
record interval
m_timeMonitor->recordSample();
glClear( GL_COLOR_BUFFER_BIT );
m_timeMonitor->recordSample();
glDrawArrays( GL_TRIANGLES, 0, 3 );
m_timeMonitor->recordSample();
QOpenGLTimeMonitor
51
● Call waitForSamples() or waitForIntervals()
to retrieve samples or intervals
(in nanoseconds)
QVector<GLuint64> samples = m_timeMonitor->waitForSamples();
QVector<GLuint64> intervals = m_timeMonitor->waitForIntervals();
o These functions block until values are ready
o Call isResultAvailable() to prevent blocking
● Reset to use again
m_timeMonitor->reset();
QOpenGLTimeMonitor
52
Conclusion
● Qt has many classes that make working with
OpenGL much more efficient.
● Cross platform capabilities of Qt enhance the
portability of OpenGL applications greatly.
● Developer efficiency translates directly to
maintenance costs and time to market.
● Qt is an ideal SDK for porting of legacy
scientific applications with requirements for
high performance visualization.

More Related Content

What's hot

Best Practices in Qt Quick/QML - Part 3
Best Practices in Qt Quick/QML - Part 3Best Practices in Qt Quick/QML - Part 3
Best Practices in Qt Quick/QML - Part 3ICS
 
Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4ICS
 
Exploring the internal state of user interfaces using sikuli
Exploring the internal state of user interfaces using sikuliExploring the internal state of user interfaces using sikuli
Exploring the internal state of user interfaces using sikuliGermiya K Jose
 
Qt for Beginners Part 3 - QML and Qt Quick
Qt for Beginners Part 3 - QML and Qt QuickQt for Beginners Part 3 - QML and Qt Quick
Qt for Beginners Part 3 - QML and Qt QuickICS
 
Practical Sikuli: using screenshots for GUI automation and testing
Practical Sikuli: using screenshots for GUI automation and testingPractical Sikuli: using screenshots for GUI automation and testing
Practical Sikuli: using screenshots for GUI automation and testingvgod
 
The Log of All Logs: Raft-based Consensus Inside Kafka | Guozhang Wang, Confl...
The Log of All Logs: Raft-based Consensus Inside Kafka | Guozhang Wang, Confl...The Log of All Logs: Raft-based Consensus Inside Kafka | Guozhang Wang, Confl...
The Log of All Logs: Raft-based Consensus Inside Kafka | Guozhang Wang, Confl...HostedbyConfluent
 
Google Kubernetes Engine (GKE) deep dive
Google Kubernetes Engine (GKE) deep diveGoogle Kubernetes Engine (GKE) deep dive
Google Kubernetes Engine (GKE) deep diveAkash Agrawal
 
Best Practices in Qt Quick/QML - Part IV
Best Practices in Qt Quick/QML - Part IVBest Practices in Qt Quick/QML - Part IV
Best Practices in Qt Quick/QML - Part IVICS
 
Introduction to the Qt Quick Scene Graph
Introduction to the Qt Quick Scene GraphIntroduction to the Qt Quick Scene Graph
Introduction to the Qt Quick Scene GraphICS
 
Qt multi threads
Qt multi threadsQt multi threads
Qt multi threadsYnon Perek
 
Software Development Best Practices: Separating UI from Business Logic
Software Development Best Practices: Separating UI from Business LogicSoftware Development Best Practices: Separating UI from Business Logic
Software Development Best Practices: Separating UI from Business LogicICS
 
Best Practices in Qt Quick/QML - Part 4
Best Practices in Qt Quick/QML - Part 4Best Practices in Qt Quick/QML - Part 4
Best Practices in Qt Quick/QML - Part 4ICS
 
Introduction to QML
Introduction to QMLIntroduction to QML
Introduction to QMLAlan Uthoff
 
Understaing Android EGL
Understaing Android EGLUnderstaing Android EGL
Understaing Android EGLSuhan Lee
 
Unreal Engine Basics 03 - Gameplay
Unreal Engine Basics 03 - GameplayUnreal Engine Basics 03 - Gameplay
Unreal Engine Basics 03 - GameplayNick Pruehs
 
Forts and Fights Scaling Performance on Unreal Engine*
Forts and Fights Scaling Performance on Unreal Engine*Forts and Fights Scaling Performance on Unreal Engine*
Forts and Fights Scaling Performance on Unreal Engine*Intel® Software
 
Best Practices in Qt Quick/QML - Part II
Best Practices in Qt Quick/QML - Part IIBest Practices in Qt Quick/QML - Part II
Best Practices in Qt Quick/QML - Part IIICS
 
Flutter + tensor flow lite = awesome sauce
Flutter + tensor flow lite = awesome sauceFlutter + tensor flow lite = awesome sauce
Flutter + tensor flow lite = awesome sauceAmit Sharma
 
Jetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on AndroidJetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on AndroidNelson Glauber Leal
 

What's hot (20)

Best Practices in Qt Quick/QML - Part 3
Best Practices in Qt Quick/QML - Part 3Best Practices in Qt Quick/QML - Part 3
Best Practices in Qt Quick/QML - Part 3
 
Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4
 
Exploring the internal state of user interfaces using sikuli
Exploring the internal state of user interfaces using sikuliExploring the internal state of user interfaces using sikuli
Exploring the internal state of user interfaces using sikuli
 
Qt for Beginners Part 3 - QML and Qt Quick
Qt for Beginners Part 3 - QML and Qt QuickQt for Beginners Part 3 - QML and Qt Quick
Qt for Beginners Part 3 - QML and Qt Quick
 
Practical Sikuli: using screenshots for GUI automation and testing
Practical Sikuli: using screenshots for GUI automation and testingPractical Sikuli: using screenshots for GUI automation and testing
Practical Sikuli: using screenshots for GUI automation and testing
 
The Log of All Logs: Raft-based Consensus Inside Kafka | Guozhang Wang, Confl...
The Log of All Logs: Raft-based Consensus Inside Kafka | Guozhang Wang, Confl...The Log of All Logs: Raft-based Consensus Inside Kafka | Guozhang Wang, Confl...
The Log of All Logs: Raft-based Consensus Inside Kafka | Guozhang Wang, Confl...
 
Google Kubernetes Engine (GKE) deep dive
Google Kubernetes Engine (GKE) deep diveGoogle Kubernetes Engine (GKE) deep dive
Google Kubernetes Engine (GKE) deep dive
 
Best Practices in Qt Quick/QML - Part IV
Best Practices in Qt Quick/QML - Part IVBest Practices in Qt Quick/QML - Part IV
Best Practices in Qt Quick/QML - Part IV
 
Qt Qml
Qt QmlQt Qml
Qt Qml
 
Introduction to the Qt Quick Scene Graph
Introduction to the Qt Quick Scene GraphIntroduction to the Qt Quick Scene Graph
Introduction to the Qt Quick Scene Graph
 
Qt multi threads
Qt multi threadsQt multi threads
Qt multi threads
 
Software Development Best Practices: Separating UI from Business Logic
Software Development Best Practices: Separating UI from Business LogicSoftware Development Best Practices: Separating UI from Business Logic
Software Development Best Practices: Separating UI from Business Logic
 
Best Practices in Qt Quick/QML - Part 4
Best Practices in Qt Quick/QML - Part 4Best Practices in Qt Quick/QML - Part 4
Best Practices in Qt Quick/QML - Part 4
 
Introduction to QML
Introduction to QMLIntroduction to QML
Introduction to QML
 
Understaing Android EGL
Understaing Android EGLUnderstaing Android EGL
Understaing Android EGL
 
Unreal Engine Basics 03 - Gameplay
Unreal Engine Basics 03 - GameplayUnreal Engine Basics 03 - Gameplay
Unreal Engine Basics 03 - Gameplay
 
Forts and Fights Scaling Performance on Unreal Engine*
Forts and Fights Scaling Performance on Unreal Engine*Forts and Fights Scaling Performance on Unreal Engine*
Forts and Fights Scaling Performance on Unreal Engine*
 
Best Practices in Qt Quick/QML - Part II
Best Practices in Qt Quick/QML - Part IIBest Practices in Qt Quick/QML - Part II
Best Practices in Qt Quick/QML - Part II
 
Flutter + tensor flow lite = awesome sauce
Flutter + tensor flow lite = awesome sauceFlutter + tensor flow lite = awesome sauce
Flutter + tensor flow lite = awesome sauce
 
Jetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on AndroidJetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on Android
 

Similar to Convert Your Legacy OpenGL Code to Modern OpenGL with Qt

OpenGL Introduction.
OpenGL Introduction.OpenGL Introduction.
OpenGL Introduction.Girish Ghate
 
openGL basics for sample program (1).ppt
openGL basics for sample program (1).pptopenGL basics for sample program (1).ppt
openGL basics for sample program (1).pptHIMANKMISHRA2
 
openGL basics for sample program.ppt
openGL basics for sample program.pptopenGL basics for sample program.ppt
openGL basics for sample program.pptHIMANKMISHRA2
 
Lecture 6 introduction to open gl and glut
Lecture 6   introduction to open gl and glutLecture 6   introduction to open gl and glut
Lecture 6 introduction to open gl and glutsimpleok
 
Necessitas - Qt on Android - from FSCONS 2011
Necessitas - Qt on Android - from FSCONS 2011Necessitas - Qt on Android - from FSCONS 2011
Necessitas - Qt on Android - from FSCONS 2011Johan Thelin
 
OpenGL Fixed Function to Shaders - Porting a fixed function application to “m...
OpenGL Fixed Function to Shaders - Porting a fixed function application to “m...OpenGL Fixed Function to Shaders - Porting a fixed function application to “m...
OpenGL Fixed Function to Shaders - Porting a fixed function application to “m...ICS
 
COMPUTER GRAPHICS PROJECT REPORT
COMPUTER GRAPHICS PROJECT REPORTCOMPUTER GRAPHICS PROJECT REPORT
COMPUTER GRAPHICS PROJECT REPORTvineet raj
 
The Ring programming language version 1.8 book - Part 60 of 202
The Ring programming language version 1.8 book - Part 60 of 202The Ring programming language version 1.8 book - Part 60 of 202
The Ring programming language version 1.8 book - Part 60 of 202Mahmoud Samir Fayed
 
01.Opengl_intro-2.ppt
01.Opengl_intro-2.ppt01.Opengl_intro-2.ppt
01.Opengl_intro-2.pptEngrZamaan
 
Intro to Computer Graphics.ppt
Intro to Computer Graphics.pptIntro to Computer Graphics.ppt
Intro to Computer Graphics.pptadil104135
 

Similar to Convert Your Legacy OpenGL Code to Modern OpenGL with Qt (20)

Open gl
Open glOpen gl
Open gl
 
Opengl (1)
Opengl (1)Opengl (1)
Opengl (1)
 
OpenGL Introduction.
OpenGL Introduction.OpenGL Introduction.
OpenGL Introduction.
 
openGL basics for sample program (1).ppt
openGL basics for sample program (1).pptopenGL basics for sample program (1).ppt
openGL basics for sample program (1).ppt
 
openGL basics for sample program.ppt
openGL basics for sample program.pptopenGL basics for sample program.ppt
openGL basics for sample program.ppt
 
Lecture 6 introduction to open gl and glut
Lecture 6   introduction to open gl and glutLecture 6   introduction to open gl and glut
Lecture 6 introduction to open gl and glut
 
Qt Programming on TI Processors
Qt Programming on TI ProcessorsQt Programming on TI Processors
Qt Programming on TI Processors
 
Baiscs of OpenGL
Baiscs of OpenGLBaiscs of OpenGL
Baiscs of OpenGL
 
18csl67 vtu lab manual
18csl67 vtu lab manual18csl67 vtu lab manual
18csl67 vtu lab manual
 
Necessitas - Qt on Android - from FSCONS 2011
Necessitas - Qt on Android - from FSCONS 2011Necessitas - Qt on Android - from FSCONS 2011
Necessitas - Qt on Android - from FSCONS 2011
 
Bai 1
Bai 1Bai 1
Bai 1
 
OpenGL Fixed Function to Shaders - Porting a fixed function application to “m...
OpenGL Fixed Function to Shaders - Porting a fixed function application to “m...OpenGL Fixed Function to Shaders - Porting a fixed function application to “m...
OpenGL Fixed Function to Shaders - Porting a fixed function application to “m...
 
Open gl
Open glOpen gl
Open gl
 
COMPUTER GRAPHICS PROJECT REPORT
COMPUTER GRAPHICS PROJECT REPORTCOMPUTER GRAPHICS PROJECT REPORT
COMPUTER GRAPHICS PROJECT REPORT
 
The Ring programming language version 1.8 book - Part 60 of 202
The Ring programming language version 1.8 book - Part 60 of 202The Ring programming language version 1.8 book - Part 60 of 202
The Ring programming language version 1.8 book - Part 60 of 202
 
01.Opengl_intro-2.ppt
01.Opengl_intro-2.ppt01.Opengl_intro-2.ppt
01.Opengl_intro-2.ppt
 
BYO3D 2011: Rendering
BYO3D 2011: RenderingBYO3D 2011: Rendering
BYO3D 2011: Rendering
 
opengl.ppt
opengl.pptopengl.ppt
opengl.ppt
 
Intro to Computer Graphics.ppt
Intro to Computer Graphics.pptIntro to Computer Graphics.ppt
Intro to Computer Graphics.ppt
 
Open gl tips
Open gl tipsOpen gl tips
Open gl tips
 

More from ICS

Practical Advice for FDA’s 510(k) Requirements.pdf
Practical Advice for FDA’s 510(k) Requirements.pdfPractical Advice for FDA’s 510(k) Requirements.pdf
Practical Advice for FDA’s 510(k) Requirements.pdfICS
 
Accelerating Development of a Safety-Critical Cobot Welding System with Qt/QM...
Accelerating Development of a Safety-Critical Cobot Welding System with Qt/QM...Accelerating Development of a Safety-Critical Cobot Welding System with Qt/QM...
Accelerating Development of a Safety-Critical Cobot Welding System with Qt/QM...ICS
 
Overcoming CMake Configuration Issues Webinar
Overcoming CMake Configuration Issues WebinarOvercoming CMake Configuration Issues Webinar
Overcoming CMake Configuration Issues WebinarICS
 
Enhancing Quality and Test in Medical Device Design - Part 2.pdf
Enhancing Quality and Test in Medical Device Design - Part 2.pdfEnhancing Quality and Test in Medical Device Design - Part 2.pdf
Enhancing Quality and Test in Medical Device Design - Part 2.pdfICS
 
Designing and Managing IoT Devices for Rapid Deployment - Webinar.pdf
Designing and Managing IoT Devices for Rapid Deployment - Webinar.pdfDesigning and Managing IoT Devices for Rapid Deployment - Webinar.pdf
Designing and Managing IoT Devices for Rapid Deployment - Webinar.pdfICS
 
Quality and Test in Medical Device Design - Part 1.pdf
Quality and Test in Medical Device Design - Part 1.pdfQuality and Test in Medical Device Design - Part 1.pdf
Quality and Test in Medical Device Design - Part 1.pdfICS
 
Creating Digital Twins Using Rapid Development Techniques.pdf
Creating Digital Twins Using Rapid Development Techniques.pdfCreating Digital Twins Using Rapid Development Techniques.pdf
Creating Digital Twins Using Rapid Development Techniques.pdfICS
 
Secure Your Medical Devices From the Ground Up
Secure Your Medical Devices From the Ground Up Secure Your Medical Devices From the Ground Up
Secure Your Medical Devices From the Ground Up ICS
 
Cybersecurity and Software Updates in Medical Devices.pdf
Cybersecurity and Software Updates in Medical Devices.pdfCybersecurity and Software Updates in Medical Devices.pdf
Cybersecurity and Software Updates in Medical Devices.pdfICS
 
MDG Panel - Creating Expert Level GUIs for Complex Medical Devices
MDG Panel - Creating Expert Level GUIs for Complex Medical DevicesMDG Panel - Creating Expert Level GUIs for Complex Medical Devices
MDG Panel - Creating Expert Level GUIs for Complex Medical DevicesICS
 
How to Craft a Winning IOT Device Management Solution
How to Craft a Winning IOT Device Management SolutionHow to Craft a Winning IOT Device Management Solution
How to Craft a Winning IOT Device Management SolutionICS
 
Bridging the Gap Between Development and Regulatory Teams
Bridging the Gap Between Development and Regulatory TeamsBridging the Gap Between Development and Regulatory Teams
Bridging the Gap Between Development and Regulatory TeamsICS
 
IoT Device Fleet Management: Create a Robust Solution with Azure
IoT Device Fleet Management: Create a Robust Solution with AzureIoT Device Fleet Management: Create a Robust Solution with Azure
IoT Device Fleet Management: Create a Robust Solution with AzureICS
 
Basic Cmake for Qt Users
Basic Cmake for Qt UsersBasic Cmake for Qt Users
Basic Cmake for Qt UsersICS
 
Software Update Mechanisms: Selecting the Best Solutin for Your Embedded Linu...
Software Update Mechanisms: Selecting the Best Solutin for Your Embedded Linu...Software Update Mechanisms: Selecting the Best Solutin for Your Embedded Linu...
Software Update Mechanisms: Selecting the Best Solutin for Your Embedded Linu...ICS
 
Qt Installer Framework
Qt Installer FrameworkQt Installer Framework
Qt Installer FrameworkICS
 
Bridging the Gap Between Development and Regulatory Teams
Bridging the Gap Between Development and Regulatory TeamsBridging the Gap Between Development and Regulatory Teams
Bridging the Gap Between Development and Regulatory TeamsICS
 
Overcome Hardware And Software Challenges - Medical Device Case Study
Overcome Hardware And Software Challenges - Medical Device Case StudyOvercome Hardware And Software Challenges - Medical Device Case Study
Overcome Hardware And Software Challenges - Medical Device Case StudyICS
 
User Experience Design for IoT
User Experience Design for IoTUser Experience Design for IoT
User Experience Design for IoTICS
 
Software Bill of Materials - Accelerating Your Secure Embedded Development.pdf
Software Bill of Materials - Accelerating Your Secure Embedded Development.pdfSoftware Bill of Materials - Accelerating Your Secure Embedded Development.pdf
Software Bill of Materials - Accelerating Your Secure Embedded Development.pdfICS
 

More from ICS (20)

Practical Advice for FDA’s 510(k) Requirements.pdf
Practical Advice for FDA’s 510(k) Requirements.pdfPractical Advice for FDA’s 510(k) Requirements.pdf
Practical Advice for FDA’s 510(k) Requirements.pdf
 
Accelerating Development of a Safety-Critical Cobot Welding System with Qt/QM...
Accelerating Development of a Safety-Critical Cobot Welding System with Qt/QM...Accelerating Development of a Safety-Critical Cobot Welding System with Qt/QM...
Accelerating Development of a Safety-Critical Cobot Welding System with Qt/QM...
 
Overcoming CMake Configuration Issues Webinar
Overcoming CMake Configuration Issues WebinarOvercoming CMake Configuration Issues Webinar
Overcoming CMake Configuration Issues Webinar
 
Enhancing Quality and Test in Medical Device Design - Part 2.pdf
Enhancing Quality and Test in Medical Device Design - Part 2.pdfEnhancing Quality and Test in Medical Device Design - Part 2.pdf
Enhancing Quality and Test in Medical Device Design - Part 2.pdf
 
Designing and Managing IoT Devices for Rapid Deployment - Webinar.pdf
Designing and Managing IoT Devices for Rapid Deployment - Webinar.pdfDesigning and Managing IoT Devices for Rapid Deployment - Webinar.pdf
Designing and Managing IoT Devices for Rapid Deployment - Webinar.pdf
 
Quality and Test in Medical Device Design - Part 1.pdf
Quality and Test in Medical Device Design - Part 1.pdfQuality and Test in Medical Device Design - Part 1.pdf
Quality and Test in Medical Device Design - Part 1.pdf
 
Creating Digital Twins Using Rapid Development Techniques.pdf
Creating Digital Twins Using Rapid Development Techniques.pdfCreating Digital Twins Using Rapid Development Techniques.pdf
Creating Digital Twins Using Rapid Development Techniques.pdf
 
Secure Your Medical Devices From the Ground Up
Secure Your Medical Devices From the Ground Up Secure Your Medical Devices From the Ground Up
Secure Your Medical Devices From the Ground Up
 
Cybersecurity and Software Updates in Medical Devices.pdf
Cybersecurity and Software Updates in Medical Devices.pdfCybersecurity and Software Updates in Medical Devices.pdf
Cybersecurity and Software Updates in Medical Devices.pdf
 
MDG Panel - Creating Expert Level GUIs for Complex Medical Devices
MDG Panel - Creating Expert Level GUIs for Complex Medical DevicesMDG Panel - Creating Expert Level GUIs for Complex Medical Devices
MDG Panel - Creating Expert Level GUIs for Complex Medical Devices
 
How to Craft a Winning IOT Device Management Solution
How to Craft a Winning IOT Device Management SolutionHow to Craft a Winning IOT Device Management Solution
How to Craft a Winning IOT Device Management Solution
 
Bridging the Gap Between Development and Regulatory Teams
Bridging the Gap Between Development and Regulatory TeamsBridging the Gap Between Development and Regulatory Teams
Bridging the Gap Between Development and Regulatory Teams
 
IoT Device Fleet Management: Create a Robust Solution with Azure
IoT Device Fleet Management: Create a Robust Solution with AzureIoT Device Fleet Management: Create a Robust Solution with Azure
IoT Device Fleet Management: Create a Robust Solution with Azure
 
Basic Cmake for Qt Users
Basic Cmake for Qt UsersBasic Cmake for Qt Users
Basic Cmake for Qt Users
 
Software Update Mechanisms: Selecting the Best Solutin for Your Embedded Linu...
Software Update Mechanisms: Selecting the Best Solutin for Your Embedded Linu...Software Update Mechanisms: Selecting the Best Solutin for Your Embedded Linu...
Software Update Mechanisms: Selecting the Best Solutin for Your Embedded Linu...
 
Qt Installer Framework
Qt Installer FrameworkQt Installer Framework
Qt Installer Framework
 
Bridging the Gap Between Development and Regulatory Teams
Bridging the Gap Between Development and Regulatory TeamsBridging the Gap Between Development and Regulatory Teams
Bridging the Gap Between Development and Regulatory Teams
 
Overcome Hardware And Software Challenges - Medical Device Case Study
Overcome Hardware And Software Challenges - Medical Device Case StudyOvercome Hardware And Software Challenges - Medical Device Case Study
Overcome Hardware And Software Challenges - Medical Device Case Study
 
User Experience Design for IoT
User Experience Design for IoTUser Experience Design for IoT
User Experience Design for IoT
 
Software Bill of Materials - Accelerating Your Secure Embedded Development.pdf
Software Bill of Materials - Accelerating Your Secure Embedded Development.pdfSoftware Bill of Materials - Accelerating Your Secure Embedded Development.pdf
Software Bill of Materials - Accelerating Your Secure Embedded Development.pdf
 

Recently uploaded

What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 

Recently uploaded (20)

What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 

Convert Your Legacy OpenGL Code to Modern OpenGL with Qt

  • 1. Convert your Legacy OpenGL Code to Modern OpenGL with Qt Dr. Roland Krause Integrated Computer Solutions
  • 2. Abstract OpenGL is a powerful, low level graphics toolkit with a steep learning curve that allows access to accelerated GPU hardware. Using OpenGL developers achieve high-fidelity, animated graphics ubiquitous in games, screen productions and scientific software. Due to OpenGL’s native C-language API large scale, professional software development endeavors wanting to utilize the advantages of direct and accelerated graphics quickly become expensive and hard to maintain. This presentation gives a comprehensive overview of the many aspects of OpenGL development where Qt provides advanced interfaces that let the developer focus on the tasks at hand instead of dealing with repetitive and error- prone, platform dependent issues. From handling of Window related tasks, providing type-safe data-structures for Vertex Array Objects to managing Shader Programs, dealing with Textures, Frame Buffer Objects all the way to support for Debugging and Profiling of OpenGL Applications we show solutions to the most common issues any OpenGL program has to address. We are able to demonstrate why Qt is the best C++ framework for development of modern OpenGL based graphics applications.
  • 3. Modern OpenGL with Qt ● OpenGL is an Application Programming Interface (API) for Rendering Graphics in 2D and 3D ○ Widely used in CAD, Virtual Reality, Scientific Visualization, Information Visualization, Flight Simulation, and Video Games. ○ Over 500 commands in Version 4.3 ○ Managed by the non-profit technology consortium Khronos Group. ● Designed as a Streamlined, Hardware Independent Interface ○ To be efficient usually implemented on graphics hardware (GPU) ○ Independent of Operating System or Windowing System, Cross-platform ○ No functions for windowing tasks, managing state, user input, 3D models or reading image files That’s where Qt comes into play!
  • 4. In the Olden Days... ● Glut (or SDL) was the way to platform independent code ○ For platform dependent code there are WGL, AGL, GLX int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(resize); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }
  • 5. A simple Triangle in Fixed Pipeline OpenGL void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_SMOOTH); } void triangle(void) { glBegin (GL_TRIANGLES); glColor3f (1.0, 0.0, 0.0); glVertex2f (5.0, 5.0); glColor3f (0.0, 1.0, 0.0); glVertex2f (25.0, 5.0); glColor3f (0.0, 0.0, 1.0); glVertex2f (5.0, 25.0); glEnd(); } void display(void) { glClear (GL_COLOR_BUFFER_BIT); triangle (); glFlush (); }
  • 6. Render a Scene with Modern OpenGL 1. Create OpenGL Context and Window 2. Create and Manage the OpenGL Scene ○ Create Geometry ■ Store Geometry in Vertex Buffer Objects (VBOs) ■ Manage VBOs using Vertex Array Objects (VAOs) ○ Compile and Link Shaders into Shader Programs ○ Configure the Rendering Pipeline ○ Set Attribute Arrays, Uniforms, Textures, etc… 3. Render the Scene using OpenGL Primitives
  • 7. Integration of OpenGL with Qt ● There are several possibilities when integrating OpenGL Rendering with Qt 1. Native OpenGL rendering using QWindow and QOpenGLContext 2. QOpenGLWindow ○ Wrapper for QWindow that hides complexity ○ Can be OpenGL Canvas with QPainter syntax 3. QOpenGLWidget ○ QWidget based applications 4. QQuickFramebufferObject ○ new since Qt-5.4 5. Rendering into the SceneGraph 6. Custom QQuickItem 7
  • 8. Create OpenGL Context and Window ● Since Qt 5 the class QWindow represents a window in the underlying windowing system ○ In Qt 4, QWidget had both Window and Widget functionality ○ In Qt 5, QWindow is part of the gui module, QWidget is in a separate and now optional module (widgets) ○ Applications will typically use QWidget or QQuickView to create user interfaces ● It is possible to render directly to a QWindow with a QOpenGLContext ● QWindow can be embedded in a QWidget 8
  • 9. QOpenGLWindow ● Convenience subclass of QWindow to perform OpenGL painting ○ Enhanced QWindow that allows easily creating windows that perform OpenGL rendering ○ API compatible with QOpenGLWidget and similar to the legacy QGLWidget. ○ No dependency on widgets module and better performance. ○ Optionally backed by a framebuffer object ○ Default behavior (and thus performance) is equivalent to QWindow. 9
  • 10. Using QOpenGLWindow ● Subclass QOpenGLWindow and reimplement the following virtual functions: ○ initializeGL() to perform OpenGL resource initialization ○ resizeGL() to set up the transformation matrices and other window size dependent resources ○ paintGL() to issue OpenGL commands or draw using QPainter ● To schedule a repaint, call update() ○ Note that this will not immediately result in a call to paintGL(). ○ This is a slot so it can be connected to a QTimer:: timeout() signal to perform animation. 10
  • 11. Simple Triangle in Modern OpenGL void OpenGLScene::initialize() {...} void OpenGLScene::createBuffers() {...} void OpenGLScene::setupVertexArrayState() {...} void OpenGLScene::paint() { glClear( GL_COLOR_BUFFER_BIT ); if(!m_shaderProgram.isLinked()) return; m_shaderProgram.bind(); m_vao.bind(); m_shaderProgram.setUniformValue("MVP", m_projection); glDrawArrays(GL_TRIANGLES, 0, 3); m_shaderProgram.release(); } void OpenGLScene::resize(int w, int h) {...} void OpenGLScene::createShaderProgram() {...} let’s look closer at the code ...
  • 12. QOpenGLWindow using QPainter ● QOpenGLWindow inherits QPaintDeviceWindow ● Allows opening a painter on itself and perform QPainter-based drawing: void paintGL() { QOpenGLFunctions *f = context()->functions(); f->glClear(GL_COLOR_BIT | GL_DEPTH_BUFFER_BIT); // issue some native OpenGL commands QPainter p(this); // draw using QPainter // animate continuously: schedule an update update(); } 12
  • 14. ● State machine that stores all data related to the OpenGL rendering state ○ Most OpenGL functions set or retrieve some state ○ Creating a window and an OpenGL context is not part of the OpenGL specification ● QOpenGLContext represents a native OpenGL context ○ Enables OpenGL rendering on a QSurface. ○ Context allow to share resources with other contexts with setShareContext() OpenGL Context 14
  • 15. QOpenGLContext To create: ● Create a QSurfaceFormat object ○ Set desired OpenGL version and profile ● Create the QOpenGLContext ○ Set the context format using the QSurfaceFormat object ● Finally call QOpenGLContext::create() ○ Use return value or isValid() to check if the context was successfully initialized ● Before using any OpenGL QOpenGLContext must be made current against a surface ○ QOpenGLContext::makeCurrent(QSurface*) 15
  • 16. ● When OpenGL rendering is done ○ Call swapBuffers() to swap the front and back buffers of the surface at the end of the update function ○ Newly rendered content becomes visible ○ QOpenGLContext requires to call makeCurrent() again before starting rendering a new frame, after calling swapBuffers() ● QOpenGLWindow takes care of all of it! ● Use QOpenGLContext::format() to retrieve info on the context ○ Returns a QSurfaceFormat ○ OpenGL version, profile, etc... QOpenGLContext 16
  • 17. Converting Legacy Qt OpenGL Code ● When porting code from Qt4 to Qt5 we find that QGLWidget is marked obsolete ● The replacement, QOpenGLWidget, has the same familiar API but works differently Qt4 Legacy Classes Qt5 Modern OpenGL Classes QGLWidget QOpenGLWidget QGLFormat QSurfaceFormat QGLContext QOpenGLContext
  • 18. QOpenGLWidget ● Can be used on Embedded Systems with eglfs and wayland plugins ● Uses same technology as QQuickWidget ○ Unlike QGLWidget it is not a native window ● On desktop platforms, OpenGL 3.x and 4.x, including core profiles, are fully supported ○ QGLWidget forced the usage of legacy, incomplete utility classes like QGLFormat and QGLContext ○ QOpenGLWidget uses the modern equivalents from the QtGui module: QSurfaceFormat, QOpenGLContext
  • 20. Important Differences QGLWidget vs QOpenGLWidget ● QOpenGLWidget always renders offscreen, using framebuffer objects. ● QGLWidget on the other hand uses a native window and surface. ○ Depending on platform native child widgets may have various limitations (e.g. eglfs) ○ QOpenGLWidget avoids this by not creating a separate native window. ● Behavior of QOpenGLWidget is very similar to QOpenGLWindow ○ Update behavior can be set to PartialUpdateBlit or PartialUpdateBlend. ○ Contents are preserved between paintGL() calls so that incremental rendering is possible.
  • 21. QOpenGLWidget Hints ● When rendering everything in the view on every paint call: ○ Important to call glClear() as early as possible in paintGL(). ○ Mobile GPUs can optimize reloads of the tile buffer. ○ Omitting the clear call can lead to significant performance drops ● Avoid calling winId() on a QOpenGLWidget. ○ This function triggers the creation of a native window, resulting in reduced performance and possibly rendering glitches. ● Putting other Widgets underneath and making the QOpenGLWidget transparent will not show as expected: ○ Widgets underneath will not be visible because QOpenGLWidget is drawn before all other non-OpenGL widgets. ○ Having widgets on top of the QOpenGLWidget, will function as expected. ● Alternative with Limitations is QOpenGLWindow with QWidget::createWindowContainer()
  • 22. Qt’s OpenGL Support ● QOpenGLFunctions are convenience classes ● Simplify writing of OpenGL code ● Hide complexities of extension handling ● Hide differences between OpenGL ES 2 and desktop OpenGL ○ Allow the use of OpenGL ES 2 functions on Desktop OpenGL ○ No need to manually resolve OpenGL function pointers ○ Allowing cross-platform development of applications targeting mobile or embedded devices 22
  • 23. QAbstractOpenGLFunctions ● Family of classes that expose all functions for a given OpenGL version and profile ○ OpenGL implementations on different platforms are able to link to a variable number of OpenGL functions depending upon the OpenGL ABI on that platform ○ On many platforms most functions must be resolved at runtime, Options are: ■ Work with raw function pointers: QOpenGLContext::getProcAddress() ■ Use QOpenGLFunctions and only expose those functions common to OpenGL ES 2 and desktop OpenGL 23
  • 24. QAbstractOpenGLFunctions (cont.) ● Provides better support for newer versions of OpenGL (especially 3.0 and higher) ● Ease development of desktop applications relying on modern, desktop-only OpenGL features ● QOpenGLFunctions_X_Y_PROFILE ○ Core and Compatibility Profiles ○ Expose every core OpenGL function by way of a corresponding member function ○ Class for every valid combination of OpenGL version and profile following the naming convention: QOpenGLFunctions_<MAJOR VERSION>_<MINOR VERSION>[_PROFILE] 24
  • 25. ● Ensure QOpenGLContext is current before using it ● Call QOpenGLFunctions_X_Y_PROFILE::initializeOpenGLFunctions() once before using it to resolve function pointers Using QOpenGLFunctions_X_Y_PROFILE 25
  • 26. Qt’s OpenGL Support ● Classes that wrap native OpenGL Resources ○ QOpenGLBuffer, QOpenGLFramebufferObject QOpenGLShaderProgram, OpenGLTexture, QOpenGLVertexArrayObject ● Qt GUI Module Contains ○ QMatrix4x4, QVector4D and QQuaternion ○ Support common mathematical operations for 3D graphics ● Miscellaneous ○ Debugging, QOpenGLDebugLogger ○ Timing, QOpenGLTimeMonitor, QOpenGLTimerQuery 26
  • 27. QOpenGLDebugLogger QOpenGLDebugMessage QOpenGLTimeMonitor QOpenGLTimerQuery QOpenGLPaintDevice QOpenGLTexture (Qt 5.3) QOpenGLWidget(Qt 5.4) QOpenGLWindow(Qt 5.4) QOpenGLContext QOpenGLContextGroup QOpenGLVersionProfile QOpenGLFunctions* QOpenGLVertexArrayObject QOpenGLBuffer QOpenGLShader QOpenGLShaderProgram QOpenGLFrameBufferObject QOpenGLFrameBufferObjectFormat Qt 5 and OpenGL Classes 27
  • 28. ● Small program that runs on the GPU ● Ran as part of the OpenGL pipeline ● Programmable ● Coded in GLSL (OpenGL Shading Language) ● Makes rendering infinitely flexible What is a Shader? 28
  • 30. Shaders ● Two kinds of shaders: ○ Shaders that deal with Vertices, i.E: Vertex, Tessellation and Geometry shaders determine where on the screen a primitive is. ○ Fragment Shader uses that information to determine what color that fragment will be. ● Must have a version identifier at top of file ● Must have a main() function ● Each shader is compiled, then they are linked together to make a shader program ● Input/output interfaces must match, and are checked at link time 30
  • 31. ● Vertex Shader ○ Executed once for every vertex ○ Input: Content of Vertex Buffer Arrays and Uniforms ○ Output: Vertex position ● Fragment Shader ○ Executed once for every fragment ○ Input: Result of Rasterization after Vertex Shader ○ Output: Candidate pixel color (aka Fragment) Shader Basics 31
  • 32. ● Preparing Shaders ○ Compile vertex shader ○ Compile fragment shader ○ Configure attribute locations before linking ○ Link both shaders into a shader program ● Preparing shaders with Qt vs pure OpenGL ○ Much less code ○ Less error prone Prepare Shaders 32
  • 33. Example: Use Qt to Create Shader Program void OpenGLScene::createShaderProgram() { QByteArray version=OpenGLCheck::getShaderVersionString()+"n"; QFile vtFile(":/vertex.vsh"); vtFile.open((QIODevice::ReadOnly | QIODevice::Text)); QFile fsFile (":/fragment.fsh"); fsFile.open((QIODevice::ReadOnly | QIODevice::Text)); if (!m_shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex,version+vtFile.readAll())) { qWarning() << "Error in vertex shader:" << m_shaderProgram.log(); exit(1); } if (!m_shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment,version+fsFile.readAll())) { qWarning() << "Error in fragment shader:" << m_shaderProgram.log(); exit(1); } #if defined ICS_OPENGL_ES2==1 m_shaderProgram.bindAttributeLocation("vertexPosition", 0); m_shaderProgram.bindAttributeLocation("vertexColor", 1); #endif if ( !m_shaderProgram.link() ) { qDebug() << "Error linking shader program:" << m_shaderProgram.log(); exit(1); } }
  • 34. ● Create buffer object ● Bind the buffer, making it the active buffer ● Copy the data to the buffer // Triangle vertices float vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.6f, 0.0f }; // Create a static buffer for vertex data m_vertexBuffer.create(); // Set usage pattern to Static Draw, (the data won't change) m_vertexBuffer.setUsagePattern( QOpenGLBuffer::StaticDraw ); // Bind the buffer to the current OpenGL context m_vertexBuffer.bind(); // Copy the data to the buffer m_vertexBuffer.allocate( vertices, 3 * 3 * sizeof( float ) ); Creating a VBO 34
  • 35. Vertex Attributes ● We have the data (in VBOs) ● We have the shaders compiled ● How do we map the data to the shader attributes? In OpenGL-ES, after compiling shaders and before linking: m_shaderProgram.bindAttributeLocation("vertexPosition", 0); This assigns the attribute vertexPosition the first location (0) 35
  • 36. Mapping Attribute Data in Shaders ● When using Desktop OpenGL (version 3.2 and higher) locations are set in the shaders: #if __VERSION__ > 320 layout(location = 0) in vec3 vertexPosition; layout(location = 1) in vec3 vertexColor; out vec3 color; #else attribute vec3 vertexPosition; attribute vec3 vertexColor; varying lowp vec3 color; #endif
  • 37. ● VBO data is mapped to shader attribute locations m_shaderProgram.bind(); m_vertexBuffer.bind(); int vertexLocation = m_shaderProgram.attributeLocation("vertexPosition"); m_shaderProgram.setAttributeBuffer( vertexLocation, // layout location GL_FLOAT, // data's type 0, // Offset to data in buffer 3); // number of components (3 for x,y,z) ○ Bind the shader program ○ Bind the VBO containing the attribute data ○ Enable the desired vertex attribute array location ○ Set the attribute buffer to desired attribute location, set number of components and stride ○ Supports VBOs with interleaved data Vertex Attribute Arrays 37
  • 38. Defining Uniform Values in Qt ● Yep, It is that simple! OpenGLShaderProgram has a myriad ways to do it, e.g.: m_shaderProgram. bind(); // Get the location of uniform value "uni" in the shader. int uniLocation = m_shaderProgram.uniformLocation("uni"); // Then update the value m_shaderProgram. setUniformValue(uniLocation,uniValue); // Or in one step m_shaderProgram.setUniformValue ("uni",0.8f,0.5f,0.5f); ● If the value changes during an animation this code would go in the updateGL function ● If it is static it could go into initializeGL after the shader program has been linked and bound 38
  • 39. Deprecated OpenGL Matrix Stack ● OpenGL Desktop version < 3 used to have “built in” matrix stacks and related functionality for dealing with transformations and projections ○ glRotate*, glTranslate*, glScale* ○ glMatrixMode(), glPushMatrix(), glPopMatrix() ○ glLoadIdentity() ○ glFrustum(), gluPerspective(...), gluLookAt(..) ● All of these are now deprecated and should/can no longer be used 39
  • 40. ● Fortunately, it is very easy to achieve the same functionality with more flexibility using Qt ● There are functions to: ○ Create or set a matrix to the identity matrix ■ Identity matrix is a diagonal matrix with all elements being 1. When multiplied with a vector the result will be the same vector. ○ Translate, Scale, Rotate ○ Create a (view) matrix representing a “camera” ○ Create perspective or orthographic projection matrix ● And then one can use QStack, QVector, QList and gain ultimate flexibility Matrices, Qt to the Rescue 40
  • 41. ● Contains convenient functions for handling Model, View, and Projection Matrices ○ QMatrix4x4::translate() ○ QMatrix4x4::scale() ○ QMatrix4x4::rotate() ○ QMatrix4x4::lookAt() ○ QMatrix4x4::perspective() ○ QMatrix4x4::ortho() QMatrix4x4 41
  • 42. Example from porting our Glut Application void resize (int w, int h) { glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); if (w <= h) gluOrtho2D (0.0, 30.0, 0.0, 30.0 * (GLfloat) h/(GLfloat) w); else gluOrtho2D (0.0, 30.0 * (GLfloat) w/(GLfloat) h, 0.0, 30.0); glMatrixMode(GL_MODELVIEW); } ● Set the current MatrixMode such that subsequent matrix operations apply to the projection matrix stack ● Load the Identity Matrix and then apply an orthogonal projection transformation ● Set the current MatrixMode back to the model-view stack
  • 43. class OpenGLScene : public QOpenGLFunctions { ... QMatrix4x4 m_projection; ... void OpenGLScene::resize(int w, int h) { glViewport( 0, 0, w, h ); float a = (float)w/(float)h; float l=30.0; m_projection.setToIdentity(); if (w<=h) m_projection.ortho(0,l,0,l/a, -1.0, 1.0f); else m_projection.ortho(0,l*a,0,l, -1.0, 1.0f); } void OpenGLScene::paint() { ... // Set MVP uniform to projection matrix // since modelview is identity m_shaderProgram.setUniformValue("MVP", m_projection); ... Equivalent in Modern OpenGL with Qt Vertex Shader Code: attribute vec3 vertexPosition; void main() { ... // Calculate the vertex position gl_Position = MVP*vec4(vertexPosition, 1.0 ); ... }
  • 44. ● Qt- 5.2 introduces QOpenGLTexture to encapsulate an OpenGL texture object ○ Makes it easy to work with OpenGL textures ○ Simplifies dealing with dependencies upon the capabilities of an OpenGL implementation ● Typical usage pattern for QOpenGLTexture is ○ Instantiate the object specifying the texture target type ○ Set properties that affect storage requirements e.g. storage format, dimensions ○ Allocate server-side storage ○ Optionally upload pixel data ○ Optionally set any additional properties e.g. filtering and border options ○ Render with texture or render to texture ○ In the common case of simply using a QImage as the source of texture pixel data most of the above steps are performed automatically. QOpenGLTexture 44
  • 45. ● Qt simplifies the process with: ○ QOpenGLFramebufferObject class ▪ Represents OpenGL FBO ▪ By default creates 2D texture for rendering target ▪ Function to return the OpenGL texture id ● Can be used for texture rendering ▪ Function to return rendered scene as a QImage ○ QOpenGLFramebufferObjectFormat() ▪ Specify format and attachments of FBO Qt Support for FBO 45
  • 46. Qt and OpenGL Extensions ● A list of all OpenGL extensions supported by the current context can be retrieved with a call to QSet<QByteArray> QOpenGLContext::​ extensions() const The context or a sharing context must be current. ● Resolve the entry points if the extension introduces a new API: QOpenGLContext::getProcAddress(). ● QtOpenGLExtensions module contains a class for every OpenGL extension in the Khronos registry that introduces new API. 46
  • 47. OpenGL Debugging with Qt ● OpenGL programming can be error prone ○ Black screen syndrom. There is no indication what is going on? ○ To be sure that no errors are being returned from OpenGL implementation check glGetError after every API call ○ OpenGL errors stack up so need to use this in a loop. ○ Additional information e.g. performance issues, warnings about using deprecated APIs are not reported through the ordinary OpenGL error reporting mechanisms ● QOpenGLDebugLogger enables logging of OpenGL debugging messages ○ Provides access to the OpenGL debug log if OpenGL implementation supports it (by exposing the GL_KHR_debug extension) ○ Messages from the OpenGL server will either be logged in an internal OpenGL log or passed in "real-time", i.e. as they're generated from OpenGL, to listeners 47
  • 48. OpenGL Debugging with Qt ● Creating an OpenGL Debug Context ○ OpenGL implementations are allowed not to create any debug output at all, unless the OpenGL context is a debug context ○ Set QSurfaceFormat::DebugContext format option on the QSurfaceFormat used to create the QOpenGLContext object: format.setOption(QSurfaceFormat::DebugContext); ● Creating and Initializing a QOpenGLDebugLogger ○ QOpenGLDebugLogger is a simple QObject-derived class ○ Create an instance and initialize it before usage by calling initialize() with a current OpenGL context: QOpenGLContext *ctx = QOpenGLContext::currentContext(); QOpenGLDebugLogger *logger = new QOpenGLDebugLogger(this); logger->initialize(); ○ Note that GL_KHR_debug extension must be available in the context in order to access the messages logged by OpenGL ○ You can check the presence of this extension by calling: ctx->hasExtension(QByteArrayLiteral("GL_KHR_debug")) 48
  • 49. Qt OpenGL Debug Messages ● Reading the Internal OpenGL Debug Log ○ Messages stored in the internal log of debug messages can be retrieved by using the loggedMessages() function QList<QOpenGLDebugMessage> messages = logger->loggedMessages(); foreach (const QOpenGLDebugMessage &message, messages) qDebug() << message; ○ Internal log has limited size; Older messages will get discarded to make room for new incoming messages ● Real-time logging of messages ○ Receive a stream of debug messages from the OpenGL server as they are generated by the implementation ○ Connect a slot to the messageLogged() signal, and start logging by calling startLogging(): connect(logger, &QOpenGLDebugLogger::messageLogged, receiver, &LogHandler::handleLoggedMessage); logger->startLogging(); ● Similarly, logging can be disabled at any time by calling the stopLogging() function. 49
  • 50. ● Measure GPU execution time of OpenGL calls ● Use to profile an application’s rendering performance ● Timed results in nanoseconds ● Create and set number of samples that will be taken, e.g: m_timeMonitor = new QOpenGLTimeMonitor(this); m_timeMonitor->setSampleCount(3); if (!m_timeMonitor->create()) ...Handle error QOpenGLTimeMonitor 50
  • 51. ● QOpenGLTimeMonitor::recordSample() to record interval m_timeMonitor->recordSample(); glClear( GL_COLOR_BUFFER_BIT ); m_timeMonitor->recordSample(); glDrawArrays( GL_TRIANGLES, 0, 3 ); m_timeMonitor->recordSample(); QOpenGLTimeMonitor 51
  • 52. ● Call waitForSamples() or waitForIntervals() to retrieve samples or intervals (in nanoseconds) QVector<GLuint64> samples = m_timeMonitor->waitForSamples(); QVector<GLuint64> intervals = m_timeMonitor->waitForIntervals(); o These functions block until values are ready o Call isResultAvailable() to prevent blocking ● Reset to use again m_timeMonitor->reset(); QOpenGLTimeMonitor 52
  • 53. Conclusion ● Qt has many classes that make working with OpenGL much more efficient. ● Cross platform capabilities of Qt enhance the portability of OpenGL applications greatly. ● Developer efficiency translates directly to maintenance costs and time to market. ● Qt is an ideal SDK for porting of legacy scientific applications with requirements for high performance visualization.