#import "extra/draw"

Collection of simple 2D primitive rendering functions. Internally the module uses OpenGL core profile for rendering and is supposed to be used for simple games or quick prototyping.

The draw module is not supposed to be an OpenGL replacement, if you want to do some advanced rendering, use OpenGL directly.


  • Rendering of colored 2D rectangles with rotation.
  • Rendering of textured 2D rectangles with rotation.
  • Text rendering.
  • PNG texture loading using png module.
  • TTF font loading using freetype2 module (subpixel and grayscale antialiasing).


  • Module does not handle window creation and system events. Use i.e. glfw to do it.
  • The module is not feature-complete and still under development, all missing/required functionality should be implemented in the future; current implementation is mainly used to demonstrate the language capabilities.

General desing

The draw API is based on switching the global context of rendering primitives (rectangles). In example to draw bunch of colored rectangles we must set the propper shader first:

using draw;
using glm;
set_shader_color(); // Prepare renderer for rendering of colored rectangles.

rect(10.f, 10.f, 100.f, 100.f, v4.{ 1.f, 0.f, 0.f, 1.f });
rect(200.f, 10.f, 100.f, 100.f, v4.{ 0.f, 1.f, 0.f, 1.f });
rect(400.f, 10.f, 100.f, 100.f, v4.{ 0.f, 0.f, 1.f, 1.f });

Internally each call to rect just appends the geometry caches; actual rendering is done when currenty used shader is changed or flush is called explicitly. This approach reduces count of required draw calls a bit.

See the example.


init :: fn (viewport_width: s32, viewport_height: s32) Error

Draw library initialization must be called once before the module is used. The viewport_width and viewport_height defines the viewport size in current opengl context. These values are usually the same as the window size.

The terminate must be called when draw module is not needed anymore.

The current OpenGL context must be aready set, the minimal required OpenGL version is 3.3 "Core Profile". You can use i.e. glfw or similar tool to create window and propper OpenGL context.

The gl_init function is called internally.


Window resizing is not supported right now.

File: draw.bl


terminate :: fn () 

Release all resources used by the module. This should be called when the module is not needed anymore.

The gl_terminate function is called internally.

File: draw.bl


clear_color :: fn (color :: )  #inline

Fill the current frame buffer with color. This is usually called each frame.

File: draw.bl


set_shader_color :: fn ()  #inline

Prepare renderer for rendering colored rectangles. Each rectangle can use different color. This method is supposed to be called before rect or rect_centered.

File: draw.bl


set_shader_texture :: fn (texture: *Texture)  #inline

Prepare renderer for rendering textured rectangles. This method is supposed to be called before rect or rect_centered (all rectangles will use the same texture).

File: draw.bl


set_shader_font :: fn (font: *Font)  #inline

Prepare the renderer for rendering of a text.

File: draw.bl


rect :: fn (position_x: f32, position_y: f32, width: f32, height: f32, color :: )  #inline

Draw a single colored rectangle or texture into the frame buffer.

File: draw.bl


rect_centered :: fn (center_x: f32, center_y: f32, width: f32, height: f32, color :: )  #inline

Draw a single colored rectangle or texture into the frame buffer.

File: draw.bl


rect_centered_rotated :: fn (center_x: f32, center_y: f32, width: f32, height: f32, angle_in_radians: f32, color :: )  #inline

Draw a single colored rectangle or texture with rotation into the frame buffer.

File: draw.bl


text :: fn (position_x: f32, position_y: f32, text: string_view, text_color : glm.v4: , background_color : glm.v4: ) 

Draw text into the frame buffer.

File: draw.bl


flush :: fn ()  #inline

Immediately render all cached stuff into the frame buffer.

File: draw.bl


TextureFormat :: enum u8 {
    RGB = 3;
    RGBA = 4;

Texture channel distribution format.

File: draw.bl


Texture :: struct {
    format: TextureFormat;
    bit_depth: u8;
    width: u32;
    height: u32;
    handle: GLuint;

Texture representation in draw module.


  • format - Texture channel distribution format.
  • bit_depth - Bit depth of each channel.
  • width - Texture image width.
  • height - Texture image height.

File: draw.bl


texture_init :: fn (texture: *Texture, directory: string_view, filename: string_view) Error

Load png texture from the directory/filename.

File: draw.bl


texture_terminate :: fn (texture: *Texture) 

Release texture data.

File: draw.bl


png_load_from_file :: fn (filepath: string_view, out_data: **u8, out_width: *u32, out_height: *u32, out_bit_depth: *u8, out_format: *TextureFormat) Error

Loads png image from filepath into out_data. The out_data shoud be released by free call on caller side.

File: draw.bl


Font :: struct {
    char_table: ;
    atlas: Texture;
    size: f32;
    height: f32;
    mode: FontAntialiasing;

File: draw.bl


GlyphInfo :: struct {
    ax: f32;
    ay: f32;
    bw: f32;
    bh: f32;
    bl: f32;
    bt: f32;
    tx: f32;
    ty: f32;
    bs: f32;

File: draw.bl


FontAntialiasing :: enum {

Fonts in draw module can be loaded in two antialiasing modes.


  • SUBPIXEL - Clear Type mode, rendered glyphs must be perfectly aligned to the display pixels and the background color must be known.

  • ALPHA - Gray scale alpha blending.

File: draw.bl


font_default_char_set :: fn () []u32 #inline

Returns default ASCII character table.

File: draw.bl


font_generate_char_set :: fn (chars: string_view, out_set: *[..]u32) 

Generate new character table based on input chars.

File: draw.bl


font_init_at_size :: fn (font: *Font, directory: string_view, filename: string_view, size: s32, mode :: , char_set :: ) Error

Initialize new font from the 'TTF' file at directory/filename at required size. Custom char_set can be specified in case we need to render some non-ascii unicode characters. Each loaded font must be terminated by font_terminate.

File: draw.bl


font_terminate :: fn (font: *Font) 

Terminate loaded font.

File: draw.bl