Created
June 5, 2022 19:21
-
-
Save samloeschen/70b9b8f90036db1345aa7e277bbd1e50 to your computer and use it in GitHub Desktop.
d3d11 hello triangle in odin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "core:fmt" | |
import "vendor:directx/d3d11" | |
import "vendor:directx/d3d_compiler" | |
import "vendor:directx/dxgi" | |
import SDL "vendor:sdl2" | |
import "core:unicode/utf16" | |
WINDOW_WIDTH : i32 = 1280 | |
WINDOW_HEIGHT : i32 = 720 | |
SHADERS_PATH : string = "shaders.hlsl" | |
BACKGROUND := [4]f32 { 0.025, 0.025, 0.025, 1.0} | |
vertex_data := [?]f32 { | |
0.0, 0.5, 0.0, 1.0, 0.0, 0.0, | |
0.5, -0.5, 0.0, 0.0, 1.0, 0.0, | |
-0.5, -0.5, 0.0, 0.0, 0.0, 1.0, | |
} | |
VERTEX_STRIDE := u32(size_of(f32) * 6) | |
VERTEX_OFFSET := u32(0) | |
main :: proc () { | |
SDL.Init({ .VIDEO }) | |
defer SDL.Quit() | |
SDL.SetHintWithPriority(SDL.HINT_RENDER_DRIVER, "direct3d11", SDL.HintPriority.OVERRIDE) | |
window_flags : SDL.WindowFlags = {.ALLOW_HIGHDPI, .HIDDEN, .RESIZABLE} | |
window := SDL.CreateWindow( | |
"Hello Triangle DX11", | |
SDL.WINDOWPOS_CENTERED, | |
SDL.WINDOWPOS_CENTERED, | |
WINDOW_WIDTH, | |
WINDOW_HEIGHT, | |
window_flags, | |
) | |
defer SDL.DestroyWindow(window) | |
window_system_info: SDL.SysWMinfo | |
SDL.GetVersion(&window_system_info.version) | |
SDL.GetWindowWMInfo(window, &window_system_info) | |
assert(window_system_info.subsystem == .WINDOWS) | |
native_window := dxgi.HWND(window_system_info.info.win.window) | |
base_device: ^d3d11.IDevice | |
base_device_ctx: ^d3d11.IDeviceContext | |
create_device_flags: d3d11.CREATE_DEVICE_FLAGS = {.BGRA_SUPPORT} | |
feature_levels := [1]d3d11.FEATURE_LEVEL{._11_0} | |
d3d11.CreateDevice(nil, .HARDWARE, nil, create_device_flags, &feature_levels[0], len(feature_levels), d3d11.SDK_VERSION, &base_device, nil, &base_device_ctx); | |
device: ^d3d11.IDevice | |
base_device->QueryInterface(d3d11.IDevice_UUID, (^rawptr)(&device)) | |
device_ctx: ^d3d11.IDeviceContext | |
base_device_ctx->QueryInterface(d3d11.IDeviceContext_UUID, (^rawptr)(&device_ctx)) | |
dxgi_device: ^dxgi.IDevice | |
device->QueryInterface(dxgi.IDevice_UUID, (^rawptr)(&dxgi_device)) | |
dxgi_adapter: ^dxgi.IAdapter | |
dxgi_device->GetAdapter(&dxgi_adapter) | |
dxgi_factory: ^dxgi.IFactory2 | |
dxgi_adapter->GetParent(dxgi.IFactory2_UUID, (^rawptr)(&dxgi_factory)) | |
swapchain_desc := dxgi.SWAP_CHAIN_DESC1 { | |
Width = 0, | |
Height = 0, // use window width and height | |
Stereo = false, | |
Format = .B8G8R8A8_UNORM, | |
SampleDesc = dxgi.SAMPLE_DESC { | |
Count = 1, | |
Quality = 0, | |
}, | |
BufferUsage = .RENDER_TARGET_OUTPUT, | |
BufferCount = 2, | |
Scaling = .STRETCH, | |
SwapEffect = .DISCARD, | |
AlphaMode = .UNSPECIFIED, | |
Flags = 0, | |
} | |
swapchain: ^dxgi.ISwapChain1 | |
dxgi_factory->CreateSwapChainForHwnd(device, native_window, &swapchain_desc, nil, nil, &swapchain) | |
framebuffer: ^d3d11.ITexture2D | |
swapchain->GetBuffer(0, d3d11.ITexture2D_UUID, (^rawptr)(&framebuffer)) | |
framebuffer_view: ^d3d11.IRenderTargetView | |
device->CreateRenderTargetView(framebuffer, nil, &framebuffer_view) | |
depth_buffer_desc: d3d11.TEXTURE2D_DESC | |
framebuffer->GetDesc(&depth_buffer_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) | |
// convert shaders path string to utf16 | |
fpath := make([dynamic]u16, len(SHADERS_PATH)) | |
utf16.encode_string(fpath[:], SHADERS_PATH) | |
vs_blob: ^d3d11.IBlob | |
d3d_compiler.CompileFromFile(&fpath[0], nil, nil, "vs_main", "vs_5_0", 0, 0, &vs_blob, nil) | |
assert(vs_blob != nil) | |
vertex_shader: ^d3d11.IVertexShader | |
device->CreateVertexShader(vs_blob->GetBufferPointer(), vs_blob->GetBufferSize(), nil, &vertex_shader) | |
ps_blob: ^d3d11.IBlob | |
d3d_compiler.CompileFromFile(&fpath[0], nil, nil, "ps_main", "ps_5_0", 0, 0, &ps_blob, nil) | |
assert(ps_blob != nil) | |
pixel_shader: ^d3d11.IPixelShader | |
device->CreatePixelShader(ps_blob->GetBufferPointer(), ps_blob->GetBufferSize(), nil, &pixel_shader) | |
vertex_desc := [?]d3d11.INPUT_ELEMENT_DESC { | |
{ "POS", 0, .R32G32B32_FLOAT, 0, 0, .VERTEX_DATA, 0 }, | |
{ "COL", 0, .R32G32B32_FLOAT, 0, d3d11.APPEND_ALIGNED_ELEMENT, .VERTEX_DATA, 0 }, | |
} | |
input_layout: ^d3d11.IInputLayout | |
device->CreateInputLayout(&vertex_desc[0], len(vertex_desc), vs_blob->GetBufferPointer(), vs_blob->GetBufferSize(), &input_layout) | |
rasterizer_desc := d3d11.RASTERIZER_DESC { | |
FillMode = .SOLID, | |
CullMode = .BACK, | |
} | |
rasterizer_state: ^d3d11.IRasterizerState | |
device->CreateRasterizerState(&rasterizer_desc, &rasterizer_state) | |
vertex_buffer_desc := d3d11.BUFFER_DESC { | |
ByteWidth = size_of(vertex_data), | |
Usage = .IMMUTABLE, | |
BindFlags = .VERTEX_BUFFER, | |
} | |
vertex_buffer: ^d3d11.IBuffer | |
device->CreateBuffer( | |
&vertex_buffer_desc, | |
&d3d11.SUBRESOURCE_DATA { | |
pSysMem = &vertex_data[0], | |
SysMemPitch = size_of(vertex_data), | |
}, | |
&vertex_buffer, | |
) | |
SDL.ShowWindow(window) | |
for quit := false; !quit; { | |
for event: SDL.Event; SDL.PollEvent(&event) != 0; { | |
#partial switch (event.type) { | |
case SDL.EventType.QUIT: | |
quit = true | |
} | |
} | |
viewport := d3d11.VIEWPORT { | |
0, 0, | |
f32(depth_buffer_desc.Width), | |
f32(depth_buffer_desc.Height), | |
0, 1, | |
} | |
device_ctx->ClearRenderTargetView(framebuffer_view, &BACKGROUND) | |
device_ctx->IASetPrimitiveTopology(d3d11.PRIMITIVE_TOPOLOGY.TRIANGLELIST) | |
device_ctx->IASetInputLayout(input_layout) | |
stride := u32(size_of(f32) * 6) | |
offset := u32(0) | |
device_ctx->IASetVertexBuffers(0, 1, &vertex_buffer, &stride, &offset) | |
device_ctx->VSSetShader(vertex_shader, nil, 0) | |
device_ctx->RSSetViewports(1, &viewport) | |
device_ctx->RSSetState(rasterizer_state) | |
device_ctx->PSSetShader(pixel_shader, nil, 0) | |
device_ctx->OMSetRenderTargets(1, &framebuffer_view, nil) | |
device_ctx->Draw(3, 0) | |
swapchain->Present(1, 0) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct vs_in { | |
float3 position : POS; | |
float3 color : COL; | |
}; | |
struct vs_out { | |
float4 position : SV_POSITION; | |
float3 color : COL; | |
}; | |
vs_out vs_main(vs_in input) { | |
vs_out output; | |
output.position = float4(input.position, 1.0); | |
output.color = input.color; | |
return output; | |
} | |
float4 ps_main(vs_out input) : SV_TARGET { | |
return float4(input.color, 1.0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment