Ver código fonte

Resizeable swapchain

Karl Zylinski 6 meses atrás
pai
commit
77c3d374c2
7 arquivos alterados com 77 adições e 38 exclusões
  1. 4 3
      README.md
  2. 48 32
      backend_d3d11.odin
  3. 1 0
      backend_interface.odin
  4. 1 1
      karl2d.doc.odin
  5. 9 2
      karl2d.odin
  6. 5 0
      window_interface.odin
  7. 9 0
      window_win32.odin

+ 4 - 3
README.md

@@ -16,13 +16,14 @@ Might not be included:
 
 Here follows my near-future TODO list
 
-* Textures: Make the sampler state configurable
-* Textures D3D11: Do we need the SRV in the texture?
-
+* win32: Gamepad support
+* win32: Resizable window
 * Do proper checks of vertex count and dispatch rendering when full
 	* What happens when list is full? We can't just empty the vertex list due to being used by input assembler etc.
 * Should we sort by depth? Maybe we should use Vec3 because some 2D games rely on it?
 	* I think we should.
+* Textures: Make the sampler state configurable
+* Textures D3D11: Do we need the SRV in the texture?
 * Shaders: Reflect and expose samplers
 
 ## DONE

+ 48 - 32
backend_d3d11.odin

@@ -21,9 +21,9 @@ state_size = proc() -> int {
 },
 
 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
+	s.window_handle = dxgi.HWND(window_handle)
 	s.width = swapchain_width
 	s.height = swapchain_height
 	feature_levels := [?]d3d11.FEATURE_LEVEL{
@@ -57,38 +57,10 @@ init = proc(state: rawptr, window_handle: Window_Handle, swapchain_width, swapch
 	ch(s.device->QueryInterface(dxgi.IDevice_UUID, (^rawptr)(&dxgi_device)))
 	base_device->Release()
 	base_device_context->Release()
-
-	dxgi_adapter: ^dxgi.IAdapter
 	
-	ch(dxgi_device->GetAdapter(&dxgi_adapter))
-	dxgi_device->Release()
-
-	dxgi_factory: ^dxgi.IFactory2
-	ch(dxgi_adapter->GetParent(dxgi.IFactory2_UUID, (^rawptr)(&dxgi_factory)))
-
-	swapchain_desc := dxgi.SWAP_CHAIN_DESC1 {
-		Format = .B8G8R8A8_UNORM,
-		SampleDesc = {
-			Count   = 1,
-		},
-		BufferUsage = {.RENDER_TARGET_OUTPUT},
-		BufferCount = 2,
-		Scaling     = .STRETCH,
-		SwapEffect  = .DISCARD,
-	}
-
-	ch(dxgi_factory->CreateSwapChainForHwnd(s.device, hwnd, &swapchain_desc, nil, nil, &s.swapchain))
-	ch(s.swapchain->GetBuffer(0, d3d11.ITexture2D_UUID, (^rawptr)(&s.framebuffer)))
-	ch(s.device->CreateRenderTargetView(s.framebuffer, nil, &s.framebuffer_view))
-
-	depth_buffer_desc: d3d11.TEXTURE2D_DESC
-	s.framebuffer->GetDesc(&depth_buffer_desc)
-	depth_buffer_desc.Format = .D24_UNORM_S8_UINT
-	depth_buffer_desc.BindFlags = {.DEPTH_STENCIL}
-
-	ch(s.device->CreateTexture2D(&depth_buffer_desc, nil, &s.depth_buffer))
-	ch(s.device->CreateDepthStencilView(s.depth_buffer, nil, &s.depth_buffer_view))
+	ch(dxgi_device->GetAdapter(&s.dxgi_adapter))
 
+	create_swapchain(swapchain_width, swapchain_height)
 
 	rasterizer_desc := d3d11.RASTERIZER_DESC{
 		FillMode = .SOLID,
@@ -150,6 +122,7 @@ shutdown = proc() {
 	s.rasterizer_state->Release()
 	s.swapchain->Release()
 	s.blend_state->Release()
+	s.dxgi_adapter->Release()
 
 	when ODIN_DEBUG {
 		debug: ^d3d11.IDebug
@@ -161,7 +134,7 @@ shutdown = proc() {
 
 		debug->Release()
 	}
-
+	
 	s.device->Release()
 	s.info_queue->Release()
 },
@@ -271,6 +244,18 @@ draw = proc(shd: Shader, texture: Texture_Handle, view_proj: Mat4, vertex_buffer
 	log_messages()
 },
 
+resize_swapchain = proc(w, h: int) {
+	s.depth_buffer->Release()
+	s.depth_buffer_view->Release()
+	s.framebuffer->Release()
+	s.framebuffer_view->Release()
+	s.swapchain->Release()
+	s.width = w
+	s.height = h
+
+	create_swapchain(w, h)
+},
+
 get_swapchain_width = proc() -> int {
 	return s.width
 },
@@ -522,9 +507,11 @@ D3D11_Shader :: struct {
 D3D11_State :: struct {
 	allocator: runtime.Allocator,
 
+	window_handle: dxgi.HWND,
 	width: int,
 	height: int,
 
+	dxgi_adapter: ^dxgi.IAdapter,
 	swapchain: ^dxgi.ISwapChain1,
 	framebuffer_view: ^d3d11.IRenderTargetView,
 	depth_buffer_view: ^d3d11.IDepthStencilView,
@@ -549,6 +536,35 @@ D3D11_State :: struct {
 	vertex_buffer_offset: int,
 }
 
+create_swapchain :: proc(w, h: int) {
+	swapchain_desc := dxgi.SWAP_CHAIN_DESC1 {
+		Width = u32(w),
+		Height = u32(h),
+		Format = .B8G8R8A8_UNORM,
+		SampleDesc = {
+			Count   = 1,
+		},
+		BufferUsage = {.RENDER_TARGET_OUTPUT},
+		BufferCount = 2,
+		Scaling     = .STRETCH,
+		SwapEffect  = .DISCARD,
+	}
+
+	dxgi_factory: ^dxgi.IFactory2
+	ch(s.dxgi_adapter->GetParent(dxgi.IFactory2_UUID, (^rawptr)(&dxgi_factory)))
+	ch(dxgi_factory->CreateSwapChainForHwnd(s.device, s.window_handle, &swapchain_desc, nil, nil, &s.swapchain))
+	ch(s.swapchain->GetBuffer(0, d3d11.ITexture2D_UUID, (^rawptr)(&s.framebuffer)))
+	ch(s.device->CreateRenderTargetView(s.framebuffer, nil, &s.framebuffer_view))
+
+	depth_buffer_desc: d3d11.TEXTURE2D_DESC
+	s.framebuffer->GetDesc(&depth_buffer_desc)
+	depth_buffer_desc.Format = .D24_UNORM_S8_UINT
+	depth_buffer_desc.BindFlags = {.DEPTH_STENCIL}
+
+	ch(s.device->CreateTexture2D(&depth_buffer_desc, nil, &s.depth_buffer))
+	ch(s.device->CreateDepthStencilView(s.depth_buffer, nil, &s.depth_buffer_view))
+}
+
 Color_F32 :: [4]f32
 
 f32_color_from_color :: proc(color: Color) -> Color_F32 {

+ 1 - 0
backend_interface.odin

@@ -31,6 +31,7 @@ Rendering_Backend_Interface :: struct {
 	load_shader: proc(shader_source: string, desc_allocator := context.temp_allocator, layout_formats: []Shader_Input_Format = {}) -> (handle: Shader_Handle, desc: Shader_Desc),
 	destroy_shader: proc(shader: Shader_Handle),
 
+	resize_swapchain: proc(width, height: int),
 	get_swapchain_width: proc() -> int,
 	get_swapchain_height: proc() -> int,
 

+ 1 - 1
karl2d.doc.odin

@@ -217,7 +217,7 @@ Texture :: struct {
 
 Camera :: struct {
 	target: Vec2,
-	origin: Vec2,
+	offset: Vec2,
 	rotation: f32,
 	zoom: f32,
 }

+ 9 - 2
karl2d.odin

@@ -133,6 +133,13 @@ process_events :: proc() {
 
 		case Window_Event_Mouse_Wheel:
 			s.mouse_wheel_delta = e.delta
+
+		case Window_Event_Resize:
+			s.width = e.width
+			s.height = e.height
+
+			rb.resize_swapchain(s.width, s.height)
+			s.proj_matrix = make_default_projection(s.width, s.height)
 		}
 	}
 
@@ -140,11 +147,11 @@ process_events :: proc() {
 }
 
 get_screen_width :: proc() -> int {
-	return rb.get_swapchain_width()
+	return s.width
 }
 
 get_screen_height :: proc() -> int  {
-	return rb.get_swapchain_height()
+	return s.height
 }
 
 set_window_position :: proc(x: int, y: int) {

+ 5 - 0
window_interface.odin

@@ -21,6 +21,7 @@ Window_Event :: union  {
 	Window_Event_Key_Went_Up,
 	Window_Event_Mouse_Move,
 	Window_Event_Mouse_Wheel,
+	Window_Event_Resize,
 }
 
 Window_Event_Key_Went_Down :: struct {
@@ -39,4 +40,8 @@ Window_Event_Mouse_Move :: struct {
 
 Window_Event_Mouse_Wheel :: struct {
 	delta: f32,
+}
+
+Window_Event_Resize :: struct {
+	width, height: int,
 }

+ 9 - 0
window_win32.odin

@@ -149,6 +149,15 @@ window_proc :: proc "stdcall" (hwnd: win32.HWND, msg: win32.UINT, wparam: win32.
 		append(&s.events, Window_Event_Mouse_Wheel {
 			delta = delta,
 		})
+
+	case win32.WM_SIZE:
+		width := win32.LOWORD(lparam)
+		height := win32.HIWORD(lparam)
+
+		append(&s.events, Window_Event_Resize {
+			width = int(width),
+			height = int(height),
+		})
 	}
 
 	return win32.DefWindowProcW(hwnd, msg, wparam, lparam)