NewLib is a family of .NET 10 libraries that provide mathematical primitives, image-buffer management, a low-level utility substrate, and an OpenGL rendering layer, all targeting the NewAge workspace ecosystem.
NewLib sits on top of two workspace repos:
| Upstream repo | What NewLib uses |
|---|---|
| JWCEssentials | JWCEssentials.net.dll — core NewAge .NET bindings |
| CrystalCatalystLibrary | CrystalCatalystLibrary.net.dll, CrystalOpenGL.dll, CrystalSkia.net.dll — cross-platform windowing and Skia rendering |
These deps are declared in Dev/NewAgeDeps.lst and resolved through the workspace lane at
$NewAge/DotNet/Libs/lib/<Configuration>/<TargetFramework>/.
NewLib ships four assemblies. They form a dependency chain:
Lightning.V1 (no dependencies)
│
NewLib (depends on Lightning.V1)
│
NewLib_Crystal (depends on NewLib + SkiaSharp + CrystalCatalystLibrary)
│
GLInterop (depends on NewLib + NewLib_Crystal + CrystalCatalystLibrary + Silk.NET.OpenGL)
Location: DotNet/Libs/Lightning.V1/
Namespace: Lightning.V1
No upstream dependencies. A standalone low-level utility library.
Key areas:
| Area | Main types |
|---|---|
| Linked list with cursor navigation | QuickList<T>, QuickDict<K,V> |
| Stack collections | LIFO<T>, ValueStack<T> |
| Ring buffer | CircularBuffer<T> |
| Hash algorithms | ElfHash, PJW_Hash, ElfHash_Table |
| Tape / step-execution engine | Tape<TContext>, Tape.IStep<T>, EnumeratorStep<T> |
| Thread pool and batching | _Threading.Manager, _Threading.Thread, _Threading.Batch, _Threading.BatchThread |
| Synchronization primitives | _Threading.Semaphore, _Threading.Barrier |
| Stream abstractions | IStream, IDataStream, StreamProxy, DataStreamProxy |
| Serialization | SerializeJsonMulti, SoftCall (IL-based dynamic dispatch) |
| Signal processing | Complex, Fourier (FFT/DFT), FIRFilter, Spline |
| Random number generation | Random_MT19937 (Mersenne Twister) |
| Utilities | Types, Arg<A…Z>, FunctionStack, Differential, Modulo, StringCursor, Timer |
The Tape system is the most distinctive Lightning design. A Tape<TContext> is an ordered sequence of IStep objects with a movable cursor. Each Execute call can advance or hold the cursor, push/pop steps, or hand control to a sub-tape. EnumeratorStep wraps a C# IEnumerable<bool> coroutine so a step can yield mid-computation without giving up its state. See Lightning.Tests/TapeTests.cs and TapeCoroutineTests.cs for usage patterns.
Location: DotNet/Libs/NewLib/NewLib/
Namespace: NewLib
Documentation generation: enabled (GenerateDocumentationFile=true)
Key areas:
| Area | Main types / files |
|---|---|
| 2D/3D vectors | Pnt2D_i/l/f/d, Pnt3D_i/l/f/d, Vec2D_f/d, Vec3D_f/d (JWC_Vec.cs) |
| 2D/3D matrices | Mat2D_f/d (3×3), Mat3D_f/d (4×4) (JWC_Mat.cs) |
| Geometry utilities | GeoOps, Frustum, Camera (stereo/mono, asymmetric frustum) |
| Pixel format structs | 32 generated pixel types: rgba_b/s/f/d, bgra_b/s/f/d, rgb_*, bgr_*, argb_*, abgr_*, rgbla_*, lum_*, hsv |
| Image buffer (Eisel) | Eisel (base), BEisel (byte), SEisel (short), FEisel (float), DEisel (double), HSVEisel |
| Color definitions | Colors, HTMLColors (147 named HTML colors) |
| Color model | Palette, rgba_fixed, AlphaMode |
| Paths and curves | PathAdapter (lines, circles, Bézier; nearest-point query, rasterization) |
| Signal processing | Fir (FIR filter, multiple window functions) |
| Math utilities | Numeric (clamp, lerp, PRNG, inverse factorial table), Nth (N-D linear interpolation), Complex_f/d, Spline_Vec3D_d |
| Code / text generation | TabWriter, TreeWriter, CodeWriter |
| Data I/O | CSV_Parser (IL-generated type parser), PrimativeIO (binary serialization) |
| Threading abstractions | MultiThreading._Event, MultiThreading._Mutex |
| Miscellaneous | CRC64, AsciiBox, FPSMonitor, Utils, InheritableList<T> |
Pixel type naming convention:
Types follow the pattern <channels>_<precision> where channels ∈ {rgb, rgba, bgr, bgra, argb, abgr, rgbla, lum, hsv} and precision ∈ {b=byte, s=ushort, f=float, d=double}. All pixel types and their Eisel bindings are enumerated in Pixels_NewLib. The pixel struct source files under Pixels/ are generated by the BuildPixels code-gen tool — edit the template, not the generated files.
Eisel system:
An Eisel is a typed, 2-D image buffer backed by a managed Array. It provides GC-pinning leases (PixelLease() → BitLease) for safe interop with native code or OpenGL texture upload. Four concrete subclasses (BEisel, SEisel, FEisel, DEisel) correspond to the four precision tiers of rgba pixels. Eisel.CreateEisel(width, height, type) is the factory entry point.
Location: DotNet/Libs/NewLib/NewLib_Crystal/
Namespace: NewLib (shared with NewLib)
Documentation generation: enabled (GenerateDocumentationFile=true)
A thin bridge assembly. Its sole file, PixDataEisel.cs, connects the Eisel image buffer to SkiaSharp:
- Create a live
SKBitmapview over an Eisel's pinned memory. - Obtain an
SKCanvasfor drawing into the buffer. - Load/save images (PNG, JPEG) through Skia.
- Convert
Arraypixel data back to Eisel types.
This is the only file in the repo that depends on SkiaSharp. Projects that do not need Skia can use NewLib alone.
Location: DotNet/Libs/GLInterop/
Namespace: GLInterop
Documentation generation: not yet enabled (see Open questions)
A modern OpenGL 3.3+ wrapper layered on top of Silk.NET.OpenGL.
Key types:
| Type | Purpose |
|---|---|
GLInteropContext |
Thread-static holder for the active Silk.NET.OpenGL.GL instance. Call GLInteropContext.Init(gl) before using any other GLInterop type. |
GL (static, in GL.Silk.cs) |
Main entry point — thin typed wrappers over raw GL calls (draw, clear, viewport, shaders, uniforms, samplers, textures). |
Texture |
2-D texture management. Accepts Eisel, byte[], IntPtr, or any typed Array. Supports render-to-texture via BeginRenderTo()/EndRenderTo(). |
Texture3D |
3-D texture management. Same upload/readback API as Texture. |
Sampler |
Wraps a GL sampler object; binds textures for shader use. |
Buffer<T> |
Wraps a GL buffer object (VBO); uploads data with Data(). |
VAO |
Wraps a vertex array object. |
IndexBuffer |
Wraps an element array buffer. |
Shader / Program |
Shader compilation and program linking; ShaderFromPath() loads GLSL from disk. |
Model / Model_BasicVertexIndexed |
Abstract model hierarchy. Model_BasicVertexIndexed manages a VAO+VBO+IBO and supports threaded normal computation via Lightning's Batch system. |
TextureQuad |
Screen-space quad renderer. DrawUnproject() unprojectors through a camera frustum for HUD overlays. |
e_ |
~7000-line GL enum definitions (GL 1.x through modern extensions). |
BasicVertex |
Vertex struct: position (Vec3D_f), normal (Vec3D_f), color (rgba_d), textel (Pnt2D_d). |
C/Libs/JWC_GLStub — this directory exists but contains no source files. It was a previous DllImport-based C stub that has been fully superseded by Silk.NET. The stub can be removed if its history is no longer needed.
All four assemblies target net10.0 and compile on Linux and Windows.
GLInterop requires an OpenGL 3.3-capable GPU and driver. The underlying CrystalCatalystLibrary handles platform windowing.
$NewAgeenvironment variable set to the workspace root — see the NewAge Developer Handbook for full workspace setupJWCEssentialsandCrystalCatalystLibraryconfigured and built first
./configure.sh # from the NewLib repo root
# or explicitly:
./configure.sh --newage /path/to/Home.NewAgeVia the workspace:
newage_build_managed.sh NewLib DebugPer-solution (from each project directory):
cd DotNet/Libs/Lightning.V1
dotnet build
cd DotNet/Libs/NewLib
dotnet build
cd DotNet/Libs/GLInterop
dotnet buildBuild order matters: Lightning.V1 must be staged before NewLib, and NewLib before GLInterop. The newage_dep_sort.sh tool in JWCEssentials handles this automatically when using workspace-level scripts.
# Build first, then:
cd DotNet/Libs/NewLib/NewLibDemo
dotnet run
cd DotNet/Libs/GLInterop/testGLInterop
dotnet run
# GLInteropTemplate is a starter template — copy it to begin a new project:
cp -r DotNet/Libs/GLInterop/GLInteropTemplate MyNewProjectLightning.V1 has an xUnit test suite:
cd DotNet/Libs/Lightning.V1/Lightning.Tests
dotnet testNewLib and GLInterop do not yet have automated test projects. TestNewLib, TestNewLib_s, and testGLInterop are manual/visual test applications.
Two executables regenerate source files. Run them from the solution directory after modifying the inputs:
| Project | Input | Output | Trigger |
|---|---|---|---|
BuildPixels |
pixel.template |
NewLib/Pixels/*.cs (32 files) |
Edit the template |
BuildHTMLColors |
HTML color table (scraped via AngleSharp) | NewLib/HTMLColors.cs |
Run to refresh the 147 named colors |
Do not hand-edit the generated files — changes will be overwritten.
| Assembly | Status |
|---|---|
Lightning.V1 |
Active; xUnit tests cover Tape, QuickList, SoftCall; API stable |
NewLib |
Active; math and color types are production-quality; some utilities (e.g., StdIO, CSV_Parser) are early-stage |
NewLib_Crystal |
Thin bridge; stable as long as SkiaSharp API is stable |
GLInterop |
Actively developed; API is still evolving (HUD path in TextureQuad is new) |
The C/Libs/JWC_GLStub directory is a dead end — no source files remain. The CMake project for it is not wired into the workspace build.
PntvsVecdistinction is intentional.Pntis a lightweight Cartesian coordinate value.Vecis the matrix-compatible homogeneous representation used by NewLib’s transformation pipeline.Vec*types carrywexplicitly and are the correct input toMat2D/Mat3Dmultiplication. This is documented inJWC_Vec.cs.Mat2D/Mat3Duse column-major field naming_C_R. Documented inJWC_Mat.cs.Tape<TContext>cursor behavior duringRemove(). When a step removes itself, the old node object survives the call;Advance()then follows the node'snextlink to the correct successor. The step object may cache a reference to its own list node viaCurrentThisto enable this.SoftCallusesSystem.Reflection.Emit. Will not work in NativeAOT-published builds. Not a current concern but noted for future packaging decisions.GenerateDocumentationFileforLightning.V1andGLInterop. Intentionally not enabled yet — those assemblies have extensive undocumented public surfaces and the CS1591 warning flood would be premature. The XML<summary>comments already in the source are compiled into assembly metadata and visible in IDEs regardless of this setting. Enable the flag per-assembly once coverage reaches a comfortable threshold.
MIT License. Copyright (c) 2024 John W. Cornell.