Bladeren bron

Some more interface shenanigans

Karl Zylinski 6 maanden geleden
bovenliggende
commit
11c9709c4e
3 gewijzigde bestanden met toevoegingen van 243 en 259 verwijderingen
  1. 141 173
      backend_d3d11.odin
  2. 13 0
      karl2d.odin
  3. 89 86
      window_win32.odin

+ 141 - 173
backend_d3d11.odin

@@ -13,36 +13,14 @@ import "core:mem"
 import hm "handle_map"
 import "base:runtime"
 
-
 @(private="package")
 BACKEND_D3D11 :: Rendering_Backend_Interface {
-	state_size = d3d11_state_size,
-	init = d3d11_init,
-	shutdown = d3d11_shutdown,
-	clear = d3d11_clear,
-	present = d3d11_present,
-	draw = d3d11_draw,
-	
-	get_swapchain_width = d3d11_get_swapchain_width,
-	get_swapchain_height = d3d11_get_swapchain_height,
-
-	set_internal_state = d3d11_set_internal_state,
-
-	load_texture = d3d11_load_texture,
-	destroy_texture = d3d11_destroy_texture,
-
-	load_shader = d3d11_load_shader,
-	destroy_shader = d3d11_destroy_shader,
-}
-
-@(private="file")
-s: ^D3D11_State
 
-d3d11_state_size :: proc() -> int {
+state_size = proc() -> int {
 	return size_of(D3D11_State)
-}
+},
 
-d3d11_init :: proc(state: rawptr, window_handle: Window_Handle, swapchain_width, swapchain_height: int, allocator := context.allocator) {
+init = proc(state: rawptr, window_handle: Window_Handle, swapchain_width, swapchain_height: int, allocator := context.allocator) {
 	hwnd := dxgi.HWND(window_handle)
 	s = (^D3D11_State)(state)
 	s.allocator = allocator
@@ -159,9 +137,9 @@ d3d11_init :: proc(state: rawptr, window_handle: Window_Handle, swapchain_width,
 		ComparisonFunc = .NEVER,
 	}
 	s.device->CreateSamplerState(&sampler_desc, &s.sampler_state)
-}
+},
 
-d3d11_shutdown :: proc() {
+shutdown = proc() {
 	s.sampler_state->Release()
 	s.framebuffer_view->Release()
 	s.depth_buffer_view->Release()
@@ -188,133 +166,20 @@ d3d11_shutdown :: proc() {
 
 	s.device->Release()
 	s.info_queue->Release()
-}
-
-d3d11_set_internal_state :: proc(state: rawptr) {
-	s = (^D3D11_State)(state)
-}
-
-d3d11_get_swapchain_width :: proc() -> int {
-	return s.width
-}
-
-d3d11_get_swapchain_height :: proc() -> int {
-	return s.height
-}
-
-D3D11_Shader_Constant_Buffer :: struct {
-	gpu_data: ^d3d11.IBuffer,
-}
-
-D3D11_Shader :: struct {
-	handle: Shader_Handle,
-	vertex_shader: ^d3d11.IVertexShader,
-	pixel_shader: ^d3d11.IPixelShader,
-	input_layout: ^d3d11.IInputLayout,
-	constant_buffers: []D3D11_Shader_Constant_Buffer,
-}
-
-D3D11_State :: struct {
-	allocator: runtime.Allocator,
-
-	width: int,
-	height: int,
-
-	swapchain: ^dxgi.ISwapChain1,
-	framebuffer_view: ^d3d11.IRenderTargetView,
-	depth_buffer_view: ^d3d11.IDepthStencilView,
-	device_context: ^d3d11.IDeviceContext,
-	depth_stencil_state: ^d3d11.IDepthStencilState,
-	rasterizer_state: ^d3d11.IRasterizerState,
-	device: ^d3d11.IDevice,
-	depth_buffer: ^d3d11.ITexture2D,
-	framebuffer: ^d3d11.ITexture2D,
-	blend_state: ^d3d11.IBlendState,
-	sampler_state: ^d3d11.ISamplerState,
-
-	textures: hm.Handle_Map(D3D11_Texture, Texture_Handle, 1024*10),
-	shaders: hm.Handle_Map(D3D11_Shader, Shader_Handle, 1024*10),
-
-	info_queue: ^d3d11.IInfoQueue,
-	vertex_buffer_gpu: ^d3d11.IBuffer,
-
-	vertex_buffer_offset: int,
-}
-
-Color_F32 :: [4]f32
-
-f32_color_from_color :: proc(color: Color) -> Color_F32 {
-	return {
-		f32(color.r) / 255,
-		f32(color.g) / 255,
-		f32(color.b) / 255,
-		f32(color.a) / 255,
-	}
-}
+},
 
-d3d11_clear :: proc(color: Color) {
+clear = proc(color: Color) {
 	c := f32_color_from_color(color)
 	s.device_context->ClearRenderTargetView(s.framebuffer_view, &c)
 	s.device_context->ClearDepthStencilView(s.depth_buffer_view, {.DEPTH}, 1, 0)
-}
-
-D3D11_Texture :: struct {
-	handle: Texture_Handle,
-	tex: ^d3d11.ITexture2D,
-	view: ^d3d11.IShaderResourceView,
-}
-
-d3d11_load_texture :: proc(data: []u8, width: int, height: int) -> Texture_Handle {
-	texture_desc := d3d11.TEXTURE2D_DESC{
-		Width      = u32(width),
-		Height     = u32(height),
-		MipLevels  = 1,
-		ArraySize  = 1,
-		// TODO: _SRGB or not?
-		Format     = .R8G8B8A8_UNORM,
-		SampleDesc = {Count = 1},
-		Usage      = .IMMUTABLE,
-		BindFlags  = {.SHADER_RESOURCE},
-	}
-
-	texture_data := d3d11.SUBRESOURCE_DATA{
-		pSysMem     = raw_data(data),
-		SysMemPitch = u32(width * 4),
-	}
+},
 
-	texture: ^d3d11.ITexture2D
-	s.device->CreateTexture2D(&texture_desc, &texture_data, &texture)
-
-	texture_view: ^d3d11.IShaderResourceView
-	s.device->CreateShaderResourceView(texture, nil, &texture_view)
-
-	tex := D3D11_Texture {
-		tex = texture,
-		view = texture_view,
-	}
-
-	return hm.add(&s.textures, tex)
-}
-
-d3d11_destroy_texture :: proc(th: Texture_Handle) {
-	if t := hm.get(&s.textures, th); t != nil {
-		t.tex->Release()
-		t.view->Release()	
-	}
-
-	hm.remove(&s.textures, th)
-}
-
-
-create_vertex_input_override :: proc(val: $T) -> Shader_Input_Value_Override {
-	assert(size_of(T) < 256)
-	res: Shader_Input_Value_Override
-	((^T)(raw_data(&res.val)))^ = val
-	res.used = size_of(T)
-	return res
-}
+present = proc() {
+	ch(s.swapchain->Present(1, {}))
+	s.vertex_buffer_offset = 0
+},
 
-d3d11_draw :: proc(shd: Shader, texture: Texture_Handle, view_proj: Mat4, vertex_buffer: []u8) {
+draw = proc(shd: Shader, texture: Texture_Handle, view_proj: Mat4, vertex_buffer: []u8) {
 	if len(vertex_buffer) == 0 {
 		return
 	}
@@ -404,16 +269,62 @@ d3d11_draw :: proc(shd: Shader, texture: Texture_Handle, view_proj: Mat4, vertex
 	dc->Draw(u32(len(vertex_buffer)/shd.vertex_size), u32(s.vertex_buffer_offset/shd.vertex_size))
 	s.vertex_buffer_offset += len(vertex_buffer)
 	log_messages()
-}
+},
 
+get_swapchain_width = proc() -> int {
+	return s.width
+},
 
-d3d11_present :: proc() {
-	ch(s.swapchain->Present(1, {}))
-	s.vertex_buffer_offset = 0
-}
+get_swapchain_height = proc() -> int {
+	return s.height
+},
 
+set_internal_state = proc(state: rawptr) {
+	s = (^D3D11_State)(state)
+},
+
+load_texture = proc(data: []u8, width: int, height: int) -> Texture_Handle {
+	texture_desc := d3d11.TEXTURE2D_DESC{
+		Width      = u32(width),
+		Height     = u32(height),
+		MipLevels  = 1,
+		ArraySize  = 1,
+		// TODO: _SRGB or not?
+		Format     = .R8G8B8A8_UNORM,
+		SampleDesc = {Count = 1},
+		Usage      = .IMMUTABLE,
+		BindFlags  = {.SHADER_RESOURCE},
+	}
+
+	texture_data := d3d11.SUBRESOURCE_DATA{
+		pSysMem     = raw_data(data),
+		SysMemPitch = u32(width * 4),
+	}
+
+	texture: ^d3d11.ITexture2D
+	s.device->CreateTexture2D(&texture_desc, &texture_data, &texture)
+
+	texture_view: ^d3d11.IShaderResourceView
+	s.device->CreateShaderResourceView(texture, nil, &texture_view)
 
-d3d11_load_shader :: proc(shader: string, layout_formats: []Shader_Input_Format = {}) -> Shader {
+	tex := D3D11_Texture {
+		tex = texture,
+		view = texture_view,
+	}
+
+	return hm.add(&s.textures, tex)
+},
+
+destroy_texture = proc(th: Texture_Handle) {
+	if t := hm.get(&s.textures, th); t != nil {
+		t.tex->Release()
+		t.view->Release()	
+	}
+
+	hm.remove(&s.textures, th)
+},
+
+load_shader = proc(shader: string, layout_formats: []Shader_Input_Format = {}) -> Shader {
 	vs_blob: ^d3d11.IBlob
 	vs_blob_errors: ^d3d11.IBlob
 	ch(d3d_compiler.Compile(raw_data(shader), len(shader), nil, nil, nil, "vs_main", "vs_5_0", 0, 0, &vs_blob, &vs_blob_errors))
@@ -637,24 +548,9 @@ d3d11_load_shader :: proc(shader: string, layout_formats: []Shader_Input_Format
 		default_input_offsets = default_input_offsets,
 		vertex_size = input_offset,
 	}
-}
+},
 
-dxgi_format_from_shader_input_format :: proc(f: Shader_Input_Format) -> dxgi.FORMAT {
-	switch f {
-	case .Unknown: return .UNKNOWN
-	case .RGBA32_Float: return .R32G32B32A32_FLOAT
-	case .RGBA8_Norm: return .R8G8B8A8_UNORM
-	case .RGBA8_Norm_SRGB: return .R8G8B8A8_UNORM_SRGB
-	case .RGB32_Float: return .R32G32B32_FLOAT
-	case .RG32_Float: return .R32G32_FLOAT
-	case .R32_Float: return .R32_FLOAT
-	}
-
-	log.error("Unknown format")
-	return .UNKNOWN
-}
-
-d3d11_destroy_shader :: proc(shd: Shader) {
+destroy_shader = proc(shd: Shader) {
 	if d3d_shd := hm.get(&s.shaders, shd.handle); d3d_shd != nil {
 		d3d_shd.input_layout->Release()
 		d3d_shd.vertex_shader->Release()
@@ -686,10 +582,82 @@ d3d11_destroy_shader :: proc(shd: Shader) {
 	}
 	delete(shd.inputs)
 	delete(shd.input_overrides)
+},
+
+// end d3d11 backend interface
+}
+
+s: ^D3D11_State
+
+D3D11_Shader_Constant_Buffer :: struct {
+	gpu_data: ^d3d11.IBuffer,
+}
+
+D3D11_Shader :: struct {
+	handle: Shader_Handle,
+	vertex_shader: ^d3d11.IVertexShader,
+	pixel_shader: ^d3d11.IPixelShader,
+	input_layout: ^d3d11.IInputLayout,
+	constant_buffers: []D3D11_Shader_Constant_Buffer,
 }
 
-temp_cstring :: proc(str: string, loc := #caller_location) -> cstring {
-	return strings.clone_to_cstring(str, context.temp_allocator, loc)
+D3D11_State :: struct {
+	allocator: runtime.Allocator,
+
+	width: int,
+	height: int,
+
+	swapchain: ^dxgi.ISwapChain1,
+	framebuffer_view: ^d3d11.IRenderTargetView,
+	depth_buffer_view: ^d3d11.IDepthStencilView,
+	device_context: ^d3d11.IDeviceContext,
+	depth_stencil_state: ^d3d11.IDepthStencilState,
+	rasterizer_state: ^d3d11.IRasterizerState,
+	device: ^d3d11.IDevice,
+	depth_buffer: ^d3d11.ITexture2D,
+	framebuffer: ^d3d11.ITexture2D,
+	blend_state: ^d3d11.IBlendState,
+	sampler_state: ^d3d11.ISamplerState,
+
+	textures: hm.Handle_Map(D3D11_Texture, Texture_Handle, 1024*10),
+	shaders: hm.Handle_Map(D3D11_Shader, Shader_Handle, 1024*10),
+
+	info_queue: ^d3d11.IInfoQueue,
+	vertex_buffer_gpu: ^d3d11.IBuffer,
+
+	vertex_buffer_offset: int,
+}
+
+Color_F32 :: [4]f32
+
+f32_color_from_color :: proc(color: Color) -> Color_F32 {
+	return {
+		f32(color.r) / 255,
+		f32(color.g) / 255,
+		f32(color.b) / 255,
+		f32(color.a) / 255,
+	}
+}
+
+D3D11_Texture :: struct {
+	handle: Texture_Handle,
+	tex: ^d3d11.ITexture2D,
+	view: ^d3d11.IShaderResourceView,
+}
+
+dxgi_format_from_shader_input_format :: proc(f: Shader_Input_Format) -> dxgi.FORMAT {
+	switch f {
+	case .Unknown: return .UNKNOWN
+	case .RGBA32_Float: return .R32G32B32A32_FLOAT
+	case .RGBA8_Norm: return .R8G8B8A8_UNORM
+	case .RGBA8_Norm_SRGB: return .R8G8B8A8_UNORM_SRGB
+	case .RGB32_Float: return .R32G32B32_FLOAT
+	case .RG32_Float: return .R32G32_FLOAT
+	case .R32_Float: return .R32_FLOAT
+	}
+
+	log.error("Unknown format")
+	return .UNKNOWN
 }
 
 // CHeck win errors and print message log if there is any error

+ 13 - 0
karl2d.odin

@@ -6,6 +6,7 @@ import "core:log"
 import "core:math"
 import "core:math/linalg"
 import "core:slice"
+import "core:strings"
 
 import "core:image"
 import "core:image/bmp"
@@ -936,4 +937,16 @@ vec3_from_vec2 :: proc(v: Vec2) -> Vec3 {
 	return {
 		v.x, v.y, 0,
 	}
+}
+
+create_vertex_input_override :: proc(val: $T) -> Shader_Input_Value_Override {
+	assert(size_of(T) < 256)
+	res: Shader_Input_Value_Override
+	((^T)(raw_data(&res.val)))^ = val
+	res.used = size_of(T)
+	return res
+}
+
+temp_cstring :: proc(str: string, loc := #caller_location) -> cstring {
+	return strings.clone_to_cstring(str, context.temp_allocator, loc)
 }

+ 89 - 86
window_win32.odin

@@ -8,92 +8,95 @@ import "base:runtime"
 
 @(private="package")
 WINDOW_INTERFACE_WIN32 :: Window_Interface {
-	state_size = proc() -> int {
-		return size_of(Win32_State)
-	},
-
-	init = proc(window_state: rawptr, window_width: int, window_height: int, window_title: string, allocator := context.allocator) {
-		assert(window_state != nil)
-		s = (^Win32_State)(window_state)
-		s.allocator = allocator
-		s.events = make([dynamic]Window_Event, allocator)
-		s.custom_context = context
-		win32.SetProcessDPIAware()
-		CLASS_NAME :: "karl2d"
-		instance := win32.HINSTANCE(win32.GetModuleHandleW(nil))
-
-		cls := win32.WNDCLASSW {
-			lpfnWndProc = window_proc,
-			lpszClassName = CLASS_NAME,
-			hInstance = instance,
-			hCursor = win32.LoadCursorA(nil, win32.IDC_ARROW),
-		}
-
-		win32.RegisterClassW(&cls)
-
-		r: win32.RECT
-		r.right = i32(window_width)
-		r.bottom = i32(window_height)
-
-		style := win32.WS_OVERLAPPEDWINDOW | win32.WS_VISIBLE
-		win32.AdjustWindowRect(&r, style, false)
-
-		hwnd := win32.CreateWindowW(CLASS_NAME,
-			win32.utf8_to_wstring(window_title),
-			style,
-			100, 10, r.right - r.left, r.bottom - r.top,
-			nil, nil, instance, nil,
-		)
-
-		assert(hwnd != nil, "Failed creating window")
-
-		s.hwnd = hwnd
-	},
-
-	shutdown = proc() {
-		delete(s.events)
-		win32.DestroyWindow(s.hwnd)
-	},
-
-	window_handle = proc() -> Window_Handle {
-		return Window_Handle(s.hwnd)
-	},
-
-	process_events = proc() {
-		msg: win32.MSG
-
-		for win32.PeekMessageW(&msg, nil, 0, 0, win32.PM_REMOVE) {
-			win32.TranslateMessage(&msg)
-			win32.DispatchMessageW(&msg)
-		}
-	},
-
-	get_events = proc() -> []Window_Event {
-		return s.events[:]
-	},
-
-	clear_events = proc() {
-		runtime.clear(&s.events)
-	},
-
-	set_position = proc(x: int, y: int) {
-		// TODO: Does x, y respect monitor DPI?
-
-		win32.SetWindowPos(
-			s.hwnd,
-			{},
-			i32(x),
-			i32(y),
-			0,
-			0,
-			win32.SWP_NOACTIVATE | win32.SWP_NOZORDER | win32.SWP_NOSIZE,
-		)
-	},
-
-	set_internal_state = proc(state: rawptr) {
-		assert(state != nil)
-		s = (^Win32_State)(state)
-	},
+
+state_size = proc() -> int {
+	return size_of(Win32_State)
+},
+
+init = proc(window_state: rawptr, window_width: int, window_height: int, window_title: string, allocator := context.allocator) {
+	assert(window_state != nil)
+	s = (^Win32_State)(window_state)
+	s.allocator = allocator
+	s.events = make([dynamic]Window_Event, allocator)
+	s.custom_context = context
+	win32.SetProcessDPIAware()
+	CLASS_NAME :: "karl2d"
+	instance := win32.HINSTANCE(win32.GetModuleHandleW(nil))
+
+	cls := win32.WNDCLASSW {
+		lpfnWndProc = window_proc,
+		lpszClassName = CLASS_NAME,
+		hInstance = instance,
+		hCursor = win32.LoadCursorA(nil, win32.IDC_ARROW),
+	}
+
+	win32.RegisterClassW(&cls)
+
+	r: win32.RECT
+	r.right = i32(window_width)
+	r.bottom = i32(window_height)
+
+	style := win32.WS_OVERLAPPEDWINDOW | win32.WS_VISIBLE
+	win32.AdjustWindowRect(&r, style, false)
+
+	hwnd := win32.CreateWindowW(CLASS_NAME,
+		win32.utf8_to_wstring(window_title),
+		style,
+		100, 10, r.right - r.left, r.bottom - r.top,
+		nil, nil, instance, nil,
+	)
+
+	assert(hwnd != nil, "Failed creating window")
+
+	s.hwnd = hwnd
+},
+
+shutdown = proc() {
+	delete(s.events)
+	win32.DestroyWindow(s.hwnd)
+},
+
+window_handle = proc() -> Window_Handle {
+	return Window_Handle(s.hwnd)
+},
+
+process_events = proc() {
+	msg: win32.MSG
+
+	for win32.PeekMessageW(&msg, nil, 0, 0, win32.PM_REMOVE) {
+		win32.TranslateMessage(&msg)
+		win32.DispatchMessageW(&msg)
+	}
+},
+
+get_events = proc() -> []Window_Event {
+	return s.events[:]
+},
+
+clear_events = proc() {
+	runtime.clear(&s.events)
+},
+
+set_position = proc(x: int, y: int) {
+	// TODO: Does x, y respect monitor DPI?
+
+	win32.SetWindowPos(
+		s.hwnd,
+		{},
+		i32(x),
+		i32(y),
+		0,
+		0,
+		win32.SWP_NOACTIVATE | win32.SWP_NOZORDER | win32.SWP_NOSIZE,
+	)
+},
+
+set_internal_state = proc(state: rawptr) {
+	assert(state != nil)
+	s = (^Win32_State)(state)
+},
+
+// end WINDOW_INTERFACE_WIN32
 }
 
 Win32_State :: struct {