Grinding gears

Oh muse, how difficult it is to catch you sometimes.
The development of Death-Mask and related frameworks (Flame Steel Core, Game Toolkit, etc.) is suspended for several months in order to decide on the artistic part of the game, the musical and sound accompaniment, and to think through the gameplay.
The plans include creating an editor for the Flame Steel Game Toolkit, writing an interpreter for game scripts (based on the Rise syntax), and implementing the Death-Mask game for as many platforms as possible.
The most difficult stage has been passed – the possibility of writing your own cross-platform game engine, your own IDE, and a set of libraries has been proven in practice.
I’m moving on to the stage of creating a truly thoughtful, interesting project, stay tuned.

Fighting Malevich, OpenGL black squares

Malevich comes to any OpenGL developer from time to time. It happens unexpectedly and boldly, you just launch the project and see a black square instead of a wonderful render:

Today I will describe the reason why I was visited by a black square, the problems found due to which OpenGL does not draw anything on the screen, and sometimes even makes the window transparent.

Use tools

Two tools helped me debug OpenGL: renderdoc and apitrace. Renderdoc is a tool for debugging the OpenGL rendering process, you can view all vertices, shaders, textures, debug messages from the driver. Apitrace is a tool for tracing graphics API calls, makes a dump of calls and shows arguments. There is also a great opportunity to compare two dumps via wdiff (or without it, but not so convenient)

Check who you work with

I have Ubuntu 16.10 operating system with old dependencies SDL2, GLM, assimp, GLEW. In the latest version of Ubuntu 18.04 I get a build of the game Death-Mask which shows nothing on the screen (only a black square). When using chroot and building in 16.10 I get a working build of the game with graphics.


Looks like something is broken in Ubuntu 18.04

LDD showed linking to identical libraries SDL2, GL. Running a non-working build in renderdoc, I saw garbage at the entrance to the vertex shader, but I needed more solid confirmation. In order to understand the difference between the binaries, I ran them both through apitrace. Comparison of dumps showed me that the build on a fresh Ubuntu breaks the transfer of perspective matrices to OpenGL, actually sending garbage there:

The matrices are built in the GLM library. After copying GLM from 16.04 – I got a working build of the game again. The problem turned out to be the difference in the initialization of the identity matrix in GLM 9.9.0, it is necessary to explicitly specify the argument mat4(1.0f) in the constructor. Having changed the initialization and written to the author of the library, I started making tests for FSGL. In the process of writing which I discovered shortcomings in FSGL, I will describe them below.

Decide who you are in life

To work correctly with OpenGL, you need to voluntarily or forcibly request a context of a certain version. This is how it looks for SDL2 (you need to specify the version strictly before initializing the context):

 SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3);SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 2);SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );

For example, Renderdoc does not work with contexts below 3.2. I would like to note that after switching the context, there is a high probability of seeing that same black screen. Why?
Because OpenGL 3.2 context necessarily requires the presence of a VAO buffer, without which 99% of graphics drivers do not work. Adding it is easy:

 glGenVertexArrays(1, &vao);glBindVertexArray(vao);

Don’t sleep, you’ll freeze

I also encountered an interesting problem on Kubuntu, instead of a black square I got a transparent one, and sometimes everything was rendered correctly. I found a solution to this problem on Stack Overflow:
https://stackoverflow.com/questions/38411515/sdl2-opengl-window-appears-semi-transparent-sometimes

The FSGL test render code also had sleep(2s); So on Xubuntu and Ubuntu I got the correct render and sent the application to sleep, but on Kubuntu I got a transparent screen in 80% of cases when launched from Dolphin and 30% of launches from the terminal. To solve this problem, I added rendering in each frame, after polling SDLEvent, as recommended in the documentation.

Test code:
https://gitlab.com/demensdeum/FSGLtests/blob/master/renderModelTest/

Talk to the driver

OpenGL supports a communication channel between the application and the driver. To activate it, you need to enable the GL_DEBUG_OUTPUT, GL_DEBUG_OUTPUT_SYNCHRONOUS flags, set the glDebugMessageControl notification, and bind the callback via glDebugMessageCallback.
An example of initialization can be found here:
https://github.com/rock-core/gui-vizkit3d/blob/master/src/EnableGLDebugOperation.cpp

Don’t be afraid, look how it grows

In this note, I will tell you about my misadventures with smart pointers shared_ptr. After implementing the generation of the next level in my game Death-Mask, I noticed a memory leak. Each new level gave an increase of + 1 megabyte to the consumed RAM. Obviously some objects remained in memory and did not release it. To correct this fact, it was necessary to implement the correct implementation of resources when overloading the level, which apparently was not done. Since I used smart pointers, there were several options for solving this problem, the first was to manually review the code (long and boring), the second involved investigating the capabilities of the lldb debugger, the source code of libstdc++ for the possibility of automatically tracking changes to the counter.

On the Internet, all the advice boiled down to manually reviewing the code, fixing it, and beating yourself with whips after finding the problematic line of code. It was also suggested to implement your own system for working with memory, as all large projects developed since the 90s and 00s have done, before smart pointers came to the C++11 standard. I attempted to use breakpoints on the constructor of a copy of all shared_ptr, but after several days nothing useful came of it. There was an idea to add logging to the libstdc++ library, but the labor costs (o)turned out to be monstrous.


Cowboy Bebop (1998)

The solution came to me suddenly in the form of tracking changes to the private variable shared_ptr – use_count. This can be done using watchpoints built into lldb. After creating a shared_ptr via make_shared, changes to the counter in lldb can be tracked using the line:

watch set var camera._M_refcount._M_pi->_M_use_count

Where “camera” is a shared_ptr object whose counter state needs to be tracked. Of course, the insides of shared_ptr will differ depending on the version of libstdc++, but the general principle is clear. After setting the watchpoint, we launch applications and read the stack trace of each counter change, then we look through the code (sic!), find the problem and fix it. In my case, objects were not released from cache tables and game logic tables. I hope this method will help you deal with leaks when working with shared_ptr, and love this memory management tool even more. Happy debugging.

Games Vision #3

The third issue of the non-permanent column about games Games Vision.

Observer (PC and consoles, Bloober Team) – cyberpunk horror from the valiant Poles. A short and very atmospheric horror starring Rutger Hauer. As a cyberpunk fan, I liked absolutely everything about the game. Not very difficult puzzles, charming glitches of the main character, gameplay with calm moments mixed with action, the ability to literally dig into the memories of the dead, a plot in the style of Ghost in the Shell + many references to Sci-Fi pop culture. Of the minuses – too much glitches, sometimes it seems that because of their abundance it is impossible to play, also some players were annoyed by specific horror elements, frightening so much that they could not continue playing.
Rating: 8/10

Paradigm (Windows/OS X, Jacob Janerka) – a quest that manages to parody and laugh at everything at once. It makes fun of the USSR, America, the quest genre, glam rock, old consoles, people, monuments, IT specialists, cones, computers, women, children, parents, artists, love, scientists, the gaming industry, the players themselves – in general, you can’t list everything. An absolutely unpredictable plot, absurd atmosphere and art, not particularly difficult puzzles. The game has rare bugs and crashes, some moments and jokes are slightly predictable and not original.
Rating: 9/10

Late Shift (PC and consoles, CtrlMovie Ltd) – interactive movie. I really regret that a basically good idea received such a bad implementation. Everything is bad – the plot, the lack of star actors, the acting, constant freezes in the PC version, almost zero variability (illusory). It is completely incomprehensible how it was possible to release a game with so many problems in the 2010s, because in fact it is an ordinary video player, the whole game could have been posted on the Internet, for example, on YouTube, but instead they used Unity and managed to break even such a powerful game engine. The official forum on Steam is dedicated to fixes, hotfixes, workarounds, etc. There is a technical disaster, no user support, all testing takes place directly on the players. Bought rave reviews and testimonials.
Rating: 3/10

Saber-Plus C++ IDE

I started developing my own IDE for C++ – Saber-Plus. The main ideas of the new IDE are to be simple, fast and *helpful* in development. At the moment, the source code is available under the MIT license on GitHub, Qt is used to work with the UI. In the future, I plan to transfer all development related to C++ to Saber-Plus – the Death-Mask game will definitely be migrated. More details on the points:

  • Simple – it is planned not to add more than necessary – for example, not to contain source control clients, built-in terminal and similar things. The functionality is focused only on editing the code, analyzing errors. The editor code should be divided into simple classes that correctly perform their part of the work (Unix-way)
  • Fast – refers to both the IDE code base and the editor behavior itself. All actions in the IDE should be as fast as possible, even such often long and complex ones as creating/importing projects.
  • Assistant – analysis of typical errors when writing, compiling code. Correction of errors, warnings at the user’s request. The idea is to add analysis of the application assembly on a specific platform and output of reference information on the installation of the necessary libraries, components.

To build the editor for your operating system, you need to install Qt 5 SDK, download the IDE code from the repository, open the Saber-Plus.pro file in Qt Creator and run the build:

https://github.com/demensdeum/saberplus