Zero aims to be the solution to this common question...
"How can I simply put a pixel on the screen?"
...by gathering different implementations, depending on the platform, language or technology you want to use, using a common and extremely simple API.
It can be used as a learning tool for children, a testbed to implement classic or new CG routines, experiment, make apps or games, for example.
It is deeply inspired by the old Demoscene library TinyPTC by Gaffer.
C | status | |
---|---|---|
PNG | Writes frames to PNG files | working |
wingdi | Windows GDI | working |
wingl | Windows OpenGL | planned |
linuxx11 | Linux X11 | working |
linuxgl | Linux OpenGL | working |
linuxfb | Linux Framebuffer | working |
Javascript | status | |
---|---|---|
canvas | HTML canvas | working |
WebGL | HTML WebGL | planned |
PRs are very very welcomed. It would be really great to convert this in a bible of how to put pixels in all architectures and languages, and that's something near impossible for a single person (at least for myself).
Corrections and suggestions are very welcomed too. I'm not an expert in this field and I already assume I'm making lots of mistakes.
Anybody trying to add an implementation should try to adhere to the KISS principle. Specially, I'd like to:
-
Keep the external dependencies to a minimum, or none. The ideal usage of the library should be a single include.
-
Do not make it too generic, full of options and supporting many pixel formats. We are only targeting typical RGB(A) and Indexed color modes, 8 bits per component.
zero_open (target, width, height, depth, scale)
zero_update (framebuffer, palette)
zero_events(handler)
zero_close()
Opens or initializes a window with specific properties.
Depending on the implementation used, target
has different meanings.
For example, in Javascript it means a DOM selector;
in windows GDI it means the title of the window to create;
in png means a file name, etc.
Dimensions of the image, in pixels.
- 1 for indexed images (that need a palette)
- 3 for RGB images
- 4 for RGBA (not supported in all implementations)
Multiplier of width
and height
, which affects the dimensions of the output (window, canvas, image file, ...).
So if you set scale
to 2, the window/canvas/image size will be the double of your frame size.
Sends the frame data (and optional color palette) to the window.
Pointer to the image buffer. No checks are done about the format of the buffer content.
If depth
is set to 1, a palette (array of R,G,B items) must be passed.
Otherwise, this value is ignored.
Closes the window, freeing resources.
Registers a function callback that will be called whenever an event occur. The handler
must be a function that takes 3 parameters:
type
a number with the event type code. See next table for a reference of the constant codes you can use.param1
andparam2
are two numeric parameters which meaning depends on the even type:
type code | param1 meaning | param2 meaning |
---|---|---|
RESIZE | new window width | height |
KEY_DOWN | key code | modifiers bitfield |
KEY_UP | key code | modifiers bitfield |
MOUSE_DOWN | button | modifiers bitfield |
MOUSE_UP | button | modifiers bitfield |
MOUSE_MOVE | x | y |
MOUSE_ENTER | none | none |
MOUSE_LEAVE | none | none |
They are mostly in pseudocode because it could be written in any of the languages supported by the library, just adapting it to the idiosyncrasies of the language.
This example produces an animated random noise. In pseudocode:
framebuffer = array of 320 x 200 x 4 bytes
zero_open("Noise app", 320, 200, 4, 1)
while True do:
for i in framebuffer.length do:
framebuffer[i] = random(0, 255)
zero_update(framebuffer, NIL)
In C:
#include "zero.h"
void main(){
unsigned char framebuffer[320 * 200 * 4];
zero_open("Noise app", 320, 200, 4, 1);
while(1){
for (int i = 0; i < 320 * 200 * 4; i++){
framebuffer[i] = rand() % 255;
}
zero_update(framebuffer, NULL);
}
}
This is a basic pseudocode example of a whole functional drawing program in a 500x500 window/canvas for drawing with mouse, and quits with any key:
run = true
drawing = false
framebuffer = array of 500 x 500 x 4 bytes
function PROCESS_EVENTS(event_type, param1, param2)
case of event_type is:
KEY_DOWN: run = false
MOUSE_DOWN: drawing = true
MOUSE_UP: drawing = false
MOUSE_MOVE: if drawing is true then:
idx = (param2 * 500 + param1) * 4 // get position in framebuffer
framebuffer[idx] = 255 // paint pixel with red
function MAIN
zero_open("Drawing program", 500, 500, 4, 1)
zero_events(PROCESS_EVENTS)
while run is true do:
zero_update(framebuffer, NIL)
zero_close()
(you can check out the Linux OpenGL implementation)