Black Shark Graphics Engine

Version 1.02 shark.engl@gmail.com
Main Gallery Forum Download Login







What is it?

Black Shark Graphics Engine is a simple 2D and 3D engine written in Pascal for developers to produce applications utilising hardware-accelerated graphics. It supports Lazarus (v. >= 2.0) and Delphi (Community Edition 10.3, another versions haven't been tested).

It's a young, a freely available for non-commercial use, project that currently has a vector of development in the 2D area. Beside, if you want, you can create 3D objects (see tests example TBSTestMesh, TBSTestEarth in a unit bs.test.mesh.pas). A main purpose of the project is creating the simplest entities for simple access to OpenGL API abilities within of version >= ES2.


Platforms

  • Windows
  • Linux (Ubuntu 18.04) (with Lazarus only)


Summary

  • Core:

    • a renderer has been based on OpenGL ES 2.0 API:
      • in Windows it uses a library from Google project the Angle;
      • in Linux it uses a native library;
      • for rendering in systems where lack of a graphic card (for example, Remote Desktop or Virtual Machine) it uses The Mesa 3D Graphics Library;
    • almost all events and animations have based on observer pattern;
    • no difference between 2D and 3D worlds; 2D objects are drawn over the nearest plane of frustum;
    • a window system for all input events (keyboard, mouse) is based on supplied component libraries in Delphi and Lazarus (VCL and LCL appropriately), but, if you want, you can replace its (bs.viewport.TBlackSharkViewPort) on own window system;
    • it has a canvas for creating any 2D-objects;
    • a simple rasterizator is used for load of textures and draw of primitives in RAM (for example, for fonts rasterization);
    • own fonts system is not depending on OS;
    • a set of visual tests for many subsystems;

  • Fonts:

    • supports fonts TrueType loaded from files *.ttf, appropriately you can load any contours TrueType, for example, smiles (emoji);
    • it has own loader of TrueType fonts with accomplish of triangulation and rasterization (without the use of external tools);
    • characters output only by a mesh (allows to get good quality of big symbols);
    • characters output from a texture (allows to get relative good quality of small symbols) beforehand prepared by the rasterizator; the texture consists only of alpha (GL_ALPHA), that is why a font can reserve very large textures;
    • supports mixed mode (with the use a special class TTrueTypeRasterFont) allowing automaticaly for a size of font a smaller threshold to display from a texture and if the size more threshold to display from meshes;
    • for sharing between consumers and managing the lifetime fonts have automatic reference counting;

  • Textures:

    • supports tga, png (for load uses tools Delphi and FPC); it is easy to add support for new formats;
    • for sharing between consumers and managing the lifetime textures have automatic reference counting;

  • Geometry instansing:

    • implements software instancing, that is, to draw a mesh for every instance invokes glDrawElements, because a hardware support exists only in the GLES 3.0; in the future planned hardware implementation, as only will be add the support to the Angle project;

  • Particle system:

    • implements drawing many textured particles by single call glDrawElements for all particles; the every particle is a quad of a texture if a property TBlackSharkParticles.IsPoints equal false, otherwise it is a point;

  • Full screen anti-aliasing implemented with help shaders:

    • Fast approXimate (FXAA);
    • Multi Sampling (MSAA);
    • Super Sampling x4 (SSAA) (with help to render to texture more than screen in 2 times and further resample (on GPU, of course) to the viewport size; in Linux works a native implementation (TODO: include property EmbeddedSSAA to TBlackSharkViewPort for switch it);

  • Canvas:

    • it has a class bs.canvas.TBCanvas that is a simple group of 2d objects (descendants of a TCanvasObject);
    • the canvas has mechanism of scaling belonging its objects relative a size of the viewport;
    • the bs.canvas unit contains the set of some primitives, so as line, circle, arc, rectangle, triangle, curves and so on;

  • Misc:

    • small and very usefull (IMHO) generic collections:
      • a list/stack;
      • a binary balanced tree (AVL-tree) that has time complexity O(log n) for all operations: search, insert and delete; a very usefull property: all values automatically ordered by key;
      • a thread-safe FIFO queue (First In First Out) without using of OS objects for synchronization;
      • a bidirectional list allowing insert and delete to any position for time complexity O(1); one has cursor for access to items by index;
      • a virtual tree fits for any hierarchical data, save and load any earlier formed structures;
      • finite-state automaton (machine) presenting Aho–Corasick algorithm, for example, allowing quickly to find all sub-strings into an input stream of data;


Install

  • download sources;
  • unzip into a new directory, desirable consisting only of Latin characters;
  • set paths in your IDE for search sources: root of the directory, /common, /core, /gui;
  • set path for a output executable file to a directory /bin;
  • for Win64 replace files libEGL.dll, libGLESv2.dll, opengl32.dll by files from a directory /bin/Win64.



Hello world




unit uMain;

{$mode Delphi}

interface

uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,

bs.basetypes,
bs.viewport,
bs.gl.context,
bs.canvas;

type

{ TFrmMain }

TFrmMain = class(TForm)
PanelScreen: TPanel;
PnlTools: TPanel;
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormShow(Sender: TObject);
private
ViewPort: TBlackSharkViewPort;
BCanvas: TBCanvas;
procedure AfterCreateContextEvent (Sender: TBlackSharkContext);
public

end;

var
FrmMain: TFrmMain;

implementation

{$R *.lfm}

{ TFrmMain }

procedure TFrmMain.FormShow(Sender: TObject);
begin
ViewPort := TBlackSharkViewPort.Create(PanelScreen);
{ set position right from PnlTools }
ViewPort.Left := PnlTools.Left + 1;
ViewPort.OnAfterCreateContext := AfterCreateContextEvent;
ViewPort.Align := alClient;
end;

procedure TFrmMain.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
BCanvas.Free;
end;

procedure TFrmMain.AfterCreateContextEvent(Sender: TBlackSharkContext);
var
txt: TCanvasText;
arc: TArc;
begin
BCanvas := TBCanvas.Create(ViewPort.CurrentScene, false, Self);
{ create a root empty object aligned to left-top corner; it is unnecessarily, but otherwise, next created object will be by root of canvas, and position other objects will be set relative its }
BCanvas.CreateEmptyCanvasObject;
{ text example }
txt := TCanvasText.Create(BCanvas, nil);
txt.Text := 'Hello world!';
txt.Position2d := vec2(70, 150);
{ arc example }
arc := TArc.Create(BCanvas, nil);
arc.Radius := 100;
arc.Angle := 60;
arc.Fill := true;
arc.Color := BS_CL_ORANGE;
arc.Build;
arc.Position2d := vec2(250, 130);
end;

end.


The project sources are located in a following folder: /tests/lazarus/Hello world/

Result: