Procházet zdrojové kódy

Render texture drawing kinda works now. Still needs some improvements.

Karl Zylinski před 3 měsíci
rodič
revize
f6bb46de32

+ 7 - 0
examples/render_texture/render_texture.odin

@@ -45,6 +45,13 @@ main :: proc() {
 		k2.draw_text("Hellöpe!", {10, 100}, 64, k2.WHITE)
 		k2.draw_texture_ex(tex, {0, 0, f32(tex.width), f32(tex.height)}, {10, 200, 900, 500}, {}, 0)
 
+		k2.set_render_texture(nil)
+
+		k2.clear(k2.GRAY)
+		k2.draw_texture(render_texture.texture, {20, 20}, k2.WHITE)
+		k2.draw_texture(render_texture.texture, {100, 500}, k2.WHITE)
+		k2.draw_texture(render_texture.texture, {400, 20}, k2.WHITE)
+
 		k2.present()
 		free_all(context.temp_allocator)
 	}

+ 36 - 13
karl2d.odin

@@ -145,7 +145,7 @@ shutdown :: proc() {
 
 // Clear the backbuffer with supplied color.
 clear :: proc(color: Color) {
-	rb.clear(s.batch_render_texture, color)
+	rb.clear(s.batch_render_target, 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, s.batch_render_texture, shader.texture_bindpoints, s.batch_scissor, s.vertex_buffer_cpu[:s.vertex_buffer_cpu_used])
+	rb.draw(shader, s.batch_render_target, shader.texture_bindpoints, s.batch_scissor, s.vertex_buffer_cpu[:s.vertex_buffer_cpu_used])
 	s.vertex_buffer_cpu_used = 0
 }
 
@@ -841,17 +841,35 @@ set_texture_filter_ex :: proc(
 // RENDER TEXTURES //
 //-----------------//
 
-create_render_texture :: proc(width: int, height: int) -> Render_Texture_Handle {
-	return rb.create_render_texture(width, height)
-}
+create_render_texture :: proc(width: int, height: int) -> Render_Texture {
+	texture, render_target := rb.create_render_texture(width, height)
 
-set_render_texture :: proc(render_texture: Render_Texture_Handle) {
-	if s.batch_render_texture == render_texture {
-		return
+	return {
+		texture = { 
+			handle = texture,
+			width = width,
+			height = height,	
+		},
+		render_target = render_target,
 	}
+}
 
-	draw_current_batch()
-	s.batch_render_texture = render_texture
+set_render_texture :: proc(render_texture: Maybe(Render_Texture)) {
+	if rt, rt_ok := render_texture.?; rt_ok {
+		if s.batch_render_target == rt.render_target {
+			return
+		}
+
+		draw_current_batch()
+		s.batch_render_target = rt.render_target
+	} else {
+		if s.batch_render_target == RENDER_TARGET_NONE {
+			return
+		}
+
+		draw_current_batch()
+		s.batch_render_target = RENDER_TARGET_NONE
+	}
 }
 
 //-------//
@@ -1239,6 +1257,11 @@ Texture :: struct {
 	height: int,
 }
 
+Render_Texture :: struct {
+	texture: Texture,
+	render_target: Render_Target_Handle,
+}
+
 Texture_Filter :: enum {
 	Point,  // Similar to "nearest neighbor". Pixly texture scaling.
 	Linear, // Smoothed texture scaling.
@@ -1345,12 +1368,12 @@ Font :: struct {
 
 Handle :: hm.Handle
 Texture_Handle :: distinct Handle
-Render_Texture_Handle :: distinct Handle
+Render_Target_Handle :: distinct Handle
 Font_Handle :: distinct int
 
 FONT_NONE :: Font_Handle {}
 TEXTURE_NONE :: Texture_Handle {}
-RENDER_TEXTURE_NONE :: Render_Texture_Handle {}
+RENDER_TARGET_NONE :: Render_Target_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
@@ -1395,7 +1418,7 @@ State :: struct {
 	batch_shader: Shader,
 	batch_scissor: Maybe(Rect),
 	batch_texture: Texture_Handle,
-	batch_render_texture: Render_Texture_Handle,
+	batch_render_target: Render_Target_Handle,
 
 	view_matrix: Mat4,
 	proj_matrix: Mat4,

+ 18 - 15
render_backend_d3d11.odin

@@ -174,10 +174,10 @@ d3d11_shutdown :: proc() {
 	s.info_queue->Release()
 }
 
-d3d11_clear :: proc(render_texture: Render_Texture_Handle, color: Color) {
+d3d11_clear :: proc(render_target: Render_Target_Handle, color: Color) {
 	c := f32_color_from_color(color)
 
-	if rt := hm.get(&s.render_textures, render_texture); rt != nil {
+	if rt := hm.get(&s.render_targets, render_target); rt != nil {
 		s.device_context->ClearRenderTargetView(rt.render_target_view, &c)
 		s.device_context->ClearDepthStencilView(rt.depth_stencil_texture_view, {.DEPTH}, 1, 0)	
 	} else {
@@ -192,7 +192,7 @@ d3d11_present :: proc() {
 
 d3d11_draw :: proc(
 	shd: Shader,
-	render_texture: Render_Texture_Handle,
+	render_target: Render_Target_Handle,
 	bound_textures: []Texture_Handle,
 	scissor: Maybe(Rect), 
 	vertex_buffer: []u8,
@@ -313,7 +313,7 @@ d3d11_draw :: proc(
 		}
 	}
 
-	if rt := hm.get(&s.render_textures, render_texture); rt != nil {
+	if rt := hm.get(&s.render_targets, render_target); 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)
@@ -321,8 +321,8 @@ d3d11_draw :: proc(
 
 	dc->OMSetDepthStencilState(s.depth_stencil_state, 0)
 	dc->OMSetBlendState(s.blend_state, nil, ~u32(0))
-
 	dc->Draw(u32(len(vertex_buffer)/shd.vertex_size), 0)
+	dc->OMSetRenderTargets(0, nil, nil)
 	log_messages()
 }
 
@@ -403,7 +403,7 @@ 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 {
+d3d11_create_render_texture :: proc(width: int, height: int) -> (Texture_Handle, Render_Target_Handle) {
 	texture_desc := d3d11.TEXTURE2D_DESC{
 		Width      = u32(width),
 		Height     = u32(height),
@@ -447,15 +447,20 @@ d3d11_create_render_texture :: proc(width: int, height: int) -> Render_Texture_H
 
 	ch(s.device->CreateRenderTargetView(texture, &render_target_view_desc, &render_target_view))
 
-	rtex := D3D11_Render_Texture {
-		texture = texture,
-		texture_view = texture_view,
+	d3d11_texture := D3D11_Texture {
+		tex = texture,
+		view = texture_view,
+		format = .RGBA_32_Float,
+		sampler = create_sampler(.MIN_MAG_MIP_POINT),
+	}
+
+	d3d11_render_target := D3D11_Render_Target {
 		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)
+	return hm.add(&s.textures, d3d11_texture), hm.add(&s.render_targets, d3d11_render_target)
 }
 
 d3d11_load_texture :: proc(data: []u8, width: int, height: int, format: Pixel_Format) -> Texture_Handle {
@@ -921,7 +926,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),
+	render_targets: hm.Handle_Map(D3D11_Render_Target, Render_Target_Handle, 1024*10),
 	shaders: hm.Handle_Map(D3D11_Shader, Shader_Handle, 1024*10),
 
 	info_queue: ^d3d11.IInfoQueue,
@@ -976,10 +981,8 @@ D3D11_Texture :: struct {
 	sampler: ^d3d11.ISamplerState,
 }
 
-D3D11_Render_Texture :: struct {
-	handle: Render_Texture_Handle,
-	texture: ^d3d11.ITexture2D,
-	texture_view: ^d3d11.IShaderResourceView,
+D3D11_Render_Target :: struct {
+	handle: Render_Target_Handle,
 	depth_stencil_texture: ^d3d11.ITexture2D,
 	depth_stencil_texture_view: ^d3d11.IDepthStencilView,
 	render_target_view: ^d3d11.IRenderTargetView,

+ 4 - 4
render_backend_gl.odin

@@ -138,7 +138,7 @@ gl_shutdown :: proc() {
 	_gl_destroy_context(s.ctx)
 }
 
-gl_clear :: proc(render_texture: Render_Texture_Handle, color: Color) {
+gl_clear :: proc(render_texture: Render_Target_Handle, color: Color) {
 	c := f32_color_from_color(color)
 	gl.ClearColor(c.r, c.g, c.b, c.a)
 	gl.ClearDepth(-1)
@@ -151,7 +151,7 @@ gl_present :: proc() {
 
 gl_draw :: proc(
 	shd: Shader,
-	render_texture: Render_Texture_Handle,
+	render_texture: Render_Target_Handle,
 	bound_textures: []Texture_Handle,
 	scissor: Maybe(Rect),
 	vertex_buffer: []u8,
@@ -380,8 +380,8 @@ 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_create_render_texture :: proc(width: int, height: int) -> (Texture_Handle, Render_Target_Handle) {
+	return {}, {}
 }
 
 gl_set_texture_filter :: proc(

+ 11 - 3
render_backend_interface.odin

@@ -19,9 +19,17 @@ 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(render_texture: Render_Texture_Handle, color: Color),
+	clear: proc(render_target: Render_Target_Handle, color: Color),
 	present: proc(),
-	draw: proc(shader: Shader, render_texture: Render_Texture_Handle, bound_textures: []Texture_Handle, scissor: Maybe(Rect), vertex_buffer: []u8),
+	
+	draw: proc(
+		shader: Shader,
+		render_target: Render_Target_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,
@@ -29,7 +37,7 @@ Render_Backend_Interface :: struct #all_or_none {
 	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,
+	create_render_texture: proc(width: int, height: int) -> (Texture_Handle, Render_Target_Handle),
 	
 	set_texture_filter: proc(
 		handle: Texture_Handle,