VGA output - some examples

All about the VGA for the ESP32-S3
User avatar
cicciocb
Site Admin
Posts: 2060
Joined: Mon Feb 03, 2020 1:15 pm
Location: Toulouse
Has thanked: 439 times
Been thanked: 1360 times
Contact:

VGA output - some examples

Post by cicciocb »

Hi,
I will provide you with some examples of how to use VGA functionalities, including how to manage page buffering for transparent text or moving objects. However, before proceeding, it's essential to update the firmware. This update is necessary to run the examples I'll be demonstrating.

You can perform an over-the-air (OTA) update of the firmware using the following link:
[Local Link Removed for Guests]
To update, copy and paste this link into the configuration page, then click SAVE and then click on OTA update.

The new firmware brings several enhancements, notably the ability to import 16-bit BMP images. These images are about 30% smaller compared to 24-bit images and come in either 565 or 1555 formats, supporting a transparent background.
This format proves highly advantageous for importing images on top of others, creating a delightful superposition effect.
I have also added the capability to save images to disk using the command "VGA.SAVE "filename.bmp"," but be mindful that each image occupies approximately 600KB at a resolution of 640x480 so you risk to saturate the internal flash disk rapidly.
For efficient storage and retrieval, I strongly recommend using an SD card, which is significantly faster.

To proceed, it's necessary to provide some preliminary theoretical explanations. First and foremost, the VGA output represents a portion of dedicated memory for the projected image. This memory can be modified to alter the image displayed on the screen. The memory's structure is such that each pixel occupies 8 bits, equivalent to 1 byte.

The system employs a color format known as "332". In this notation, 3 bits are allocated to the red channel, another 3 bits to the green channel, and 2 bits to the blue channel. Thanks to this configuration, up to 256 distinct colors can be represented.

The choice of this color format is a compromise between efficient use of memory, chip resources and the number of GPIOs used..

It's important to note that the ESP32 has a limited amount of memory available. For instance, to support a resolution of 640x480 pixels, approximately 300KB of memory is required. This constraint presents a significant challenge, in particular when the memory is already used for the other functionalities (Wifi, disk, ...).

Fortunately, the ESP32-S3 variant offers the capability to utilize DMA mode on external PSRAM memory. This choice opens doors to a potential additional 8 megabytes of memory. Nonetheless, it's crucial to recognize that access to this external memory is slower than internal memory, affecting the overall system performance.

Despite this limitation, the expanded memory provided by the external PSRAM—amounting to 8 megabytes—enables the creation of different memory "pages,". This approach facilitates writing to one page while displaying another, allowing for smooth and visually smooth transitions for users.

Additionally, images can be imported in JPEG and BMP formats. In the case of BMP format, the feature to import images with transparent backgrounds has been added. This feature allows for seamless image overlaying without any visible edges and paving the way for image usage as objects (sprites) that can be animated fluidly.

Traditionally, to create the display, various parts that are intended to be shown are drawn on the screen. Consequently, a user observing the screen will see these objects draw one after another. This effect can be unpleasant, particularly when updating text of significant size, such as a long text. In such cases, users cannot help but notice a bothersome "flash" as the complete update unavoidably takes time.

To surpass this limitation, a straightforward mechanism can be implemented using three distinct pages.namely page 0, page 1, and page 2). Initially, a background image is loaded into Page N°2, which serves only as a reference. Subsequently, this image is copied to Page 0, and all parts to be overlaid onto the image are drawn. At this point, the composed image is displayed on the screen. From here onwards, copying Page N°2 into Page 1 can be performed, with all overlaid parts being redrawn while the user continues to observe Page 0. As soon as the content of Page 1 is completed, the content of Page 1 can be shown to the user. Then, the process repeats by copying the content of Page N°2 into Page 0, and so on.

This approach circumvents the intermediate updates that caused user disturbance, offering a continuous and seamless visual experience.

This first example try to show this process :

Code: [Local Link Removed for Guests]

''demo transparent text
vga.pinout 4,5,6, 7,15,16, 17, 18, 8,3
vga.delete
tft.loadfont "/fonts/FreeSansBold20pt7b.bin", 10
tft.loadfont "/fonts/FreeMonoBold24pt7b.bin", 11
vga.init 2, 3 '640x480 3 buffers
vga.WritePage 0 ' active
vga.fill black
vga.text.align ALIGN_MID_MID
vga.text.draw "Transparent Text", 320, 240, 11
vga.showpage 0 'shows the page 0
vga.show 'refresh the cache memory (and flush the cache memory)
pause 3000

vga.writepage 2 'select to write into page 2
vga.image "/img/aircraft.jpg"
act = 0
while 1
      vga.writepage act 'active the writing page
      vga.copy 2, act  ' copy the reference image into the active page
      vga.text.draw "Random " + str$(rnd(10000)), 100, 100
      vga.showpage act 'shows the final result (and flush the cache memory)
      pause 100
      act = 1 - act 'invert the page
wend
Other examples will follow ...
User avatar
Electroguard
Posts: 860
Joined: Mon Feb 08, 2021 6:22 pm
Has thanked: 276 times
Been thanked: 323 times

Re: VGA output - some examples

Post by Electroguard »

Thank you for such a very good and clear explanation.
User avatar
cicciocb
Site Admin
Posts: 2060
Joined: Mon Feb 03, 2020 1:15 pm
Location: Toulouse
Has thanked: 439 times
Been thanked: 1360 times
Contact:

Re: VGA output - some examples

Post by cicciocb »

Let's talk about sprites.
Sprites are images that can be freely positioned and moved on the screen.
They can be composed of different images (frames) that depict objects in various states, like an on/off lamp or different poses for a character in a video game.

Sprites can be loaded from BMP files, with transparency or opacity, and can often be organized into spritesheets, simplifying management. One notable advantage of spritesheets is that they allow multiple images for different sprites to be loaded onto a single sheet, streamlining the process.

The command to load a spritesheet is as VGA.SPRITESHEET image$ where image$ represents the file path of the BMP image that you want to load.
By calling this function, the specified BMP image is read and its data is stored in memory, allowing for easier access and manipulation.
One notable advantage of this function is that it enables you to extract specific portions or sections of the loaded image, which can then be copied into the video pages.

This can be done with the the command VGA.SPRITE

The function "VGA.SPRITE x, y, width, height, x_in_bmp, y_in_bmp" serves the purpose of copying a specific portion of a loaded SPRITESHEET image onto the active graphical display page. This function is a fundamental tool in graphical programming, enabling the rendering and manipulation of graphical elements on the screen.

Here's an explanation of the parameters and their meanings:

- x and y: These parameters define the target coordinates on the active graphical display page where the copied portion of the SPRITESHEET image will be placed. "x" represents the horizontal position, and "y" represents the vertical position.

- width and height: These parameters specify the dimensions of the portion of the SPRITESHEET image that will be copied. The "width" determines the horizontal size, and the "height" determines the vertical size of the copied portion.

- x_in_bmp and y_in_bmp: These parameters determine the starting position within the SPRITESHEET image from which the copying will occur. "x_in_bmp" represents the horizontal offset, and "y_in_bmp" represents the vertical offset, indicating the initial point within the SPRITESHEET image.

By providing these parameters, the function copies the specified portion of the SPRITESHEET image onto the active graphical display page. This enables programmers to create dynamic visual effects, move graphical elements around the screen, and construct interactive interfaces within their applications.

The following example, rely on this spreadsheet image with transparent background

In this spreadsheet there are 30 icons separated of exactly 128 pixels
icons128_1555.bmp
This example draws 4 lines of 4 icons that are refreshed from a total of 30 present in the spritesheet; this example use only one page (the 0)

Code: [Local Link Removed for Guests]

'demo sprites 1
vga.pinout 4,5,6, 7,15,16, 17, 18, 8,3
vga.delete
tft.loadfont "/fonts/FreeSansBold20pt7b.bin", 10
tft.loadfont "/fonts/FreeMonoBold24pt7b.bin", 11
vga.init 2, 1 '640x480 1 buffer
vga.WritePage 0 ' active
vga.fill black
vga.text.align ALIGN_MID_MID
vga.text.draw "Sprites demo 1", 320, 240, 11
vga.show
pause 3000
vga.image "/img/aircraft.jpg", 0, 0
vga.show
VGA.SPRITESHEET "/sprites/icons128_1555.bmp"
i = 0
while 1
  for y = 0 to 3
    for x = 0 to 3
      incr i
      i = i mod 30 'there are 30 icons in the spritesheet
      'each icon is 128x128 and the distance between them is 128
      vga.sprite 30+x*150, y * 118, 128, 128, 128 * i, 0 
      vga.show
      pause 100
    next x
  next y
wend


The result on the screen :
image.png
You do not have the required permissions to view the files attached to this post.
User avatar
cicciocb
Site Admin
Posts: 2060
Joined: Mon Feb 03, 2020 1:15 pm
Location: Toulouse
Has thanked: 439 times
Been thanked: 1360 times
Contact:

Re: VGA output - some examples

Post by cicciocb »

By utilizing different display pages, it becomes possible to employ additional and more powerful sprite-related functions that allow for animation and free movement, all while maintaining a transparent background. The ability to switch between various display pages while managing sprite elements opens up opportunities for creating dynamic animations. Using functions tailored for sprite manipulation, these elements can be smoothly transitioned between different frames, facilitating captivating movement and interaction.

here are several functions available for managing sprites in VGA graphics programming:

VGA.SETSPRITE id, width, height, x_in_bmp, y_in_bmp [, nextframe_delta_x, nextframe_delta_y]:

This function plays a pivotal role in managing animated sprites.
It serves to define the properties of an animated sprite that can be manipulated and displayed on the screen.
Here's an explanation of the parameters:

- 'id' (from 0 to 255): The 'id' parameter serves as a unique identifier for the sprite. This identifier is essential for managing and referencing the sprite throughout your code. It falls within the range of 0 to 255, providing a broad spectrum of possible sprite identifiers.

Width and height: These parameters determine the dimensions of the sprite. The "width" and "height" values specify the extent of the sprite's graphical representation, influencing its visual size on the screen.

- x_in_bmp and y_in_bmp: These parameters establish the position of the sprite within a loaded spritesheet image. The "x_in_bmp" parameter represents the horizontal offset, indicating where the sprite's graphical content starts within the spritesheet. Similarly, the "y_in_bmp" parameter signifies the vertical offset, defining the starting point of the sprite's imagery.

- nextframe_delta_x, nextframe_delta_y (optional): In scenarios where a sprite consists of multiple frames for animation, these parameters come into play. They dictate the spatial relationship between the current frame and the next frame in terms of positioning. "nextframe_delta_x" signifies the horizontal displacement, while "nextframe_delta_y" signifies the vertical displacement.

By utilizing these parameters, you can accurately position the subsequent frame of an animated sprite. This is particularly useful when creating smooth and seamless animations that transition between different frames.


VGA.DRAWSPRITE id, x, y, [frame=0]
This function serves to display an animated sprite on the active graphical page.
This function is crucial for rendering sprites and bringing them to life within visual applications.

Here's a breakdown of the parameters and their significance:

- id: This parameter refers to the identifier of the sprite you want to draw. The 'id' corresponds to the sprite you've defined using the "VGA.SETSPRITE" function. It ensures that the correct sprite is retrieved from memory and displayed.

- x and y: These parameters denote the precise coordinates on the active graphical page where the sprite will be drawn. "x" represents the horizontal position, while "y" signifies the vertical position. By specifying these coordinates, you control where the sprite appears on the screen.

- frame (optional, default=0): If the sprite is composed of multiple frames for animation, this parameter determines which frame will be displayed. It indicates the index of the desired frame within the animation sequence. If not specified, the default frame is typically frame 0.


VGA.REMOVESPRITE id, src, dest
serves a crucial purpose by facilitating the removal of a sprite's visual representation from one image and copying the corresponding image from another. This function enables efficient management and manipulation of sprites within graphical applications.

Here's a breakdown of the parameters and their significance:

- id: This parameter specifies the identifier of the sprite that you want to remove. The 'id' corresponds to the unique identifier assigned to the sprite when it was defined using the "VGA.SETSPRITE" function. This ensures that the correct sprite is targeted for removal.

- src: This parameter represents the source image page from which the corresponding image segment will be copied. The "src" designation ensures that the correct portion of the image, associated with the sprite, is selected for removal.

- dest: This parameter indicates the destination image page to which the corresponding image segment will be copied. By copying the image from the "src" to the "dest," the function effectively eliminates the sprite's presence on the designated page.


VGA.HIDESPRITE id, visibility
This function offers a mechanism to control the visibility of a sprite's visual representation on the screen. This function is instrumental for managing the appearance and disappearance of sprites within graphical applications.

Here's a detailed breakdown of the function and its parameters:

- id: This parameter specifies the unique identifier of the sprite that you intend to control. The 'id' corresponds to the identifier assigned to the sprite during its creation using the "VGA.SETSPRITE" function.

- visibility: The second parameter, "visibility," determines whether the sprite's visual representation is hidden or shown. It serves as a binary switch that takes two values: 0 and 1. A value of 0 signifies that the sprite is hidden, while a value of 1 indicates that the sprite is visible.

Importantly, the effect of "VGA.HIDESPRITE id, visibility" is contextually tied to subsequent calls to the "VGA.DRAWSPRITE" function. When "visibility" is set to 0 (hide), the corresponding sprite will not be rendered when "VGA.DRAWSPRITE id" is called. Conversely, setting "visibility" to 1 (show) will allow the sprite to be displayed upon invoking "VGA.DRAWSPRITE id."

It is essential to note that executing "VGA.HIDESPRITE id, visibility" on its own may not cause an immediate change on the screen. The true impact becomes evident during subsequent calls to "VGA.DRAWSPRITE id," where the sprite's visibility toggles according to the specified "visibility" value.

examples will follow .....
User avatar
Fernando Perez
Posts: 378
Joined: Mon Feb 15, 2021 10:09 pm
Location: Santander (Spain)
Has thanked: 195 times
Been thanked: 267 times

Re: VGA output - some examples

Post by Fernando Perez »

updated to version Annex32-S3 CAN DMT VGA 1.51.1 qio opi LFS. No problem.
Executed the first two examples without problems, with the exception that I had to enter "pause 3000" instructions before the vga.show to see the texts "Transparent Text" and ""Sprites demo 1". If not, skip directly to while loops.
I don't know if it's because of my monitor, but it always happens to me. From the time I launch a program until the image appears, a few seconds pass with a black screen. I've gotten used to inserting those pauses at the beginning of my programs.

On the other hand, can you explain to me the use of the VGA.TEXT.PADDING align statement that appears in the help?
User avatar
Electroguard
Posts: 860
Joined: Mon Feb 08, 2021 6:22 pm
Has thanked: 276 times
Been thanked: 323 times

Re: VGA output - some examples

Post by Electroguard »

The latest update available from the manual page is only 1.50.82


Edit: Not on same firmware as you Fernando, but example1 works fine for me, the only change needed was to remove Francescos vga.pinouts
So if your vga.pinouts are different to his, it could explain why the "Invisible Text" is actually invisible to you, until it becomes visible floating over the image.


Edit2: BTW, thanks, my countdown progress bar works great.

countdown.jpg
You do not have the required permissions to view the files attached to this post.
User avatar
cicciocb
Site Admin
Posts: 2060
Joined: Mon Feb 03, 2020 1:15 pm
Location: Toulouse
Has thanked: 439 times
Been thanked: 1360 times
Contact:

Re: VGA output - some examples

Post by cicciocb »

[Local Link Removed for Guests] wrote: [Local Link Removed for Guests]Sat Aug 19, 2023 6:33 pm updated to version Annex32-S3 CAN DMT VGA 1.51.1 qio opi LFS. No problem.
Executed the first two examples without problems, with the exception that I had to enter "pause 3000" instructions before the vga.show to see the texts "Transparent Text" and ""Sprites demo 1". If not, skip directly to while loops.
I don't know if it's because of my monitor, but it always happens to me. From the time I launch a program until the image appears, a few seconds pass with a black screen. I've gotten used to inserting those pauses at the beginning of my programs.

On the other hand, can you explain to me the use of the VGA.TEXT.PADDING align statement that appears in the help?
That time is normal, the monitor takes few seconds to synchronise the signal. I forgot to put the pause. For the padding, you can try yourself. Put the value at 500 and then set the colour for the text and the background and then draw the text in the middle of the screen
User avatar
Electroguard
Posts: 860
Joined: Mon Feb 08, 2021 6:22 pm
Has thanked: 276 times
Been thanked: 323 times

Re: VGA output - some examples

Post by Electroguard »

Had a bit of a scare, but managed to upgrade ok after reading the instructions properly.
Have taken a zip backup, so now want to delete all the existing files, and then upload the examples zip.
Then eventually will want to delete all the examples, then restore from my backup zip.
So what is the best way to clear multiple files from the device without having to select each one individually to delete it ?
I suppose an Annex script could do it if necessary, but is there a better way ?
EasyRider
Posts: 28
Joined: Sat Jun 05, 2021 1:27 am
Has thanked: 7 times
Been thanked: 2 times

Re: VGA output - some examples

Post by EasyRider »

I have not followed every detail of the new VGA support, so I'm not sure if my next question has been covered before.

I guess it depends on different users and their applications on how they see the benefits of large VGA display.
To me, VGA as a display only, has limited use without interactive input support, keyboard and some sort of mouse support.
I am not technically competent to comment if USB or PS2 type keyboard and mouse could be supported by ESP32.
This could potentially be a true stand alone Annex basic computer.
Or true stand alone interactive user terminal.
User avatar
cicciocb
Site Admin
Posts: 2060
Joined: Mon Feb 03, 2020 1:15 pm
Location: Toulouse
Has thanked: 439 times
Been thanked: 1360 times
Contact:

Re: VGA output - some examples

Post by cicciocb »

[Local Link Removed for Guests] wrote: [Local Link Removed for Guests]Sat Aug 19, 2023 9:45 pm Had a bit of a scare, but managed to upgrade ok after reading the instructions properly.
Have taken a zip backup, so now want to delete all the existing files, and then upload the examples zip.
Then eventually will want to delete all the examples, then restore from my backup zip.
So what is the best way to clear multiple files from the device without having to select each one individually to delete it ?
I suppose an Annex script could do it if necessary, but is there a better way ?
You can use shift or control to select multiple files
Post Reply