Apple Metal is Apple’s primary computer graphics API, and after depreciating OpenGL, the only graphics API supported and maintained by Apple.

Metal is limited to only Apple operating systems:

  • 🍎 Mac OS
  • 📱 iOS / iPad OS

Metal is also limited to only a few languages, with the rest having to opt for external calls to Objective C/C++ or Swift.

  • Objective C
  • Objective C++
  • Swift

Though despite these limitations, Apple Metal is an extremely elegant, concise, and robust API with decent support on all Apple supported platforms and driver engineers happy to help with any issues that may arise during development. You’ll also find that writing the same code in Apple Metal tends to take significantly fewer lines of code than other graphics APIs like Vulkan or DirectX 12.

I’ve prepared a Github Repo with everything we need to get started. We’re going to walk through a Hello Triangle app in modern C++, a program that creates a triangle and renders it onto the screen.

Setup

First install:

Then type the following in your terminal.

Overview

The following will explain snippets that can be found in the Github repo, with certain parts omitted, and member variables (mMemberVariable) declared inline without the m prefix so their type is easier to see and the examples here can work on their own.

Window Creation

We’re using CrossWindow to handle cross platform window creation, so creating a window and updating it is very easy:

Just note that on iOS, iPad OS, tvOS, and watchOS, the backend API will be **UIKit**, with MacOS using the **Cocoa** windowing API.

Initialize API

Metal Layer

Every Apple Window can have layers attached to it that handle things like OpenGL or Metal.

Device

A Device is the entry point to the Metal API.

Command Queue

A Command Queue functions similarly to other modern graphics APIs, a queue from which you can send graphics function calls to the GPU.

Initialize Resources

Vertex Buffer

Vertex Buffers are blocks of data stored in the GPU that are used to create triangles.

You could describe this data with one big buffer containing everything or with independent arrays for each element in your vertex layout, whichever best fits your use case and performance requirements.

Having them split can be easier to update if you’re changing your vertex buffer data often, which may be useful for CPU animations or procedurally generated geometry.

Index Buffer

Index Buffers are blocks of data stored in the GPU used to describe triangles, each 3 numbers corresponds ot the index of that triangle.

If you’re making triangles, there should be 3 points per triangle in the index buffer, for lines there should be 2, and points only need 1.

Uniform Buffer

Uniform Buffers are blocks of memory describing data that’s meant to be sent to your shader during rendering, such values to control effects, positional matrices, etc.

Shader Libraries

Shader Libraries are unique to Metal, they function as intermediary objects that can perform reflection on those shaders. As the name suggests, you can create uber-shaders, large shaders with different main functions.

Shader Functions are handles to a particular shader function in a shader library.

Pipeline State

Pipeline State describes all the data that’s to be fed into the execution of a raster based graphics pipeline.

Rendering

Render Pass

Render Passes are a combination of Frame Buffer Descriptions for a given set of render calls.

Command Buffer

Command Buffers encode all the draw commands you intend to execute, and once you’re done providing it with calls, can be submitted to the GPU. In that sense a command buffer is analogous to a callback that executes draw functions on the GPU once it’s submitted to the queue.

Destroying Handles

Like most system level programming languages with managed memory models, in Objective C++ you must destroy any objects that you create. This however isn’t the case if automatic reference counting (or ARC) is enabled at some point in your code’s execution with @autoreleasepool.

Conclusion

Metal is arguably the easiest modern computer graphics API to use, with smart defaults and an intuitive API that maps easily to modern GPUs.

Here’s a few other resources to further your understanding of the Metal API:

You’ll find all the source code described in this post in the Github repo here.

https://Alain.xyz | Graphics Software Engineer @ Marmoset.co. Guest lecturer talking about 🛆 Computer Graphics, ✍ tech author.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store