mrcodetastic / ESP32-HUB75-MatrixPanel-DMA

An Adafruit GFX Compatible Library for the ESP32, ESP32-S2, ESP32-S3 to drive HUB75 LED matrix panels using DMA for high refresh rates. Supports panel chaining.
MIT License
951 stars 211 forks source link

Draw gif animation #53

Closed tsctrl closed 3 years ago

tsctrl commented 3 years ago

Hi mrfaptastic, i want to thank you so much for such a great library and afford you did to deliver this library.

I would like to have this library to be capable on drawing gif animation as was previously done by the Sprite_TM but my knowledge, capability on writing good codes and understanding all the technic written in the library are very limited. I have issue to reimplement back the gif animation code as below:

#include "anim.h"
inline void MatrixPanel_I2S_DMA::drawGif() {

    int apos=0; //which frame in the animation we're on
    int backbuf_id=0; //which buffer is the backbuffer, as in, which one is not active so we can write to it
    while(1) {
        //Fill bitplanes with the data for the current image
        const uint8_t *pix=&anim[apos*64*32*3];     //pixel data for this animation frame
        for (int pl=0; pl<ROWS_PER_FRAME; pl++) {
            int mask=(1<<(8-ROWS_PER_FRAME+pl)); //bitmask for pixel data in input for this bitplane

            //uint16_t *p=bitplane[backbuf_id][pl]; //bitplane location to write to

            rowColorDepthStruct *fb_row_malloc_ptr = (rowColorDepthStruct *) matrix_row_framebuffer_malloc[pl];
            // The destination for the pixel bitstream
            rowBitStruct *pRowBitStruct = &fb_row_malloc_ptr[back_buffer_id].rowbits[pl]; //matrixUpdateFrames location to write to uint16_t's
            uint16_t *p= pRowBitStruct->data;

            for (unsigned int y=0; y<16; y++) {
                int lbits=0;                //Precalculate line bits of the *previous* line, which is the one we're displaying now
                if ((y-1)&1) lbits|=BIT_A;
                if ((y-1)&2) lbits|=BIT_B;
                if ((y-1)&4) lbits|=BIT_C;
                if ((y-1)&8) lbits|=BIT_D;
                for (int fx=0; fx<64; fx++) {

    #if DISPLAY_ROWS_SWAPPED
                        int x=fx^1; //to correct for the fact that the stupid LED screen I have has each row swapped...
    #else
                        int x=fx;
    #endif

                    int v=lbits;
                    //Do not show image while the line bits are changing
                    if (fx<1 || fx>=brightness) v|=BIT_OE;
                    if (fx==62) v|=BIT_LAT; //latch on second-to-last bit... why not last bit? Dunno, probably a timing thing.

                    //int c1, c2;
                    int c1=getpixel((uint8_t*)pix, x, y);
                    int c2=getpixel((uint8_t*)pix, x, y+16);
                    if (c1 & (mask<<16)) v|=BIT_R1;
                    if (c1 & (mask<<8)) v|=BIT_G1;
                    if (c1 & (mask<<0)) v|=BIT_B1;
                    if (c2 & (mask<<16)) v|=BIT_R2;
                    if (c2 & (mask<<8)) v|=BIT_G2;
                    if (c2 & (mask<<0)) v|=BIT_B2;

                    //Save the calculated value to the bitplane memory
                    *p++=v;
                }
            }
        }

        //Show our work!
        i2s_parallel_flip_to_buffer(&I2S1, backbuf_id);
        backbuf_id^=1;
        //Bitplanes are updated, new image shows now.
       //vTaskDelay(100 / portTICK_PERIOD_MS); //animation has an 100ms interval

        apos++;
        if (apos>=12) apos=0;

    }

Basically i did not know how to write the plane and update the display as per new struct structure that was implemented. I hope you can shed some light as how to write to the struct and properly update the matrix. Thank you in advance.

Cheers, TS

mrcodetastic commented 3 years ago

Hi @tsctrl, thank you for the kind words.

I think it would be easier to refer and base your project on this example: https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/tree/master/examples/AnimatedGIFPanel

tsctrl commented 3 years ago

Hi @mrfaptastic, thank you so much for the example. I have one more queries which i not able to find the answer/example anywhere specifically for matrix panel. Is it possible to run the row select thru PCF8574 or 74HC595? i would like to save builtin DAC for audio and also the SPI for sd.

Thank you

mrcodetastic commented 3 years ago

I don't know anything about the PCF8574 or 74HC595 chips to be honest. Techincally it could be possible, but the library would need to be completely re-engineered. Do you not have enough pins free? DAC and SPI would still be available to use if you have enough spare pins.

tsctrl commented 3 years ago

yup, i have short of free pins. esp32-devkit-esp32-wroom-gpio-pinout the matrix already consume 13 gpio pins for 64x32 6124 panel. 34,35,36,39 is input only pin which only work with mic/sensors or buttons. i have to sacrifice 25,26 dac output to spare the spi (sdcard support) and i2c port as it is more the most expandable pins. there is nothing missing with your library. there always other solution out there. by looking at this library, this lib does not have tight dependency to Arduino such as the protomatter and yet simple to use. specific for esp32. which for me does not have messy if statement to cater different devices (they should use different includes for different devices in my opinion). provide what is needed, do what it should without complex layering etc. the code is clean and generic. if i need to light up a stadium with panel. i would use other approach than using imbedded device though. if you are in a speed race. you already won.

thank you again for the library. this is a good one!