headless-gl

repository·master·Indexed 23 days ago

https://github.com/stackgl/headless-gl

A Node.js package (gl) that provides a WebGL context without requiring a browser or windowing environment. Designed to conform to the WebGL 1.0.3 specification, it is used for server-side rendering and headless testing. It includes support for WebGL 2 via context attributes and provides custom extensions like STACKGL_resize_drawingbuffer and STACKGL_destroy_context for resource management.

Tokens
4.8K
Snippets
11
Records
36
Agent score
84%

What's inside headless-gl

  1. Regenerating gl.h

    master

    If you need to regenerate the gl.h header used by ANGLE GLES 1.0, follow these steps to modify the Khronos OpenGL-Registry generation script to include function pointer types and function prototype guards.

    Prerequisites

    • Python 3 (Python 2 is not supported).
    • The lxml addon for Python. Install it via:
      pip install lxml
    • A clone of the KhronosGroup/OpenGL-Registry repository.

    Steps

    1. Modify the generation script: Open OpenGL-Registry/xml/genheaders.py and locate the section # GLES 1.x API + mandatory extensions - GLES/gl.h (no function pointers). Apply the following changes:
      • Change prefixText = prefixStrings + gles1PlatformStrings + genDateCommentString, to prefixText = prefixStrings + gles1PlatformStrings + apiEntryPrefixStrings + genDateCommentString,
      • Change genFuncPointers = False, to genFuncPointers = True,
      • Change protectProto = False, to protectProto = 'nonzero',
      • Change protectProtoStr = 'GL_GLEXT_PROTOTYPES', to protectProtoStr = 'GL_GLES_PROTOTYPES',
    2. Generate the header:
      • Set your working directory to OpenGL-Registry/xml/.
      • Run the following command:
        python genheaders.py ../api/GLES/gl.h
    3. Update the project:
      • Copy the newly generated header from OpenGL-Registry/api/GLES/gl.h to your local project folder.
      • Update scripts/gl.xml with the latest version from OpenGL-Registry/xml/.
    python genheaders.py ../api/GLES/gl.h
  2. Use headless-gl on a headless Linux machine

    master

    If you are running on a minimal Linux server (e.g., AWS) without an X11 or OpenGL environment, you must provide a software implementation of OpenGL and an X11 server.

    1. Install Mesa: Provides the software OpenGL implementation.
      • CentOS: yum install -y mesa-dri-drivers
      • Ubuntu/Debian: apt-get install libgl1-mesa-dev
    2. Install Xvfb: A lightweight X11 server for offscreen rendering.
      • CentOS: yum install -y Xvfb
      • Ubuntu: Typically preinstalled.

    To run your Node.js program, use the xvfb-run wrapper to handle the X11 lifecycle automatically.

    xvfb-run -s "-ac -screen 0 1280x1024x24" <node program>
  3. Set up a development environment for headless-gl

    master

    To develop for headless-gl locally, follow these steps after installing your system dependencies:

    1. Clone the repository: git clone git@github.com:stackgl/headless-gl.git
    2. Enter the directory: cd headless-gl
    3. Install npm dependencies: npm install
    4. Generate build scripts: npm run rebuild

    Running Tests:

    • Run all tests: npm test
    • Run specific tests: Execute them directly using node.

    Optimization Tip: On Unix-like platforms, perform incremental rebuilds by running make inside the build/ directory instead of running npm build every time. This is significantly faster.

    git clone git@github.com:stackgl/headless-gl.git
    cd headless-gl
    npm install
    npm run rebuild
  4. Configure system dependencies for headless-gl

    master

    If prebuilt binaries are unavailable for your platform, you must configure your build environment to compile the native module.

    macOS:

    • Python 3
    • Xcode

    Ubuntu/Debian:

    • Python 3
    • GNU C++ environment (build-essential)
    • libxi-dev
    • Up-to-date OpenGL drivers
    • GLEW
    • pkg-config

    Run the following to install dependencies on Ubuntu/Debian:

    sudo apt-get install -y build-essential libxi-dev libglu1-mesa-dev libglew-dev pkg-config

    Windows:

    • Python 3
    • Microsoft Visual Studio
    • Ensure d3dcompiler_47.dll is in c:\windows\system32 (otherwise, a copy can be found in the deps/ folder).
  5. Configure TravisCI for headless-gl

    master

    When using TravisCI with a Linux VM, you must install Mesa and Xvfb and initialize the Xvfb display in the before_script section. Create a .travis.yml file in your repository root with the following configuration:

    language: node_js
    os: linux
    sudo: required
    dist: trusty
    addons:
      apt:
        packages:
        - mesa-utils
        - xvfb
        - libgl1-mesa-dri
        - libglapi-mesa
        - libosmesa6
    node_js:
      - '20'
    before_script:
      - export DISPLAY=:99.0; sh -e /etc/init.d/xvfb start
  6. Use the OES_vertex_array_object extension

    master

    The OES_vertex_array_object extension allows you to encapsulate vertex state (like buffer bindings and attribute pointers) into Vertex Array Objects (VAOs). To use it, call getOESVertexArrayObject(ctx) to check for support and retrieve the extension interface.

    Available methods on the returned OESVertexArrayObject instance:

    • createVertexArrayOES(): Creates and returns a new WebGLVertexArrayObjectOES instance. Returns null if creation fails.
    • bindVertexArrayOES(array): Binds a WebGLVertexArrayObjectOES instance to the current context. Passing null unbinds the current VAO and restores the default vertex state.
    • deleteVertexArrayOES(array): Deletes the specified VAO. If the VAO is currently bound, it will be unbound.
    • isVertexArrayOES(object): Returns true if the provided object is a valid WebGLVertexArrayObjectOES.

    Note: The constant VERTEX_ARRAY_BINDING_OES is 0x85B5.

  7. Debug headless-gl with RenderDoc

    master

    To enable debugging with RenderDoc:

    1. Open src/native/webgl.cc.
    2. Set the RENDERDOC_ENABLED define.
    3. Install RenderDoc on your system.
    4. Attach RenderDoc to the gl process when launching your program.

    Note: To make attaching easier, you can uncomment the MessageBoxA call in src/native/webgl.cc to pause execution.

  8. Resize the drawing buffer with STACKGL_resize_drawingbuffer

    master

    Since headless-gl does not have a DOM or canvas element, you cannot resize the buffer by modifying canvas properties. Instead, use the STACKGL_resize_drawingbuffer extension to resize the drawing buffer of an existing context.

    Method:

    • ext.resize(width, height): Resizes the drawing buffer to the specified width and height.
    const assert = require('assert')
    const gl = require('gl')(10, 10)
    assert(gl.drawingBufferHeight === 10 && gl.drawingBufferWidth === 10)
    
    const ext = gl.getExtension('STACKGL_resize_drawingbuffer')
    ext.resize(20, 5)
    assert(gl.drawingBufferHeight === 20 && gl.drawingBufferWidth === 5)
  9. Destroy the WebGL context with STACKGL_destroy_context

    master

    For long-running jobs, Node.js garbage collection might not reclaim WebGL contexts quickly enough, potentially overloading the system. Use the STACKGL_destroy_context extension to immediately reclaim all resources associated with a context.

    Method:

    • ext.destroy(): Immediately destroys the context and all associated resources.
    const gl = require('gl')(10, 10)
    
    const ext = gl.getExtension('STACKGL_destroy_context')
    ext.destroy()
  10. Create a WebGL context with createGL()

    master

    The gl module exports a single function used to create a new WebGLRenderingContext in Node.js without a browser or window.

    Arguments:

    • width (number): The width of the drawing buffer.
    • height (number): The height of the drawing buffer.
    • contextAttributes (optional object): An object containing WebGL context attributes. To enable WebGL 2 support, set createWebGL2Context: true within this object.
    const createGL = require('gl')
    
    const width = 64
    const height = 64
    const gl = createGL(width, height, { preserveDrawingBuffer: true })
  11. Supported WebGL extensions in headless-gl

    master

    The following extensions are currently supported by headless-gl:

    • STACKGL_resize_drawingbuffer
    • STACKGL_destroy_context
    • ANGLE_instanced_arrays
    • OES_element_index_uint
    • OES_texture_float
    • OES_texture_float_linear
    • OES_vertex_array_object
    • OES_standard_derivatives
    • WEBGL_draw_buffers
    • EXT_blend_minmax
    • EXT_texture_filter_anisotropic
    • EXT_shader_texture_lod