2D/3D Graphics Library (TGX)

Hi all,

I’ve been playing around with the SmartMatrix for a while now, and it’s been fun! However, I wondered if there was a good Teensy-based graphics library that would allow 2D/3D graphics to be rendered on the SmartMatrix. And I found that there was! I haven’t seen it mentioned in the forums here, but I thought I’d share it in case someone else found it useful (apologies if you have already covered this, or if it’s common knowledge).

The library is available here: GitHub - vindar/tgx: tgx - a tiny/teensy 3D graphics library

I didn’t write the library, nor do I have any relation to the author(s), and all credit must go to them.

I put together the code below for you to try it out, and it’s heavily based on the Teensy 4 3D borg_cube example from the library. It renders a rotating cube with a constantly changing texture created in real-time (see image below). The changes required to make it work with SmartMatrix were pretty minimal:

  • Remove all the references to the TFT display that the example uses
  • Resize the frame buffers for the display size (128 x 128 in my case)
  • Change the colour depth from RGB565 to RGB24
  • Use memcpy to copy the rendering frame buffer to the SmartMatrix frame buffer (I could write directly to the SM frame buffer, but I wanted to keep it as close to the example as possible).

On a Teensy 4.1, I’m getting consistent 159 FPS, which is very impressive I think! I believe it should work on other set-ups just by changing the SM parameters at the top of the file. There are other examples that come with the library if anyone wants to experiment with it.

I hope that’s of interest to anyone.
welshcoder

The code:

#include <Arduino.h>
#include <tgx.h>
#include <font_tgx_OpenSans_Bold.h>
#include <MatrixHardware_Teensy4_ShieldV5.h>        // SmartLED Shield for Teensy 4 (V5)
#include <SmartMatrix.h>

#define COLOR_DEPTH 24                  // Choose the color depth used for storing pixels in the layers: 24 or 48 (24 is good for most sketches - If the sketch uses type `rgb24` directly, COLOR_DEPTH must be 24)

const uint16_t kMatrixWidth = 128;       // Set to the width of your display, must be a multiple of 8
const uint16_t kMatrixHeight = 128;      // Set to the height of your display
const uint8_t kRefreshDepth = 36;       // Tradeoff of color quality vs refresh rate, max brightness, and RAM usage.  36 is typically good, drop down to 24 if you need to.  On Teensy, multiples of 3, up to 48: 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48.  On ESP32: 24, 36, 48
const uint8_t kDmaBufferRows = 4;       // known working: 2-4, use 2 to save RAM, more to keep from dropping frames and automatically lowering refresh rate.  (This isn't used on ESP32, leave as default)
const uint8_t kPanelType = SM_PANELTYPE_HUB75_64ROW_MOD32SCAN;   // Choose the configuration that matches your panels.  See more details in MatrixCommonHub75.h and the docs: https://github.com/pixelmatix/SmartMatrix/wiki
const uint32_t kMatrixOptions = ( SM_HUB75_OPTIONS_BOTTOM_TO_TOP_STACKING); //(SM_HUB75_OPTIONS_NONE);        // see docs for options: https://github.com/pixelmatix/SmartMatrix/wiki
const uint8_t kIndexedLayerOptions = (SM_INDEXED_OPTIONS_NONE);
const uint8_t kBackgroundLayerOptions = (SM_BACKGROUND_OPTIONS_NONE);
const uint8_t kScrollingLayerOptions = (SM_SCROLLING_OPTIONS_NONE);

SMARTMATRIX_ALLOCATE_BUFFERS(matrix, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions);

SMARTMATRIX_ALLOCATE_BACKGROUND_LAYER(backgroundLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kBackgroundLayerOptions);

const int defaultBrightness = 254;        // full (100%) brightness

//const int defaultBrightness = (15*255)/100;       // dim: 15% brightness

const int defaultScrollOffset = 6;

const rgb24 defaultBackgroundColor = {0x00, 0, 0};

// Teensy 4.0 has the LED on pin 13

const int ledPin = 13;

using namespace std;

// let's not burden ourselves with the tgx:: prefix

using namespace tgx;

// screen dimension (landscape mode)

static const int SLX = kMatrixWidth;

static const int SLY = kMatrixHeight;

// main screen framebuffer (48K in DTCM for fastest access)

RGB24 fb[SLX * SLY];                

// zbuffer (64K in DMAMEM)

DMAMEM float zbuf[SLX * SLY];          

// image that encapsulates the framebuffer fb.

Image<RGB24> im(fb, SLX, SLY);

// the texture image

const int tex_size = 128;

RGB24 texture_data[tex_size*tex_size];

Image<RGB24> texture(texture_data, tex_size, tex_size);

// 3D mesh drawer : using perspective projection.

Renderer3D<RGB24, SLX, SLY, true, false> rendererP;

// 3D mesh drawer : using orthoscopic projection.

Renderer3D<RGB24, SLX, SLY, true, true> rendererO;

// the cube 8 vertices

fVec3 tab_vertices[8] =

    {

    {-1,-1,1},

    {1,-1,1},

    {1,1,1},

    {-1,1,1},

    {-1,-1,-1},

    {1,-1,-1},

    {1,1,-1},

    {-1,1,-1}

    };

// texture indices

fVec2 tab_tex[4] =

    {

    {0.0f, 0.0f},

    {1.0f, 0.0f},

    {1.0f, 1.0f},

    {0.0f, 1.0f},

    };

// list of quads.

uint16_t vert_ind[6 * 4] =

    {

    0, 1, 2, 3, // front

    1, 5, 6, 2, // right

    5, 4, 7, 6, // back

    4, 0, 3, 7, // left

    0, 4, 5, 1, // bottom

    3, 2, 6, 7  // top

    };

// use the same texture on each quad

uint16_t tex_ind[6 * 4] =

    {

    0, 1, 2, 3,

    0, 1, 2, 3,

    0, 1, 2, 3,

    0, 1, 2, 3,

    0, 1, 2, 3,

    0, 1, 2, 3

    };

// the setup() method runs once, when the sketch starts

void setup() {

    // initialize the digital pin as an output.

    pinMode(ledPin, OUTPUT);

    Serial.begin(115200);

    matrix.addLayer(&backgroundLayer);

    matrix.begin();

    matrix.setBrightness(defaultBrightness);

    backgroundLayer.enableColorCorrection(true);

    // clear screen

    backgroundLayer.fillScreen(defaultBackgroundColor);

    backgroundLayer.swapBuffers();

   

    const float ratio = ((float)SLX) / SLY;

    // setup the 3D renderer with perspective projection

    rendererP.setOffset(0, 0);

    rendererP.setImage(&im);

    rendererP.setZbuffer(zbuf, SLX * SLY);

    rendererP.setPerspective(45, ratio, 0.1f, 1000.0f);

    rendererP.setCulling(1);

    rendererP.useBilinearTexturing(true);

    // setup the 3D renderer with orthoscopic projection

    rendererO.setOffset(0, 0);

    rendererO.setImage(&im);

    rendererO.setZbuffer(zbuf, SLX * SLY);

    rendererO.setOrtho(-1.8*ratio, 1.8 *ratio, -1.8, 1.8, 0.1f, 1000.0f);

    rendererO.setCulling(1);

    rendererO.useBilinearTexturing(true);

    // initial textrure color

    texture.fillScreen(RGB565_Blue);

}

             

/** draw a random rectangle on the texture */

void splash()

    {

    static int count = 0;    

    static RGB565 color;

    if (count == 0)

        color = RGB565((int)random(32), (int)random(64), (int)random(32));

    count = (count + 1) % 400;

    iVec2 pos(random(tex_size), random(tex_size));

    int r = random(10);

    texture.drawRect(iBox2( pos.x - r, pos.x + r, pos.y - r, pos.y + r ), color);

    }

/** draw the current fps on the image */

void fps(const char* str)

    {

    static elapsedMillis em = 0; // number of milli elapsed since last fps update

    static int fps = 0;         // last fps

    static int count = 0;       // number of frames since the last update

    // recompute fps every second.

    count++;

    if ((int)em > 1000)

        {

        em = 0;

        fps = count;

        count = 0;

        }

    // display

    //im.drawText(str, {3,12 }, RGB565_Red, font_tgx_OpenSans_Bold_10, false);

    char buf[10];

    sprintf(buf, "%d FPS", fps);

    auto B = im.measureText(buf, { 0,0 }, font_tgx_OpenSans_Bold_10, false);

    im.drawText(buf, { SLX - B.lx() - 3,12 }, RGB565_Red, font_tgx_OpenSans_Bold_10, false);

    }

elapsedMillis em = 0; // time

int nbf = 0; ; // number frames drawn

int projtype = 0; // current projection used.

void loop()

    {

   

    // model matrix

    fMat4 M;

    M.setRotate(em / 11.0f, { 0,1,0 });

    M.multRotate(em / 23.0f, { 1,0,0 });

    M.multRotate(em / 41.0f, { 0,0,1 });

    M.multTranslate({ 0, 0, -5 });

    if (projtype)

        {        

        im.fillScreen(RGB565_Black); // erase the screen

        rendererP.clearZbuffer(); // clear the z buffer        

        rendererP.setModelMatrix(M);// position the model        

        rendererP.drawQuads(TGX_SHADER_TEXTURE, 6, vert_ind, tab_vertices, nullptr, nullptr, tex_ind, tab_tex, &texture); // draw !        

        fps("Perspective projection"); // overlay some infos

        }

    else

        {

        im.fillScreen(RGB565_Gray); // erase the screen

        rendererO.clearZbuffer();

        rendererO.setModelMatrix(M);

        rendererO.drawQuads(TGX_SHADER_TEXTURE, 6, vert_ind, tab_vertices, nullptr, nullptr, tex_ind, tab_tex, &texture); // draw !

        fps("Orthoscopic projection"); // overlay some infos

        }

    // update the screen (async).

    memcpy(backgroundLayer.getRealBackBuffer(),fb,sizeof(fb));

    backgroundLayer.swapBuffers();

    // add a random rect on the texture.

    splash();

    // swith between perspective and orthogonal projection every 1000 frames.

        if (nbf++ % 1000 == 0)

            {

            projtype = 1 - projtype;

            }

    }

       

/** end of file */
1 Like

Looks great, thanks for sharing!

No worries!

In the meantime, here’s the “scream” example, complete with a RGB24 version of the image used: Example of TGX Library with SmartMatrix · GitHub

This one runs at about 16 to 20 FPS, but I’m still very impressed with what that little chip is doing in real-time!

Looks cool. I’ve been using matrices for pictures and gif videos. I must try this. Thanks for sharing!

Thanks @welshcoder .
May I encourage you to write this on top of framebuffer::gfx? That way it will work on all hardware backends, including rgbpanels on smartmatrix and rPi for bigger panels (and FastLED, and TFTs, and even rendered directly on linux for easier writing/debugging). See

Hello Louis,
I want to create a pointer image with HUB75 RGB panels.
The pointers are slowly rotating lines that together form a pattern.
I can create simple lines using the examples from SmartMatrix and the GFX commands. (looks not good)

#define USE_ADAFRUIT_GFX_LAYERS
#include <MatrixHardware_Teensy4_ShieldV5.h>        
#include <SmartMatrix.h>

#define COLOR_DEPTH 24                  // Farbtiefe: 24 oder 48 (24 ist standard)
const uint16_t kMatrixWidth = 32;       // Anzahl Pixel Breite 
const uint16_t kMatrixHeight = 32;      // Anzahl Pixel Höhe 
const uint8_t kRefreshDepth = 36;       // Tradeoff of color quality vs refresh rate, max brightness, and RAM usage.  36 is typically good, drop down to 24 if you need to.  On Teensy, multiples of 3, up to 48: 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48.  On ESP32: 24, 36, 48
const uint8_t kDmaBufferRows = 4;       // known working: 2-4, use 2 to save RAM, more to keep from dropping frames and automatically lowering refresh rate.  (This isn't used on ESP32, leave as default)
const uint8_t kPanelType = SM_PANELTYPE_HUB75_32ROW_MOD16SCAN;   // Choose the configuration that matches your panels.  See more details in MatrixCommonHub75.h and the docs: https://github.com/pixelmatix/SmartMatrix/wiki
const uint32_t kMatrixOptions = (SM_HUB75_OPTIONS_NONE);        // see docs for options: https://github.com/pixelmatix/SmartMatrix/wiki

SMARTMATRIX_ALLOCATE_BUFFERS(matrix, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions);
const uint8_t kBackgroundLayerOptions = (SM_BACKGROUND_OPTIONS_NONE);
SMARTMATRIX_ALLOCATE_BACKGROUND_LAYER(backgroundLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kBackgroundLayerOptions);


#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF


void setup()
{
  Serial.begin(115200);
  matrix.addLayer(&backgroundLayer); 
  matrix.begin();
  delay(1000);
  matrix.setBrightness(60);

 float angle = 90;
 float x = 0;
 float y = 0;
 int pointer_length = 30;

 for(int i = 0; i < 900; i++)
 {
  angle = angle + 0.1;
  x = sin(angle * 3.1415926 / 180) * pointer_length;
  y = cos(angle * 3.1415926 / 180) * pointer_length;
  y = abs(y);

  backgroundLayer.fillScreen(BLACK);
  backgroundLayer.drawLine(0, 0, x, y, WHITE);
  backgroundLayer.swapBuffers();

  delay(100);

  Serial.print("Angle: ");
  Serial.println(angle);
  Serial.print("x: ");
  Serial.println(x);
  Serial.print("y: ");
  Serial.println(y);
  Serial.print(" ");
 }
}



void loop()
{

}


Now I’ve read that the tgx library offers a way to create lines with antialasing and sub-pixel precision. That would be great for my project!
Unfortunately, I haven’t managed to integrate the tgx library. (Error compiling)

//#define USE_ADAFRUIT_GFX_LAYERS
#include <MatrixHardware_Teensy4_ShieldV5.h>        
#include <SmartMatrix.h>
#include <tgx.h>

#define COLOR_DEPTH 24                  // Farbtiefe: 24 oder 48 (24 ist standard)
const uint16_t kMatrixWidth = 32;       // Anzahl Pixel Breite 
const uint16_t kMatrixHeight = 32;      // Anzahl Pixel Höhe 
const uint8_t kRefreshDepth = 36;       // Tradeoff of color quality vs refresh rate, max brightness, and RAM usage.  36 is typically good, drop down to 24 if you need to.  On Teensy, multiples of 3, up to 48: 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48.  On ESP32: 24, 36, 48
const uint8_t kDmaBufferRows = 4;       // known working: 2-4, use 2 to save RAM, more to keep from dropping frames and automatically lowering refresh rate.  (This isn't used on ESP32, leave as default)
const uint8_t kPanelType = SM_PANELTYPE_HUB75_32ROW_MOD16SCAN;   // Choose the configuration that matches your panels.  See more details in MatrixCommonHub75.h and the docs: https://github.com/pixelmatix/SmartMatrix/wiki
const uint32_t kMatrixOptions = (SM_HUB75_OPTIONS_NONE);        // see docs for options: https://github.com/pixelmatix/SmartMatrix/wiki

SMARTMATRIX_ALLOCATE_BUFFERS(matrix, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions);
const uint8_t kBackgroundLayerOptions = (SM_BACKGROUND_OPTIONS_NONE);
SMARTMATRIX_ALLOCATE_BACKGROUND_LAYER(backgroundLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kBackgroundLayerOptions);

const rgb24 defaultBackgroundColor = {0x0000};
const rgb24 defaultBackgroundColor_w = {0xFFFF};



void setup()
{
  Serial.begin(115200);
  matrix.addLayer(&backgroundLayer); 
  matrix.begin();
  delay(1000);
  matrix.setBrightness(60);

 float angle = 90;
 float x = 0;
 float y = 0;
 int pointer_length = 30;

 for(int i = 0; i < 900; i++)
 {
  angle = angle + 0.1;
  x = sin(angle * 3.1415926 / 180) * pointer_length;
  y = cos(angle * 3.1415926 / 180) * pointer_length;
  y = abs(y);

  backgroundLayer.fillScreen(defaultBackgroundColor);
  backgroundLayer.drawWideLine(0, 0, x, y, 10, defaultBackgroundColor_w, 1.0f);
  backgroundLayer.swapBuffers();

  delay(100);

  Serial.print("Angle: ");
  Serial.println(angle);
  Serial.print("x: ");
  Serial.println(x);
  Serial.print("y: ");
  Serial.println(y);
  Serial.print(" ");
 }
}



void loop()
{

}


This is probably a small problem, but I’m a beginner and I usually look for example code that I then change. But, I haven’t found anything!
Maybe you can help me! (what needs to be changed in my code to make it work)

Thanks Tomes

Please show a error message in full

this is the error message when compiling:

In file included from E:\Projekte\LED_Matrix\LED_Matrix_test_tgx\LED_Matrix_test_tgx.ino:2:
e:\Projekte\libraries\SmartMatrix\src/MatrixHardware_Teensy4_ShieldV5.h:41:17: note: '#pragma message: MatrixHardware: SmartLED Shield for Teensy 4 (V5)'
   41 | #pragma message "MatrixHardware: SmartLED Shield for Teensy 4 (V5)"
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from E:\Projekte\LED_Matrix\LED_Matrix_test_tgx\LED_Matrix_test_tgx.ino:3:
e:\Projekte\libraries\SmartMatrix\src/SmartMatrix.h:40:21: note: '#pragma message: SmartMatrix Library version 4.000.003'
   40 | #    pragma message "SmartMatrix Library version 4.000.003"
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
E:\Projekte\LED_Matrix\LED_Matrix_test_tgx\LED_Matrix_test_tgx.ino: In function 'void setup()':
E:\Projekte\LED_Matrix\LED_Matrix_test_tgx\LED_Matrix_test_tgx.ino:44:19: error: 'class SMLayerBackground<rgb24, 0>' has no member named 'drawWideLine'; did you mean 'drawLine'?
   44 |   backgroundLayer.drawWideLine(0, 0, x, y, 10, defaultBackgroundColor_w, 1.0f);
      |                   ^~~~~~~~~~~~
      |                   drawLine
In file included from e:\Projekte\libraries\SmartMatrix\src/Layer_Background.h:124,
                 from e:\Projekte\libraries\SmartMatrix\src/SmartMatrix.h:55,
                 from E:\Projekte\LED_Matrix\LED_Matrix_test_tgx\LED_Matrix_test_tgx.ino:3:
e:\Projekte\libraries\SmartMatrix\src/Layer_Background_Impl.h: In instantiation of 'void SMLayerBackground<RGB, optionFlags>::swapBuffers(bool) [with RGB = rgb24; unsigned int optionFlags = 0]':
E:\Projekte\LED_Matrix\LED_Matrix_test_tgx\LED_Matrix_test_tgx.ino:45:30:   required from here
e:\Projekte\libraries\SmartMatrix\src/Layer_Background_Impl.h:970:19: warning: 'void* memcpy(void*, const void*, size_t)' writing to an object of type 'struct rgb24' with no trivial copy-assignment; use copy-assignment or copy-initialization instead [-Wclass-memaccess]
  970 |             memcpy(backgroundBuffers[1], backgroundBuffers[0], sizeof(RGB) * (this->matrixWidth * this->matrixHeight));
      |             ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from e:\Projekte\libraries\SmartMatrix\src/SmartMatrix.h:50,
                 from E:\Projekte\LED_Matrix\LED_Matrix_test_tgx\LED_Matrix_test_tgx.ino:3:
e:\Projekte\libraries\SmartMatrix\src/MatrixCommon.h:139:16: note: 'struct rgb24' declared here
  139 | typedef struct rgb24 {
      |                ^~~~~
In file included from e:\Projekte\libraries\SmartMatrix\src/Layer_Background.h:124,
                 from e:\Projekte\libraries\SmartMatrix\src/SmartMatrix.h:55,
                 from E:\Projekte\LED_Matrix\LED_Matrix_test_tgx\LED_Matrix_test_tgx.ino:3:
e:\Projekte\libraries\SmartMatrix\src/Layer_Background_Impl.h:972:19: warning: 'void* memcpy(void*, const void*, size_t)' writing to an object of type 'struct rgb24' with no trivial copy-assignment; use copy-assignment or copy-initialization instead [-Wclass-memaccess]
  972 |             memcpy(backgroundBuffers[0], backgroundBuffers[1], sizeof(RGB) * (this->matrixWidth * this->matrixHeight));
      |             ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from e:\Projekte\libraries\SmartMatrix\src/SmartMatrix.h:50,
                 from E:\Projekte\LED_Matrix\LED_Matrix_test_tgx\LED_Matrix_test_tgx.ino:3:
e:\Projekte\libraries\SmartMatrix\src/MatrixCommon.h:139:16: note: 'struct rgb24' declared here
  139 | typedef struct rgb24 {
      |                ^~~~~
In file included from e:\Projekte\libraries\SmartMatrix\src/SmartMatrix.h:218,
                 from E:\Projekte\LED_Matrix\LED_Matrix_test_tgx\LED_Matrix_test_tgx.ino:3:
e:\Projekte\libraries\SmartMatrix\src/MatrixTeensy4Hub75Refresh_Impl.h: In instantiation of 'static void SmartMatrixRefreshT4<refreshDepth, matrixWidth, matrixHeight, panelType, optionFlags>::hardwareSetup() [with int refreshDepth = 36; int matrixWidth = 32; int matrixHeight = 32; unsigned char panelType = 0; long unsigned int optionFlags = 0]':
e:\Projekte\libraries\SmartMatrix\src/MatrixTeensy4Hub75Refresh_Impl.h:389:18:   required from 'static void SmartMatrixRefreshT4<refreshDepth, matrixWidth, matrixHeight, panelType, optionFlags>::begin() [with int refreshDepth = 36; int matrixWidth = 32; int matrixHeight = 32; unsigned char panelType = 0; long unsigned int optionFlags = 0]'
e:\Projekte\libraries\SmartMatrix\src/MatrixTeensy4Hub75Calc_Impl.h:272:97:   required from 'void SmartMatrixHub75Calc<refreshDepth, matrixWidth, matrixHeight, panelType, optionFlags>::begin() [with int refreshDepth = 36; int matrixWidth = 32; int matrixHeight = 32; unsigned char panelType = 0; long unsigned int optionFlags = 0]'
E:\Projekte\LED_Matrix\LED_Matrix_test_tgx\LED_Matrix_test_tgx.ino:27:15:   required from here
e:\Projekte\libraries\SmartMatrix\src/MatrixTeensy4Hub75Refresh_Impl.h:669:88: warning: taking address of packed member of 'SmartMatrixRefreshT4<36, 32, 32, 0, 0>::timerpair' may result in an unaligned pointer value [-Waddress-of-packed-member]
  669 |     sourceAddress = (volatile uint32_t*) & (matrixUpdateRows[0].rowbits[0].timerValues.timer_oe);
      |                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
In file included from e:\Projekte\libraries\SmartMatrix\src/SmartMatrix.h:219,
                 from E:\Projekte\LED_Matrix\LED_Matrix_test_tgx\LED_Matrix_test_tgx.ino:3:
e:\Projekte\libraries\SmartMatrix\src/MatrixTeensy4Hub75Calc_Impl.h: In instantiation of 'static void SmartMatrixHub75Calc<refreshDepth, matrixWidth, matrixHeight, panelType, optionFlags>::loadMatrixBuffers48(volatile rowDataStruct*, unsigned int) [with int refreshDepth = 36; int matrixWidth = 32; int matrixHeight = 32; unsigned char panelType = 0; long unsigned int optionFlags = 0; SmartMatrixHub75Calc<refreshDepth, matrixWidth, matrixHeight, panelType, optionFlags>::rowDataStruct = SmartMatrixRefreshT4<36, 32, 32, 0, 0>::rowDataStruct]':
e:\Projekte\libraries\SmartMatrix\src/MatrixTeensy4Hub75Calc_Impl.h:548:24:   required from 'static void SmartMatrixHub75Calc<refreshDepth, matrixWidth, matrixHeight, panelType, optionFlags>::loadMatrixBuffers(unsigned int) [with int refreshDepth = 36; int matrixWidth = 32; int matrixHeight = 32; unsigned char panelType = 0; long unsigned int optionFlags = 0]'
e:\Projekte\libraries\SmartMatrix\src/MatrixTeensy4Hub75Calc_Impl.h:168:113:   required from 'static void SmartMatrixHub75Calc<refreshDepth, matrixWidth, matrixHeight, panelType, optionFlags>::matrixCalculations(bool) [with int refreshDepth = 36; int matrixWidth = 32; int matrixHeight = 32; unsigned char panelType = 0; long unsigned int optionFlags = 0]'
e:\Projekte\libraries\SmartMatrix\src/MatrixTeensy4Hub75Calc_Impl.h:270:121:   required from 'void SmartMatrixHub75Calc<refreshDepth, matrixWidth, matrixHeight, panelType, optionFlags>::begin() [with int refreshDepth = 36; int matrixWidth = 32; int matrixHeight = 32; unsigned char panelType = 0; long unsigned int optionFlags = 0]'
E:\Projekte\LED_Matrix\LED_Matrix_test_tgx\LED_Matrix_test_tgx.ino:27:15:   required from here
e:\Projekte\libraries\SmartMatrix\src/MatrixTeensy4Hub75Calc_Impl.h:384:15: warning: 'void* memset(void*, int, size_t)' clearing an object of non-trivial type 'rgb48' {aka 'struct rgb48'}; use assignment or value-initialization instead [-Wclass-memaccess]
  384 |         memset(tempRow0, 0, sizeof(tempRow0));
      |         ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from e:\Projekte\libraries\SmartMatrix\src/SmartMatrix.h:50,
                 from E:\Projekte\LED_Matrix\LED_Matrix_test_tgx\LED_Matrix_test_tgx.ino:3:
e:\Projekte\libraries\SmartMatrix\src/MatrixCommon.h:159:16: note: 'rgb48' {aka 'struct rgb48'} declared here
  159 | typedef struct rgb48 {
      |                ^~~~~
In file included from e:\Projekte\libraries\SmartMatrix\src/SmartMatrix.h:219,
                 from E:\Projekte\LED_Matrix\LED_Matrix_test_tgx\LED_Matrix_test_tgx.ino:3:
e:\Projekte\libraries\SmartMatrix\src/MatrixTeensy4Hub75Calc_Impl.h:385:15: warning: 'void* memset(void*, int, size_t)' clearing an object of non-trivial type 'rgb48' {aka 'struct rgb48'}; use assignment or value-initialization instead [-Wclass-memaccess]
  385 |         memset(tempRow1, 0, sizeof(tempRow1));
      |         ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from e:\Projekte\libraries\SmartMatrix\src/SmartMatrix.h:50,
                 from E:\Projekte\LED_Matrix\LED_Matrix_test_tgx\LED_Matrix_test_tgx.ino:3:
e:\Projekte\libraries\SmartMatrix\src/MatrixCommon.h:159:16: note: 'rgb48' {aka 'struct rgb48'} declared here
  159 | typedef struct rgb48 {
      |                ^~~~~

exit status 1

Compilation error: 'class SMLayerBackground<rgb24, 0>' has no member named 'drawWideLine'; did you mean 'drawLine'?