The basic commands for using apitrace with an OpenGL application are:
apitrace trace --api=gl MyApp
apitrace dump --blobs MyApp.trace
The last command generates blobs that can be inspected with the following command, for example:
tail -c $((12*10)) ~/repos/MyApp/build/blob_call2325.bin | xxd -g1
Or by writing a simple C++ program that converts them into CVS format:
To learn OpenGL I wrote a simple game that utilizes the most of basic OpenGL ES 2.0 (and partially 3.0) techniques:
- MVP matrix. In 3D version of the game the projection matrix is calculated depending on the window size (viewport).
- All the objects including the board, balls, path arrows, sparkles, explosion particles sit in vertex buffers and are rendered with vertex/fragment shaders.
- The light is implemented with common fragment shader calculating ambient, specular and diffuse coefficients. The sparkle position is found by iterating over the normals and searching the maximum light coefficient.
- The antialiasing is achieved by rendering the scene first to 4 times bigger offscreen buffer and then rendering the buffer to the screen with multisampling.
- Color coding is used to determine what object the user has clicked on. The board and the balls are rendered first with alpha containing the object identifier (that is why the board size is limited with 15×15), then alpha is erased and the background is rendered over it with a specific blending operation.
- Textures are used for rendering the background images, sparkles and particles.
- All the rendering is done on a separate thread and the swaps (flips) are synchronized with the monitor refresh cycles. This prevents screen tearing and saves the battery power.
In my previous post Testing XAML App for OpenGL ES on Windows 10 Mobile Device I described the changes I made to UWP application based on “XAML App for OpenGL ES (Universal Windows)” template to demonstrate some strange effect related to the transparency of the image drawn with OpenGL ES in SwapChainPanel. But I did yet another experiment with this application and got some beautiful pictures that demonstrate what happens if I make the scene completely transparent with the following code:
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Today I played a bit with a UWP application based on “XAML App for OpenGL ES (Universal Windows)” template and realized that there is some specific bug probably related to the interaction between SwapChainPanel and OpenGL surface. First, I made the cube transparent by changing two lines of code in the vertex shader:
const std::string vs = STRING
uniform mat4 uModelMatrix;
uniform mat4 uViewMatrix;
uniform mat4 uProjMatrix;
attribute vec4 aPosition;
attribute vec3 aColor;
varying vec4 vColor;
gl_Position = uProjMatrix * uViewMatrix * uModelMatrix * aPosition;
vColor = vec4(aColor, 0.1);
Typically ANGLE library is used with OpenGL 2.0, but I successfully tried to enable OpenGL 3.0:
const EGLint contextAttributes =
and used some OpenGL 3.0 features in my Universal Windows App. But today I tried to compile my application with the new version of ANGLE library and got EGL_BAD_CONFIG error while creating the OpenGL context. The source code that returns this error checks some EGL_OPENGL_ES3_BIT_KHR that is not set in the new version:
if (clientMajorVersion == 3 && !(configuration->conformant & EGL_OPENGL_ES3_BIT_KHR))
In this article, I will show how the basic OpenGL ES 2.0/3.2 techniques, allowing to utilize the power of modern GPUs, can be used to draw 2D vector nautical charts by the example of S57 format. And as you probably already have guessed, the first technique I am going to consider is using vertex buffers for storing objects that makes up the chart. I will say at once that it is not a trivial task because, for example, some area in S57 chart can be filled and outlined with specific patterns generated from so called Presentation Library and at that, the fill pattern should be aligned to the left-top corner of the screen, but not to the area itself, so when the user shift the chart, the fill pattern does not move. The other example is a point objects or symbol that should be shown in the center of the visible part of an area, so its geographical coordinates changes when the user offsets or scales the chart. Theoretically, if we have OpenGL ES 3.2, we can use geometry shaders for drawing patterns, but if we have only OpenGL ES 2.0 that does not support geometry shaders, those patterns can also be drawn with the vertex buffers that should be regenerated each time the user changes the scale. So let’s start to solve this complex task with a simple example when we have geographic area or polygon filled with blue color, at least this example will demonstrate the basic idea of using the vertex buffers.
Cross platform (Android, iOS, UWP) OpenGLES 2 application can be easily created in VS2015 using “OpenGLES 2 Application (Android, iOS, Windows Universal)” project template:
Visual Studio 2015 allows easily combine OpenGL graphics with XAML controls in a single window. To accomplish this task we can create a new project based on “XAML App for OpenGL ES (Universal Windows)” template:
ANGLE is a wrapper library that implements OpenGL ES API (version 2.0 and parts of 3.0) and translates OpenGL ES calls to their DirectX equivalents. See https://github.com/MSOpenTech/angle for more information.
There are two options how to use ANGLE: install its binaries as a NuGet package or compile it from the source code. I believe that cool software developers, like real heroes, never search easy ways, so I decided to compile ANGLE from the source code with VS2015 Community.
First I cloned the repository and ensured that my branch is ms-master:
Probably it would be better if I learned Java 15 years ago because Java technologies do not change so rapidly, but I love C++ very much and I spent some time investigating how the application based on DirectX 11 and XAML Visual Studio 2015 template works on relatively new UWP platform.
In opposite to Win32, there are no main thread in UWP applications, because in UWP application each top-level window runs on its own thread. Our application has only one top-level window so it has one UI thread and also it has event handling thread and renderer thread (creating new top-level window will require some adaptive changes in our application).