People have been asking me about Vulkan. Maybe you’ve seen it in the gaming news: Vulkan is coming! Vulkan is the next big thing! Developers are excited about Vulkan! Being a naturally curious gamer, you want to know what this new thing is and what it means. So you look it up, and you find something to the effect of:
Vulkan is a graphics and compute API from Kronos Group that provides high-efficiency, cross-platform access to modern GPU.
It’s a definition that explains one thing you don’t know in terms of half a dozen other words you don’t know. All you know is that it has something to do with graphics, and figuring out what this is and why it’s happening is starting to look like more trouble than it’s worth.
Sorry about that. We programmers are really bad at explaining things. We over-use jargon and are generally bad at adjusting explanations for non-technical people. But you’re in luck. While all the other programmers are min-maxers who dumped their skill points into logic and mathematics or whatever, I actually snuck a few points into communication skills. So I think I can untangle this for you.
But we are going to need just a little bit of jargon. Going back to that original definition of Vulkan, there’s at least one mystery term we need to sort out. That’s this one:
API
You don’t actually need to know what this stands for. It doesn’t matter. It’s just an acronym of more jargon”Application Programming Interface”. See? Not very interesting., and if we try to define those terms then we’ll end up needing to define other terms and we’d be here all day. For our purposes, API is just a tool. Or actually it’s a way of using a tool made by other programmers.
See, back in the day – and I mean WAY back in the day – back in the days of big iron, mainframes, and punch cards – back when I was just a wee baby Shamus – most projects were written from scratch. You need to sort a list of stuff in alphabetical order, or handle something the user typed, or print something out? You just sit down and hammer it out yourself. It’s not like you could go on the internet and ask for help. The web didn’t exist yet.
But as time went on, things began to get complicated. So maybe a game developer is working on sound code. In the early days, it’s easy. You just write a little code to have the speaker blurt out one sound. But as the years go on, and games become more complex, you sometimes need to layer many sounds together. And you need sounds to pan between left / right speakers so the player can tell where that monster is coming from. Distance attenuation. Surround sound. Doppler effects. Reverb.
Eventually our hard-working programmer will think to themselves, “Gosh. It sure is a lot of work to add all of these features to my sound code. Hang on. I’m obviously not the first person to write something like this. Lots of other people must have written sound code. Maybe I can use their solution instead of writing my own, and I’ll be able to spend more time working on the game parts of my videogame.” So they go out and see if anyone else has already solved the problem and is willing to share.
Sometimes a programmer will share their solution out of the kindness of their heart. Sometimes they charge money for it. In any case, when a programmer bundles a bunch of code like this for other people to use, it’s called a library. You can think of a library as a black box. You know what it does and how to use it, but you have no idea how it works inside. You can find out if you want, of course. Assuming you’ve got the source code, you can just read it to see how the library works inside. But to a certain extent this would defeat the purpose of using a library in the first place. You don’t want to have to worry about reading someone else’s code. You just want to plug it in and have it work.
So API is how your program talks to this library. It is the control panel by which you manipulate what’s going on inside the black box. Maybe this sound library has a function to begin a new sound or set the volume of the sound effects. But if for some reason the programmer that made the library forgot to add a function to lower the volume, then you wouldn’t be able to do that. Which would kind of make this particular library useless.
The programmers out there are likely freaking out by this point because I’m being sloppy with terms and making broad over-simplifications. But I’m okay with that. This need for precision at all times is one of the reasons they’re sometimes bad at explaining things to non-coders.
There is a certain art to making a good API. You want the controls to be as simple as possible without taking away functionality. A well-designed library should be obvious to use and shouldn’t require you to worry about any messy details of what might be going on inside of that black box.
When you’re using a toaster, you don’t care about the voltage the device is using, the temperature of the heating coils, or the specific electrical resistance being used by the heating elements. You just know you want your toast to be medium. If a toaster forced you to worry about all those details, then the controls would be too complicated. If it just had an on and off button with no way to choose how dark to make the toast, then it would be too simple. A good API should be designed to hit that sweet spot between complexity and features, and it should gracefully hide everything you don’t need to worry about.
But Vulkan isn’t a sound library, and you’ve hopefully already figured out that it’s not a toaster. It’s a graphics library. So now it’s time to talk about just one more bit of jargon:
OpenGL
If you’ve done any PC gaming over the years, you’ve probably heard the term OpenGL, even if you didn’t know what it was or why you should care.
OpenGL stands for Open Graphics Library. It’s a library for making graphics happen. It’s one of only two libraries that can accomplish this. Any game made in the last 20 years or so is going to use either DirectX or OpenGL to draw polygons using your graphics cardYes, there are occasionally obscure examples that don’t use either, but let’s keep this simple.. I don’t care if the game looks like Crysis or Minecraft, somewhere between the game and the stuff that shows up on your monitor, you’ve got either DirectX or OpenGL making those visuals happen. At least, on personal computers. Let’s leave consoles out for now, since that’s another whole can of worms.
The problem with DirectX is that it was created by Microsoft and they decide where it will be available, which tends to be limited to Microsoft devices.
But now you’re asking, “Shamus, what about game engines like Unity, Frostbite, or the Unreal Engine?”
Well, I was hoping you wouldn’t bring this up, but now you’ve forced my hand. Graphics libraries are complicated. So complicated that it’s tempting to take the black box and stick it inside of another box to hide away some of the complexity. If you were to open up the black box of a modern game engine, you’d find they contain either OpenGL or DirectX. Or even both.
Game » Engine » OpenGL » GFX Driver » GFX Card » Monitor » YOUR AMAZED EYEBALLS
OpenGL dates all the way back to 1991. You may notice that this is several years before the first consumer-level graphics cards appeared. I know it’s strange to think about today, but there was a time when games didn’t require special graphics hardware. Games drew their simple graphics using nothing more than the processor that was already busy running the rest of the computer. As you can imagine, this was pretty slow.
Rendering graphics was very different in 1991 than it is today. Few games did 3D graphics, and those that did probably relied on flat-color polygons with no lighting effects. Over the years we’ve introduced texture maps, transparency, lighting, fog, shadows, specular effects, bump mapping, god rays, subsurface scattering, refraction, ambient occlusion, depth of field, motion blur, and dozens of other things. OpenGL grew in complexity as we came up with newer, better, faster ways of drawing things.
More importantly, we keep adding more and more processors to graphics cards, which means they can draw more things at the same time. If you’ve got a kitchen with one chef, it doesn’t matter how you send him the orders, since he can only do one at a time. But if you have fifty chefs then you can theoretically prepare things fifty times faster, but only if you can organize them so the entire group is always busy. So a lot of changes have been made to OpenGL to keep your graphics card as busy as possible. But this means changing the entire way you approach rendering. To do that, the authors of OpenGL needed to add a lot more buttons to the outside of the OpenGL black box. Every few years there was a new gizmo added on, a new way of doing things.
The trick is that you don’t want to remove the old things from OpenGL. You need to leave them there because some people are still using them. Sure, a modern AAA game should not be using the old ways, but OpenGL isn’t just used by AAA studios. It’s used by hobby projects, retro games, old engines, educational projects, and non-game applications like CAD and such. There’s a whole world of different projects out there who use the old bits of OpenGL because they’re so much simpler than the new ways, and because performance isn’t a priority for them.
But adding to a system like this causes a new problem, which is…
Cruft
To explain this, I’m going to have to resort to the time-honored tradition of the terrible car analogy. Let’s imagine there’s this car that’s been modernized over the years. Instead of making a whole new model every few years, they took the existing model and added new stuff to it without ever taking anything away. It began as a Ford Model T in 1908 and they tinkered with it until it had all the capabilities of a fully loaded 2016 Ford Fusion. But like I said above, you can’t remove the old stuff.
So our 2016 Ford Fusion still has that 1908 crank on the front to start the engine. But it’s also got a push-button on the dash that does the same thing. Or you can use the ignition key. Or the remote starter. Or the phone app, but only if you’ve already enabled the Bluetooth systems.
In the 30’s they added an AM radio. In the 1950’s they added another radio that did both AM and FM. A CB was added in the 70’s, along with an 8-track player. Then in the 80’s we got another AM/FM radio, plus a cassette player. A car phone. A CD player. Satellite radio. USB music player. A GPS.
It still has the original kerosene engine in the trunk, and then a gasoline engine under the hood, which can be switched between using leaded and unleaded gas using some levers that are hard to find and confusingly labeled. Or you can use the electric engine. Or you can run in hybrid mode, although hybrid mode only works with the unleaded version of the gasoline engine. That fact isn’t documented, because “everyone knows it”.
The windows still have the old crank controls, but also electric control, although if you switch between the two systems it will get stuck and you won’t be able to close it all the way.
There’s a shifter for the original engine to the left of the driver’s seat, then controls for the automatic transmission on the steering column, then a manual transmission to the right. There are three different sets of headlights, two different sets of turn signals, and five different gauges for reporting the status of the three different gas tanks you have connected to your two different engines.
Try to picture this car in your mind. The controls would be horrendous. There would be so many levers, switches, knobs, and buttons for all of these different systems from all of these various time periods. It would look like some kind of steampunk space shuttle. There would be six ways to do everything and dozens of different, conflicting versions of the user’s manual.
Even if all you want to do is a very simple task – like driving to the store without crashing or breaking any traffic laws – you’ll likely have to deal with all sorts of confusing frustrations as you struggle to figure out which of the half-dozen similarly labeled things actually does the thing you need to do. The interface has become confusing and there are lots of systems – like the old-time AM radio – that nobody wants or needs and that only serve to confuse you when you’re looking for something else.
When a piece of software is under development long enough, this kind of thing tends to happen. When it does, the extraneous stuff is called cruft. OpenGL has accumulated a lot of cruft over the years.
Cruft is a bad thing, but in a strange way it’s also a mark of distinction. OpenGL only got this crufty because it’s been so useful for so long. Most software libraries don’t survive for a quarter century, and it’s to the credit of OpenGL that so many people found it so indispensable for all these years.
It’s not just the software that acquires cruft. The documentation does, too. You’ll find a tutorial saying, “NOTICE! Don’t use (this old system) anymore! From now on, you should use (some other system that’s not nearly as well documented) at ALL TIMES!” This tutorial doesn’t have a date on it, but it’s actually from 2004. It’s all outdated and the “new” way it talks about is now terrible and wrong, because there’s something even newer you should be using. The well of documentation is poisoned, and a generation of young coders are busy soaking up bad habits and destructive advice.
But cruft isn’t just an annoying headache for coders. It’s actually really bad for our games. Because…
Simplicity is Stability
In an ideal world, programs would fall neatly into one of two categories: Either it’s Totally Wrong and it doesn’t work at all, or it’s Totally Correct and it works flawlessly. But there’s a third option that’s actually far worse than being wrong and broken, which is being Nearly Correct.
Nearly Correct is bad because to our programmer it looks indistinguishable from Totally Correct. The programmer moves on, assuming their software works. But because it’s not Totally Correct, it will exhibit problems. Maybe it will run slower than it should. Maybe it will have occasional, inexplicable visual glitches. Maybe it will crash, but only on some systems and in some rare circumstances.
As an API accumulates cruft, the number of “Nearly Correct” solutions increases. More solutions fall into the dangerous “Nearly Correct” zone. It’s easier to create bugs, harder to detect them, much harder to track them down, and impossible to be 100% certain that you’ve done things properly. Each new layer of features brings with it a new layer of confusion and uncertainty.
Now, the obvious solution is to just remove those old controls. Get rid of that old AM radio. And that CB? Who uses those these days? But the problem is that some programmers actually do use the old stuff. They shouldn’t. You’re only supposed to use the most recent features. But programmers don’t want to have to re-write code that works. So then they won’t want to use the new versions of OpenGL, which would split the community and further complicate the documentation, which is already byzantine enough as it is.
So rather than tamper with the existing OpenGL controls, Vulkan is an attempt to wipe the slate clean. Kronos Group – the people behind OpenGL – have gotten rid of the cruft and designed a totally new set of controls for us to use. These controls are designed around the way you’re supposed to render things today, and aren’t hobbled by 1991 paradigms. Rather than trying to get everyone to update all of their old engines, those old engines can continue to use old OpenGL and they’ll work as well as they ever did.
Vulkan is for people making new engines. If it works out, games written under Vulkan will be a little faster and (we hope) less buggy. As of this writing, a few games have been made with it. (Notably Talos Principle, and DOTA.) The real test will come when the really big games start using it: Open world games, shooters, and “cinematic” games built around 3D spectacle.
So that’s Vulkan. You don’t need to worry about it unless it’s your job to worry about it, in which case you should probably get started worrying about it as soon as you can.
Footnotes:
[1] ”Application Programming Interface”. See? Not very interesting.
[2]
[3] Yes, there are occasionally obscure examples that don’t use either, but let’s keep this simple.
Starcraft: Bot Fight
Let's do some scripting to make the Starcraft AI fight itself, and see how smart it is. Or isn't.
Stolen Pixels
A screencap comic that poked fun at videogames and the industry. The comic has ended, but there's plenty of archives for you to binge on.
Crash Dot Com
Back in 1999, I rode the dot-com bubble. Got rich. Worked hard. Went crazy. Turned poor. It was fun.
The Biggest Game Ever
How did this niche racing game make a gameworld so massive, and why is that a big deal?
Black Desert Online
This Korean title would be the greatest MMO ever made if not for the horrendous monetization system. And the embarrassing translation. And the terrible progression. And the developer's general apathy towards its western audience.
Oooooooo. This is almost enough to make me want to start fiddling with programming again. Almost.
To a programmer, learning a new library is like buying that car: a huge investment. Because as crazy as Shamus’ Fusion-T sounded, once you’ve driven it for a couple years, you know where all the knobs you care about are, and even when it’s occasionally okay to poke one of the knobs you normally ignore.
This is part of why Shamus is getting questions about Vulkan now when a game was released on it two years ago. Programmers who were used to driving the old car are still saving up to buy the new one. Some have bought it already, but they’re driving erratically while they figure out the new set of controls. A few lucky people are buying their first car, and won’t ever have to see the old one, except all the documentation they can find will still have big chunks where it explains new knobs in terms of combinations of old knobs and levers rather than what it does. So it will take a good while before people are all driving the new cars, and there will be brief period where a savvy programmer can take advantage of this if they learn how to drive both – they can become driving instructors when some pointy-haired boss buys a fleet of new cars and tells everyone that’s all they get to drive, and all their most experienced workers start driving in circles while they figure out the new controls.
Wow, car analogies are fun.
And a few programmers will drive their brand new library off a cliff and will have to return to driving their old jalopy…
Good writeup – gets a fairly complicated concept through clearly.
Small typo – you call it Vulcan in the last paragraph. Unless you intended to refer to either space logic elves or gatling guns, that’s probably a typo.
Maybe it is a reference to the Roman god of artifice?
“Vulcan” is also the term for a graduate of the University of Hawaii at Hilo (such as yours truly), probably due to all the volcanoes (four active, one dormant, and one extinct) within 50 miles.
I thought it was a continuation of the car metaphors https://en.wikipedia.org/wiki/Aston_Martin_Vulcan
Doom (2016) – how I jate having to do that bracket thing – also uses Vulkan. Which is the german word for volcano, btw.
Derived from Vulcan, who was the Roman god of volcanoes and forges. They borrowed Hephaestos from the Greeks and changed the name, basically.
Its a city in romania.
It’s Norwegian for volcano, too.
Other Germanic languages, too: German, Swedish and Danish. Dutch doubles the a to make it Vulkaan, though.
In Iceland, volcano is eldfjall, fire mountain. :)
I guess Icelandic retains the Old Norse term, while the other Germanic languages took up the Latin one?
I suppose. “Eld” and “fjall” are the Icelandic words for “fire” and “mountain”? It’s “ild” and “fjell” in Norway today. It’s been ages since I watched a Littlefoot movie, but in those movies the dinosaurs would name stuff according to what they looked like. A predator would be a “Sharp-tooth”. I feel certain they called volcanoes ildfjell.
Fire seems to have two separate strains in the Germanic languages.
There’s “eld”/”ild”, which is used in Icelandic, Norwegian, Swedish, Danish.
And there’s “fire” in English, “Feuer” in German, “vuur” in Dutch. Wiktionary says there’s also “fyr” in Swedish and Norwegian, but I have no idea how prevelant it is (I’m a native German speaker with some entry-level Swedish knowledge).
I’m not a linguistic, but I find stuff like that interesting. :)
I love a chance to talk about my language. Mostly, it’s like, who cares, so I appreciate the opportunity. “Fyr” is used occasionally as a translation of “light”. Like “Do you have a light?”/”Har du fyr?” or “Lighthouse”/”Fyrtà¥rn”. Or “to light a fire(bonfire)”/”Fॠfyr pॠbà¥let”. It’s mostly the word you use for a “guy” or a “dude”, though. So we’ve got it, but it’s not the main word.
In both of those situations, you’re still actually asking for fire. If a native English speaker asks you for a “light”, it’s slang for a lighter and he’ll probably be quite ungracious if you give him a flashlight instead.
This is actually one of the rare examples of a conscious effort to expunge a language of loanwords that succeeded, and is still continuing to be successful. Since Icelandic doesn’t have these loanwords anymore, it instead repurposes Old Norse words, either compounding them (as in eldfjall, from eldur + fjall), or by repurposing or modifying older words, such as coining sàmi (“telephone”) from sàma “Ž(“cord”).
What?! Everyone knows API stands for active pharmaceutical ingredient! ;)
I guess this is why people get so confused. My personal pet peeve is when people shorten games titles to the same abbreviation as a previously available game… :)
Particularly this month: “Hey guys, TF2 is on sale for $30!”
Eh what? Oh, right, you mean Titanfall 2….
Or when RPS did an article today about the latest Dishonored 2 patch and referred to it as D2 the entire time. What does Diablo II have to do with this pat… oh right.
…Wait, what’s Diablo 2? I thought you meant Descent II…
:-P
There’s only one D2.
There’s only 36^3 possible three character alphanumerical.
That’s highly locale-dependent (in Swedish, you’d have 39, although people may consider V and W to be the same letter, for a useful 38).
Like Blizzard cleverly naming their MOBA “Heroes of the Storm” (HotS) when they already had a SC2 expansion named Heart of the Swarm (also HotS). >.>
At least we’re on to a new expansion (LotV) now, so it isn’t as confusing as it could have been.
I mean, at least Blizzard acknowledged that it was confusing.
LoL was and always will be Lands of Lore to me. :P
I think you dropped an ‘r’.
No he didn’t. cf. https://www.opengl.org/wiki/Compute_Shader
Alex is right, and this gets into some of the cool things about Vulkan and the way it’s designed to better reflect they way graphics cards are designed and used today, rather than in the 90’s.
It boils down to the fact that graphics cards used to be, basically, dumb state machines that you sent instructions to. Like, “pick up the small paint brush. dip it in the blue paint. draw the following 2,000 triangles: xyz, abc, 123, …, etc.”
Modern graphics cards are almost entirely independent computers, with gigabytes of memory and tons of processing cores, specialized for doing relatively simple calculations on tons of pieces of data simultaneously. This is great for pushing pretty pixels in games, but it also turns out to be great for the kinds of highly parallel math used in machine learning algorithms and neural nets, among other things.
Vulkan is designed to reflect that change, and make it easier to take advantage of the full capabilities of modern GPUs.
Holy crap is that car analogy ever on point for OpenGL. 90% of my problems learning to use it came from all of the conflicting information and incompatible tutorials.
For those of you who don’t know: There are actually APIs which wrap OpenGL, which everybody who writes tutorials for OpenGL seems to use. I don’t mean graphics engines; all they do is wrap the function calls and help with loading OpenGL up, because there are a lot of fiddly bits with OpenGL that make just doing that complicated. So you can have:
GFX Card -> GFX Driver -> OpenGL -> GLEW (The OpenGL Extension Wrangler Library) -> Graphics Engine -> Actual Game
Yup. And those wrapper libraries are at various levels of synchronization with OpenGL itself and the various OSs that they serve. Add the confusion of OpenGL’s various versions and paradigm changes with SDL or GLEW or GLFW’s evolutionary changes over time and you’ve got yourself a real problem trying to learn how to use OpenGL.
And, until recently, you may have been trying to use a tutorial printed in a book that references a particular version of Microsoft Visual Studio that works entirely differently from the versions on either side of it in time or uses features not available in the Express / hippy-freeloader edition.
It killed several attempts on my part to learn OpenGL.
This entire article is a strong argument for stricter API versioning (not just better documentation). Yes, OpenGL has versions, but it seems like they refuse to use the new versions as a chance to deprecate the cruft. Version 2 still has all the commands of Version 1, plus the new ones, and Version 3 does the same to Version 2. My experience with OpenGL was well over a decade ago, so take with a grain of salt, but if I remember correctly you don’t specify a version explicitly when you link the library. Without that, you can’t effectively rid the cruft from earlier forms. My experience with DirectX is roughly half as long ago, but I do remember the targeting being quite explicit, and because of that it wasn’t uncommon for older, outdated features to disappear when you target new versions.
Version 3.3 did actually cut the crust. They deprecated a huge amount of the old stuff to cut the API down to size, this then carried onto later versions. Trouble was, hardware still allowed for older version 1 and 2 stuff so people who didn’t know better didn’t move up onto the newer versions.
I’ve been programming with 3.3 for a few years now and it is actually quite nice for modern rendering, however finding documentation in the sea of version 1 and 2 stuff from decades of internet posts is a nightmare.
Also depends on what profile you’re requesting.
Beginning with OpenGL 3.2, you can request a Core profile, and there you only get the functions that have not been removed. You don’t access to the Fixed Function Pipeline (glBegin()/glEnd()), for example. If you request a Compatibility profile instead, you do have access to these deprecated functions.
AFAIK, only the Core profile is “mandatory”, though. Whether a Compatibility profile is available is implementation-defined and some vendors, Apple for example, don’t implement it. So on macOS, you can choose between OpenGL 2.1 (not getting access to the new stuff) and OpenGL 3.2 Core (not getting access to the old stuff).
I’m not sure what the market penetration of 3.3+ cards is. It has to be pretty high by now, but most games still ship with Direct X 9 modes (which is roughly equivalent to GL 2.x) so there must be a pretty good sized market of people that still have old cards. Most tutorials recommend you stick with 2.x and manually request 3.0+ extensions for the functionality you want.
This is why you just pick up Unity or Unreal 4, honestly. I love building my own engines, but if I want to actually ship a game and have it work on hardware there’s way too much crap to deal with. 2D games excepted.
Sure, versioning allows to create nicer API in the long run. That’s probably why Carmack, who once complained about D3D in the nineties, now say it might be better than OpenGL.
However, if you want to use new features available in SomeAPI 7 but your code use SomeAPI 6, you have to upgrade everything. This might not be possible because you need to support hardware incompatible with SomeAPI 7. Or you need to provide two executable, or wrap the API calls behind an interface… So it is messy and a lot of work.
This is OK for game developers, because once a game is released there is no reason to add new features (unless you are one of these company that sell your game with shiny graphics and want people to talk about the fact that you are one of the first to support DirectX25 effects). So you decide to target some specific version and never look back. But for a company that release a product with a long lifespan and regular updates with new features (think any 3D software), it is just a pain. So being able to upgrade progressively and to access new features while still having legacy code is really helpful.
See also: Lawyers.
In both cases: substantially increased job security. (And diminished social life, which enables longer work hours. )
Also see also; Almost all scientists.
Does anyone know if Vulkan is going to give an open-source, non-GPU-vendor-specific alternative to CUDA?
Isn’t that what OpenCL is?
Yes. But you can also use compute shader in Vulkan or OpenGL. And they now use the same intermediate bytecode for shaders / kernels. I don’t know if OpenCL has any advantage over the graphic API.
All I know, is that when I go to find a package that does math I want on the GPU, it’s always dependent on CUDA. My vain hope is that maybe I’ll see some stuff built on Vulkan in the future
When you're using a toaster, you don't care about the voltage the device is using…
Sure I do. Depending upon what country I’m in and what country my toaster is made in.
Thats kind of the point though – you only care because your toaster isnt a good enough black box to handle voltage differences for you. An ideal toaster would just adjust to whatever voltage you give it to work with.
Precisely. For a good example of something that handles most countries’ voltages: look at the power brick for your laptop, TV, or random gadget in the house. On the certification sticker/plate, it’ll show something like “input: 100 – 240 V, 50 – 60 Hz” which covers pretty much all households in the world. For example (from what I understand) North America is 120V or 110 or 100-ish, depending on the decade and jurisdiction, which is why the power bricks need to go all the way down to 100, not just whatever today’s voltage/standard is. Also note that the frequency is different in Europe vs North America – which is why you get flickery video when filming a lamp in Europe with a NA camera.
This is the programming-explaning I dream and wait for on Twenty Sided. Thank you so much! As a non-coder taking his first steps to learn coding, these little drops are invaluable.
I mean, mostly invaluable. I’m starting with Swift 3 language & the Xcode IDE on macOS and will likely eventually deal with Apple’s Metal API. But still, wrapping my head around the core concepts as I tangle with even the smallest hurdles in higher level programming are valuable in an indirect way.
Oh poor guy, I hope someone will give you a real OS and a language and framework for real work soon. Seriously, if they’re forcing Swift on you they might as well teach you Fortran. Hell, with Fortran you can at least get a job in scientific programming.
I too, really appreciate these long-form tech-centric posts! :)
The programmer’s quote never ends, btw.
I prefer to think of it as a metaphor. There is always something annoying about the library you are currently using so, like the quote, the quest for the perfect library never ends.
I may be reading too deeply into things…
The programmer was talking the whole time… woooOOOOooooo…
It’s actually very appropriate that the quote doesn’t end in a sense because very often the sentiment there will derail into a long tangent.
Vulcan and Jai. The future is an exciting place!
Wait, what, you code with dark text on a light background?
https://drmccoy.de/zeugs/desktop_20160420.png
That looks familiar… is that WindowMaker?
Mine, BTW: on KDE.
No, Enlightenment DR16. Been using that for 15+ years now :)
Couple of points:
* You say DirectX and OpenGL were the only 2 graphics options. I’m pretty sure there were some other custom ones (particularly during the early 3D hardware jousting, when it wasn’t clear who would win) that have subsequently died off, and recently there have been a spate of “new architecture” libraries that seek to cut out a lot of the bloat, like Vulkan does — Metal (for iOS) and Mantle (for AMD hardware), as a couple of examples. But that’s picking a nit — what you said is mostly true.
* I’m also pretty sure OpenGL was not used in early, software-rendered games. I don’t think OpenGL saw wide use until after Quake. In fact, OpenGL was developed by Silicon Graphics for use on their dedicated graphics hardware for doing commercial CAD work, primarily.
Well, Mantle kinda of lives on: it was the basis for Vulkan. From what I hear, when the Khronos Group was starting looking into a more low-level API, AMD basically approached them and offered them Mantle, no strings attached.
Say what you will about AMD, and as a long-term Linux user who used to have a laptop with an AMD (well, then ATI) card I have Opinions(TM) about nVidia vs AMD driver quality, but they are relatively open about their tech.
Ah, the nVidia vs AMD flamewars on GOL are a thing of beauty.
Still, if Vulkan will support Windows (main install base for games) and Linux (scrappy underdog with lots of hope) compared to Metal’s macOS/iOS (ultimate walled garden for hipsters) there’s little doubt which one will be more popular in my eyes.
I believe Apple is counting on iOS to push Mantle. It might work because there is a lot of games targeted at this platform. Or people will keep using OpenGL. Or Molten ?
Also, I think you partially miss the point of Vulkan, or at least forget the main difference between OpenGL and Vulkan.
Vulkan is not necessarily the one true way to do things now. AFAIK, the Khronos group doesn’t want to deprecate OpenGL in favour of Vulkan. They expect Vulkan and OpenGL to live side-by-side, serving different clientele.
The main difference between OpenGL and Vulkan is that Vulkan gives you fuller, more low-level access to the graphics hardware, while OpenGL abstracts more. And Vulkan requires you to go low-level, and do all the work yourself. OpenGL gives you quick and easy access, by abstracting all the fiddly details away [1], Vulkan doesn’t.
Just to get a plain, untextured triangle displayed, you need to write pages upon pages of code. With new OpenGL (i.e. VBO/IBO), it’s just half a page, with old OpenGL (glBegin()) just a few lines.
On the plus side, giving you more control also has the potential of higher performance (because you’ll only pay for what you use, while OpenGL abstractions very often give you more than you need) and more flexibility (leading to new effects, interesting new approaches, etc.).
However, it’s of course not a given. Depending on how your data is structured and what exactly you do, your code could be even worse performing.
This doesn’t really mesh with the comparison between Direct3D and OpenGL anymore though, because AFAIK, Direct3D 12 is also a low-level approach like Vulkan (and Metal on macOS).
[1] Yes, the abstractions grew and are in parts leaky and horrible, too
I was about to say it. Now that GPUs are similar general-purpose processors and evolve much more slowly than before, it is possible to create APIs that are closer to the hardware, with less abstractions. The result is somewhat simpler but not necessarily easy to use. For instance, Vulkan gives a direct access to GPU memory, which allows to do funny stuff (and awesome optimizations), but requires you to deal with synchronization (which is a pain).
In the end, the goal is not really to create a simpler API (for the user). Vulkan is really technical and probably not a good entry point for beginners. That’s why Kronos will still support OpenGL. Vulkan is really designed for advanced users that want to push the hardware to the limit.
Also, Shamus, you could have told that OpenGL and Vulkan are not libraries, but just APIs. This is interesting because it mean there is several different implementations of them. Typically one per hardware vendor. So AMD, NVidia, Intel, Apple and so on all have different implementations, with slightly different behavior.
This is actually the real problem with OpenGL. When you have a good, up to date documentation about OpenGL (like the OpenGL wiki) it is not so hard to find what are the “good” features and what is deprecated. (Finding the “fast path” is another story.) But dealing with all the discrepancies of the different implementations is a nightmare.
Vulkan is a much simpler API than OpenGL at the driver level. It is not supposed to do anything smart. Basically, it should mostly forward every calls to the GPU. That way, there is much less chances of incompatibilities between vendor. Plus I believe Kronos planned to some validation tools to check the conformity of the implementations, so this should help.
And not just that, they have different implementations on different platforms, too. From what I remember, Intel has completely separate teams for their Windows driver and their Mesa-based Linux driver, even. And while Mesa is a common implementation on Linux, both AMD’s and Nvidia’s closed driver have their own. Really quite messy. :)
I started freaking out in the paragraph before you said programmers were going to freak out. So well predicted I suppose.
When I was a kid my dad (an embedded systems programmer) used to explain his job in terms of devices “talking” to each other. Didn’t make any sense at the time, but now that I know more about computers, it makes perfect sense. I don’t know, maybe it would have been a good explanation if I had been a little older. Like when he tried to use algebra to explain a “Jim has 4 apples and Jim and Joe have 13 apples together” type problem to my 8 year old self, without bothering to explain what algebra was.
Also I use white text on a dark background when programming and nothing else is acceptable. FIGHT ME.
The distinction between Totally Correct and Nearly Correct reminds me of a classic saying… If a program appears to work, it falls into one of two categories: Obviously Not Flawed, or Not Obviously Flawed.
The first category only exists for toy examples used to teach programming syntax. Anything interesting that seems to work is Not Obviously Flawed. That said, anything you can do to push your code towards Obviously Not Flawed is likely to help at some point.
The sad thing is, the older versions really do seem more straightforward. Which is why I’ve been using them. >_>
I’m making a 2d game and don’t see why I should have to act as if I’m rendering a zillion polygons in a 3d world. Of course, maybe that just means I should be using an engine instead of manipulating OpenGL directly. :P
Also, it’s not at all clear how compatibility works. If I use OpenGL 2.0, will it work on a card that supports 4? If I use 3, on the other hand, it won’t work on low-end laptops. If I want the broadest possible compatibility for my graphically non-demanding game, I kind of have to do it the “wrong” way regardless.
So, maybe this is all a good thing. But I kind of lament the loss of accessibility.
Another great article Shamus! I now understand what Vulkan is clearly, even though I’m not a programmer.
Also, that car analogy was beautiful. A real work of art. It completely encapsulates the frustration I get when I have a new thing and can’t figure out how to do X, where X is something trivial and simple. One of my favorites on this site, right up there with how you compared Oblivion to a strangely-designed sports car WAAAY back in 2006-ish.
Great article!
(I shared it on HN, so if your server crash because of people coming from there, you know it’s me =) )
Interesting etymological fact about cruft: it’s crust, but from a time so long ago that the “s”s look like “f”s. example
Aw, I was looking forward to an in-depth discussion of Warhammer 40K Lore about the Primarch of the Salamnders, especially with the new information revealed by The Beast Arises series.
I mean… I could read the first few paragraphs of this before the cut, and it very clearly wasn’t about any of that, but I still had hope.
Vulkan lives!
Thank you, Shamus. This was very informative, interesting, and easy to understand as well. One of those is rare enough, but all three at once was a real treat to read.
I’d add the horrible car analogy that Vulkan is a lot more like driving a manual than an automatic. Vulkan is extremely, extremely, extremely fiddly. It takes a ton of effort to do something that’s basic Open GL (with the tradeoff that this means you can have less overhead because you only use the parts you need).
For technical people, I think their example “display a triangle” program was 1000 lines long. You have to do a ton of legwork like manually querying device information, asking for buffers, and setting up the rendering pipeline and draw call batching yourself. I’ve worked with it. I do not recommend working with it unless it’s for fun. DO NOT MAKE A GAME IN VULKAN IF YOU WANT TO SHIP IT IN A REASONABLE TIME FRAME.
For non-technical people, it’s about the difference between getting furniture from Ikea versus buying a used Ikea couch off Craigslist. It’s more time consuming and confusing, but you’re able to assemble it the way you need it and have a new couch, rather than being at the mercy of some college student who was stoned while putting it together.
Edit: Since we’ve already defined the OpenGL jargon, I’d add that Vulkan is, in its essence, “so you want the tools to write your own version of OpenGL that’s more suited to your program”. There’s a bunch of fiddly extra details about multithreading and stuff, but they’re irrelevant for the purposes of explaining it to non-technical people.
I’m curious how much you’ve actually played around with Vulkan Shamus. I’ve skimmed the documentation and read the Vulkan Programming Guide and when they say “low level” they are not kidding. I’d love a programming post about it once you’re done with your other five billion projects!
I’d love to see an old-school practiced GL programmer play with Vulkan and actually explain what half of these buffers and hardware requests mean to me. I’ve used it, but some of this stuff is poorly documented and inscrutable unless you have a pretty detailed knowledge of graphics cards that only comes from experience.
Web Host troubles not withstanding, I think this does seem a viable answer to Shamus’ earlier question of how to bring in new readership. As he pointed out in his Art Coder article, he is in an interesting position of understanding the technical and being able to communicate it to non technical people. I think this is something that is sorely lacking on the internet. It might be a good aspect for Shamus to capitalize on.
I balked at the length and dry subject matter, but I do feel like I got it when you explained it in these terms.
ugh, more technology and programming posts? Can we do less of these, and more snarking about silly trends in video game output?
No. There aren’t enough of these posts as it is.
If you want other stuff, go elsewhere.
When I took up Java a couple of years ago, I decided to learn to code GUIs by hand rather than use an IDE with drag-and-drop, WYSIWYG capability. I thought that I would learn and understand more that way. How silly of me. Nevertheless, I’ve been hand-coding GUIs using the Swing API ever since. While I can honestly say that I have learned to produce GUIs that look and function the way that I want them to–well, mostly–I doubt that I am any closer to honestly understanding GUIs now than I would have been if I had gone the drag-and-drop route. The reason, of course, is that I’m using the Swing API, which does all the really hard work for me. I understand primitives. I understand classes and methods and objects. I do not understand graphics at all. (The last time I did was over 25 years ago when I used BASIC to draw dots and lines on the screen of an Apple IIc.) But thanks to Swing, I don’t need to understand graphics. Swing does that for me. I just need to tell Swing what the graphics–be they windows, drop down menus, text boxes, or what have you–should look like and Swing draws them for me.
The interesting thing about Swing is that, to judge by Oracle’s documentation, it is built on top of an older API for GUIs called the Advanced Windows Toolkit, or AWT. I know nothing of AWT, but most Swing classes ultimately inherit from one or more AWT classes. I’m not sure exactly why Oracle (or whomever) decided to build a new API on top of an older one, but the idea that AWT might somehow be less convenient than Swing is a little scary. There’s a third Java API for GUIs called JavaFX but that isn’t supported by the OpenJDK so I haven’t looked at it too closely.
Okay, so basically AWT is a Java interface to native system GUI code present in your OS. It will not work the same on every system, although it tries.
Swing is a more-or-less pure-Java GUI. It uses AWT to create an operating system window and then paints pictures of buttons, labels, text, checkboxes, etc., into that window and responds to all of your mouse-clicks, key entries, etc., deciding for itself what to do instead of letting the operating system handle it. Thus Swing is 100% portable and is the same across platforms (although it is skinnable and has a “pluggable look and feel” that can make it look more or less like how the native windows and widgets would look).
Because Swing tries to do everything possible in Java other than the very raw graphics routines provided by a native GUI window, it’s a fair bit slower than AWT.
Neither of those allow you to shove stuff off to the GPU, so for anything performant you should use something like JOGL or LWJGL; or even better, a lower-level language.
Hey, thanks! That was really interesting. Portability is important to me, since I want the programs I write to work on both my various Linux machines and my wife’s Windows laptop. Portability–and the fact that Swing has some very useful online documentation–are the reason that I decided to learn Java and Swing rather than C++ and, say, GTK or QT. Most of the programs I write are simple–a time-tracking application, a random password generator–or frivolous–a program for planning character builds in the [i]Shadowrun Returns[/i] games–and speed isn’t much of an issue.
@Shamus “Form now on, you should use” that should probably be “From” ?
Also, “But programmers don't want to have to re-write code that works.”
You forgot to mention that in some cases a piece of software is no longer actively being developed and the user may be unable to (or unable to afford) to upgrade the software.
I guess you could call this legacy software, but sometimes some companies abandon a software just months later and you are stuck with “old” OpenGL being used and you have to pay a lot to use the new one. And in some case users like the old version so much they refuse to update to a newer version.
Wow, that’s one amazing, hilarious, and also absolutely spot on car analogy!
@Shamus if you use the dev console in your browser your website is sitting out debug info:
“JQMIGRATE: Migrate is installed, version 1.4.1”
A quick google turned up this: https://github.com/jquery/jquery-migrate/blob/master/warnings.md
“The use jQuery Migrate in production has performance impacts and can complicate debugging as it modifies the normal behavior of the version of jQuery being used.”
That’s on purpose. The idea of jQuery Migrate is that you get access to the previous way of doing things (so you don’t need to rewrite old code) while using a newer version of jQuery.
The performance impact is actually quite minimal provided you aren’t doing complex stuff. Which this site isn’t. It’s not a problem at all. And Shamus probably knows, anyways.
(Incidentally this actually relates to the article. One way to deal with cruft is to dump it out but create a separate optional package that people can choose to add to get their old functionality back)
I really appreciate the explanation. I unfortunately can’t tell whether it’s my job to worry about it, since I’m still learning to use an engine. I do worry about low-level performance and such, it just isn’t always clear which low-level stuff is practical or worthwhile to mess with. But thank you for helping in case I do need to worry about this!
Clicked the “wee baby Shamus” footnote. Was not disappointed.
Using your great car analogy, this has been my process of trying to learn OpenGL
Tutorial 1, moving the car:
Point the steering wheel the direction you want to go, and press on the gas pedal.
Ok, it’s raining so I need to use the windshield wipers
Tutorial 2, using the windshield wiper:
After using the throttle in the passenger seat to move the car, and making sure that you are in reverse using the 3rd shifter knob to the left, we can finally turn the windshield wipers on.
I haven’t tried Vulkan yet, but I really hope it is as good as everyone says it is.
So I have a copy of the OpenGL Superbible Fifth Edition. I don’t regret buying it, because it taught me the most important lesson about OpenGL I’ve ever learned: OpenGL is for other people, and unless I somehow suddenly have a team of 3D artists working for me, GameMaker Studio and GML is 100% adequate for all my current needs.
Whenever I’m tempted to try to spend time learning something similar, I just look at that book to remind me I’m not a full-time programmer yet and I don’t have the time to learn it. Worth every penny.
Hmm… I’ve not seen the insides of a PC before about 1994 but at that point every consumer-level PC had a graphics card becuase on-board graphics was not a thing that existed… remember upgrading my mum’s PC to a Cirrus Logic card with a whole megabyte of RAM. That allowed it to display up to 1024×768, with 256 colours! More than any sensible monitor could display without interlacing. Huge step up from the 640×480, 16 colours we’d had before.
… the thing that actually was not available until later in the nineties was 3D acceleration. I paid an incredible sum for my first PC in 1997, and over a third of that was for the much-lauded Diamond FireGL 1000 pro — which was completely outclassed by much cheaper devices only a year or two later. Worst investment ever.
So Mass Effect 3’s Crucible was naturally full of Cruft, explaining the blast away panels and the spinning arms!
I’m no programmer, but that was an interesting read. Talos Principle was awesome, for the record.