Drawing Images#
Once you have an Image, drawing it is a single Graphics call. Images can be
CPU-backed, GPU-backed, or both - YUP uploads and caches a GPU texture as needed.
Basic drawing#
Inside a Component::paint (or any Graphics scope):
g.drawImageAt (image, { x, y }); // natural size, top-left at the point
g.drawImage (image, targetArea); // scaled to fill a rectangle
drawImage stretches the image to the target Rectangle<float>. To preserve
aspect ratio, compute the target rectangle yourself (see the
Rectangle helpers) or use a
Drawable for vector content.
Images on the GPU#
An Image can carry a GPU texture alongside (or instead of) its CPU pixels.
This is what makes repeated drawing allocation-free and fast.
Upload CPU pixels to the GPU#
image.createTextureIfNotPresent (context); // uploads once if not present
auto texture = image.getGpuTexture(); // GpuTexture::Ptr (may be null)
Call invalidateTexture() after mutating the CPU pixels so the next request
re-uploads:
image.setPixelColor (0, 0, Colors::red);
image.invalidateTexture(); // GPU copy is now stale
You can also assign a texture directly with setGpuTexture (tex).
Wrap an existing GPU texture#
Image::fromTexture wraps a GpuTexture::Ptr - for example the result of
GpuCanvas::asTexture() - with no CPU-side
allocation. The image is drawable but has no readable CPU pixels, so
getPixel / getRawData will assert:
Image gpuImage = Image::fromTexture (canvas->asTexture());
g.drawImage (gpuImage, targetArea); // composited on the GPU
Returns an invalid Image if the texture is null or invalid.
Draw a texture without an Image#
When you already hold a GpuTexture::Ptr, skip the Image wrapper entirely and
draw it straight into the 2D pipeline - the fastest path for GPU-generated
content:
g.drawTexture (canvas->asTexture(), targetArea);
See RHI: Buffers & textures
for where GpuTexture values come from.
Rendering into an image (offscreen)#
You can also go the other direction: render 2D content into an Image on the
GPU and read it back on the CPU - useful for thumbnails, export, and tests.
Image target { 512, 512, PixelFormat::RGBA };
{
Graphics g { context, target }; // offscreen frame begins immediately
g.setFillColor (Colors::cornflowerblue);
g.fillAll();
g.setFillColor (Colors::white);
g.fillEllipse (Rectangle<float> { 64.0f, 64.0f, 384.0f, 384.0f });
g.readPixelsToImage(); // fills target's CPU pixel buffer
}
// target now holds both a GPU texture and readable CPU pixels
Related Graphics methods: isOffscreen(), commitOffscreenTarget(),
commitToImage() (sets the rendered GPU texture on the target Image for later
drawImage without a CPU round-trip), and readPixelsToImage().
For full custom GPU pipelines and render passes, step down to the RHI.
See also#
The Graphics class -
drawImage,drawImageAt,drawTexture, and offscreen rendering.