Low-Level Graphics Library

LLGR, a Low-Level Graphics Library, is designed to be an output-only API for rendering with WebGL or OpenGL, and to support picking, selection highlights, and translucency. Shadows are also desirable but will be added later. Also support for various optimizations, e.g., instancing and level-of-detail, is provided. Except for the rendering code, it is a thin-layer over the underlying graphics library, and exposes shader programs, program uniforms, vertex attributes, and vertex attribute buffers. Additional OpenGL concepts, eg., uniform buffers, may be exposed later.

Typical Usage

To display the contents of those buffers, a flat scene graph of objects is used. Objects contain references to a particular shader program, a transformation matrix, and the attributes needed to draw the object. All attributes refer to buffers, but should refer to a singleton buffer when the value of the attribute is constant within the object. Objects that only differ only by their singleton attributes can be automatically instanced for faster drawing.

The default rendering code expects various uniforms and attributes to be present, and they are documented below.

Typical Usage

A reasonable scenario would be to:

  1. Instantiate the shader programs with create_program()
  2. Instantiate the vertex coordinate (and vertex index) buffers with create_buffer()
  3. Instantiate other vertex attributes, such as color, as buffers with create_buffer() or singletons with create_singleton()
  4. For each object create a std::vector describing its attributes with AttributeInfo and instantiate it with create_object()
  5. Set shader program uniforms with set_uniform() and set_uniform_matrix()
  6. render()

C++ API

All data types are limited to 32-bit quantities or less. In the future, we might allow 64-bit quantities for desktop OpenGL.

Types

type Bytes

For C++, Bytes is just ‘void *’. It is a separate type, so a Python wrapper generator can easily find byte arguments.

type Id

API client provided identifier. Negative values are reserved for internal use and should not appear in client code. Zero has special meaning depending on where it is used, so all user-generated content should have positive identifiers.

type BufferTarget

Buffer array types:

ARRAY
for array of data,
ELEMENT_ARRAY
for array of indices
type DataType

Buffer data types:

Byte
8-bit integer
UByte
8-bit unsigned integer
Short
16-bit integer
UShort
16-bit unsigned integer
Int
32-bit integer
UInt
32-bit unsigned integer
Float
32-bit IEEE floating point
type ShaderType

Shader variable types:

IVec1, IVec2, IVec3, IVec4
Integer vectors of 1-4 elements
UVec1, UVec2, UVec3, UVec4
Unsigned integer vectors of 1-4 elements Not implemented. Reserved for forward compatibility with a WebGL that is based on OpenGL ES 3.0.
FVec1, FVec2, FVec3, FVec4
Floating point vectors of 1-4 elements
Mat2x2, Mat3x3, Mat4x4
Square matrices
Mat2x3, Mat3x2, Mat2x4, Mat4x2, Mat3x4, Mat4x3
Rectangular matrices. Not implemented. Reserved for forward compatibility with a WebGL that is based on OpenGL ES 3.0.
type PrimitiveType

Drawing primitive types:

Points, Lines, Line_loop, Line_strip, Triangles, Triangle_strip, Triangle_fan
Same primitives that WebGL provides.
type Objects

A std::vector of object identifiers

Shader Programs

Shaders problems need to be compatible with the rendering code. Since the rendering code may change, or there might be more than one way to render objects, those requirements are documented below with the rendering code.

Managing shader programs is expected to be done by a library layered on top of llgr.

void create_program(Id program_id, const char* vertex_shader, const char* fragment_shader)
Parameters:
  • program_id – user-provided identifier to reference in other functions (zero is reserved, see set_uniform())
  • vertex_shader – vertex shader text
  • fragment_shader – fragment shader text

To reuse a program_id, just recreate it.

void delete_program(Id program_id)
Parameters program_id:
 existing program identifier

Remove resources associated with program identifier.

void clear_programs()

Remove all existing programs.

void set_uniform(Id program_id, const char* name, DataType type, uint32_t data_length, Bytes data)
Parameters:
  • program_id – existing program identifier (program id zero means to set uniform in all existing programs)
  • name – uniform name
  • type – data type
  • data_length – size of the data in bytes
  • data – the actual data
template <typename T> void set_uniform(Id program_id, const char *name, const T *data)

Template versions for all of the shader variable types, where the type and size are inferred from the data argument’s type.

Buffers

Buffers contain coordinate and attribute data.

void create_buffer(Id data_id, BufferTarget target, uint32_t data_length, Bytes data)
Parameters:
  • data_id – provided buffer data id
  • target – type of buffer
  • data_length – size of the data in bytes
  • data – the actual data

Create buffer data.

void create_singleton(Id data_id, uint32_t data_length, Bytes data)
Parameters:
  • data_id – provided buffer data id
  • data_length – size of the data in bytes
  • data – the actual data
void update_buffer(Id data_id, uint32_t offset, uint32_t stride, uint32_t data_length, Bytes data)

TODO: future function to update column of existing buffer

void delete_buffer(Id buffer_id)
Parameters buffer_id:
 existing buffer identifier

Remove resources associated with buffer identifier.

void clear_buffers()

Remove all existing buffers.

Matrices

A matrix_id of zero is always the identity matrix. Matrices are a separate kind of data

void create_matrix(Id matrix_id, const float matrix[4][4], bool renormalize=false)
Parameters:
  • data_id – provided matrix id
  • matrix – the matrix
  • renormalize – true if shear or scale matrix (TODO: not implemented)
void delete_matrix(Id matrix_id)
Parameters matrix_id:
 existing matrix identifier

Remove resources associated with matrix identifier.

void clear_matrices()

Remove all existing matrices.

Objects

type AttributeInfo
std::string name

name of attribute

Id data_id

Data to use for attribute (singleton or buffer Id)

uint32_t offset

Byte offset into data for first attribute value

uint32_t stride

Byte stride through data to next attribute value

uint32_t count

Number of data type (1-4)

DataType type

Type of attribute

bool normalized

For integer types, true if attribute values should be normalized to 0.0-1.0

type AttributeInfos

std::vector<AttributeInfo>

void set_attribute_alias(const std::string& name, const std::string& value)

Create an alias for a vertex attribute name. This can be used to make common object creation code work with different shader programs, or hide differences between different versions of OpenGL. To remove an alias, either set it to itself or the empty string.

For example, the built-in primitives use “position” and “normal”, but for OpenGL 2, you should minimally:

llgr.set_attribute_alias("position", "gl_Vertex")

Since in OpenGL 2, glVertex has to be called instead of using a vertex attribute, but the normal could be be given either as a vertex attribute or with glNormal depending on the shader program.

void create_object(Id obj_id, Id program_id, Id matrix_id, const AttributeInfos& ais, PrimitiveType pt, uint32_t first, uint32_t count, Id index_data_id=0, DataType index_data_type=Byte)
Parameters:
  • obj_id – provided object identifier
  • program_id – provided program identifier
  • matrix_id – provided matrix identifier
  • ais – vector of attribute information
  • pt – primitive type
  • first – staring index into buffer arrays, or, for indexed drawing, the index of the starting drawing index
  • count – number of indices to use
  • index_data_id – provided data identifier for index data, zero if none
  • index_data_type – data type of indexes (must be unsigned byte/short/int)
void delete_object(Gluint obj_id)
Parameters obj_id:
 existing object identifier

Remove resources associated with object identifier.

void clear_objects()

Remove all existing objects.

Object annotations

void hide_objects(const Objects& objs)

Don’t draw given objects.

void show_objects(const Objects& objs)

Draw given objects (default).

void transparent(const Objects& objs)

Object is transparent, so draw it with extra code.

void opaque(const Objects& objs)

Object is opaque, so draw it normally (default).

void selection_add(const Objects& objs)

Add objects to selection set.

void selection_remove(const Objects& objs)

Remove objects from selection set.

void selection_clear()

Clear selection set.

LOD primitives

Level-of-detail primitives. TODO: implement LOD

void add_sphere(Id obj_id, float radius, Id program_id, Id matrix_id, const AttributeInfos& ais)

Add sphere.

Parameters:
  • obj_id – provided object identifier
  • radius – the sphere’s radius
  • program_id – provided program identifier
  • matrix_id – provided matrix identifier
  • ais – vector of attribute information

The default vertex attribute names are “position” and “normal”. See set_attribute_alias() to change them.

void add_cylinder(Id obj_id, float radius, float length, Id program_id, Id matrix_id, const AttributeInfos& ais)

Add cylinder.

Parameters:
  • obj_id – provided object identifier
  • radius – the cylinder’s radius
  • length – the cylinder’s length
  • program_id – provided program identifier
  • matrix_id – provided matrix identifier
  • ais – vector of attribute information

The default vertex attribute names are “position” and “normal”. See set_attribute_alias() to change them.

void clear_primitives()

Remove all existing primitive objects and associated internal data.

Miscellaneous

void clear_all()

Remove data for all existing identifiers.

void set_clear_color(float red, float green, float blue, float alpha)

Set background clear color.

void render()

Render objects. Will invoke optimizer if some types of data have changed.

Table Of Contents

This Page