Official Metal and Direct3D Support

Odin now officially supports both the Metal API and Direct3D 11 & 12 out-of-the box! This makes Odin currently the only language that officially supports all of the major graphics APIs: OpenGL, Vulkan, Direct3D11, Direct3D12, Metal, and WebGL 1 & 2.

Metal #


Odin now has NATIVE Metal support, and it is even cleaner than writing it in Objective-C in numerous cases!

Native support means that Odin is directly caling the Objective-C runtime, and not through a wrapper of another language. This means that the Metal package in Odin will have virtually the same performance as Objective-C code. This means you can now write Metal code without being locked into using an Apple-specific language.

Example and Documentation #

You can check out a minimal demonstration of Metal in Odin here:

And the automatically generated package documentation here: package vendor:darwin/Metal documentation.

Metal in Objective-C #

MTLSamplerDescriptor *samplerDescriptor = [[MTLSamplerDescriptor alloc] init];

[samplerDescriptor setSAddressMode: MTLSamplerAddressModeRepeat];
[samplerDescriptor setTAddressMode: MTLSamplerAddressModeRepeat];
[samplerDescriptor setRAddressMode: MTLSamplerAddressModeRepeat];
[samplerDescriptor setMagFilter: MTLSamplerMinMagFilterLinear];
[samplerDescriptor setMinFilter: MTLSamplerMinMagFilterLinear];
[samplerDescriptor setMipFilter: MTLSamplerMipFilterLinear];
[samplerDescriptor setSupportArgumentBuffers: YES];

id< MTLSamplerState > samplerState = [device newSamplerStateWithDescriptor:samplerDescriptor];

[samplerDescriptor release];

// ...

[samplerState release];

Metal in Odin #

samplerDescriptor := MTL.SamplerDescriptor.alloc()->init()


samplerState := device->newSamplerState(samplerDescriptor)


// ...


DirectX #


Example and Documentation #

You can check out a minimal demonstration of Direct3D11 in Odin here:

And the automatically generated package documentation here for both D3D11 and D3D12:

Writing Direct3D code is Odin is really simple! The code will be nearly the same as writing it as if you were using the APIs in native C++ with thanks to the -> operator:

depth_buffer_desc: D3D11.TEXTURE2D_DESC
depth_buffer_desc.Format = .D24_UNORM_S8_UINT
depth_buffer_desc.BindFlags = .DEPTH_STENCIL

depth_buffer: ^D3D11.ITexture2D
device->CreateTexture2D(&depth_buffer_desc, nil, &depth_buffer)

depth_buffer_view: ^D3D11.IDepthStencilView
device->CreateDepthStencilView(depth_buffer, nil, &depth_buffer_view)
sampler_desc := D3D11.SAMPLER_DESC{
	Filter         = .MIN_MAG_MIP_POINT,
	AddressU       = .WRAP,
	AddressV       = .WRAP,
	AddressW       = .WRAP,
	ComparisonFunc = .NEVER,
sampler_state: ^D3D11.ISamplerState
device->CreateSamplerState(&sampler_desc, &sampler_state)