Trusted Software Excellence across Desktop and Embedded
Take a glance at the areas of expertise where KDAB excels ranging from swift troubleshooting, ongoing consulting and training to multi-year, large-scale software development projects.
Find out why customers from innovative industries rely on our extensive expertise, including Medical, Biotech, Science, Renewable Energy, Transportation, Mobility, Aviation, Automation, Electronics, Agriculture and Defense.
High-quality Embedded Engineering across the Stack
To successfully develop an embedded device that meets your expectations regarding quality, budget and time to market, all parts of the project need to fit perfectly together.
Learn more about KDAB's expertise in embedded software development.
Where the capabilities of modern mobile devices or web browsers fall short, KDAB engineers help you expertly architect and build high-functioning desktop and workstation applications.
Extensible, Safety-compliant Software for the Medical Sector
Create intelligent, patient-focused medical software and devices and stay ahead with technology that adapts to your needs.
KDAB offers you expertise in developing a broad spectrum of clinical and home-healthcare devices, including but not limited to, internal imaging systems, robotic surgery devices, ventilators and non-invasive monitoring systems.
Building digital dashboards and cockpits with fluid animations and gesture-controlled touchscreens is a big challenge.
In over two decades of developing intricate UI solutions for cars, trucks, tractors, scooters, ships, airplanes and more, the KDAB team has gained market leading expertise in this realm.
Build on Advanced Expertise when creating Modern UIs
KDAB assists you in the creation of user-friendly interfaces designed specifically for industrial process control, manufacturing, and fabrication.
Our specialties encompass the custom design and development of HMIs, enabling product accessibility from embedded systems, remote desktops, and mobile devices on the move.
Legacy software is a growing but often ignored problem across all industries. KDAB helps you elevate your aging code base to meet the dynamic needs of the future.
Whether you want to migrate from an old to a modern GUI toolkit, update to a more recent version, or modernize your code base, you can rely on over 25 years of modernization experience.
KDAB offers a wide range of services to address your software needs including consulting, development, workshops and training tailored to your requirements.
Our expertise spans cross-platform desktop, embedded and 3D application development, using the proven technologies for the job.
When working with KDAB, the first-ever Qt consultancy, you benefit from a deep understanding of Qt internals, that allows us to provide effective solutions, irrespective of the depth or scale of your Qt project.
Qt Services include developing applications, building runtimes, mixing native and web technologies, solving performance issues, and porting problems.
KDAB helps create commercial, scientific or industrial desktop applications from scratch, or update its code or framework to benefit from modern features.
Discover clean, efficient solutions that precisely meet your requirements.
Boost your team's programming skills with in-depth, constantly updated, hands-on training courses delivered by active software engineers who love to teach and share their knowledge.
Our courses cover Modern C++, Qt/QML, Rust, 3D programming, Debugging, Profiling and more.
The collective expertise of KDAB's engineering team is at your disposal to help you choose the software stack for your project or master domain-specific challenges.
Our particular focus is on software technologies you use for cross-platform applications or for embedded devices.
Since 1999, KDAB has been the largest independent Qt consultancy worldwide and today is a Qt Platinum partner. Our experts can help you with any aspect of software development with Qt and QML.
KDAB specializes in Modern C++ development, with a focus on desktop applications, GUI, embedded software, and operating systems.
Our experts are industry-recognized contributors and trainers, leveraging C++'s power and relevance across these domains to deliver high-quality software solutions.
KDAB can guide you incorporating Rust into your project, from as overlapping element to your existing C++ codebase to a complete replacement of your legacy code.
Unique Expertise for Desktop and Embedded Platforms
Whether you are using Linux, Windows, MacOS, Android, iOS or real-time OS, KDAB helps you create performance optimized applications on your preferred platform.
If you are planning to create projects with Slint, a lightweight alternative to standard GUI frameworks especially on low-end hardware, you can rely on the expertise of KDAB being one of the earliest adopters and official service partner of Slint.
KDAB has deep expertise in embedded systems, which coupled with Flutter proficiency, allows us to provide comprehensive support throughout the software development lifecycle.
Our engineers are constantly contributing to the Flutter ecosystem, for example by developing flutter-pi, one of the most used embedders.
KDAB invests significant time in exploring new software technologies to maintain its position as software authority. Benefit from this research and incorporate it eventually into your own project.
Start here to browse infos on the KDAB website(s) and take advantage of useful developer resources like blogs, publications and videos about Qt, C++, Rust, 3D technologies like OpenGL and Vulkan, the KDAB developer tools and more.
The KDAB Youtube channel has become a go-to source for developers looking for high-quality tutorial and information material around software development with Qt/QML, C++, Rust and other technologies.
Click to navigate the all KDAB videos directly on this website.
In over 25 years KDAB has served hundreds of customers from various industries, many of them having become long-term customers who value our unique expertise and dedication.
Learn more about KDAB as a company, understand why we are considered a trusted partner by many and explore project examples in which we have proven to be the right supplier.
The KDAB Group is a globally recognized provider for software consulting, development and training, specializing in embedded devices and complex cross-platform desktop applications.
Read more about the history, the values, the team and the founder of the company.
When working with KDAB you can expect quality software and the desired business outcomes thanks to decades of experience gathered in hundreds of projects of different sizes in various industries.
Have a look at selected examples where KDAB has helped customers to succeed with their projects.
KDAB is committed to developing high-quality and high-performance software, and helping other developers deliver to the same high standards.
We create software with pride to improve your engineering and your business, making your products more resilient and maintainable with better performance.
KDAB has been the first certified Qt consulting and software development company in the world, and continues to deliver quality processes that meet or exceed the highest expectations.
In KDAB we value practical software development experience and skills higher than academic degrees. We strive to ensure equal treatment of all our employees regardless of age, ethnicity, gender, sexual orientation, nationality.
Interested? Read more about working at KDAB and how to apply for a job in software engineering or business administration.
Qt 6 is nearly upon us. While this has not been addressed by other publications, Qt 3D is also introducing a number of changes with this major release. This includes changes in the public API that will bring a number of new features and many internal changes to improve performance and leverage new, low-level graphics features introduced in QtBase. I will focus on API changes now, while my colleague, Paul Lemire, will cover other changes in a follow up post.
Distribution of Qt 3D for Qt 6
Before looking at what has changed in the API, the first big change concerns how Qt 3D is distributed. Qt 3D has been one of the core modules that ship with every Qt release. Starting with Qt 6, however, Qt 3D will be distributed as a separate source-only package. Qt 6 will ship with a number of such modules, and will use conan to make it easy for those modules to be built. This means that users interested in using Qt 3D will need to compile once for every relevant platform.
Since it ships independently, Qt 3D will also most likely be on a different release cycle than the main Qt releases. We will be able to release more, frequent minor releases with new features and bug fixes.
Another consequence of this is that Qt 3D will not be bound by the same binary compatibility constraints as the rest of Qt. We do however, aim to preserve source compatibility for the foreseeable future.
Basic Geometry Types
The first API change is minimal, but, unfortunately, it is source-incompatible. You will need to change your code in order to compile against these changes.
In order to make developing new aspects that access geometry data more straight forward, we have moved a number of classes that relate to that from the Qt3DRender aspect to the Qt3DCore aspect. These include QBuffer, QAttribute and QGeometry.
When using the QML API, impact should be minimal, the Buffer element still exists, and importing the Render module implicitly imports the Core module anyway. You may have to change your code if you've been using module aliases, though.
In C++, this affects which namespace these classes live in, which is potentially more disruptive. So if you were using Qt3DRender::QBuffer (often required to avoid clash with QBuffer class in QtCore), you would now need to use Qt3DCore::QBuffer, and so on...
If you need to write code that targets both Qt5 and Qt6, one trick you can use to ease the porting is to use namespace aliases, like this:
The main reason this was done is so that all aspects could have access to the complete description of a mesh. Potential collision detection or physics simulation aspects don't need to have their own representation of a mesh, separate from the one used for rendering.
So QBuffer, QAttribute and QGeometry are now in Qt3DCore. But this is not enough to completely describe a mesh.
Changes in Creating Geometry
A mesh is typically made of a collection of vertices. Each vertex will have several properties (positions, normal, texture coordinates, etc.) associated to it. The data for those properties is stored somewhere in memory. So in order to register a mesh with Qt 3D, you need:
A QGeometry instance that is simply a collection of QAttribute instances
Each QAttribute instance to define the details of a vertex attribute. For example, for the position, it would include the number of components (usually 3), the type of the component (usually floats), the name of the attribute as it will be exposed to the shaders (usually "position" or QAttribute::defaultNormalAttributeName(), if you are using Qt3D built-in materials), etc.
Each QAttribute to also point to a QBuffer instance. This may be the same for all attributes, or it may be different, especially for attribute data that needs to be updated often.
But this is still incomplete. We are missing details such as how many points make up the mesh and what type of primitives these points make up (triangles, strips, lines, etc) and more.
Prior to Qt 6, these details were stored on a Qt3DRender::QGeometryRenderer class. The name is obviously very rendering-related (understatement), so we couldn't just move that class.
For these reasons, Qt 6 introduces a new class, Qt3DCore::QGeometryView. It includes a pointer to a QGeometry and completely defines a mesh. It just doesn't render it. This is useful as the core representation of a mesh that can then be used for rendering, bounding volume specifications, picking, and much more.
Bounding Volume Handling
One of the very first things Qt 3D needs to do before rendering is compute the bounding volume of the mesh. This is needed for view frustum culling and picking. Internally, the render aspect builds a bounding volume hierarchy to quickly find objects in space. To compute the bounding volume, it needs to go through all the active vertices of a mesh. Although this is cached, it can take time the first time the object is rendered or any of its details change.
Furthermore, up to now, this was completely internal to Qt 3D's rendering backend and the results were not available to the user for using in the rest of the application.
So Qt 6 introduces a QBoundingVolume component which serves two purposes:
it has implicit minimum point and maximum point properties that contain the result of the bounding volume computations done by the backend. This can be used by the application.
it has explicit minimum point and maximum point properties which the user can set. This will prevent the backend from having to calculate the bounds in order to build the bounding volume hierarchy.
The minimum and maximum extents points are the corners of the axis-aligned box that fits around the geometry.
But how does QBoundingVolume know which mesh to work on? Easy -- it has a view property which points to a QGeometryView instance!
Reading bounding volume extents
So if you need to query the extents of a mesh, you can use the implicit values:
Note that if the backend needs to compute the bounding volume, this is done at the next frame using the thread pool. So the implicit properties might not be immediately available when updating the mesh.
If you need the extents immediately after setting or modifying the mesh, you can call QBoundingVolume::updateImplicitBounds() method, which will do the computations and update the implicit properties.
Setting bounding volume extents
But you know the extents. You can set them explicitly to stop Qt 3D from computing them:
Note that, since setting the explicit bounds disables the computation of the bounding volume in the backend, the implicit properties will NOT be updated in this case.
Mesh Rendering
Now, before everyone goes and adds QBoundingVolume components to all their entities, one other thing: QGeometryRenderer, in the Qt3DRender module, now derives from QBoundingVolume. So, it will also have all the extents properties.
It also means you can provide it with a geometry view to tell it what to draw, rather than providing a QGeometry and all the other details.
It still, however, has all the old properties that are now taken care of by the QGeometryView instance. If that is defined, all the legacy properties will be ignored. We will deprecate them soon and remove them in Qt 7.
So what happens if you provide both a QBoundingVolume and a QGeometryRenderer component to an entity? In this case, the actual bounding volume component takes precedence over the geometry renderer. If it specifies explicit bounds, those will be used for the entity.
The main use case for that is to specify a simpler geometry for the purpose of bounding volume computation. If you don't know the extents of a mesh but you know that a simpler mesh (with much fewer vertices) completely wraps the object you want to render, using that simpler mesh can be a good way of speeding up the computations that Qt 3D needs to do.
New Core Aspect
Most of these computations took place previously in the Render aspect. Since this is now in core, and in order to fit in with Qt 3D's general architecture, we introduce a new Core aspect. This aspect will be started automatically if you are using Scene3D or Qt3DWindow. In cases where you are creating your own aspect engine, it should also automatically be started as long as the render aspect is in use via the new aspect dependency API (see below).
The core aspect will take care of the all the bounding volume updates for the entities that use the new geometry view-based API (legacy scenes using a QGeometryRenderer instances without using views will continue to be updated by the rendering aspect).
The Core aspect also introduces a new QCoreSettings component. Like the QRenderSettings component, a single instance can be created. It is, by convention, attached to the root entity.
Currently, its only purpose is to be able to completely disable bounding volume updating. If you are not using picking and have disabled view frustum culling, bounding volumes are actually of no use to Qt 3D. You can disable all the jobs which are related to bounding volume updates by setting QCoreSettings::boundingVolumesEnabled to false. Note that implicit extent vertices on QBoundingVolume component will then not be updated.
New Aspect and AspectJob API
The base class for aspects, QAbstractAspect, has gained a few useful virtual methods:
QAbstractAspect::dependencies() should return the list of aspect names that should be started automatically if an instance of this aspect is registered.
QAbstractAspect::jobsDone() is called on the main thread when all the jobs that the aspect has scheduled for a given frame have completed. Each aspect has the opportunity to take the results of the jobs and act upon them. It is called every frame.
QAbstractAspect::frameDone() is called when all the aspects have completed the jobs AND the job post processing. In the case of the render aspect, this is when rendering actually starts for that frame.
Similarly, jobs have gained a number of virtual methods on QAspectJob:
QAspectJob::isRequired() is called before a job is submitted. When building jobs, aspects will build graphs of jobs with various dependencies. It's often easier to build the same graph every frame, but not all jobs might have something to do on a given frame. For example, the picking job has nothing to do if there are no object pickers or the mouse has not moved. The run method can test for this and return early, but this still causes the job to be scheduled onto a thread in the pool, with all the associated, sometime expensive locking. If QAspectJob::isRequired() returns false, the job will not be submitted to the thread pool and processing will continue with its dependent jobs.
QAspectJob::postFrame() is called on the main thread once all the jobs are completed. This is place where most jobs can safely update the foreground classes with the results of the backend computations (such as bounding volume sizes, picking hits, etc).
Picking Optimization
We have introduced optimization for picking. A QPickingProxy component has been introduced, deriving from QBoundingVolume. If it has an associated geometry view, that mesh will be used instead of the rendered mesh for picking tests. This applies to QObjectPicker and the QRayCaster and QScreenRayCaster classes. Since precise picking (when QPickingSettings is not set to use bounding volume picking) needs to look at every primitive (triangle, line, vertex), it can be very slow. Using QPickingProxy makes it possible to provide a much simpler mesh for the purpose of picking.
So for example, you can provide a down sampled mesh, such as the bunny on the right (which only includes 5% of the total of primitives in the original mesh), to get fast picking results.
Of course, the picking results (the local coordinate, the index of the picked primitive, etc) will all be defined relative to the picking proxy mesh (not the rendered mesh).
Finally, QRayCaster and QScreenRayCaster now have pick() methods, which do a ray casting test synchronously, whereas the pre-existing trigger() methods would schedule a test for the next frame. This will block the caller until completed and return the list of hits. Thus, it's possible for an application to implement event delegation. For example, if the user right clicks, the application can decide to do something different depending on the type of the closest object, or display a context menu if nothing was hit.
Conclusion
As you can see, Qt 3D for Qt 6 has quite a few changes. My colleague, Paul Lemire, will go through many more internal changes in a later post. We hope this ensures an on-going successful future for Qt 3D in the Qt 6 series.
KDAB provides a number of services around Qt 3D, including mentoring your team and embedding Qt 3D code into your application, among others. You can find out more about these services here.
About KDAB
Trusted software excellence across embedded and desktop platforms
The KDAB Group is a globally recognized provider for software consulting, development and training, specializing in embedded devices and complex cross-platform desktop applications. In addition to being leading experts in Qt, C++ and 3D technologies for over two decades, KDAB provides deep expertise across the stack, including Linux, Rust and modern UI frameworks. With 100+ employees from 20 countries and offices in Sweden, Germany, USA, France and UK, we serve clients around the world.
I like the changes and the decoupling from Qt! Are there any plans to develop Qt3d on a modern code platform like Gitlab or Github? The current Qt coding platform with the old jira, gerrit and awful cgit is really a not easy to learn for new developer...
18 - Nov - 2020
Mike Krus
Hi, Qt3D remains a Qt module. Everything is mirrored to GitHub I believe. But issue tracking etc remains on Qt's infrastructure.
Mike Krus
Senior Software Engineer & Teamlead
Senior Software Engineer at KDAB. Mike has been developing with C++ since 1996 and Qt since 2004. He has a broad range of experience in scientific applications, mainly in civil engineering and oil & gas industries. His range of expertise includes C++, QML and interactive 3D visualization software design on desktop and mobile as well as macOS development. Mike is the Qt maintainer for the tvOS platform, one of the core contributors to Qt 3D and is interested in building mobile applications with Qt, mainly on iOS. He has a PhD in Computer Science.
2 Comments
18 - Nov - 2020
Elias
I like the changes and the decoupling from Qt! Are there any plans to develop Qt3d on a modern code platform like Gitlab or Github? The current Qt coding platform with the old jira, gerrit and awful cgit is really a not easy to learn for new developer...
18 - Nov - 2020
Mike Krus
Hi, Qt3D remains a Qt module. Everything is mirrored to GitHub I believe. But issue tracking etc remains on Qt's infrastructure.