Black Shark Graphics Engine

Version 2.0 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, 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; for access OpenGL context uses a library from Google project the Angle;
    • 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; if you want to use pure 2D-world only, you can set TBlackSharkFrustum.OrtogonalProjection in True, that allows avoid few distortions objects;
    • a window system for all input events (keyboard, mouse) is based on supplied component libraries in Delphi and Lazarus (VCL/FMX 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;
    • any graphic objects (2D or 3D) may be interactive;
    • 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;
    • the canvas has scalable mode for automatic scaling of its objects when viewport changing;

  • 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 hash-table that has time complexity O(1) in the average case;
      • 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);
{ 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: