Keywords

These keywords were added by machine and not by the authors. This process is experimental and the keywords may be updated as the learning algorithm improves.

Every chapter in this book includes a demo program to explain the material, the theory behind digital image topics, and provides code that the reader can run and manipulate. Instead of writing command line demo programs with little user interaction, we opted to write programs with a User Interface (UI) that includes essential UI elements such as buttons, sliders, and ability to display images on the screen. Thus, in this chapter, we present the UI library we have chosen to use and how to use it in the context of the digital image programming.

The UI library we selected for all the projects is ImGui, which is an open-source library written in C++ with MIT license. ImGui is defined on its GitHub page as a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application and can be found at http://github.com/ocornut/imgui.

ImGui is different than the traditional UI C++ libraries. The internals of ImGui resembles a state-machine instead. There are no classes for each UI class objects such as a button, a text box, a window, etc. There is no need to create separate files for UI code or the main logic code. Each function resides in the ImGui namespace and the order of objects to be rendered are dictated by the order of function calls made. A bit more experience with graphics programing is needed, however, to be able to use it. There exists no framework that renders the vertex buffers ImGui creates, so the programmer needs to create a window context, initialize graphics libraries (OpenGL in our case), and write the code for transferring user input such as key strokes and mouse clicks over to ImGui for processing. For OpenGL initialization, we use the GLEW library.

For creating a window and processing user input, we make use of GLFW, another useful wrapper library. To learn more about GLEW and GLFW, visit glew.sourceforge.net and glfw.org. The maintainers of ImGui have already provided a full implementation that uses GLEW and GLFW so we made use of that. To observe how ImGui interacts with GFLW, read imgui_glfw.h and observe how user input is processed and vertex buffers are rendered in the graphics pipeline.

All the code for UI is inside the main ‘forever’ loop featured in the code text box. ImGui gives the ability to create multiple windows inside one OS windows. Windows and groups are created by making begin and end calls. To create a new ImGui window, a call to ImGui::Begin(…) is made. Next, any UI object is created by calling the necessary function. A button with label ‘click me’ simply requires ImGui::Button(“click me”) call. When a user click on that button, the function returns true, so putting the ImGui::Button(…) call in an if statement lets the programmer write the code for the button click event. Once all objects are put into the rendering list by their respective ImGui calls, a final ImGui::End() call is made. At the end of the main loop, ImGui::Render() is called, buffers are switched, rendered, and put to the screen.

We present next a simple example program. With the help of glfw, glew, and ImGui libraries, the program creates an UI window, which contains a single button and a text area. Each time the user clicks the button, the number is incremented in the text area; refer to Fig. 2.1.

Fig. 2.1
figure 1

User interface example: outcome of the program

The function calls between the start of main and the while loop initializes GLFW and GLEW libraries and creates an OS window that we can use to render our UI. The while-loop will run forever as long as the user does not close the window. If a terminate message makes it way from the OS to the GLFW context, the glfwWindowShouldClose(window) statement will return true, end the while loop, initiate cleanup, and terminate the program.

At the start of the loop once user input is polled with glfwPollEvents() and ImGui is informed that a new frame is being rendered with ImGui_ImplGlfwGL3_NewFrame(), we can begin calling the necessary UI functions for window display. In this example, we create a window that includes a button and a text area that displays the current x value. The x value initially has a value of zero, but with each click of the button, the value of x is incremented by one. To render our UI components to the screen, we call a few more functions. After fetching the OS window size, we tell OpenGL to clear the screen with the already defined vector clear_color. Then, ImGui::Render() renders whatever UI component function we previously called (ImGui window, button, text, etc.) and glfwSwapBuffers(window) makes the changes on the screen. This pattern of library initialization, loop, and cleanup is present throughout all the projects in the following chapters. The program shown next includes library initializations, main loop, ImGui calls, and rendering.

figure a

2.1 Compiling the Program

For every chapter in this book, we have written one or two demo programs in C++ to go along with the explanation of each topic. To successfully compile and run each program, let us discuss the steps of acquiring a C++ compiler, libraries we used, and the source code for the demo programs. The programs were compiled using Windows 7, 9 and 10 so if you are running Linux or MacOS checkout the GitHub repository of ImGui for instructions on how to compile on these platforms.

The source code for the demo programs can be found on GitHub by downloading the repository (github.com/scarface382/multimedia-examples). You can unzip the file in any location in your computer. Each folder corresponds to a chapter in this book and contains the files for the source code and a makefile which contains information of where libraries are located and what compiler flags needs to be passed on to the compiler. Here is the content of the makefile for this chapter:

figure b

The library repository, which includes ImGui, GLEW, GLFW, and the utility functions, are used in the demo programs and can be found at (https://github.com/scarface382/libraries). Make sure to download and move the content of this repository to C:/libraries.

To make installing both g++ and make programs easier for you, we’ve also included an installation application mingw-w64-install in the libraries repository. When you run the installation, make sure that you select x_86 architecture if your computer has a 64-bit architecture (almost all new computers do) under installation settings. For the destination folder, install everything under C:/mingw. Once you are done with installation, rename mingw32-make.exe to make.exe under C:/mingw/mingw64/bin. This is so that we don’t have to keep typing mingw32-make every time we want to run a makefile script to compile a program.

At this point, we have acquired our compiler, source code, and all the necessary libraries but we are not ready to compile the code yet. We need to add the path of our libraries folder and the location of our compiler and make program to the global environment variables of Windows so that when we compile by running make in the console, the make program along with g++ can be located. To add these paths, simply run these two commands in your console ran as administrator:

figure c
figure d

Finally, we are ready to compile. Open a new console and change working directory to the directory of the demo program for first chapter then run:

figure e

The code should be compiled by g++ and it should output a new executable with the name ‘demo.exe’.

We have discussed the UI library that we used in demo programs and how to acquire and compile the source code for all the chapters. In the next chapter we discuss how images are decoded, loaded, and rendered.