Bladeren bron

Some D3D11 Render Texture work. Needs a better split between RT and Texture so we can use the RT as a normal texture as well.

Karl Zylinski 3 maanden geleden
bovenliggende
commit
34716065a5

+ 2 - 2
.sublime/karl2d.sublime-project

@@ -22,9 +22,9 @@
 					"working_dir": "$project_path/../examples/fonts"
 				},
 				{
-					"name": "render_target",
+					"name": "render_texture",
 					"shell_cmd": "odin run . -vet -strict-style -keep-executable -debug",
-					"working_dir": "$project_path/../examples/render_target"
+					"working_dir": "$project_path/../examples/render_texture"
 				},
 				{
 					"name": "snake",

+ 4 - 4
examples/render_target/render_target.odin → examples/render_texture/render_texture.odin

@@ -26,16 +26,16 @@ main :: proc() {
 		}
 	}
 
-	k2.init(1080, 1080, "Karl2D Minimal Program")
+	k2.init(1080, 1080, "Karl2D Render Texture Example")
 	k2.set_window_position(300, 100)
 	tex := k2.load_texture_from_file("sixten.jpg")
 
-	render_target := k2.create_texture(200, 200, .RGBA_32_Float)
-
-	log.info(render_target)
+	render_texture := k2.create_render_texture(200, 200)
 
 	for !k2.shutdown_wanted() {
 		k2.process_events()
+
+		k2.set_render_texture(render_texture)
 		k2.clear(k2.BLUE)
 
 		k2.draw_rect({10, 10, 60, 60}, k2.GREEN)

+ 1 - 0
karl2d.doc.odin

@@ -409,6 +409,7 @@ Font :: struct {
 
 Handle :: hm.Handle
 Texture_Handle :: distinct Handle
+Render_Texture_Handle :: distinct Handle
 Font_Handle :: distinct int
 FONT_NONE :: Font_Handle {}
 TEXTURE_NONE :: Texture_Handle {}

+ 17 - 5
karl2d.odin

@@ -145,7 +145,7 @@ shutdown :: proc() {
 
 // Clear the backbuffer with supplied color.
 clear :: proc(color: Color) {
-	rb.clear(color)
+	rb.clear(s.batch_render_texture, color)
 	s.depth = s.depth_start
 }
 
@@ -308,7 +308,7 @@ draw_current_batch :: proc() {
 		shader.texture_bindpoints[def_tex_idx] = s.batch_texture
 	}
 
-	rb.draw(shader, shader.texture_bindpoints, s.batch_scissor, s.vertex_buffer_cpu[:s.vertex_buffer_cpu_used])
+	rb.draw(shader, s.batch_render_texture, shader.texture_bindpoints, s.batch_scissor, s.vertex_buffer_cpu[:s.vertex_buffer_cpu_used])
 	s.vertex_buffer_cpu_used = 0
 }
 
@@ -837,9 +837,18 @@ set_texture_filter_ex :: proc(
 // RENDER TEXTURES //
 //-----------------//
 
-/*create_render_texture :: proc(width: int, height: int) -> Render_Texture {
+create_render_texture :: proc(width: int, height: int) -> Render_Texture_Handle {
+	return rb.create_render_texture(width, height)
+}
+
+set_render_texture :: proc(render_texture: Render_Texture_Handle) {
+	if s.batch_render_texture == render_texture {
+		return
+	}
 
-}*/
+	draw_current_batch()
+	s.batch_render_texture = render_texture
+}
 
 //-------//
 // FONTS //
@@ -1332,10 +1341,12 @@ Font :: struct {
 
 Handle :: hm.Handle
 Texture_Handle :: distinct Handle
+Render_Texture_Handle :: distinct Handle
 Font_Handle :: distinct int
+
 FONT_NONE :: Font_Handle {}
 TEXTURE_NONE :: Texture_Handle {}
-
+RENDER_TEXTURE_NONE :: Render_Texture_Handle {}
 
 // This keeps track of the internal state of the library. Usually, you do not need to poke at it.
 // It is created and kept as a global variable when 'init' is called. However, 'init' also returns
@@ -1380,6 +1391,7 @@ State :: struct {
 	batch_shader: Shader,
 	batch_scissor: Maybe(Rect),
 	batch_texture: Texture_Handle,
+	batch_render_texture: Render_Texture_Handle,
 
 	view_matrix: Mat4,
 	proj_matrix: Mat4,

+ 82 - 4
render_backend_d3d11.odin

@@ -21,6 +21,7 @@ RENDER_BACKEND_INTERFACE_D3D11 :: Render_Backend_Interface {
 	load_texture = d3d11_load_texture,
 	update_texture = d3d11_update_texture,
 	destroy_texture = d3d11_destroy_texture,
+	create_render_texture = d3d11_create_render_texture,
 	set_texture_filter = d3d11_set_texture_filter,
 	load_shader = d3d11_load_shader,
 	destroy_shader = d3d11_destroy_shader,
@@ -173,10 +174,16 @@ d3d11_shutdown :: proc() {
 	s.info_queue->Release()
 }
 
-d3d11_clear :: proc(color: Color) {
+d3d11_clear :: proc(render_texture: Render_Texture_Handle, 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)
+
+	if rt := hm.get(&s.render_textures, render_texture); rt != nil {
+		s.device_context->ClearRenderTargetView(rt.render_target_view, &c)
+		s.device_context->ClearDepthStencilView(rt.depth_stencil_texture_view, {.DEPTH}, 1, 0)	
+	} else {
+		s.device_context->ClearRenderTargetView(s.framebuffer_view, &c)
+		s.device_context->ClearDepthStencilView(s.depth_buffer_view, {.DEPTH}, 1, 0)
+	}
 }
 
 d3d11_present :: proc() {
@@ -185,6 +192,7 @@ d3d11_present :: proc() {
 
 d3d11_draw :: proc(
 	shd: Shader,
+	render_texture: Render_Texture_Handle,
 	bound_textures: []Texture_Handle,
 	scissor: Maybe(Rect), 
 	vertex_buffer: []u8,
@@ -305,7 +313,12 @@ d3d11_draw :: proc(
 		}
 	}
 
-	dc->OMSetRenderTargets(1, &s.framebuffer_view, s.depth_buffer_view)
+	if rt := hm.get(&s.render_textures, render_texture); rt != nil {
+		dc->OMSetRenderTargets(1, &rt.render_target_view, rt.depth_stencil_texture_view)
+	} else {
+		dc->OMSetRenderTargets(1, &s.framebuffer_view, s.depth_buffer_view)
+	}
+
 	dc->OMSetDepthStencilState(s.depth_stencil_state, 0)
 	dc->OMSetBlendState(s.blend_state, nil, ~u32(0))
 
@@ -390,6 +403,61 @@ d3d11_create_texture :: proc(width: int, height: int, format: Pixel_Format) -> T
 	return create_texture(width, height, format, nil)
 }
 
+d3d11_create_render_texture :: proc(width: int, height: int) -> Render_Texture_Handle {
+	texture_desc := d3d11.TEXTURE2D_DESC{
+		Width      = u32(width),
+		Height     = u32(height),
+		MipLevels  = 1,
+		ArraySize  = 1,
+		Format     = dxgi_format_from_pixel_format(.RGBA_32_Float),
+		SampleDesc = {Count = 1},
+		Usage      = .DEFAULT,
+		BindFlags  = {.SHADER_RESOURCE, .RENDER_TARGET},
+	}
+
+	texture: ^d3d11.ITexture2D
+	ch(s.device->CreateTexture2D(&texture_desc, nil, &texture))
+
+	texture_view: ^d3d11.IShaderResourceView
+	ch(s.device->CreateShaderResourceView(texture, nil, &texture_view))
+
+	depth_stencil_desc := d3d11.TEXTURE2D_DESC{
+		Width      = u32(width),
+		Height     = u32(height),
+		MipLevels  = 1,
+		ArraySize  = 1,
+		Format     = .D24_UNORM_S8_UINT,
+		SampleDesc = {Count = 1},
+		Usage      = .DEFAULT,
+		BindFlags  = {.DEPTH_STENCIL},
+	}
+
+	depth_stencil_texture: ^d3d11.ITexture2D
+	ch(ch(s.device->CreateTexture2D(&depth_stencil_desc, nil, &depth_stencil_texture)))
+
+	depth_stencil_texture_view: ^d3d11.IDepthStencilView
+	ch(s.device->CreateDepthStencilView(depth_stencil_texture, nil, &depth_stencil_texture_view))
+
+	render_target_view_desc := d3d11.RENDER_TARGET_VIEW_DESC {
+		Format = texture_desc.Format,
+		ViewDimension = .TEXTURE2D,
+	}
+
+	render_target_view: ^d3d11.IRenderTargetView
+
+	ch(s.device->CreateRenderTargetView(texture, &render_target_view_desc, &render_target_view))
+
+	rtex := D3D11_Render_Texture {
+		texture = texture,
+		texture_view = texture_view,
+		depth_stencil_texture = depth_stencil_texture,
+		depth_stencil_texture_view = depth_stencil_texture_view,
+		render_target_view = render_target_view,
+	}
+
+	return hm.add(&s.render_textures, rtex)
+}
+
 d3d11_load_texture :: proc(data: []u8, width: int, height: int, format: Pixel_Format) -> Texture_Handle {
 	return create_texture(width, height, format, raw_data(data))
 }
@@ -853,6 +921,7 @@ D3D11_State :: struct {
 	blend_state: ^d3d11.IBlendState,
 
 	textures: hm.Handle_Map(D3D11_Texture, Texture_Handle, 1024*10),
+	render_textures: hm.Handle_Map(D3D11_Render_Texture, Render_Texture_Handle, 1024*10),
 	shaders: hm.Handle_Map(D3D11_Shader, Shader_Handle, 1024*10),
 
 	info_queue: ^d3d11.IInfoQueue,
@@ -907,6 +976,15 @@ D3D11_Texture :: struct {
 	sampler: ^d3d11.ISamplerState,
 }
 
+D3D11_Render_Texture :: struct {
+	handle: Render_Texture_Handle,
+	texture: ^d3d11.ITexture2D,
+	texture_view: ^d3d11.IShaderResourceView,
+	depth_stencil_texture: ^d3d11.ITexture2D,
+	depth_stencil_texture_view: ^d3d11.IDepthStencilView,
+	render_target_view: ^d3d11.IRenderTargetView,
+}
+
 dxgi_format_from_pixel_format :: proc(f: Pixel_Format) -> dxgi.FORMAT {
 	switch f {
 	case .Unknown: return .UNKNOWN

+ 7 - 1
render_backend_gl.odin

@@ -20,6 +20,7 @@ RENDER_BACKEND_INTERFACE_GL :: Render_Backend_Interface {
 	load_texture = gl_load_texture,
 	update_texture = gl_update_texture,
 	destroy_texture = gl_destroy_texture,
+	create_render_texture = gl_create_render_texture,
 	set_texture_filter = gl_set_texture_filter,
 	load_shader = gl_load_shader,
 	destroy_shader = gl_destroy_shader,
@@ -137,7 +138,7 @@ gl_shutdown :: proc() {
 	_gl_destroy_context(s.ctx)
 }
 
-gl_clear :: proc(color: Color) {
+gl_clear :: proc(render_texture: Render_Texture_Handle, color: Color) {
 	c := f32_color_from_color(color)
 	gl.ClearColor(c.r, c.g, c.b, c.a)
 	gl.ClearDepth(-1)
@@ -150,6 +151,7 @@ gl_present :: proc() {
 
 gl_draw :: proc(
 	shd: Shader,
+	render_texture: Render_Texture_Handle,
 	bound_textures: []Texture_Handle,
 	scissor: Maybe(Rect),
 	vertex_buffer: []u8,
@@ -378,6 +380,10 @@ gl_destroy_texture :: proc(th: Texture_Handle) {
 	hm.remove(&s.textures, th)
 }
 
+gl_create_render_texture :: proc(width: int, height: int) -> Render_Texture_Handle {
+	return {}
+}
+
 gl_set_texture_filter :: proc(
 	th: Texture_Handle,
 	scale_down_filter: Texture_Filter,

+ 5 - 3
render_backend_interface.odin

@@ -15,19 +15,21 @@ Shader_Desc :: struct {
 	inputs: []Shader_Input,
 }
 
-Render_Backend_Interface :: struct {
+Render_Backend_Interface :: struct #all_or_none {
 	state_size: proc() -> int,
 	init: proc(state: rawptr, window_handle: Window_Handle, swapchain_width, swapchain_height: int, allocator := context.allocator),
 	shutdown: proc(),
-	clear: proc(color: Color),
+	clear: proc(render_texture: Render_Texture_Handle, color: Color),
 	present: proc(),
-	draw: proc(shader: Shader, bound_textures: []Texture_Handle, scissor: Maybe(Rect), vertex_buffer: []u8),
+	draw: proc(shader: Shader, render_texture: Render_Texture_Handle, bound_textures: []Texture_Handle, scissor: Maybe(Rect), vertex_buffer: []u8),
 	set_internal_state: proc(state: rawptr),
 
 	create_texture: proc(width: int, height: int, format: Pixel_Format) -> Texture_Handle,
 	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),
+
+	create_render_texture: proc(width: int, height: int) -> Render_Texture_Handle,
 	
 	set_texture_filter: proc(
 		handle: Texture_Handle,