Export A Shader For Your Raspberry Pi 4

You need the following Simdify® modules to complete all exercises involving the Raspberry Pi 4: Simdify® Free Edition, Simdify® Video Module, Simdify® Raspberry Pi 4 Export Module

This exercise teaches you how to export C++ source code for a shader, copy the source code to your Raspberry Pi 4, and compile and run the program on your Raspberry Pi 4 device. This section assumes you have completed the previous exercise.

Export The Application Framework

  1. Select File » Export » Video Shader Raspberry to Pi 4.0 from the main menu.

    This displays the Raspberry Pi 4 export wizard.

    This is a picture of the Raspberry Pi 4 export wizard.

    For now, you don't need to worry about these options, as we can use the defaults.

  2. Click OK or hit ENTER when you are finished.

    The software generates a framework for a small C++ application and opens a Windows® folder to the directory containing the exported files. Note that the export directory is simply a sub-directory of the directory that contains the shader document.

    This is a picture of export results.

    The following files are generated:

    File Description
    Application.cpp, Application.h Implements a class Application that serves as the basic application object type.
    BindConstants.cpp, BindConstants.h Implements a class BindConstants that contains the OpenGL® function calls to set uniform values for the uniforms declared and used in your shader source code.
    BindSamplers.cpp, BindSamplers.h Implements a class BindSamplers that binds samplers on the GPU. In the case of exporting a video shader to the Raspberry Pi 4, we only bind a single sampler.
    DebugPrint.cpp, DebugPrint.h Contains a helper function that prints debug logging information to the Raspberry Pi 4 console.
    FileHelpers.cpp, FileHelpers.h Implements a class FileHelpers that loads files from disk.
    GlFuncBindings.h Implements a class GlFuncBindings that loads OpenGL® extensions required by the application.
    main.cpp Implements the main function for the application.
    Makefile Implements a build script.
    ProgramOptions.cpp, ProgramOptions.h Implements a class ProgramOptions that stores application settings such as video width, video height, and colorspace information.
    Run.sh Implements a script that runs the application.
    UniformData.h Implements static declarations that store values specified by <VariableNode> objects that represent uniforms.
    user_edge_detection_fragment_shader.glsl The fragment shader translation unit, which is the complete fragment shader after all #include statements have been processed.
    user_edge_detection_vertex_shader.glsl The vertex shader translation unit, which is the complete vertex shader after all #include statements have been processed.
    VideoCapture.cpp, VideoCapture.h Implements a class VideoCapture that manages video stream loading, buffering, and termination.

    The output window also contains a detailed log of the operations. Note that you can see whether variables were exported or not.

    --- <Executing Command 'ExportShaderToTargetPlatform'> ---
    
    Exporting : /Visual Shader/Program
    Exporting vertex shader: D:\Release6\Content\Library\Shader\User Edge Detection\300\user_edge_detection_vertex_shader.glsl
    Exporting fragment shader: D:\Release6\Content\Library\Shader\User Edge Detection\300\user_edge_detection_fragment_shader.glsl
    
    Exporting to folder: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection
    Exporting with display dimensions: 1920x1080
    
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\Application.cpp
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\Application.h
    SSL::GenerateGlData. Exported <VariableNodegt;: uniform SPA_VideoParams SPA_Video
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\UniformData.h
    SSL::GlSetUniformCall. Exported <VariableNodegt;: uniform SPA_VideoParams SPA_Video
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\BindConstants.cpp
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\BindConstants.h
    SSL::GlSetUniformCall. Exported <VariableNode>: uniform usampler2D src_video_plane0
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\BindSamplers.cpp
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\BindSamplers.h
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\DebugPrint.cpp
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\DebugPrint.h
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\FileHelpers.cpp
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\FileHelpers.h
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\GpuProgram.cpp
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\GpuProgram.h
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\GlFuncBindings.h
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\Graphics.h
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\main.cpp
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\Makefile
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\ProgramOptions.cpp
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\ProgramOptions.h
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\Run.sh
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\VideoCapture.cpp
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\VideoCapture.h
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\user_edge_detection_vertex_shader.glsl
    Exported to disk: D:\Release6\Content\Library\Shader\User Edge Detection\Export User Edge Detection\user_edge_detection_fragment_shader.glsl
    
    Document export complete.
    

    Next we'll need to copy these files to the hard disk on your Raspberry Pi 4 device.

Copy Exported Source To Your Raspberry Pi 4

  1. Use CTRL + A to select all the files in the folder. This is a picture of the exported files after being selected.
  2. Hit CTRL + C to copy all the files.
  3. Using the drive on the Windows PC to which you mapped the Samba shared folder of the Raspberry Pi 4, open the folder named Simdify. This is a picture of the empty destination folder.
  4. Hit CTRL + V to paste all the exported files to the folder on the Raspberry Pi 4. This is a picture of the exported files after being copied to the Raspberry Pi folder.

    Next, we'll compile and run the project on your Raspberry Pi 4.

Compile The Application

  1. Using RealVNC on your Windows PC, connect to your Raspberry Pi 4.
  2. Open a terminal window on your Raspberry Pi 4.
  3. Navigate to the Simdify folder we created earlier in this series of exercises.
  4. Type make from the command line and hit ENTER.

    The command line output looks something like this:

    pi@raspberrypi:~/Simdify $ make
    make: Warning: File 'Makefile' has modification time 1000159 s in the future
    Creating intermediate and output directories ...
    Compiling main.cpp
    Compiling FileHelpers.cpp
    Compiling BindConstants.cpp
    Compiling BindSamplers.cpp
    Compiling VideoCapture.cpp
    Linking Program
    g++ -v  -Wall -Werror -g  -I/opt/vc/include -I/opt/vc/include/interface/vmcs_host/linux -o Program  ./obj/main.o  ./obj/FileHelpers.o  ./obj/BindConstants.o  ./obj/BindSamplers.o  ./obj/VideoCapture.o  -L/usr/lib/arm-linux-gnueabihf/ -L/opt/vc/lib/  -lm -lrt -lGL -lGLESv2 -lEGL -lX11 -Wl,-Map,Program.map
    Using built-in specs.
    COLLECT_GCC=g++
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/8/lto-wrapper
    Target: arm-linux-gnueabihf
    Configured with: ../src/configure -v --with-pkgversion='Raspbian 8.3.0-6+rpi1' --with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-8 --program-prefix=arm-linux-gnueabihf- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm --disable-libquadmath --disable-libquadmath-support --enable-plugin --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-sjlj-exceptions --with-arch=armv6 --with-fpu=vfp --with-float=hard --disable-werror --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf
    Thread model: posix
    gcc version 8.3.0 (Raspbian 8.3.0-6+rpi1)
    COMPILER_PATH=/usr/lib/gcc/arm-linux-gnueabihf/8/:/usr/lib/gcc/arm-linux-gnueabihf/8/:/usr/lib/gcc/arm-linux-gnueabihf/:/usr/lib/gcc/arm-linux-gnueabihf/8/:/usr/lib/gcc/arm-linux-gnueabihf/
    LIBRARY_PATH=/usr/lib/gcc/arm-linux-gnueabihf/8/:/usr/lib/gcc/arm-linux-gnueabihf/8/../../../arm-linux-gnueabihf/:/usr/lib/gcc/arm-linux-gnueabihf/8/../../../:/lib/arm-linux-gnueabihf/:/lib/:/usr/lib/arm-linux-gnueabihf/:/usr/lib/
    COLLECT_GCC_OPTIONS='-v' '-Wall' '-Werror' '-g' '-I' '/opt/vc/include' '-I' '/opt/vc/include/interface/vmcs_host/linux' '-o' 'Program' '-L/usr/lib/arm-linux-gnueabihf/' '-L/opt/vc/lib/' '-shared-libgcc'  '-mfloat-abi=hard' '-mfpu=vfp' '-mtls-dialect=gnu' '-marm' '-march=armv6+fp'
    /usr/lib/gcc/arm-linux-gnueabihf/8/collect2 -plugin /usr/lib/gcc/arm-linux-gnueabihf/8/liblto_plugin.so -plugin-opt=/usr/lib/gcc/arm-linux-gnueabihf/8/lto-wrapper -plugin-opt=-fresolution=/tmp/ccnyUXxM.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr -dynamic-linker /lib/ld-linux-armhf.so.3 -X --hash-style=gnu -m armelf_linux_eabi -o Program /usr/lib/gcc/arm-linux-gnueabihf/8/../../../arm-linux-gnueabihf/crt1.o /usr/lib/gcc/arm-linux-gnueabihf/8/../../../arm-linux-gnueabihf/crti.o /usr/lib/gcc/arm-linux-gnueabihf/8/crtbegin.o -L/usr/lib/arm-linux-gnueabihf/ -L/opt/vc/lib/ -L/usr/lib/gcc/arm-linux-gnueabihf/8 -L/usr/lib/gcc/arm-linux-gnueabihf/8/../../../arm-linux-gnueabihf -L/usr/lib/gcc/arm-linux-gnueabihf/8/../../.. -L/lib/arm-linux-gnueabihf -L/usr/lib/arm-linux-gnueabihf ./obj/main.o ./obj/FileHelpers.o ./obj/BindConstants.o ./obj/BindSamplers.o ./obj/VideoCapture.o -lrt -lGL -lGLESv2 -lEGL -lX11 -Map Program.map -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/arm-linux-gnueabihf/8/crtend.o /usr/lib/gcc/arm-linux-gnueabihf/8/../../../arm-linux-gnueabihf/crtn.o
    COLLECT_GCC_OPTIONS='-v' '-Wall' '-Werror' '-g' '-I' '/opt/vc/include' '-I' '/opt/vc/include/interface/vmcs_host/linux' '-o' 'Program' '-L/usr/lib/arm-linux-gnueabihf/' '-L/opt/vc/lib/' '-shared-libgcc'  '-mfloat-abi=hard' '-mfpu=vfp' '-mtls-dialect=gnu' '-marm' '-march=armv6+fp'
    Finished building Program
    make: warning:  Clock skew detected.  Your build may be incomplete.
    pi@raspberrypi:~/Simdify $
    

    At the bottom of the output, you'll see Finished building Program, which indicates a successful build. If you receive compiler or linker errors, it's most likely due to missing OpenGL® packages. If OpenGL® packages are missing, identify which ones they are, and ensure that they are properly installed on your Raspberry Pi. Please review the tutorial Raspberry Pi 4 OpenGL Package Installation.

    If compilation was successful, you can run the application. To view the running application, you'll need to access your Raspberry Pi 4 via Real VNC® or you'll need to have a video monitor connected to your Raspberry Pi 4.

  5. Type ./Run.sh to run the application.

    You should see the edge detection shader processing the video stream.

    This exercise is complete. Return to tutorials.