소스 검색

Update texture support

Karl Zylinski 4 달 전
부모
커밋
4cedfee91c
3개의 변경된 파일32개의 추가작업 그리고 8개의 파일을 삭제
  1. 6 7
      karl2d.odin
  2. 25 1
      render_backend_d3d11.odin
  3. 1 0
      render_backend_interface.odin

+ 6 - 7
karl2d.odin

@@ -46,17 +46,10 @@ init :: proc(window_width: int, window_height: int, window_title: string,
 	fs.Init(&s.fs, 1024, 1024, .TOPLEFT)
 
 	ROBOTO_FONT_DATA :: #load("roboto.ttf")
-	//SIMSUN_FONT_DATA :: #load("simsun.ttc")
-	//MALGUN_FONT_DATA :: #load("malgun.ttf")
 
 	roboto_font := fs.AddFontMem(&s.fs, "roboto", ROBOTO_FONT_DATA, false)
 	fs.SetFont(&s.fs, roboto_font)
 
-	//simsun_font := fs.AddFontMem(&s.fs, "simsun", SIMSUN_FONT_DATA, false)
-	//malgun_font := fs.AddFontMem(&s.fs, "malgun", MALGUN_FONT_DATA, false)
-	//fs.AddFallbackFont(&s.fs, roboto_font, simsun_font)
-	//fs.AddFallbackFont(&s.fs, roboto_font, malgun_font)
-
 	win = s.win
 
 	window_state_alloc_error: runtime.Allocator_Error
@@ -754,6 +747,12 @@ get_texture_rect :: proc(t: Texture) -> Rect {
 	}
 }
 
+// Update a texture with new pixels. `bytes` is the new pixel data. `rect` is the rectangle in
+// `tex` where the new pixels should end up.
+update_texture :: proc(tex: Texture, bytes: []u8, rect: Rect) -> bool {
+	return rb.update_texture(tex.handle, bytes, rect)
+}
+
 destroy_texture :: proc(tex: Texture) {
 	rb.destroy_texture(tex.handle)
 }

+ 25 - 1
render_backend_d3d11.odin

@@ -16,6 +16,7 @@ RENDER_BACKEND_INTERFACE_D3D11 :: Render_Backend_Interface {
 	get_swapchain_height = d3d11_get_swapchain_height,
 	set_internal_state = d3d11_set_internal_state,
 	load_texture = d3d11_load_texture,
+	update_texture = d3d11_update_texture,
 	destroy_texture = d3d11_destroy_texture,
 	load_shader = d3d11_load_shader,
 	destroy_shader = d3d11_destroy_shader,
@@ -325,7 +326,7 @@ d3d11_load_texture :: proc(data: []u8, width: int, height: int, format: Pixel_Fo
 		// TODO: _SRGB or not?
 		Format     = dxgi_format_from_pixel_format(format),
 		SampleDesc = {Count = 1},
-		Usage      = .IMMUTABLE,
+		Usage      = .DEFAULT,
 		BindFlags  = {.SHADER_RESOURCE},
 	}
 
@@ -342,12 +343,34 @@ d3d11_load_texture :: proc(data: []u8, width: int, height: int, format: Pixel_Fo
 
 	tex := D3D11_Texture {
 		tex = texture,
+		format = format,
 		view = texture_view,
 	}
 
 	return hm.add(&s.textures, tex)
 }
 
+d3d11_update_texture :: proc(th: Texture_Handle, data: []u8, rect: Rect) -> bool {
+	tex := hm.get(&s.textures, th)
+
+	if tex == nil {
+		return false
+	}
+
+	box := d3d11.BOX {
+		left = u32(rect.x),
+		top = u32(rect.y),
+		bottom = u32(rect.y + rect.h),
+		right = u32(rect.x + rect.w),
+		back = 1,
+		front = 0,
+	}
+
+	row_pitch := pixel_format_size(tex.format) * int(rect.w)
+	s.device_context->UpdateSubresource(tex.tex, 0, &box, raw_data(data), u32(row_pitch), 0)
+	return true
+}
+
 d3d11_destroy_texture :: proc(th: Texture_Handle) {
 	if t := hm.get(&s.textures, th); t != nil {
 		t.tex->Release()
@@ -622,6 +645,7 @@ D3D11_Texture :: struct {
 	handle: Texture_Handle,
 	tex: ^d3d11.ITexture2D,
 	view: ^d3d11.IShaderResourceView,
+	format: Pixel_Format,
 }
 
 dxgi_format_from_pixel_format :: proc(f: Pixel_Format) -> dxgi.FORMAT {

+ 1 - 0
render_backend_interface.odin

@@ -26,6 +26,7 @@ Render_Backend_Interface :: struct {
 	set_internal_state: proc(state: rawptr),
 
 	load_texture: proc(data: []u8, width: int, height: int, format: Pixel_Format) -> Texture_Handle,
+	update_texture: proc(handle: Texture_Handle, data: []u8, rect: Rect) -> bool,
 	destroy_texture: proc(handle: Texture_Handle),
 
 	load_shader: proc(shader_source: string, desc_allocator := context.temp_allocator, layout_formats: []Pixel_Format = {}) -> (handle: Shader_Handle, desc: Shader_Desc),