NewLib: Mathematical, Image, Utility, and OpenGL Foundations for .NET

View NewLib on GitHub

Back to overview

A mature software ecosystem eventually needs more than isolated utilities.

It needs mathematical types that agree with its rendering pipeline. It needs image buffers that can move safely between managed code, native libraries, Skia, and OpenGL. It needs collections and execution structures that support parsers, symbolic systems, background work, and procedural computation. It needs graphics wrappers that are expressive enough for real applications without discarding access to the underlying platform.

NewLib brings those concerns together.

It is a family of .NET 10 libraries built for the NewAge workspace ecosystem. Rather than presenting one oversized assembly with every dependency attached, NewLib is divided into four cooperating layers:

Lightning.V1
    Low-level collections, execution structures,
    threading, streams, signal processing, and utilities
             ↓
NewLib
    Mathematics, geometry, pixels, image buffers,
    colors, interpolation, paths, and data tools
             ↓
NewLib_Crystal
    A narrow bridge from Eisel buffers
    into PixData, SkiaSharp, and CrystalCatalyst
             ↓
GLInterop
    OpenGL textures, buffers, shaders, models,
    framebuffers, samplers, and rendering helpers

This organization gives consumers control over how much of the ecosystem they adopt.

A project that needs only core collections or signal-processing tools can use Lightning.V1. A mathematical or image-processing project can add NewLib without bringing in Skia or OpenGL. A 2D graphics application can use NewLib_Crystal to connect NewLib image buffers with CrystalCatalyst and SkiaSharp. A 3D application can add GLInterop and build upon the same mathematical and pixel foundations.

NewLib is therefore both a library collection and an architectural ladder.

The Integration Layer of the Public Ecosystem

The other public repositories establish increasingly capable forms of infrastructure.

JWCEssentials defines the shared workspace, native utility conventions, staging lanes, and low-level interoperability structures.

CrystalCatalystLibrary provides windows, events, pixel presentation, OpenGL contexts, Skia integration, clipboard behavior, and drag-and-drop.

JWCCommandSpawn provides shell-aware execution and communication with external processes.

NewLib builds above that groundwork and supplies the reusable managed types from which applications, renderers, symbolic systems, image tools, and experiments can be assembled.

Its upstream relationship is explicit:

JWCEssentials
      └── managed NewAge utility bindings

CrystalCatalystLibrary
      ├── native-backed windowing
      ├── PixData
      ├── CrystalOpenGL
      └── CrystalSkia
                 ↓
               NewLib

The repository resolves these dependencies through the shared NewAge workspace lane, preserving the same configuration- and framework-aware staging model used by the other projects.

This makes NewLib the natural capstone of the current public repository family. It does not replace the lower layers. It gathers them into a broader managed environment.

Four Assemblies Instead of One Monolith

NewLib’s dependency chain is one of its most important design decisions.

Lightning.V1
     │
   NewLib
     │
NewLib_Crystal
     │
  GLInterop

Each assembly introduces a new level of responsibility.

Lightning.V1 has no upstream dependency and can stand alone.

NewLib depends on Lightning and introduces mathematical, geometric, pixel, image, color, interpolation, and general-purpose facilities.

NewLib_Crystal is deliberately thin. It adds only the dependencies needed to connect NewLib’s image system to SkiaSharp and CrystalCatalystLibrary.

GLInterop adds the OpenGL stack, including Silk.NET.OpenGL, while reusing NewLib’s vectors, matrices, pixel types, and image buffers.

This layered structure avoids a common library-design failure: requiring every consumer to install a complete graphics and native interop stack just to use one data structure or numerical helper.

Dependencies appear where their responsibilities begin.

Lightning.V1: The Low-Level Utility Substrate

At the bottom of the family is Lightning.V1.

Lightning contains the structures that support control flow, collections, execution, concurrency, signal processing, dynamic dispatch, serialization, and general computation.

Its major areas include:

  • cursor-driven linked collections;

  • stack and ring-buffer structures;

  • hashing;

  • thread and batch management;

  • synchronization primitives;

  • stream abstractions;

  • JSON and binary-oriented serialization support;

  • dynamic invocation using emitted intermediate language;

  • Fourier transforms and filters;

  • spline interpolation;

  • random-number generation;

  • reusable argument, timing, differential, modulo, and text utilities.

The name “Lightning” is appropriate because many of these facilities sit close to the execution path of higher-level systems. They are not domain-specific application features. They are mechanisms through which other systems move, schedule, transform, and inspect work.

QuickList and Cursor-Oriented Collections

One of Lightning’s recurring themes is explicit navigation.

QuickList<T> is a linked collection with cursor support. Instead of exposing only ordinary enumeration, it allows a caller to maintain a position, move forward or backward, insert relative to that position, remove nodes, push values into the execution path, and clone cursor state.

This kind of structure is especially useful in systems where a collection is not merely stored but actively traversed and rewritten.

Examples include:

  • parsers;

  • transformation pipelines;

  • symbolic expression processing;

  • schedulers;

  • interpreter-like execution;

  • recursive work queues;

  • procedural generation.

An ordinary index is often a poor fit for these systems. Removing or inserting items can invalidate positions, and array-backed collections can obscure the relationship between the current item and its successor.

A node-aware cursor makes the traversal state explicit.

Lightning extends this pattern through structures such as QuickDict<K,V>, LIFO<T>, ValueStack<T>, and CircularBuffer<T>. Each addresses a different recurring shape of state while remaining lightweight enough to serve as infrastructure.

Tape: Mutable Execution as a Data Structure

The most distinctive Lightning design is Tape<TContext>.

A Tape is an ordered sequence of executable steps with a movable cursor. Each step receives the Tape and a caller-provided context when it executes.

The step may:

  • inspect the current context;

  • mutate the context;

  • advance to the next step;

  • remain at the current location;

  • insert new steps;

  • remove itself;

  • replace itself with a sequence;

  • hand control to another Tape;

  • preserve state across repeated executions.

The key interface is intentionally small:

public interface IStep<TContext>
{
    bool Execute(
        Tape<TContext> tape,
        TContext context
    );
}

The returned Boolean controls orientation.

A step may return true when normal forward movement should occur. It may return false when it has changed the Tape itself, inserted prerequisite work, or needs to remain active.

This creates a late-collapse execution model. The full sequence of future work does not have to be fixed before execution begins. Steps can expand, defer, replace, or remove work as the computation unfolds.

That makes Tape suitable for systems where control flow is itself part of the mutable state.

Enumerator Steps and Resumable Computation

Lightning can also wrap a C# enumerable as a Tape step.

EnumeratorStep<TContext> lazily creates an IEnumerator<bool> and advances it one yield at a time. The enumerator preserves its local state between executions, allowing a step to pause and resume without building a separate state machine by hand.

Conceptually:

IEnumerable<bool> Work(
    Tape<MyContext> tape,
    MyContext context)
{
    PerformFirstStage();
    yield return false;

    PerformSecondStage();
    yield return true;
}

This gives Tape a coroutine-like execution style.

A computation can yield midway, allow other steps to run, and later resume from the same local position. When the enumerator finishes, the step can automatically remove itself from the Tape.

The result combines three useful ideas:

  • mutable step sequences;

  • cursor-directed execution;

  • resumable local computation.

That combination is relevant to parsers, agent workflows, simulations, animation sequencing, symbolic transforms, incremental processing, and any system where work evolves during execution.

Observable Execution

Tape includes before- and after-step hooks, and Lightning provides a disposable watcher that subscribes to them.

A watcher can report:

  • the iteration number;

  • the current step type;

  • the current step count;

  • whether the step requested advancement;

  • whether the Tape has reached its end.

This makes dynamic execution inspectable.

Mutable workflows can otherwise become difficult to debug because the sequence being executed may no longer resemble the sequence originally constructed. Execution hooks make those transformations visible without requiring each step to implement its own logging system.

This reflects a useful design principle throughout NewLib: powerful low-level mechanisms should expose observation points.

Threading and Batch Work

Lightning also contains its own thread-management and batch abstractions.

The threading family includes manager, thread, batch, and batch-thread types, along with synchronization primitives such as semaphores and barriers.

These are useful for workloads that can be divided into independent or semi-independent units, including:

  • image processing;

  • geometry calculations;

  • model normal generation;

  • simulation;

  • Fourier or filter operations;

  • bulk transformations;

  • test workloads.

The GLInterop model layer uses Lightning’s batching system for operations such as threaded normal computation. This is a good example of the assembly structure working as intended: a higher graphics layer reuses a general lower-level facility instead of embedding its own unrelated thread scheduler.

Signal Processing and Numerical Foundations

Lightning includes complex-number support, Fourier transforms, finite impulse response filters, splines, and Mersenne Twister random generation.

These components reveal the repository’s history in practical computational work.

The library is not limited to graphical concerns. It provides reusable numerical tools that can support:

  • audio and signal analysis;

  • filtering;

  • procedural generation;

  • interpolation;

  • simulation;

  • random experiments;

  • image-domain transforms;

  • spectral visualization.

Because Lightning has no upstream dependencies, these facilities can be used independently of the NewAge graphics stack.

SoftCall and Dynamic Dispatch

Another notable Lightning component is SoftCall.

SoftCall uses System.Reflection.Emit to construct dynamic invocation paths. This permits runtime-generated dispatch without repeatedly paying the full cost or complexity of ordinary reflection.

It is useful in systems where:

  • a method or member is discovered dynamically;

  • the invocation pattern can then be compiled;

  • repeated calls should use a prepared path;

  • a flexible runtime structure needs stronger execution performance.

The repository correctly records the tradeoff: emitted intermediate language is not compatible with every deployment model, particularly NativeAOT.

That caveat is not a design failure. It is an example of NewLib making its operating assumptions explicit.

NewLib: Mathematical and Image Primitives

The central NewLib assembly builds on Lightning and introduces the types most directly associated with geometry, rendering, images, colors, interpolation, and application utilities.

Its major areas include:

  • two- and three-dimensional points;

  • homogeneous vectors;

  • transformation matrices;

  • camera and frustum geometry;

  • generated pixel structures;

  • typed image buffers;

  • palettes and color models;

  • named HTML colors;

  • path and curve operations;

  • multidimensional interpolation;

  • filters and splines;

  • CSV and binary data tools;

  • source and text-generation helpers;

  • threading wrappers;

  • diagnostic and timing utilities.

These are not all one conceptual feature, but they share an important trait: they are reusable building blocks that higher-level applications should not have to reinvent.

Points and Vectors Are Intentionally Different

NewLib distinguishes between points and homogeneous vectors.

Point types include forms such as:

Pnt2D_i
Pnt2D_l
Pnt2D_f
Pnt2D_d

Pnt3D_i
Pnt3D_l
Pnt3D_f
Pnt3D_d

Vector types include:

Vec2D_f
Vec2D_d

Vec3D_f
Vec3D_d

The distinction is mathematical rather than cosmetic.

A point records a Cartesian position or coordinate. It does not automatically carry a homogeneous w component.

A vector used in the transformation pipeline includes w, allowing it to participate correctly in matrix multiplication and projective transformations.

This allows NewLib to make intent visible in the type system.

A pixel coordinate or array location can remain a lightweight point. A value intended for matrix transformation can become a vector. The distinction reduces accidental misuse and clarifies when perspective or homogeneous operations are expected.

The structures use sequential memory layout and are serializable, making them suitable for P/Invoke and OpenGL buffer uploads as well as ordinary managed calculation.

Transformation Matrices, Cameras, and Frustums

NewLib provides 3×3 matrices for two-dimensional transformations and 4×4 matrices for three-dimensional transformations.

These types support the common operations needed for graphical and geometric systems:

  • translation;

  • scaling;

  • rotation;

  • composition;

  • point or vector transformation;

  • projection;

  • camera orientation.

The camera and frustum types include mono and stereo behavior as well as asymmetric frustums.

Asymmetric projection is particularly useful in contexts such as:

  • stereo rendering;

  • off-axis projection;

  • head-tracked displays;

  • split views;

  • projected overlays;

  • specialized visualization systems.

The matrix field naming uses a column-major convention, matching the graphics-oriented transformation model. That convention is documented explicitly so users can reason correctly about multiplication and upload order.

Generated Pixel Types

NewLib defines a broad family of strongly typed pixel structures.

Channel arrangements include:

  • RGB;

  • RGBA;

  • BGR;

  • BGRA;

  • ARGB;

  • ABGR;

  • luminance;

  • luminance with color-related channels;

  • HSV.

Precision tiers include:

  • byte;

  • unsigned short;

  • float;

  • double.

The naming convention expresses both dimensions:

<channels>_<precision>

Examples include:

rgba_b
bgra_b
rgb_f
lum_d
hsv

This is preferable to representing every image as an anonymous byte array.

A typed pixel structure can communicate:

  • channel count;

  • channel order;

  • component precision;

  • expected memory layout;

  • conversion target;

  • compatibility with a rendering or native API.

The pixel files are generated from a shared template. That prevents dozens of closely related structures from drifting apart through manual edits.

The repository also maintains a central pixel registry through Pixels_NewLib, which maps between type names, runtime types, and pixel-format strings.

Eisel: A Typed Managed Image Buffer

The Eisel system is the core of NewLib’s image architecture.

An Eisel is a typed, two-dimensional image buffer backed by a managed array. Concrete variants represent different component precisions:

BEisel  — byte
SEisel  — unsigned short
FEisel  — float
DEisel  — double
HSVEisel — HSV-oriented data

The buffer records its width, height, pixel type, and pixel-format identity.

This gives image data a richer form than a detached memory pointer. An Eisel knows what its elements mean and how they are arranged.

The name also distinguishes the abstraction from a file format or operating-system bitmap. An Eisel is an in-memory working surface that can participate in processing, drawing, conversion, native transfer, or GPU upload.

Safe Pinning Through Leases

Managed arrays normally move under the control of the garbage collector. Native code or OpenGL cannot safely retain a pointer to such memory unless the array is pinned.

Eisel addresses this through a lease model.

Calling PixelLease() pins the underlying managed memory and returns a disposable object containing the native address. When the lease is disposed, the pin is released.

Conceptually:

using var lease = eisel.PixelLease();

IntPtr pixels = lease.Data;

// Use pixels only while the lease remains active.

This pattern makes the lifetime of the native pointer visible.

It avoids a dangerous API shape in which a raw pointer escapes without any indication of when it becomes invalid. The lease defines a bounded period during which the garbage collector will not relocate the image memory.

That is particularly valuable for:

  • native image presentation;

  • Skia bitmap views;

  • OpenGL texture uploads;

  • native pixel conversion;

  • interop with CrystalCatalyst;

  • temporary access by external libraries.

Image Memory Without Unnecessary Copies

The lease system allows other libraries to create temporary views over Eisel memory rather than immediately copying it.

A Skia bitmap can point directly at the pinned buffer. A PixData structure can temporarily describe the same bytes. OpenGL can upload from the pinned address.

This creates an efficient path:

Managed Eisel array
        ↓ pin
Temporary native pointer
        ├── PixData view
        ├── SKBitmap view
        └── OpenGL upload

The memory remains owned by the Eisel. The view remains valid only for the duration of the lease.

This is a disciplined zero-copy design. It gains performance without obscuring ownership.

Colors and Palettes

NewLib includes typed color definitions, palettes, alpha modes, fixed RGBA representations, and a generated collection of 147 named HTML colors.

Named colors are useful for more than convenience. They provide a familiar vocabulary for:

  • user interfaces;

  • visualization;

  • SVG-related work;

  • theme systems;

  • generated content;

  • diagnostics;

  • tests and demos.

The broader color system permits applications to work with strongly typed channel formats while retaining meaningful color-level abstractions.

N-Dimensional Interpolation

NewLib includes generalized N-dimensional linear interpolation through the Nth system.

Instead of defining separate interpolation code for one-dimensional, two-dimensional, and three-dimensional arrays, the algorithm treats dimensionality as data.

For each dimension, it identifies a base coordinate and an interpolation fraction. It then combines the surrounding sample corners according to their weights.

This provides a general conceptual foundation for:

  • resampling;

  • image interpolation;

  • multidimensional lookup tables;

  • volumetric data;

  • procedural fields;

  • simulation grids;

  • higher-dimensional parameter spaces.

The importance of this design is that interpolation is separated from any one storage domain. Pixels are one use, but not the only one.

Paths, Curves, and Rasterization

PathAdapter provides operations involving:

  • line segments;

  • circles;

  • Bézier curves;

  • nearest-point queries;

  • rasterization.

This helps bridge continuous geometry and discrete pixel output.

A path can be described mathematically, queried spatially, and then rendered or sampled into image space.

That is useful for drawing tools, procedural art, motion paths, hit testing, geometric analysis, and vector-to-raster conversion.

Code and Data Utilities

NewLib also includes TabWriter, TreeWriter, and CodeWriter for structured text and source generation.

These tools support codebases where generated output must remain readable and consistently indented.

Data utilities include CSV parsing and primitive binary I/O. The CSV parser uses generated intermediate-language paths for type conversion, again reflecting the repository’s preference for moving repeated dynamic work into prepared execution structures where practical.

Other utilities include CRC64, ASCII boxes, frame-rate monitoring, inherited list structures, and general numerical helpers.

NewLib’s range is broad, but these facilities share one lineage: they emerged as reusable answers to problems encountered across larger systems.

NewLib_Crystal: A Narrow Graphics Bridge

NewLib_Crystal exists to keep optional graphics dependencies isolated.

Its main responsibility is to connect:

  • Eisel;

  • CrystalCatalyst PixData;

  • SkiaSharp SKBitmap;

  • SkiaSharp SKCanvas.

This assembly can create a temporary PixData view over an Eisel’s pinned memory. It can then use CrystalSkia to construct an SKBitmap over that view or an SKCanvas that draws directly into the image buffer.

The bridge can also:

  • load and save images through Skia;

  • convert pixel formats;

  • copy PixData into Eisel storage;

  • convert typed arrays into pixel structures;

  • convert pixel structures back into managed arrays.

The important architectural point is that the bridge does not redefine any of these systems.

Eisel remains the NewLib image buffer.

PixData remains CrystalCatalyst’s cross-boundary pixel currency.

SKBitmap and SKCanvas remain SkiaSharp rendering objects.

NewLib_Crystal defines the controlled transitions between them.

Temporary PixData Views

A typical bridge operation pins the Eisel, constructs a non-owning PixData description, executes a caller action, and then releases the lease.

The PixData view receives:

  • width;

  • height;

  • pixel-format string;

  • native pointer;

  • byte length;

  • no independent free callback.

The absence of a free callback is intentional. The temporary PixData does not own the memory. The Eisel and its active lease do.

This distinction prevents two systems from both believing they own the same allocation.

Drawing Directly Into Eisel with Skia

The bridge can expose an Eisel as an SKBitmap and then create an SKCanvas targeting that bitmap.

Conceptually:

PixDataEisel.WithCanvasView(
    eisel,
    (bitmap, canvas) =>
    {
        canvas.Clear();
        // Draw with Skia directly into Eisel memory.
    });

No separate intermediate image buffer is required.

When the drawing action completes, the Eisel already contains the rendered pixels. Those pixels can then be:

  • presented through CrystalCatalyst;

  • uploaded to OpenGL;

  • saved to a file;

  • processed numerically;

  • examined as a typed array;

  • reused as a cursor or icon source.

This is an excellent example of the repository layers cooperating without collapsing into one another.

Format Conversion at the Boundary

The bridge checks whether incoming PixData matches the destination Eisel format.

When the formats differ, it requests conversion through CrystalCatalyst’s pixel facilities, copies the converted data into the pinned Eisel buffer, and disposes of the temporary converted allocation.

This makes conversion explicit and localized.

The core Eisel type does not need to depend on CrystalCatalyst. The bridge assembly performs the translation only when a project has opted into that relationship.

GLInterop: A Managed OpenGL Layer

At the top of the dependency chain is GLInterop.

GLInterop is a modern OpenGL 3.3-or-newer wrapper built on Silk.NET.OpenGL.

It provides managed abstractions for:

  • OpenGL context access;

  • textures;

  • three-dimensional textures;

  • samplers;

  • vertex buffers;

  • index buffers;

  • vertex-array objects;

  • shaders;

  • linked programs;

  • render targets;

  • models;

  • screen-space quads;

  • pixel upload and readback.

Its purpose is not to hide OpenGL completely.

Instead, it gives common OpenGL resources clear managed ownership and typed operations while preserving the ability to reach the underlying Silk.NET GL instance.

Context Ownership Remains Explicit

GLInteropContext stores the active Silk.NET OpenGL instance in thread-static state.

Before using GLInterop objects, the caller initializes the context:

GLInteropContext.Init(gl);

This reflects a fundamental OpenGL rule: commands apply to a current context associated with the executing thread.

GLInterop does not pretend that one process-wide global context exists. Its thread-static holder aligns the managed helper layer with the native graphics model.

CrystalCatalystLibrary remains responsible for creating the platform context and making it current. Silk.NET provides the raw managed bindings. GLInterop builds typed resources above that foundation.

Texture as a Central Graphics Object

The Texture class accepts pixel data from multiple sources:

  • Eisel;

  • typed arrays;

  • byte arrays;

  • native pointers;

  • other supported image forms.

This makes the Eisel system directly useful for GPU rendering.

An image can be generated or drawn in managed memory, pinned, and uploaded into a texture. A rendered texture can later be read back into a compatible image form.

Textures also support render-to-texture operations through paired begin and end methods. Internally, this requires framebuffer and renderbuffer management, viewport changes, and restoration of surrounding OpenGL state.

The texture layer therefore serves both as a data resource and as a rendering destination.

Buffers, Vertex Arrays, and Models

GLInterop wraps vertex buffers through Buffer<T>, element arrays through IndexBuffer, and vertex layout state through VAO.

This gives models a structured basis for uploading geometry.

The BasicVertex structure brings together:

  • position;

  • normal;

  • color;

  • texture coordinate.

These fields reuse NewLib’s own mathematical and color types, demonstrating why the repository is organized as a chain.

A model should not need one unrelated vector type for CPU geometry and another for GPU upload. NewLib’s sequentially laid-out structures can serve both purposes.

Model_BasicVertexIndexed combines a vertex-array object, vertex buffer, and index buffer into a reusable indexed model implementation. It can also use Lightning’s batch system to calculate normals across multiple work units.

The path from the lowest assembly to the highest is therefore concrete:

Lightning batch processing
          ↓
NewLib vectors and colors
          ↓
GLInterop vertex structures
          ↓
Indexed OpenGL model

Shaders and Programs

GLInterop provides managed wrappers for shader compilation and program linking.

Shaders can be created from source or loaded from disk. Programs can attach shaders, link them, expose uniforms, and participate in the typed rendering workflow.

The wrapper simplifies recurring ownership and error-checking patterns while retaining OpenGL’s core concepts.

This is consistent with NewLib’s general philosophy: do not erase the underlying system; make its common operations safer, more reusable, and easier to compose.

TextureQuad and Screen-Space Rendering

TextureQuad supports drawing textures onto a screen-aligned or projected quad.

Its unprojection path can use camera and frustum information from NewLib to position overlays relative to the rendered scene.

This connects several of the repository’s mathematical and graphics layers:

Camera and Frustum
        ↓
Projection / unprojection
        ↓
TextureQuad geometry
        ↓
Shader and texture
        ↓
CrystalCatalyst OpenGL context

The result can support HUDs, overlays, image previews, compositing, and post-rendered surfaces.

A Living Graphics API

GLInterop is actively evolving.

That is appropriate for its position in the repository. OpenGL wrappers tend to grow in response to actual rendering requirements. Texture workflows, framebuffer handling, state restoration, shader helpers, extension support, and model abstractions become clearer as they are exercised.

The repository identifies this maturity honestly.

Lightning has established tests and a comparatively stable API. Core NewLib mathematics and color types are production-quality, while some utility areas remain earlier-stage. The Crystal bridge is intentionally small and stable. GLInterop remains active, with newer paths such as HUD rendering still developing.

Public software benefits from this kind of explicit maturity map. It helps users distinguish dependable foundations from active experimentation.

Code Generation as Maintenance Infrastructure

NewLib uses code generation where families of source files must remain structurally consistent.

The pixel generator expands a shared template into the complete set of typed pixel structures.

The HTML color generator produces the named-color table.

This avoids two undesirable alternatives:

  • hand-maintaining dozens of nearly identical files;

  • replacing strongly typed source with a fully dynamic runtime abstraction.

Generated source preserves compile-time types while centralizing the repetitive pattern.

The repository clearly marks generated files and instructs maintainers to edit the source template rather than the output.

Build Order as an Architectural Map

NewLib’s build order is not arbitrary.

Lightning.V1
      ↓
NewLib
      ↓
NewLib_Crystal
      ↓
GLInterop

The NewAge dependency tools sort and stage the projects accordingly.

This gives the build system a machine-readable version of the architecture. The dependency chain is not merely described in prose; it controls how the assemblies are produced and made available to one another.

All four assemblies target .NET 10 and compile on Linux and Windows. GLInterop additionally requires an OpenGL 3.3-capable environment, while CrystalCatalystLibrary supplies the platform-specific window and context layer.

Reuse Without Forced Coupling

The strongest unifying principle in NewLib is selective composition.

A user can adopt:

  • only Lightning for core execution and utility structures;

  • Lightning plus NewLib for mathematics and images;

  • the Crystal bridge for Skia and native pixel presentation;

  • GLInterop for full OpenGL rendering.

This keeps dependency cost proportional to capability.

The library does not force Skia into numerical projects. It does not force OpenGL into image-processing tools. It does not force CrystalCatalyst into users who only need vectors or interpolation.

At the same time, when the layers are used together, their types are designed to cooperate.

A Common Data Journey

The architecture becomes clearest when following one image through the system.

An application may:

  1. create a BEisel;

  2. draw into it with Skia through NewLib_Crystal;

  3. expose it temporarily as PixData;

  4. present it in a CrystalCatalyst window;

  5. upload it into a GLInterop texture;

  6. render that texture through an OpenGL model or quad;

  7. read the result back into a managed image buffer;

  8. save it through Skia.

The conceptual flow is:

Typed managed pixels
        ↓
      Eisel
   ↙     ↓      ↘
Skia   PixData   OpenGL
  ↓       ↓         ↓
drawing  window   texture/model

This is not accidental interoperability. It is the central value created by the repository family.

Infrastructure Grown From Real Work

NewLib’s breadth reflects its origin in larger practical systems.

Tape supports dynamic and symbolic execution.

QuickList supports mutable traversal.

Vectors, matrices, frustums, and cameras support graphics.

Eisel supports image processing and native transfer.

Fourier transforms and filters support signal work.

GLInterop supports real-time rendering.

Code writers and serializers support tooling.

These components were not collected merely to fill category headings. They represent reusable solutions extracted from ongoing development.

That history gives NewLib an identity different from a generic utility package. It is a toolbox shaped by the needs of a coherent body of software.

Its Place in the Public Ecosystem

NewLib is the broad managed library and integration layer of the public JWC ecosystem.

The complete relationship now looks like this:

JWCEssentials
    Workspace, native foundations,
    shared structures, staging
             ↓
    ┌────────┴──────────┐
    ↓                   ↓
CrystalCatalyst     JWCCommandSpawn
Windows, pixels,    Processes, shells,
events, graphics    pipes, external tools
    └────────┬──────────┘
             ↓
           NewLib
Collections, execution, mathematics,
images, Skia bridges, and OpenGL

JWCEssentials establishes common ground.

CrystalCatalystLibrary gives applications a native surface.

JWCCommandSpawn connects applications to the external tool environment.

NewLib supplies the managed structures, mathematical vocabulary, image representations, rendering abstractions, and execution mechanisms through which larger systems can be built.

Its purpose can therefore be summarized as:

NewLib is a layered family of reusable .NET libraries that connects low-level execution structures, mathematics, typed image buffers, Skia interoperability, and modern OpenGL rendering into a coherent cross-platform development environment.

View NewLib on GitHub

Back to overview