stimmer/DueVGA

Stop rendering

Closed this issue · 16 comments

Sorry for a lot of questions, but
How can I stop rendering frame from video-memory to the screen? Or Is there a small function which send video-mem data to the screen? I believe, that while main program runs this function is called by interrupt.

I don't really understand the question - is there a reason you want to stop the frame rendering? The actual sending of the data to the screen is done by DMA. Maybe it could be stopped by disabling DMA but I don't know what side effects that might have.

Look. I made a frame, after that I call this function and image appears on the screen.
Code:
while() {
VGA.putCPixelFast(x, y, data);
VGA.putCPixelFast(x, y, data);
VGA.cb[y*VGA.cw+x] = data;
//............
VGA.SendData(); //This function
}

I found [void Vga::dmapri] function in your library. Is it a function which I need?

dmapri is just a private function, it won't help with this.

Because the screen display is interrupt driven the video data is sent to the screen automatically. It's difficult to stop the interrupts because they also control the sync signals - if they are stopped the display will turn off.

It sounds like you want to do double-buffering - unfortunately the Due does not have enough memory for this. The colour buffer array cb itself takes over 70k and the Due only has 96k.

if I replace videomem buffer variable to zero in this function? Then I will be able control rendering, won't I?

It shoud be simple, I believe. I need only fast turn on and off the screen...
while() {
VGA.turnOff();
//....
//......
VGA.turnOn();
//........
}

It's the 'fast' bit that's tricky. I can turn off / on the screen quite easily by stopping the sync, but most displays take over a second to turn the screen back on again and that's too slow.

I'm trying out a few other ideas at the moment....

ok, try this:

VGA.mode |= 128;  // blanks the screen

VGA.mode &=~ 128;  // displays the screen

Screen is always black :(

My code:

void render() {
VGA.mode |= 128; //Turn off
VGA.clearcvideomem();
drawTiles(FirstMap.tile1, TexturePack3, xCam[0]/10, yCam[0], xBl[0], yBl[0]);
drawTiles(FirstMap.tile2, TexturePack1, xCam[1], yCam[1], xBl[1], yBl[1]);
drawTiles(FirstMap.tile3, TexturePack2, xCam[2], yCam[2], xBl[2], yBl[2]);
VGA.mode &=~ 128; //Turn on
}

That wouldn't work as the pins are already 'disabled' because they are being used by the SMC - there might be a way to disable the SMC though.

I can't understand why the VGA.mode method isn't working as it works OK for me.

"VGA.mode" works with "delay(16);", but my screen blinks.

Is your code repeatedly calling render(), and therefore the display is being blanked again almost as soon as it has been enabled?

My code repeatedly calling render()->

void render() {
VGA.mode |= 128;
VGA.clearcvideomem(); //0) - Clear VRAM
VGA.fillcvideomem(FirstMap.background); //1) - Fill VRAM
drawTiles(FirstMap.tile1, TexturePack3, xCam[0]/10, yCam[0], xBl[0], yBl[0]); //2) - Draw first layer
drawTiles(FirstMap.tile2, TexturePack1, xCam[1], yCam[1], xBl[1], yBl[1]); //3) - Draw second layer
drawTiles(FirstMap.tile3, TexturePack2, xCam[2], yCam[2], xBl[2], yBl[2]); //4) - Draw third layer
VGA.mode &=~ 128;
}

void loop() {
render();
}

If I change places "VGA.mode |= 128;" with "VGA.mode &=~ 128;" then display shows image. But it is not what I need... I need to blanks the screen until render() function hasn't completed its actions.

JerryI commented

Hi again. Sure, double buffering is a key.
Thanks a lot, @stimmer! Your library did help me a lot in understanding how the whole pipeline of computer graphics works.
I should have been said that ~10 years ago. But it is never late ;)