arsd.pixmappresenter

Pixmap Presenter is a high-level display library for one specific scenario: Blitting fully-rendered frames to the screen.

This is useful for software-rendered applications. Think of old-skool games, emulators etc.

This library builds upon arsd.simpledisplay and arsd.color. It wraps a SimpleWindow and displays the provided frame data. Each frame is automatically centered on, and optionally scaled to, the carrier window. This processing is done with hardware acceleration (OpenGL). Later versions might add a software-mode.

Several scaling modes are supported. Most notably contain that scales pixmaps to the window’s current size while preserving the original aspect ratio. See Scaling for details.

This module is work in progress. API is subject to changes until further notice.

Usage examples

Basic usage

This example displays a blue frame that increases in color intensity, then jumps back to black and the process repeats.

void main() {
	// Internal resolution of the images (“frames”) we will render.
	// From the PixmapPresenter’s perspective,
	// these are the “fully-rendered frames” that it will blit to screen.
	// They may be up- & down-scaled to the window’s actual size
	// (according to the chosen scaling mode) by the presenter.
	const resolution = Size(240, 120);

	// Let’s create a new presenter.
	// (For more fine-grained control there’s also a constructor overload that
	// accepts a [PresenterConfig] instance).
	auto presenter = new PixmapPresenter(
		"Demo",         // window title
		resolution,     // internal resolution
		Size(960, 480), // initial window size (optional; default: =resolution)
	);

	// This variable will be “shared” across events (and frames).
	int blueChannel = 0;

	// Run the eventloop.
	// The callback delegate will get executed every ~16ms (≙ ~60FPS) and schedule a redraw.
	presenter.eventLoop(16, delegate() {
		// Update the pixmap (“framebuffer”) here…

		// Construct an RGB color value.
		auto color = Pixel(0x00, 0x00, blueChannel);
		// For demo purposes, apply it to the whole pixmap.
		presenter.framebuffer.clear(color);

		// Increment the amount of blue to be used by the next frame.
		++blueChannel;
		// reset if greater than 0xFF (=ubyte.max)
		if (blueChannel > 0xFF)
			blueChannel = 0;
	});
}

Minimal example

void main() {
	auto pmp = new PixmapPresenter("My Pixmap App", Size(640, 480));
	pmp.framebuffer.clear(rgb(0xFF, 0x00, 0x99));
	pmp.eventLoop();
}

Advanced example

1 import arsd.pixmappresenter;
2 import arsd.simpledisplay : MouseEvent;
3 
4 int main() {
5 	// Internal resolution of the images (“frames”) we will render.
6 	// For further details, check out the “Basic usage” example.
7 	const resolution = Size(240, 120);
8 
9 	// Configure our presenter in advance.
10 	auto cfg = PresenterConfig();
11 	cfg.window.title = "Demo II";
12 	cfg.window.size = Size(960, 480);
13 	cfg.renderer.resolution = resolution;
14 	cfg.renderer.scaling = Scaling.integer; // integer scaling
15 	                                        // → The frame on-screen will
16 	                                        // always have a size that is a
17 	                                        // multiple of the internal
18 	                                        // resolution.
19 	// The gentle reader might have noticed that the integer scaling will result
20 	// in a padding/border area around the image for most window sizes.
21 	// How about changing its color?
22 	cfg.renderer.background = ColorF(Pixel.white);
23 
24 	// Let’s instantiate a new presenter with the previously created config.
25 	auto presenter = new PixmapPresenter(cfg);
26 
27 	// Start with a green frame, so we can easily observe what’s going on.
28 	presenter.framebuffer.clear(rgb(0x00, 0xDD, 0x00));
29 
30 	int line = 0;
31 	ubyte color = 0;
32 	byte colorDelta = 2;
33 
34 	// Run the eventloop.
35 	// Note how the callback delegate returns a [LoopCtrl] instance.
36 	return presenter.eventLoop(delegate() {
37 		// Determine the start and end index of the current line in the
38 		// framebuffer.
39 		immutable x0 = line * resolution.width;
40 		immutable x1 = x0 + resolution.width;
41 
42 		// Change the color of the current line
43 		presenter.framebuffer.data[x0 .. x1] = rgb(color, color, 0xFF);
44 
45 		// Determine the color to use for the next line
46 		// (to be applied on the next update).
47 		color += colorDelta;
48 		if (color == 0x00)
49 			colorDelta = 2;
50 		else if (color >= 0xFE)
51 			colorDelta = -2;
52 
53 		// Increment the line counter; reset to 0 once we’ve reached the
54 		// end of the framebuffer (=the final/last line).
55 		++line;
56 		if (line == resolution.height)
57 			line = 0;
58 
59 		// Schedule a redraw in ~16ms.
60 		return LoopCtrl.redrawIn(16);
61 	}, delegate(MouseEvent ev) {
62 		// toggle fullscreen mode on double-click
63 		if (ev.doubleClick) {
64 			presenter.toggleFullscreen();
65 		}
66 	});
67 }

Members

Aliases

ColorF
alias ColorF = arsd.color.ColorF
Pixel
alias Pixel = Color
Point
alias Point = arsd.color.Point
Size
alias Size = arsd.color.Size
WindowResizedCallback
alias WindowResizedCallback = void delegate(Size)

Classes

OpenGl1PixmapRenderer
class OpenGl1PixmapRenderer

Legacy OpenGL (1.x) renderer implementation

OpenGl3PixmapRenderer
class OpenGl3PixmapRenderer

OpenGL 3.0 implementation of a PixmapRenderer

PixmapPresenter
class PixmapPresenter

Pixmap Presenter window

Enums

Scaling
enum Scaling

Scaling/Fit Modes

ScalingFilter
enum ScalingFilter

Functions

calculateViewport
Viewport calculateViewport(PresenterConfig config)

Calculates the dimensions and position of the viewport for the provided config.

glViewportPMP
void glViewportPMP(Viewport vp)

Calls glViewport with the data from the provided Viewport.

rgb
Pixel rgb(ubyte r, ubyte g, ubyte b)
rgba
Pixel rgba(ubyte r, ubyte g, ubyte b, ubyte a)
typeCast
T typeCast(S v)

casts value v to type T

Interfaces

PixmapRenderer
interface PixmapRenderer

Renderer abstraction

Structs

LoopCtrl
struct LoopCtrl
Pixmap
struct Pixmap

Pixel data container

PresenterConfig
struct PresenterConfig
Viewport
struct Viewport
WantsOpenGl
struct WantsOpenGl
Suggestion Box / Bug Report