vindar / tgx

tgx - a tiny/teensy 3D graphics library
GNU Lesser General Public License v2.1
176 stars 31 forks source link

About LovyanGFX using tgx #13

Open modi12jin opened 2 years ago

modi12jin commented 2 years ago

https://github.com/lovyan03/LovyanGFX

#define LGFX_USE_V1

#include <LovyanGFX.hpp>

// graphic library
#include <tgx.h>

// the mesh to draw
#include "naruto.h"

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

class LGFX : public lgfx::LGFX_Device
{

   lgfx::Panel_ST7796 _panel_instance; 

   lgfx::Bus_Parallel8 _bus_instance;

   lgfx::Light_PWM _light_instance;

   lgfx::Touch_FT5x06  _touch_instance; 

public:
   LGFX(void)
   {
      {  
         auto cfg = _bus_instance.config();

         cfg.port = 0;  
         cfg.freq_write = 20000000;
         cfg.pin_wr = 47;           // WR を接続しているピン番号
         cfg.pin_rd = -1;           // RD を接続しているピン番号
         cfg.pin_rs = 0;           // RS(D/C)を接続しているピン番号
         cfg.pin_d0 = 9;            // D0を接続しているピン番号
         cfg.pin_d1 = 46;            // D1を接続しているピン番号
         cfg.pin_d2 = 3;            // D2を接続しているピン番号
         cfg.pin_d3 = 8;            // D3を接続しているピン番号
         cfg.pin_d4 = 18;            // D4を接続しているピン番号
         cfg.pin_d5 = 17;            // D5を接続しているピン番号
         cfg.pin_d6 = 16;            // D6を接続しているピン番号
         cfg.pin_d7 = 15;            // D7を接続しているピン番号

         _bus_instance.config(cfg);              // 設定値をバスに反映します。
         _panel_instance.setBus(&_bus_instance); // バスをパネルにセットします。
      }

      {                                       // 表示パネル制御の設定を行います。
         auto cfg = _panel_instance.config(); // 表示パネル設定用の構造体を取得します。

         cfg.pin_cs = -1;   // CSが接続されているピン番号   (-1 = disable)
         cfg.pin_rst = 4;  // RSTが接続されているピン番号  (-1 = disable)
         cfg.pin_busy = -1; // BUSYが接続されているピン番号 (-1 = disable)

         // ※ 以下の設定値はパネル毎に一般的な初期値が設定さ BUSYが接続されているピン番号 (-1 = disable)れていますので、不明な項目はコメントアウトして試してみてください。

         cfg.memory_width = 320;   // ドライバICがサポートしている最大の幅
         cfg.memory_height = 480;  // ドライバICがサポートしている最大の高さ
         cfg.panel_width = 320;    // 実際に表示可能な幅
         cfg.panel_height = 480;   // 実際に表示可能な高さ
         cfg.offset_x = 0;         // パネルのX方向オフセット量
         cfg.offset_y = 0;         // パネルのY方向オフセット量
         cfg.offset_rotation = 1;  //值在旋转方向的偏移0~7(4~7是倒置的)
         cfg.dummy_read_pixel = 8; // 在读取像素之前读取的虚拟位数
         cfg.dummy_read_bits = 1;  // 读取像素以外的数据之前的虚拟读取位数
         cfg.readable = false;      // 如果可以读取数据,则设置为 true
         cfg.invert = true;       // 如果面板的明暗反转,则设置为 true
         cfg.rgb_order = false;    // 如果面板的红色和蓝色被交换,则设置为 true
         cfg.dlen_16bit = false;   // 对于以 16 位单位发送数据长度的面板,设置为 true
         cfg.bus_shared = false;    // 如果总线与 SD 卡共享,则设置为 true(使用 drawJpgFile 等执行总线控制)

         _panel_instance.config(cfg);
      }

    { // バックライト制御の設定を行います。(必要なければ削除)
      auto cfg = _light_instance.config();    // バックライト設定用の構造体を取得します。

      cfg.pin_bl = 45;              // バックライトが接続されているピン番号
      cfg.invert = false;           // バックライトの輝度を反転させる場合 true
      cfg.freq   = 44100;           // バックライトのPWM周波数
      cfg.pwm_channel = 1;          // 使用するPWMのチャンネル番号

      _light_instance.config(cfg);
      _panel_instance.setLight(&_light_instance);  // バックライトをパネルにセットします。
    }

    { // タッチスクリーン制御の設定を行います。(必要なければ削除)
      auto cfg = _touch_instance.config();

      cfg.x_min      = 0;    // タッチスクリーンから得られる最小のX値(生の値)
      cfg.x_max      = 319;  // タッチスクリーンから得られる最大のX値(生の値)
      cfg.y_min      = 0;    // タッチスクリーンから得られる最小のY値(生の値)
      cfg.y_max      = 479;  // タッチスクリーンから得られる最大のY値(生の値)
      cfg.pin_int    = 7;   // INTが接続されているピン番号
      cfg.bus_shared = false; // 如果您使用与屏幕相同的总线,则设置为 true
      cfg.offset_rotation = 0;// 显示和触摸方向不匹配时的调整 设置为 0 到 7 的值

// I2C接続の場合
      cfg.i2c_port = 0;      // 使用するI2Cを選択 (0 or 1)
      cfg.i2c_addr = 0x38;   // I2Cデバイスアドレス番号
      cfg.pin_sda  = 6;     // SDAが接続されているピン番号
      cfg.pin_scl  = 5;     // SCLが接続されているピン番号
      cfg.freq = 400000;     // I2Cクロックを設定

      _touch_instance.config(cfg);
      _panel_instance.setTouch(&_touch_instance);  // タッチスクリーンをパネルにセットします。
    }

      setPanel(&_panel_instance); // 使用するパネルをセットします。
   }
};

LGFX tft;

// size of the drawing framebuffer
// (limited by the amount of memory in the ESP32S3). 
#define SLX 320
#define SLY 320

// the framebuffer we draw onto
uint16_t fb[SLX * SLY];

// second framebuffer used by eSPI_TFT for DMA update
// allocated via malloc
uint16_t* fb2;

// the z-buffer in 16 bits precision
uint16_t* zbuf;

// the image that encapsulate framebuffer fb
Image<RGB565> imfb(fb, SLX, SLY);

// only load the shaders we need.
const int LOADED_SHADERS = TGX_SHADER_PERSPECTIVE | TGX_SHADER_ZBUFFER | TGX_SHADER_FLAT | TGX_SHADER_GOURAUD | TGX_SHADER_NOTEXTURE | TGX_SHADER_TEXTURE_NEAREST |TGX_SHADER_TEXTURE_WRAP_POW2;

// the renderer object that performs the 3D drawings
Renderer3D<RGB565, SLX, SLY, LOADED_SHADERS, uint16_t> renderer;

// the setup function runs once when you press reset or power the board
void setup()
{
    Serial.begin(115200);

    // allocate the second framebuffer
    fb2 = (uint16_t*)malloc(SLX * SLY * sizeof(uint16_t));
    while (fb2 == nullptr)
    {
        Serial.println("Error: cannot allocate memory for fb2");
        delay(1000);
    }

    // allocate the zbuffer
    zbuf = (uint16_t*)malloc(SLX * SLY * sizeof(uint16_t));
    while (zbuf == nullptr)
    {
        Serial.println("Error: cannot allocate memory for zbuf");
        delay(1000);
    }

    // initialize the screen driver
    tft.init();
    tft.setRotation(0);
    tft.setSwapBytes(true);
    tft.fillScreen(TFT_BLACK);
    tft.setTextColor(TFT_RED);

    tft.initDMA();
    tft.startWrite();

    // setup the 3D renderer.
    renderer.setImage(&imfb); // set the image to draw onto (ie the screen framebuffer)
    renderer.setZbuffer(zbuf); // set the z buffer for depth testing
    renderer.setPerspective(45, ((float)SLX) / SLY, 1.0f, 100.0f);  // set the perspective projection matrix.     
    renderer.setMaterial(RGBf(0.85f, 0.55f, 0.25f), 0.2f, 0.7f, 0.8f, 64); // bronze color with a lot of specular reflexion. 
    renderer.setOffset(0, 0);
    renderer.setCulling(1);
    renderer.setTextureQuality(TGX_SHADER_TEXTURE_NEAREST);
    renderer.setTextureWrappingMode(TGX_SHADER_TEXTURE_WRAP_POW2);        
}

/** Compute the model matrix according to the current time */
tgx::fMat4 moveModel(int& loopnumber)
{
    const float end1 = 6000;
    const float end2 = 2000;
    const float end3 = 6000;
    const float end4 = 2000;

    int tot = (int)(end1 + end2 + end3 + end4);
    int m = millis();

    loopnumber = m / tot;
    float t = m % tot;

    const float dilat = 9; // scale model
    const float roty = 360 * (t / 4000); // rotate 1 turn every 4 seconds        
    float tz, ty;
    if (t < end1)
    { // far away
        tz = -25;
        ty = 0;
    }
    else
    {
        t -= end1;
        if (t < end2)
        { // zooming in
            t /= end2;
            tz = -25 + 18 * t;
            ty = -6.5f * t;
        }
        else
        {
            t -= end2;
            if (t < end3)
            { // close up
                tz = -7;
                ty = -6.5f;
            }
            else
            { // zooming out
                t -= end3;
                t /= end4;
                tz = -7 - 18 * t;
                ty = -6.5 + 6.5 * t;
            }
        }
    }

    fMat4 M;
    M.setScale({ dilat, dilat, dilat }); // scale the model
    M.multRotate(-roty, { 0,1,0 }); // rotate around y
    M.multTranslate({ 0,ty, tz }); // translate
    return M;
}

int loopnumber = 0;
int prev_loopnumber = -1;

/** Main loop */
void loop()
{
    // compute the model position
    fMat4  M = moveModel(loopnumber);
    renderer.setModelMatrix(M);

    // draw the 3D mesh
    imfb.fillScreen(RGB565_Cyan);              // clear the framebuffer (black background)
    renderer.clearZbuffer();                    // clear the z-buffer

    // choose the shader to use
    switch (loopnumber % 4)
        {
        case 0: renderer.setShaders(TGX_SHADER_GOURAUD | TGX_SHADER_TEXTURE);
                renderer.drawMesh(&naruto_1, false); 
                break;

        case 1: renderer.drawWireFrameMesh(&naruto_1, true);
                break;

        case 2: renderer.setShaders(TGX_SHADER_FLAT);
                renderer.drawMesh(&naruto_1, false); 
                break;

        case 3: renderer.setShaders(TGX_SHADER_GOURAUD);
                renderer.drawMesh(&naruto_1, false); 
                break;        
        }

    if (prev_loopnumber != loopnumber)
        {
        prev_loopnumber = loopnumber;
        tft.fillRect(0, 300, 240, 20, TFT_BLACK);
        tft.setCursor(5, 305);
        switch (loopnumber % 4)
            {
            case 0: tft.print("Gouraud shading / texturing"); break;
            case 1: tft.print("Wireframe"); break;
            case 2: tft.print("Flat Shading"); break;
            case 3: tft.print("Gouraud shading"); break;
            }
        }

    // upload the framebuffer to the screen (async. via DMA)
    tft.waitDMA();
    tft.pushImageDMA((tft.width() - SLX) / 2, (tft.height() - SLY) / 2, SLX, SLY, fb);  
}
modi12jin commented 1 year ago
In file included from /home/jin/Arduino/libraries/tgx/src/Image.h:3592,
                 from /home/jin/Arduino/libraries/tgx/src/tgx.h:35,
                 from /home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:6:
/home/jin/Arduino/libraries/tgx/src/Image.inl: In member function 'int tgx::Image<color_t>::_scanfill(int, int, color_t, color_t)':
/home/jin/Arduino/libraries/tgx/src/Image.inl:544:13: error: jump to label 'TGX_SCANFILL_SKIP' [-fpermissive]
             TGX_SCANFILL_SKIP:
             ^~~~~~~~~~~~~~~~~
/home/jin/Arduino/libraries/tgx/src/Image.inl:532:31: note:   from here
             if (x >= x1) goto TGX_SCANFILL_SKIP;
                               ^~~~~~~~~~~~~~~~~
/home/jin/Arduino/libraries/tgx/src/Image.inl:533:17: note:   crosses initialization of 'int start'
             int start = x + 1;
                 ^~~~~
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino: At global scope:
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:139:54: error: wrong number of template arguments (5, should be at least 1)
 Renderer3D<RGB565, SLX, SLY, LOADED_SHADERS, uint16_t> renderer;
                                                      ^
In file included from /home/jin/Arduino/libraries/tgx/src/tgx.h:37,
                 from /home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:6:
/home/jin/Arduino/libraries/tgx/src/Renderer3D.h:92:11: note: provided for 'template<class color_t, int LOADED_SHADERS, class ZBUFFER_t> class tgx::Renderer3D'
     class Renderer3D
           ^~~~~~~~~~
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino: In function 'void setup()':
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:177:14: error: request for member 'setImage' in 'renderer', which is of non-class type 'int'
     renderer.setImage(&imfb); // set the image to draw onto (ie the screen framebuffer)
              ^~~~~~~~
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:178:14: error: request for member 'setZbuffer' in 'renderer', which is of non-class type 'int'
     renderer.setZbuffer(zbuf); // set the z buffer for depth testing
              ^~~~~~~~~~
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:179:14: error: request for member 'setPerspective' in 'renderer', which is of non-class type 'int'
     renderer.setPerspective(45, ((float)SLX) / SLY, 1.0f, 100.0f);  // set the perspective projection matrix.
              ^~~~~~~~~~~~~~
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:180:14: error: request for member 'setMaterial' in 'renderer', which is of non-class type 'int'
     renderer.setMaterial(RGBf(0.85f, 0.55f, 0.25f), 0.2f, 0.7f, 0.8f, 64); // bronze color with a lot of specular reflexion.
              ^~~~~~~~~~~
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:181:14: error: request for member 'setOffset' in 'renderer', which is of non-class type 'int'
     renderer.setOffset(0, 0);
              ^~~~~~~~~
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:182:14: error: request for member 'setCulling' in 'renderer', which is of non-class type 'int'
     renderer.setCulling(1);
              ^~~~~~~~~~
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:183:14: error: request for member 'setTextureQuality' in 'renderer', which is of non-class type 'int'
     renderer.setTextureQuality(TGX_SHADER_TEXTURE_NEAREST);
              ^~~~~~~~~~~~~~~~~
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:184:14: error: request for member 'setTextureWrappingMode' in 'renderer', which is of non-class type 'int'
     renderer.setTextureWrappingMode(TGX_SHADER_TEXTURE_WRAP_POW2);
              ^~~~~~~~~~~~~~~~~~~~~~
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino: In function 'void loop()':
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:260:14: error: request for member 'setModelMatrix' in 'renderer', which is of non-class type 'int'
     renderer.setModelMatrix(M);
              ^~~~~~~~~~~~~~
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:264:14: error: request for member 'clearZbuffer' in 'renderer', which is of non-class type 'int'
     renderer.clearZbuffer();                    // clear the z-buffer
              ^~~~~~~~~~~~
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:269:26: error: request for member 'setShaders' in 'renderer', which is of non-class type 'int'
         case 0: renderer.setShaders(TGX_SHADER_GOURAUD | TGX_SHADER_TEXTURE);
                          ^~~~~~~~~~
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:270:26: error: request for member 'drawMesh' in 'renderer', which is of non-class type 'int'
                 renderer.drawMesh(&naruto_1, false);
                          ^~~~~~~~
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:273:26: error: request for member 'drawWireFrameMesh' in 'renderer', which is of non-class type 'int'
         case 1: renderer.drawWireFrameMesh(&naruto_1, true);
                          ^~~~~~~~~~~~~~~~~
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:276:26: error: request for member 'setShaders' in 'renderer', which is of non-class type 'int'
         case 2: renderer.setShaders(TGX_SHADER_FLAT);
                          ^~~~~~~~~~
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:277:26: error: request for member 'drawMesh' in 'renderer', which is of non-class type 'int'
                 renderer.drawMesh(&naruto_1, false);
                          ^~~~~~~~
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:280:26: error: request for member 'setShaders' in 'renderer', which is of non-class type 'int'
         case 3: renderer.setShaders(TGX_SHADER_GOURAUD);
                          ^~~~~~~~~~
/home/jin/桌面/ESP32S3_3D/ESP32S3_3D.ino:281:26: error: request for member 'drawMesh' in 'renderer', which is of non-class type 'int'
                 renderer.drawMesh(&naruto_1, false);
                          ^~~~~~~~

exit status 1

Compilation error: wrong number of template arguments (5, should be at least 1)

Sorry to bother you! how to fix this error @vindar