PicoVGA icon indicating copy to clipboard operation
PicoVGA copied to clipboard

Trying to scale a simple image

Open remy opened this issue 2 years ago • 1 comments

I apologise in advance, my c is very rusty and this seems like a fairly straight forward task but I've been at it for hours and somehow I'm getting nothing coming out of the vga port anymore (though I should make clear compiling and running the demos included all worked).

I have an image that's 192x144 and I want to scale it to the VESA resolution, but I can't seem to get there. I've converted the source bmp using the tool you included and have:

// format: 8-bit pixel graphics
// image width: 192 pixels
// image height: 144 lines
// image pitch: 192 bytes
const u8 myImage[27648] __attribute__ ((aligned(4))) = {
// ...

I call this method to prepare the transform:

void SetMat()
{
  // IMGW = 192, IMGH=144, WIDTH=1152, HEIGHT=864
  Mat.PrepDrawImg(IMGW, IMGH, 0, 0, WIDTH, HEIGHT, 0, 0, 0, 0, 0);
  Mat.ExportInt(MatInt);
}

Then my main is - the setup videomode bit being where I think it's going wrong but I copied from the other examples in the hope I could get it to work.

int main()
{
  imageCanvas.img = (u8 *)myImage;
  imageCanvas.w = IMGW;
  imageCanvas.h = IMGH;
  imageCanvas.wb = IMGW;
  imageCanvas.format = CANVAS_8;

  Canvas.w = WIDTH;
  Canvas.h = HEIGHT;
  Canvas.wb = WIDTH;
  Canvas.format = CANVAS_8;

  SetMat();

  // setup videomode
  VgaCfgDef(&Cfg);        // get default configuration
  Cfg.video = &VideoVESA; // video timings
  Cfg.width = WIDTH;      // screen width
  Cfg.height = HEIGHT;    // screen height
  Cfg.wfull = WIDTH;      // full width
  Cfg.dbly = False;       // double Y
  VgaCfg(&Cfg, &Vmode); // calculate videomode setup

  // // initialize base layer 0 to simple color (will be not visible)
  // ScreenClear(pScreen);
  // sStrip *t = ScreenAddStrip(pScreen, Vmode.height);
  // sSegm *g = ScreenAddSegm(t, Vmode.width);
  // ScreenSegmColor(g, 0xff00ff00, 0x00ff00ff);
  // initialize system clock
  if (clock_get_hz(clk_sys) != Vmode.freq * 1000)
  set_sys_clock_pll(Vmode.vco * 1000, Vmode.pd1, Vmode.pd2);

  // initialize videomode
  VgaInitReq(&Vmode);

  DrawImgMat(&Canvas, &imageCanvas, 0, 0, WIDTH, HEIGHT, &Mat, DRAWIMG_CLAMP, 0);

  while (true)
  {
    // maybe call again later
    // DrawImgMat(&Canvas, &imageCanvas, 0, 0, WIDTH, HEIGHT, &Mat, DRAWIMG_CLAMP, 0);
  }
}

This isn't putting anything out on the the video port once it's running on the pico, and I'm hoping that … someone(?) might be able to set me straight, again, on what I'd imagine is fairly straight forward.

Thanks in advance.

remy avatar Mar 02 '22 00:03 remy

At first, you forgot to create a frame buffer to canvas.img. It should be WIDTH x HEIGHT, 8 bits per pixel. But don't create it - because you don't have enough RAM for such a buffer. An 1152 x 864 / 8-bit frame buffer would require 1 MB of RAM, but the processor only has 256 KB of RAM. With video mode at that resolution you have to use other image formats like 2-color image, tiles, etc.

Panda381 avatar Mar 02 '22 01:03 Panda381