The new Mag­num mile­stone brings We­bGL 2.0 and We­bAssem­bly, VR sup­port, lots of niceties for Win­dows users, iOS port, new ex­per­i­men­tal UI li­brary, im­proved test­ing ca­pa­bil­i­ties, sup­port for over 80 new as­set for­mats, new ex­am­ples and much more.

With near­ly three years of de­vel­op­ment since the pre­vi­ous re­lease, I’m ex­cit­ed to an­nounce the re­lease of Mag­num 2018.02. Lots of things hap­pened, so I’ll fo­cus on the most prom­i­nent fea­tures, for a de­tailed list fol­low the changel­og links at the end. This re­lease al­so in­tro­duces a new ver­sion­ing scheme. Orig­i­nal­ly this was meant to be 1.0, but af­ter much thought I de­cid­ed to go with year/month in­stead, as it fits more in­to the rolling re­lease phi­los­o­phy of Mag­num.

Brand new web­site and doc­u­men­ta­tion theme

Un­til very re­cent­ly, Mag­num lacked a cen­tral place with con­sis­tent de­sign for show­cas­ing the fea­tures, pro­vid­ing doc­u­men­ta­tion and keep­ing you up­dat­ed. You can read more in the web­site an­nounce­ment post, be sure to al­so sub­scribe to the blog Atom feed to not miss any up­dates. The doc­u­men­ta­tion got an over­haul in a sim­i­lar style, with ex­tra ef­fort put in­to be­ing fast, easy-to-read and with first-class search func­tion­al­i­ty. There’s a blog post ded­i­cat­ed to ex­plain­ing how the new search works, if you want to learn about the in­ner work­ings.

One no­table non-ob­vi­ous fea­ture is an abil­i­ty to search us­ing OpenGL or Ope­nAL API names — very handy in case you are port­ing ex­ist­ing OpenGL code to Mag­num:

OpenGL symbol search

Mag­num wouldn’t be any­thing with­out the great com­mu­ni­ty that formed around it and com­mu­ni­ty in­volve­ment is im­por­tant al­so for the web­site con­tent — if you want to share a suc­ces sto­ry with Mag­num or have some­thing in­ter­est­ing to say, sub­mit a Guest Post and we’ll be hap­py to pub­lish it.

If you didn’t no­tice yet, there’s al­so a Mag­num chat room on Git­, full of peo­ple that are hap­py to help if you have ques­tions or need a bit of sup­port. You can join sim­ply with your GitHub or Twit­ter ac­count.

First-class We­bGL 2.0 sup­port, We­bAssem­bly

An area that re­ceived great care is the We­bGL port. We­bGL 2.0 is now ful­ly sup­port­ed and there is a set of new de­pen­den­cy-less plug­ins so you can now more eas­i­ly play au­dio, con­vert im­ages or ren­der text on the web. The StbIm­age­Con­vert­er and Stb­True­Type­Font plug­ins are one of them. The Bul­let­Inte­gra­tion code and ex­am­ple now runs on the web and the mag­num-in­fo / Mag­num Ope­nAL In­fo util­i­ties were port­ed to pro­vide in­for­ma­tion about your We­bGL im­ple­men­ta­tion as well.

Bullet Physics example screenshot
Bul­let Physics Ex­am­ple we­bgl1 physics in­stanc­ing
Shows a ro­tat­ing ta­ble full of cubes that you can shoot down.
Magnum GL Info screenshot
Mag­num GL In­fo asm.js fall­back we­bgl1 we­bgl2
Text util­i­ty print­ing in­fo about Mag­num OpenGL ca­pa­bil­i­ties. Ver­sions for We­bGL 1, asm.js We­bGL 1 and We­bGL 2.

A bunch of code size op­ti­miza­tions is al­ready in place and fur­ther size im­prove­ments are on the roadmap. Com­pi­la­tion to We­bAssem­bly for bet­ter per­for­mance is now pos­si­ble, which in fact re­placed the un­main­tained Na­Cl port. See the post about We­bAssem­bly sup­port for more in­for­ma­tion.

Vir­tu­al Re­al­i­ty, We­b­VR

Thanks to years of hard work by @Squareys, Mag­num now pro­vides seam­less in­te­gra­tion of the Ocu­lus VR SDK in the OvrIn­te­gra­tion li­brary, to­geth­er with a sim­ple ex­am­ple that show­cas­es a ba­sic use. Be­sides that, there’s a live ex­am­ple show­ing We­b­VR in­te­gra­tion in Em­scripten:

WebXR example screenshot
We­bXR Ex­am­ple we­bgl1 we­bxr
A ba­sic demon­stra­tion of how to use the Em­scripten We­bXR li­brary with Mag­num.

Win­dows im­prove­ments

Vis­ual Stu­dio 2015, 2017, Win­dows Store/Phone, AN­GLE, Vcp­kg

Win­dows sup­port did a huge leap for­ward com­pared to the pre­vi­ous ver­sion. Thanks to big im­prove­ments in C++11 sup­port in re­cent Vis­ual Stu­dio ver­sions it’s now pos­si­ble to build Mag­num with MSVC 2015 and 2017 and al­so tar­get the UWP plat­form us­ing the AN­GLE OpenGL-to-D3D trans­la­tion lay­er. On the oth­er hand, sup­port for MSVC 2013 and MinG­W32 (the non-w64 ver­sion) was dropped to sim­pli­fy main­te­nance ef­forts.

To make de­vel­op­ment and de­pen­den­cy han­dling on Win­dows even eas­i­er, Mag­num now has Vcp­kg pack­ages, which al­low you to in­stall it to­geth­er with all de­pen­den­cies us­ing a sin­gle com­mand:

vcpkg install magnum

Pack­ages in­stalled us­ing Vcp­kg can be used straight away in Vis­ual Stu­dio — all you need to do is to #include the head­ers you want, the buildsys­tem will do all need­ed li­brary link­ing and set­up be­hind the scenes au­to­mat­i­cal­ly. (Cool, isn’t it?)

It’s of course al­so pos­si­ble to use Vcp­kg-in­stalled pack­ages with CMake. See the doc­u­men­ta­tion for de­tails.

UTF-8 ev­ery­where

Among oth­er no­table things is im­proved Uni­code sup­port on Win­dows. In line with the UTF-8 Man­i­fes­to, all Mag­num APIs were de­signed to ex­pect strings and paths en­cod­ed in UTF-8. This is now work­ing prop­er­ly al­so on Win­dows — as long as you use Mag­num APIs such as Util­i­ty::Di­rec­to­ry or Trade::Ab­strac­tIm­porter to ac­cess the filesys­tem, Win­dows wide-char APIs will be used be­hind the scenes to en­sure prop­er path en­cod­ing.

mac­OS im­prove­ments, iOS port

Mag­num is be­ing used in a project that’s tight­ly cou­pled to Ap­ple plat­forms, which means the code now runs on iOS as well. Plat­form::Sdl2Ap­pli­ca­tion was up­dat­ed for Reti­na sup­port and oth­er iOS-spe­cif­ic fea­tures.

There’s al­so a new Plat­form::Win­dow­lessIos­Ap­pli­ca­tion that’s use­ful for run­ning head­less OpenGL tests on iOS. The Test­Suite li­brary now pro­vides in­te­gra­tion with Xcode and XCTest so you can run tests di­rect­ly from the IDE. The cor­rade_ad­d_test() macro is al­so able to do all the nec­es­sary boil­er­plate to al­low you to run your tests di­rect­ly on an iOS de­vice or sim­u­la­tor sim­ply by run­ning CMake ctest from the com­mand-line.

To make life eas­i­er for mac­OS users, there are now Home­brew pack­ages that you can in­stall sim­ply by typ­ing

brew install mosra/magnum/magnum

You can al­so add all Mag­num pack­ages as a tap, see the doc­u­men­ta­tion for more in­for­ma­tion.

Broad­er test­ing ca­pa­bil­i­ties

Mag­num was in­volved in a project that was all about pro­cess­ing of im­age and spa­tial da­ta. Thanks to that, the Test­Suite li­brary re­ceived loads of im­prove­ments to make au­to­mat­ed test­ing a breeze. The test out­put is now col­ored to make it eas­i­er to spot fail­ures and it gained bench­mark­ing ca­pa­bil­i­ties so you can com­pare how your al­go­rithms per­form against base­line im­ple­men­ta­tions — us­ing CPU time, wall clock time, in­struc­tion counter or any cus­tom mea­sured quan­ti­ty such as amount of al­lo­cat­ed mem­o­ry.

Starting InvSqrtBenchmark with 4 test cases...
 BENCH [1]   8.24 ± 0.19   ns naive()@499x1000000 (wall time)
 BENCH [2]   8.27 ± 0.19   ns naive()@499x1000000 (CPU time)
 BENCH [3]   0.31 ± 0.01   ns fast()@499x1000000 (wall time)
 BENCH [4]   0.31 ± 0.01   ns fast()@499x1000000 (CPU time)
Finished InvSqrtBenchmark with 0 errors out of 0 checks.

Be­sides the al­ready men­tioned iOS test­ing, there are sim­i­lar im­prove­ments for An­droid — the cor­rade_ad­d_test() can em­ploy adb to up­load the test ex­e­cutable to­geth­er with all bun­dled files to a de­vice or em­u­la­tor, run it there and re­trieve the re­sults just as if you would be run­ning the tests on your lo­cal ma­chine.

The test suite is now able to han­dle in­stanced tests (or, in oth­er words, da­ta-driv­en tests). Lots of at­ten­tion was put in­to fuzzy com­par­i­son — from sim­ple nu­mer­ic com­par­i­son us­ing Test­Suite::Com­pare::Around to com­par­ing im­age da­ta to a ground truth with er­ror thresh­olds us­ing De­bug­Tools::Com­pareIm­age. Be­cause prop­er vi­su­al­iza­tion of large da­ta is es­sen­tial for pro­duc­tiv­i­ty, the lat­ter is able to print ASCII art vi­su­al­iza­tion of the dif­fer­ence so you can see what’s wrong di­rect­ly from your CI log:

Starting ProcessingTest with 1 test cases...
  FAIL [1] process() at …/debugtools-compareimage.cpp on line 77
        Images actual and expected have max delta above threshold, actual 189
        but at most 170 expected. Mean delta 13.5776 is below threshold 96.
        Delta image:
          |                                |
          |                                |
          |         ~8070DNMN8$ZD7         |
          |       ?I0:   :++~.  .I0Z       |
          |      7I   ?$D8ZZ0DZ8,  +?      |
          |     ~+   +I        ,7NZZ$      |
          |     :    ~                     |
          |     .    .                     |
          |     ,    :                     |
          |     ~.   +.         +ID8?.     |
          |      ?.  .Z0:     +0I  :7      |
          |      .$$.  ~D8$Z0DZ.  =Z+      |
          |        =8$DI=,. .:+ZDI$        |
          |           :70DNMND$+.          |
          |                                |
          |                                |
        Top 10 out of 66 pixels above max/mean threshold:
          [16,5] #000000ff, expected #fcfcfcff (Δ = 189)
          [16,27] #fbfbfbff, expected #000000ff (Δ = 188.25)
          [15,27] #f2f2f2ff, expected #000000ff (Δ = 181.5)
          [17,5] #000000ff, expected #f1f1f1ff (Δ = 180.75)
          [15,5] #000000ff, expected #efefefff (Δ = 179.25)
          [17,27] #eeeeeeff, expected #000000ff (Δ = 178.5)
          [22,20] #000000ff, expected #e7e7e7ff (Δ = 173.25)
          [18,23] #060606ff, expected #eaeaeaff (Δ = 171)
          [18,9] #e5e5e5ff, expected #040404ff (Δ = 168.75)
          [21,26] #efefefff, expected #0f0f0fff (Δ = 168)
Finished ProcessingTest with 1 errors out of 1 checks.

Base class for tests re­quir­ing OpenGL con­text is now avail­able in a ded­i­cat­ed OpenGLTester li­brary and it gained sup­port for GPU time bench­marks. For eas­i­er test­ing on OpenGL ES and We­bGL, there are now De­bug­Tools::buf­fer­Sub­Da­ta() and De­bug­Tools::tex­ture­SubIm­age() helper util­i­ties that sup­ple­ment the lack of Buf­fer::da­ta() and Tex­ture::im­age() on those plat­forms.

To en­sure sta­bil­i­ty and make main­te­nance eas­i­er, Mag­num and all its li­braries are now al­so com­piled and test­ed with code cov­er­age on all sup­port­ed plat­forms — see the Build Sta­tus page for the whole test­ing ma­trix. This al­so means that ev­ery sub­mit­ted pull re­quest gets au­to­mat­i­cal­ly test­ed for re­gres­sions, stream­lin­ing the whole re­view process.

There’s much more to men­tion re­gard­ing test­ing — it’ll be a part of a more de­tailed blog post in the fu­ture, stay tuned!

Ex­per­i­men­tal UI li­brary

Some years ago I was re­spon­si­ble for UI ren­der­ing in a project that fo­cused on vi­su­al­iz­ing large amounts of tex­tu­al and plot da­ta. The new ex­per­i­men­tal Mag­num::Ui li­brary builds on the knowl­edge gained dur­ing that project and its de­sign goal is be­ing ale to ren­der huge UIs (such as ed­i­tors) fast while stay­ing ful­ly cus­tom­iz­a­ble and easy to use for quick pro­to­typ­ing.

Due to its heavy use of uni­form buf­fers and in­stanc­ing it’s re­quir­ing at least OpenGL ES 3.0 (or We­bGL 2.0). The cur­rent state is very ex­per­i­men­tal — it will grad­u­al­ly sta­bi­lize, gain more wid­gets and get doc­u­ment­ed in the next months. You can see how it looks in the UI Wid­get Gallery, it was al­so used to pro­vide some knobs and tog­gles for the Area Lights de­mo:

Magnum::Ui Gallery screenshot
Mag­num::Ui Gallery we­bgl2 ui
A gallery of var­i­ous wid­gets (but­tons, la­bels, in­puts, modals) pro­vid­ed by the Mag­num::Ui li­brary.

As­set man­age­ment im­prove­ments

A large new fea­ture is sup­port for com­pressed im­ages — load­ing them from files, up­load­ing and down­load­ing them from tex­tures; plus there are new in­ter­faces in Trade::Ab­strac­tIm­age­Con­vert­er ready for in­te­grat­ing var­i­ous GPU com­pres­sion li­braries. To­geth­er with com­pressed im­ages Mag­num gained sup­port for var­i­ous pix­el stor­age op­tions in the Pix­el­Stor­age class to al­low di­rect ma­nip­u­la­tion of im­age sub-rec­tan­gles, with fur­ther con­ve­nience fea­tures such as Image::slice() planned for the next re­leas­es.

There’s al­so a new util­i­ty called mag­num-im­age­con­vert­er that sim­ply ex­pos­es all ex­ist­ing *Im­porter and *Im­age­Con­vert­er plug­ins on a com­mand line. To­geth­er with a new Any­Im­age­Con­vert­er plug­in it’s able to au­tode­tect source and des­ti­na­tion file for­mats based on ex­ten­sion, so you can eas­i­ly use it in your pipe­line for da­ta con­ver­sion, for ex­am­ple:

magnum-imageconverter image.bmp image.png

Many ex­ter­nal con­tri­bu­tions went in­to as­set man­age­ment and con­ver­sion — you can now use the As­simpIm­porter plug­in to load about 40 new scene for­mats us­ing the As­simp li­brary; the Dev­Il­Im­ageIm­porter plug­in us­es Dev­IL to load 40 new im­age for­mats. Ini­tial work went in­to cam­era and light prop­er­ty im­port, with sup­port in the As­simp and OpenGEX im­porter.

Among the oth­ers there’s a pos­si­bil­i­ty to load DXT-com­pressed tex­tures us­ing DdsIm­porter or con­vert im­ages to PNG and EXR us­ing PngIm­age­Con­vert­er and MiniExrIm­age­Con­vert­er. The StbIm­age­Con­vert­er can now use stb_im­age_write to out­put HDR and BMP for­mats in ad­di­tion to PNG.

Au­dio li­brary good­ies

The Au­dio li­brary re­ceived HRTF sup­port that’s very im­por­tant for im­mer­sive au­dio in VR, be­sides that it sup­ports many new buf­fer for­mats. The HRTF sup­port is ac­com­pa­nied with a new ex­am­ple and the whole Au­dio li­brary was up­dat­ed to work on the web as well:

Audio example screenshot
Au­dio Ex­am­ple we­bgl1 au­dio
Loads an OGG file and shows how to play spa­tial­ized au­dio with the Mag­num Au­dio li­brary.

Many new de­pen­den­cy-less im­port plug­ins were con­trib­uted — Stb­Vor­bisAudioIm­porter for load­ing OGG Vor­bis files us­ing stb_vor­bis, Dr­WavAu­dioIm­porter and Dr­Fla­cAu­dioIm­porter for load­ing WAV and FLAC files us­ing dr_wav/dr_flac. The WavAu­dioIm­porter plug­in that’s main­tained di­rect­ly in Mag­num re­ceived var­i­ous up­dates, broad­er buf­fer for­mat sup­port and bet­ter er­ror han­dling.

Full con­trol over ini­tial­iza­tion and own­er­ship

While all types in Mag­num are by de­fault ini­tial­ized to a de­fined val­ue, it’s now pos­si­ble to over­ride the be­hav­ior for greater flex­i­bil­i­ty. For ex­am­ple if you will be over­writ­ing all val­ues in a con­tain­er any­way; to avoid un­nec­es­sary mem­o­ry ze­ro­ing in­struc­tions in a tight loop; or to de­fer OpenGL ob­ject ini­tial­iza­tion to a point where a con­text is ready with­out in­tro­duc­ing ad­di­tion­al in­di­rec­tion us­ing point­ers or op­tion­al ob­jects:

/* Generate grid positions */
Containers::Array<Vector3> positions{Containers::NoInit, 16*16};
for(auto& i: positions)
    i = ...;

/* Zero-init the matrix instead of setting it to identity */
Matrix3x3 m{Math::ZeroInit};

/* Defer buffer initialization for later when GL context is ready */
Buffer buffer{NoCreate};

// ...

buffer = Buffer{};

To­geth­er with this it’s now pos­si­ble to trans­fer own­er­ship of all un­der­ly­ing re­sources — wrap­ping ex­ter­nal­ly al­lo­cat­ed ar­rays and pro­vid­ing cus­tom deleters, or, on the oth­er hand, us­ing Con­tain­ers::Ar­ray::re­lease() to re­lease own­er­ship of the al­lo­cat­ed mem­o­ry. There are al­so two new class­es, Con­tain­ers::Stati­cAr­ray and Con­tain­ers::Stati­cAr­rayView, for han­dling stack-al­lo­cat­ed, com­pile-time-sized ar­rays and views on them. New APIs like Con­tain­ers::ar­ray­Cast() or Con­tain­ers::ar­ray­Size() pro­vide fur­ther con­ve­nience util­i­ties:

/* custom allocator functions */
char* allocate(std::size_t);
void deallocate(char*, std::size_t);

// ...

/* Allocate the data and wrap them in a RAII container */
Containers::Array<char> data{allocate(128), 128, [](char* data, std::size_t size) {
    deallocate(data, size);

/* The allocated array is in fact 16 four-component float vectors */
Containers::ArrayView<Vector4> vectors = Containers::arrayCast<Vector4>(data);
for(Vector4& i: vectors)
    // ...

Math li­brary ad­di­tions

The Math li­brary re­ceived a class rep­re­sent­ing Bezi­er curves and a Frus­tum struc­ture. The Math::Ge­om­e­try::In­ter­sec­tion names­pace is ex­tend­ed with frus­tum culling al­go­rithms and fur­ther ad­di­tions are al­ready be­ing worked on.

There’s a new Half type for rep­re­sent­ing 16-bit half-float num­bers. It’s just a stor­age type, pro­vid­ing con­ver­sions from and to float types. In ad­di­tion to the ex­ist­ing _deg/_rad lit­er­als there is a new _h lit­er­al for half-floats and var­i­ous lit­er­als for en­ter­ing hexa­dec­i­mal RGB(A) col­ors in lin­ear RGB or sRGB:

Color3ub a = 0x33b27f_rgb;      // {0x33, 0xb2, 0x7f}
Color4 c = 0x33b27fcc_srgbaf;   // {0.0331048f, 0.445201f, 0.212231f, 0.8f}

There’s much more added for more con­ve­nience and bet­ter fea­ture par­i­ty with GLSL, check out the com­plete changel­og at the end of the ar­ti­cle.

Bet­ter in­ter­op­er­abil­i­ty with 3rd-par­ty code

One of de­sign goals of Mag­num is to be a col­lec­tion of use­ful non-in­tru­sive tools that works well with third-par­ty li­braries — not be­ing a big mono­lith­ic en­gine that takes over ev­ery­thing and forces a par­tic­u­lar work­flow. With this and the fol­low­ing re­leas­es this de­sign goal is be­ing pushed fur­ther than ev­er be­fore.

One com­mon case is that Mag­num is not the on­ly li­brary ac­cess­ing the OpenGL con­text — for ex­am­ple it’s on­ly tak­ing care of da­ta vi­su­al­iza­tion in a big­ger ap­pli­ca­tion that’s writ­ten in Qt. Be­cause OpenGL is a lot of glob­al state, care must be tak­en so li­braries know what state can be trust­ed and what not — that’s han­dled with Con­text::re­set­State(). It’s al­so pos­si­ble to wrap ex­ter­nal­ly cre­at­ed OpenGL ob­jects us­ing *::wrap() and, con­verse­ly, re­lease their own­er­ship with re­lease(). A re­duced ex­am­ple show­ing ren­der­ing in­to QQuick­Frame­buf­fer­Ob­ject:

#include <Magnum/Context.h>
#include <Magnum/Framebuffer.h>
#include <Magnum/Mesh.h>
#include <Magnum/Shaders/Phong.h>
#include <QQuickFramebufferObject>

struct MagnumRenderer: QQuickFramebufferObject::Renderer {
    // ...

    QOpenGLFramebufferObject* createFramebufferObject(const QSize& size) override {
        /* Create Qt framebuffer object and wrap it to use with Magnum APIs */
        auto fb = new QOpenGLFramebufferObject(size, ...);
        _fb = Framebuffer::wrap(fb->handle(), {{}, {size.width(), size.height()}});
        return fb;

    void render() override {
        /* Reset Magnum state tracker after Qt did its job */

        /* Clear the framebuffer and draw a mesh */

        /* Clean up to avoid Magnum state being modified by Qt */

    Framebuffer _fb{NoInit};
    Mesh _mesh;
    Shaders::Phong _shader;

Some­times you may need to ac­cess the un­der­ly­ing APIs that Mag­num is wrap­ping — for ex­am­ple to test out a new fea­ture that hasn’t been ex­posed yet. Both Plat­form::Sdl2Ap­pli­ca­tion and Plat­form::GlfwAp­pli­ca­tion now pro­vide ac­cess to the un­der­ly­ing tool­kit struc­tures. If you need to go even deep­er, you can ditch the *Application class­es com­plete­ly and sim­ply at­tach Mag­num to an ex­ist­ing OpenGL con­text. How to do that with GLFW is shown on a sim­ple tri­an­gle ren­der­ing ex­am­ple.

Sim­i­lar thing is with as­set im­porters — if you need to ac­cess par­tic­u­lar As­simp fea­ture di­rect­ly or parse an OpenGEX ex­ten­sion struc­ture, it’s now avail­able through type-erased importerState() ac­ces­sors. In case of As­simp it’s al­so pos­si­ble to take over an ex­ist­ing As­simp in­stance us­ing open­State(). See re­lat­ed sec­tions in As­simpIm­porter and OpenGex­Im­porter plug­in doc­u­men­ta­tion for de­tails.

Con­ver­sion of math struc­tures from and to ex­ter­nal types was ex­tend­ed to all struc­tures in the Math names­pace, so with prop­er boil­er­plate head­er in­clud­ed it is pos­si­ble to have seam­less in­te­gra­tion with, for ex­am­ple, GLM:

glm::gtc::quaternion a{4.0f, 1.0f, 2.0f, 3.0f};

Quaternion q{a};
Debug{} << q.vector();              // {1.0, 2.0, 3.0}

glm::gtc::quaternion b{q.normalized()};

Even more new stuff

The list of new things doesn’t stop here. It’s im­por­tant to note that all ex­am­ple code is now put in­to pub­lic do­main (or UN­LI­CENSE) to free you from le­gal ob­sta­cles when us­ing the code in your apps. There’s a new ex­am­ple show­ing how to use Par­al­lel Split / Cas­cad­ed Shad­ow Maps and al­so a sim­ple Ob­ject Pick­ing ex­am­ple:

Object picking example screenshot
Ob­ject Pick­ing Ex­am­ple we­bgl2
Show­cas­es us­age of mul­ti­ple frame­buffer at­tach­ments to im­ple­ment ob­ject pick­ing.

There’s al­so a new ex­per­i­men­tal Dart­In­te­gra­tion li­brary be­ing worked on — it in­te­grates the DART Dy­nam­ic An­i­ma­tion and Ro­bot­ics Tool­kit in­to Mag­num in a sim­i­lar way that’s done with the Bul­let Physics li­brary. A first draft is al­ready merged with sec­ond re­vi­sion be­ing cur­rent­ly in the works. This li­brary alone de­serves a blog post on its own — stay tuned!

Up­grad­ing from pre­vi­ous ver­sions

Be­cause there was no mile­stone since 2015, great care was tak­en to main­tain back­wards com­pat­i­bil­i­ty with the 2015.05 ver­sion. De­pend­ing on how big your up­grade jump is, up­grad­ing to 2018.02 should be large­ly source com­pat­i­ble, with dep­re­ca­tion warn­ings is­sued for APIs that were re­placed with new func­tion­al­i­ty.

In con­trast, im­me­di­ate­ly fol­low­ing this re­lease there’s some cleanup work sched­uled — purg­ing of APIs dep­re­cat­ed for a long time and do­ing some re­or­ga­ni­za­tion to make space for new fea­tures, such as Vulkan and SPIR-V sup­port.

Com­plete changel­og

If you sur­vived all the way down here, con­grats! There’s much more and it’s not pos­si­ble to fit ev­ery­thing in this an­nounce­ment. You can find a de­tailed list of changes in ver­sion 2018.02 in the doc­u­men­ta­tion:

Spe­cial thanks

This re­lease wouldn’t be pos­si­ble with­out ex­treme ded­i­ca­tion of nu­mer­ous vol­un­teers:

  • Jonathan Hale (@Squareys) — Ocu­lus VR in­te­gra­tion, We­b­VR ex­am­ple, HRTF sup­port in the Au­dio li­brary; DDS As­simp and Vor­bis im­porters, Area Lights ex­am­ple, GLFW ap­pli­ca­tion, frus­tum culling and much much more
  • Al­ice Mar­ga­troid (@Al­ice­mar­ga­troid) — mul­ti-chan­nel sup­port in Au­dio li­brary, stan­dard con­for­mance, huge im­prove­ments in the WAV im­porter plug­in, dr_wav and dr_flac im­porter plug­ins, Dev­IL im­porter plug­in, var­i­ous bug re­ports, fea­ture sug­ges­tions and much more
  • Kon­stan­ti­nos Chatzi­lyger­oud­is (@costashatz) — on­go­ing work on the DART in­te­gra­tion li­brary and re­lat­ed func­tion­al­i­ty
  • Bill Robin­son (@wivlaro) — shad­ow map­ping ex­am­ple, var­i­ous bug re­ports and sug­ges­tions
  • Ash­win Ravichan­dran (@ashrko619) — Bézi­er curve im­ple­men­ta­tion
  • Michael Di­etschi (@mdi­etsch) — col­ored out­put in Win­dows con­sole, nu­mer­ous bug re­ports
  • Ger­hard de Cler­cq — ini­tial Win­dows RT (Store/Phone) port
  • @sig­man78 — ini­tial MSVC 2017 port, ini­tial ver­sion of Vcp­kg pack­ages
  • Joel Clay (@jclay) — up­dates to Vcp­kg pack­ages

This list is not ex­haus­tive — sor­ry if I for­got about some­body! Over the time there were many more peo­ple re­port­ing is­sues, help­ing with bug­fix­es, giv­ing en­cour­ag­ing and con­struc­tive feed­back or just be­ing hap­py to help each oth­er on the Git­ter chat. Thank you, ev­ery­body, and cheers!