Ver código fonte

Reworked how constants are exposed from backend to end-user. Now there are only named constants, but those may or may not be backed by a constant buffer behind the scences. This will play nicer with GL while allowing the typical constant buffer blocks of d3d

Karl Zylinski 4 meses atrás
pai
commit
4c468a2972

+ 22 - 0
config.odin

@@ -0,0 +1,22 @@
+package karl2d
+
+when ODIN_OS == .Windows {
+	DEFAULT_BACKEND :: RENDER_BACKEND_INTERFACE_D3D11
+} else {
+	DEFAULT_BACKEND :: RENDER_BACKEND_INTERFACE_GL
+}
+
+CUSTOM_BACKEND_STR :: #config(KARL2D_BACKEND, "")
+
+when CUSTOM_BACKEND_STR != "" {
+	when CUSTOM_BACKEND_STR == "gl" {
+		BACKEND :: RENDER_BACKEND_INTERFACE_GL
+	} else when CUSTOM_BACKEND_STR == "d3d11" {
+		BACKEND :: RENDER_BACKEND_INTERFACE_D3D11
+	} else {
+		#panic(CUSTOM_BACKEND_STR + " is not a valid value for KARL2D_BACKEND. Available backends are: gl, d3d11")
+		BACKEND :: DEFAULT_BACKEND
+	}
+} else {
+	BACKEND :: DEFAULT_BACKEND
+}

+ 1 - 0
examples/minimal/minimal.odin

@@ -11,6 +11,7 @@ main :: proc() {
 	for !k2.shutdown_wanted() {
 		k2.process_events()
 		k2.clear(k2.BLUE)
+
 		k2.draw_rect({10, 10, 60, 60}, k2.GREEN)
 		k2.draw_rect({20, 20, 40, 40}, k2.BLACK)
 		k2.draw_circle({120, 40}, 30, k2.BLACK)

+ 47 - 47
examples/raylib_ports/shaders_texture_waves/shaders_texture_waves.odin

@@ -10,49 +10,49 @@ SCREEN_WIDTH :: 800
 SCREEN_HEIGHT :: 450
 
 main :: proc() {
-    context.logger = log.create_console_logger()
-
-    k2.init(SCREEN_WIDTH, SCREEN_HEIGHT, "Karl2D: texture waves (raylib [shaders] example - texture waves)")
-
-    texture := k2.load_texture_from_file("space.png")
-
-    WAVE_SHADER_DATA :: #load("wave.hlsl")
-
-    shader := k2.load_shader(string(WAVE_SHADER_DATA), string(WAVE_SHADER_DATA))
-    seconds_loc := shader.constant_lookup["seconds"]
-    freq_x_loc := shader.constant_lookup["freqX"]
-    freq_y_loc := shader.constant_lookup["freqY"]
-    amp_x_loc := shader.constant_lookup["ampX"]
-    amp_y_loc := shader.constant_lookup["ampY"]
-    speed_x_loc := shader.constant_lookup["speedX"]
-    speed_y_loc := shader.constant_lookup["speedY"]
-
-    freq_x := f32(25)
-    freq_y := f32(25)
-    amp_x := f32(5)
-    amp_y := f32(5)
-    speed_x := f32(8)
-    speed_y := f32(8)
-
-    screen_size := [2]f32 { f32(k2.get_screen_width()),	f32(k2.get_screen_height()) }
-    k2.set_shader_constant(shader, shader.constant_lookup["size"], screen_size)
-    k2.set_shader_constant(shader, freq_x_loc, freq_x)
-    k2.set_shader_constant(shader, freq_y_loc, freq_y)
-    k2.set_shader_constant(shader, amp_x_loc, amp_x)
-    k2.set_shader_constant(shader, amp_y_loc, amp_y)
-    k2.set_shader_constant(shader, speed_x_loc, speed_x)
-    k2.set_shader_constant(shader, speed_y_loc, speed_y)
-
-    seconds: f32
-
-    last_frame_time := time.now()
-
-    for !k2.shutdown_wanted() {
-    	k2.process_events()
-    	now := time.now()
-    	dt := f32(time.duration_seconds(time.diff(last_frame_time, now)))
-    	last_frame_time = now
-    	seconds += dt
+	context.logger = log.create_console_logger()
+
+	k2.init(SCREEN_WIDTH, SCREEN_HEIGHT, "Karl2D: texture waves (raylib [shaders] example - texture waves)")
+
+	texture := k2.load_texture_from_file("space.png")
+
+	WAVE_SHADER_DATA :: #load("wave.hlsl")
+
+	shader := k2.load_shader(string(WAVE_SHADER_DATA), string(WAVE_SHADER_DATA))
+	seconds_loc := shader.constant_lookup["seconds"]
+	freq_x_loc := shader.constant_lookup["freqX"]
+	freq_y_loc := shader.constant_lookup["freqY"]
+	amp_x_loc := shader.constant_lookup["ampX"]
+	amp_y_loc := shader.constant_lookup["ampY"]
+	speed_x_loc := shader.constant_lookup["speedX"]
+	speed_y_loc := shader.constant_lookup["speedY"]
+
+	freq_x := f32(25)
+	freq_y := f32(25)
+	amp_x := f32(5)
+	amp_y := f32(5)
+	speed_x := f32(8)
+	speed_y := f32(8)
+
+	screen_size := [2]f32 { f32(k2.get_screen_width()),	f32(k2.get_screen_height()) }
+	k2.set_shader_constant(shader, shader.constant_lookup["size"], screen_size)
+	k2.set_shader_constant(shader, freq_x_loc, freq_x)
+	k2.set_shader_constant(shader, freq_y_loc, freq_y)
+	k2.set_shader_constant(shader, amp_x_loc, amp_x)
+	k2.set_shader_constant(shader, amp_y_loc, amp_y)
+	k2.set_shader_constant(shader, speed_x_loc, speed_x)
+	k2.set_shader_constant(shader, speed_y_loc, speed_y)
+
+	seconds: f32
+
+	last_frame_time := time.now()
+
+	for !k2.shutdown_wanted() {
+		k2.process_events()
+		now := time.now()
+		dt := f32(time.duration_seconds(time.diff(last_frame_time, now)))
+		last_frame_time = now
+		seconds += dt
 
 		k2.set_shader_constant(shader, seconds_loc, seconds)
 		k2.set_shader(shader)
@@ -62,10 +62,10 @@ main :: proc() {
 
 		k2.set_shader(nil)
 		k2.present()
-    }
+	}
 
-    k2.destroy_shader(shader)
-    k2.destroy_texture(texture)
+	k2.destroy_shader(shader)
+	k2.destroy_texture(texture)
 
-    k2.shutdown()
+	k2.shutdown()
 }

+ 10 - 10
examples/raylib_ports/shaders_texture_waves/wave.hlsl

@@ -11,21 +11,21 @@ cbuffer constants : register(b0) {
 	float speedY;
 }
 struct vs_in {
-	float3 position : POS;
-	float2 uv       : UV;
-	float4 color    : COL;
+	float3 position : position;
+	float2 texcoord : texcoord;
+	float4 color    : color;
 };
 struct vs_out {
 	float4 position : SV_POSITION;
-	float2 uv       : UV;
-	float4 color    : COL;
+	float2 texcoord : texcoord;
+	float4 color    : color;
 };
 Texture2D    tex : register(t0);
 SamplerState smp : register(s0);
 vs_out vs_main(vs_in input) {
 	vs_out output;
-	output.position = mul(mvp, float4(input.position, 0, 1.0f));
-	output.uv = input.uv;
+	output.position = mul(mvp, float4(input.position, 1.0f));
+	output.texcoord = input.texcoord;
 	output.color = input.color;
 	return output;
 }
@@ -36,9 +36,9 @@ float4 ps_main(vs_out input) : SV_TARGET {
 	float boxLeft = 0.0;
 	float boxTop = 0.0;
 
-	float2 p = input.uv;
-    p.x += cos((input.uv.y - boxTop)*freqX/(pixelWidth*750.0) + (seconds*speedX))*ampX*pixelWidth;
-    p.y += sin((input.uv.x - boxLeft)*freqY*aspect/(pixelHeight*750.0) + (seconds*speedY))*ampY*pixelHeight;
+	float2 p = input.texcoord;
+    p.x += cos((input.texcoord.y - boxTop)*freqX/(pixelWidth*750.0) + (seconds*speedX))*ampX*pixelWidth;
+    p.y += sin((input.texcoord.x - boxLeft)*freqY*aspect/(pixelHeight*750.0) + (seconds*speedY))*ampY*pixelHeight;
 
 	float4 c = tex.Sample(smp, p);
 	return c * input.color;

+ 23 - 12
karl2d.doc.odin

@@ -136,6 +136,10 @@ draw_texture_rect :: proc(tex: Texture, rect: Rect, pos: Vec2, tint := WHITE)
 
 draw_texture_ex :: proc(tex: Texture, src: Rect, dst: Rect, origin: Vec2, rotation: f32, tint := WHITE)
 
+vec3 :: proc(v2: Vec2, z: f32) -> Vec3
+
+get_next_depth :: proc() -> f32
+
 measure_text :: proc(text: string, font_size: f32) -> Vec2
 
 draw_text :: proc(text: string, pos: Vec2, font_size: f32, color: Color)
@@ -174,7 +178,7 @@ get_default_font :: proc() -> Font_Handle
 //---------//
 // SHADERS //
 //---------//
-load_shader :: proc(shader_source: string, layout_formats: []Pixel_Format = {}) -> Shader
+load_shader :: proc(vertex_shader_source: string, fragment_shader_source: string, layout_formats: []Pixel_Format = {}) -> Shader
 
 destroy_shader :: proc(shader: Shader)
 
@@ -236,7 +240,8 @@ Color :: [4]u8
 WHITE :: Color { 255, 255, 255, 255 }
 BLACK :: Color { 0, 0, 0, 255 }
 GRAY  :: Color { 127, 127, 127, 255 }
-RED   :: Color { 198, 80, 90, 255 }
+RED   :: Color { 198, 40, 90, 255 }
+GREEN :: Color { 30, 240, 30, 255 }
 BLANK :: Color { 0, 0, 0, 0 }
 BLUE  :: Color { 30, 116, 240, 255 }
 
@@ -291,10 +296,22 @@ Shader_Handle :: distinct Handle
 
 SHADER_NONE :: Shader_Handle {}
 
+Shader_Constant_Location :: struct {
+	offset: int,
+	size: int,
+}
+
 Shader :: struct {
 	handle: Shader_Handle,
-	constant_buffers: []Shader_Constant_Buffer,
+
+	// We store the CPU-side value of all constants in a single buffer to have less allocations.
+	// The 'constants' array says where in this buffer each constant is, and 'constant_lookup'
+	// maps a name to a constant location.
+	constants_data: []u8,
+	constants: []Shader_Constant_Location,
 	constant_lookup: map[string]Shader_Constant_Location,
+
+	// Maps built in constant types such as "model view projection matrix" to a location.
 	constant_builtin_locations: [Shader_Builtin_Constant]Maybe(Shader_Constant_Location),
 
 	inputs: []Shader_Input,
@@ -303,10 +320,6 @@ Shader :: struct {
 	vertex_size: int,
 }
 
-Shader_Constant_Buffer :: struct {
-	cpu_data: []u8,
-}
-
 SHADER_INPUT_VALUE_MAX_SIZE :: 256
 
 Shader_Input_Value_Override :: struct {
@@ -339,11 +352,6 @@ Shader_Input :: struct {
 	format: Pixel_Format,
 }
 
-Shader_Constant_Location :: struct {
-	buffer_idx: u32,
-	offset: u32,
-}
-
 Pixel_Format :: enum {
 	Unknown,
 	
@@ -422,6 +430,9 @@ State :: struct {
 	view_matrix: Mat4,
 	proj_matrix: Mat4,
 
+	depth: f32,
+	depth_start: f32,
+	depth_increment: f32,
 	vertex_buffer_cpu: []u8,
 	vertex_buffer_cpu_used: int,
 	default_shader: Shader,

+ 59 - 60
karl2d.odin

@@ -24,27 +24,6 @@ import hm "handle_map"
 // SETUP, WINDOW MANAGEMENT AND FRAME MANAGEMENT //
 //-----------------------------------------------//
 
-when ODIN_OS == .Windows {
-	DEFAULT_BACKEND :: RENDER_BACKEND_INTERFACE_D3D11
-} else {
-	DEFAULT_BACKEND :: RENDER_BACKEND_INTERFACE_GL
-}
-
-CUSTOM_BACKEND_STR :: #config(KARL2D_BACKEND, "")
-
-when CUSTOM_BACKEND_STR != "" {
-	when CUSTOM_BACKEND_STR == "gl" {
-		BACKEND :: RENDER_BACKEND_INTERFACE_GL
-	} else when CUSTOM_BACKEND_STR == "d3d11" {
-		BACKEND :: RENDER_BACKEND_INTERFACE_D3D11
-	} else {
-		#panic(CUSTOM_BACKEND_STR + " is not a valid value for KARL2D_BACKEND. Available backends are: gl, d3d11")
-		BACKEND :: DEFAULT_BACKEND
-	}
-} else {
-	BACKEND :: DEFAULT_BACKEND
-}
-
 // Opens a window and initializes some internal state. The internal state will use `allocator` for
 // all dynamically allocated memory. The return value can be ignored unless you need to later call
 // `set_internal_state`.
@@ -143,6 +122,7 @@ shutdown :: proc() {
 // Clear the backbuffer with supplied color.
 clear :: proc(color: Color) {
 	rb.clear(color)
+	s.depth = s.depth_start
 }
 
 // Present the backbuffer. Call at end of frame to make everything you've drawn appear on the screen.
@@ -150,7 +130,6 @@ present :: proc() {
 	draw_current_batch()
 	rb.present()
 	free_all(s.frame_allocator)
-	s.depth = s.depth_start
 }
 
 // Call at start or end of frame to process all events that have arrived to the window.
@@ -278,20 +257,26 @@ set_window_flags :: proc(flags: Window_Flags) {
 draw_current_batch :: proc() {
 	update_font(s.batch_font)
 
+	if s.vertex_buffer_cpu_used == 0 {
+		return
+	}
+
 	shader := s.batch_shader
 
 	mvp := s.proj_matrix * s.view_matrix
 	for mloc, builtin in shader.constant_builtin_locations {
-		loc, loc_ok := mloc.?
+		constant, constant_ok := mloc.?
 
-		if !loc_ok {
+		if !constant_ok {
 			continue
 		}
 
 		switch builtin {
 		case .MVP:
-			dst := (^matrix[4,4]f32)(&shader.constant_buffers[loc.buffer_idx].cpu_data[loc.offset])
-			dst^ = mvp
+			if constant.size == size_of(mvp) {
+				dst := (^matrix[4,4]f32)(&shader.constants_data[constant.offset])
+				dst^ = mvp
+			} 
 		}
 	}
 
@@ -855,9 +840,16 @@ load_shader :: proc(vertex_shader_source: string, fragment_shader_source: string
 		return {}
 	}
 
+	constants_size: int
+
+	for c in desc.constants {
+		constants_size += c.size
+	}
+
 	shd := Shader {
 		handle = handle,
-		constant_buffers = make([]Shader_Constant_Buffer, len(desc.constant_buffers), s.allocator),
+		constants_data = make([]u8, constants_size, s.allocator),
+		constants = make([]Shader_Constant_Location, len(desc.constants), s.allocator),
 		constant_lookup = make(map[string]Shader_Constant_Location, s.allocator),
 		inputs = slice.clone(desc.inputs, s.allocator),
 		input_overrides = make([]Shader_Input_Value_Override, len(desc.inputs), s.allocator),
@@ -867,23 +859,26 @@ load_shader :: proc(vertex_shader_source: string, fragment_shader_source: string
 		input.name = strings.clone(input.name, s.allocator)
 	}
 
-	for cb_idx in 0..<len(desc.constant_buffers) {
-		cb_desc := &desc.constant_buffers[cb_idx]
+	constant_offset: int
 
-		shd.constant_buffers[cb_idx] = {
-			cpu_data = make([]u8, desc.constant_buffers[cb_idx].size, s.allocator),
+	for cidx in 0..<len(desc.constants) {
+		constant_desc := &desc.constants[cidx]
+
+		loc := Shader_Constant_Location {
+			offset = constant_offset,
+			size = constant_desc.size,
 		}
 
-		for &v in cb_desc.variables {
-			if v.name == "" {
-				continue
-			}
+		shd.constants[cidx] = loc 
 
-			shd.constant_lookup[strings.clone(v.name, s.allocator)] = v.loc
+		constant_offset += constant_desc.size
 
-			switch v.name {
+		if constant_desc.name != "" {
+			shd.constant_lookup[strings.clone(constant_desc.name, s.allocator)] = loc
+
+			switch constant_desc.name {
 			case "mvp":
-				shd.constant_builtin_locations[.MVP] = v.loc
+				shd.constant_builtin_locations[.MVP] = loc
 			}
 		}
 	}
@@ -910,11 +905,8 @@ load_shader :: proc(vertex_shader_source: string, fragment_shader_source: string
 destroy_shader :: proc(shader: Shader) {
 	rb.destroy_shader(shader.handle)
 
-	for c in shader.constant_buffers {
-		delete(c.cpu_data)
-	}
-	
-	delete(shader.constant_buffers)
+	delete(shader.constants_data)
+	delete(shader.constants)
 
 	for k, _ in shader.constant_lookup {
 		delete(k)
@@ -948,22 +940,26 @@ set_shader :: proc(shader: Maybe(Shader)) {
 }
 
 set_shader_constant :: proc(shd: Shader, loc: Shader_Constant_Location, val: any) {
+	if shd.handle == SHADER_NONE {
+		log.error("Invalid shader")
+		return
+	}
+
 	draw_current_batch()
 
-	if int(loc.buffer_idx) >= len(shd.constant_buffers) {
-		log.warnf("Constant buffer idx %v is out of bounds", loc.buffer_idx)
+	if loc.offset + loc.size > len(shd.constants_data) {
+		log.errorf("Constant with offset %v and size %v is out of bounds. Buffer ends at %v", loc.offset, loc.size, len(shd.constants_data))
 		return
 	}
 
 	sz := reflect.size_of_typeid(val.id)
-	b := &shd.constant_buffers[loc.buffer_idx]
 
-	if int(loc.offset) + sz > len(b.cpu_data) {
-		log.warnf("Constant buffer idx %v is trying to be written out of bounds by at offset %v with %v bytes", loc.buffer_idx, loc.offset, size_of(val))
+	if sz != loc.size {
+		log.errorf("Trying to set constant of type %v, but it is not of correct size %v", val.id, loc.size)
 		return
 	}
 
-	mem.copy(&b.cpu_data[loc.offset], val.data, sz)
+	mem.copy(&shd.constants_data[loc.offset], val.data, sz)
 }
 
 override_shader_input :: proc(shader: Shader, input: int, val: any) {
@@ -1160,10 +1156,22 @@ Shader_Handle :: distinct Handle
 
 SHADER_NONE :: Shader_Handle {}
 
+Shader_Constant_Location :: struct {
+	offset: int,
+	size: int,
+}
+
 Shader :: struct {
 	handle: Shader_Handle,
-	constant_buffers: []Shader_Constant_Buffer,
+
+	// We store the CPU-side value of all constants in a single buffer to have less allocations.
+	// The 'constants' array says where in this buffer each constant is, and 'constant_lookup'
+	// maps a name to a constant location.
+	constants_data: []u8,
+	constants: []Shader_Constant_Location,
 	constant_lookup: map[string]Shader_Constant_Location,
+
+	// Maps built in constant types such as "model view projection matrix" to a location.
 	constant_builtin_locations: [Shader_Builtin_Constant]Maybe(Shader_Constant_Location),
 
 	inputs: []Shader_Input,
@@ -1172,10 +1180,6 @@ Shader :: struct {
 	vertex_size: int,
 }
 
-Shader_Constant_Buffer :: struct {
-	cpu_data: []u8,
-}
-
 SHADER_INPUT_VALUE_MAX_SIZE :: 256
 
 Shader_Input_Value_Override :: struct {
@@ -1208,11 +1212,6 @@ Shader_Input :: struct {
 	format: Pixel_Format,
 }
 
-Shader_Constant_Location :: struct {
-	buffer_idx: u32,
-	offset: u32,
-}
-
 Pixel_Format :: enum {
 	Unknown,
 	
@@ -1666,7 +1665,7 @@ set_font :: proc(fh: Font_Handle) {
 }
 
 DEPTH_START :: -0.99
-DEPTH_INCREMENT :: (1.0/20000.0) // I've stolen this number from raylib.
+DEPTH_INCREMENT :: (1.0/10000000.0)
 
 _ :: jpeg
 _ :: bmp

+ 59 - 22
render_backend_d3d11.odin

@@ -230,24 +230,50 @@ d3d11_draw :: proc(shd: Shader, texture: Texture_Handle, scissor: Maybe(Rect), v
 
 	dc->VSSetShader(d3d_shd.vertex_shader, nil, 0)
 
-	assert(len(shd.constant_buffers) == len(d3d_shd.constant_buffers))
+	assert(len(shd.constants) == len(d3d_shd.constants))
 
-	for cb_idx in 0..<len(shd.constant_buffers) {
-		cpu_data := shd.constant_buffers[cb_idx].cpu_data
-		gpu_data := d3d_shd.constant_buffers[cb_idx].gpu_data
+	maps := make([]rawptr, len(d3d_shd.constant_buffers), frame_allocator)
+
+	cpu_data := shd.constants_data
+	for cidx in 0..<len(shd.constants) {
+		cpu_loc := shd.constants[cidx]
+		gpu_loc := d3d_shd.constants[cidx]
+		gpu_buffer_info := d3d_shd.constant_buffers[gpu_loc.buffer_idx]
+		gpu_data := gpu_buffer_info.gpu_data
 		
 		if gpu_data == nil {
 			continue
 		}
 
-		cb_data: d3d11.MAPPED_SUBRESOURCE
-		ch(dc->Map(gpu_data, 0, .WRITE_DISCARD, {}, &cb_data))
-		mem.copy(cb_data.pData, raw_data(cpu_data), len(cpu_data))
-		dc->Unmap(gpu_data, 0)
-		dc->VSSetConstantBuffers(u32(cb_idx), 1, &gpu_data)
-		dc->PSSetConstantBuffers(u32(cb_idx), 1, &gpu_data)
+		if maps[gpu_loc.buffer_idx] == nil {
+			// We do this little dance with the 'maps' array so we only have to map the memory once.
+			// There can be multiple constants within a single constant buffer. So mapping and
+			// unmapping for each one is slow.
+			map_data: d3d11.MAPPED_SUBRESOURCE
+			ch(dc->Map(gpu_data, 0, .WRITE_DISCARD, {}, &map_data))
+			maps[gpu_loc.buffer_idx] = map_data.pData
+		}
+
+		data_slice := slice.bytes_from_ptr(maps[gpu_loc.buffer_idx], gpu_buffer_info.size)
+		dst := data_slice[gpu_loc.offset:gpu_loc.offset+u32(cpu_loc.size)]
+		src := cpu_data[cpu_loc.offset:cpu_loc.offset+cpu_loc.size]
+		copy(dst, src)
+	}
+
+	constant_buffers := make([]^d3d11.IBuffer, len(d3d_shd.constant_buffers), frame_allocator)
+	for cb, cb_idx in d3d_shd.constant_buffers {
+		constant_buffers[cb_idx] = cb.gpu_data
+
+		if maps[cb_idx] != nil {
+			dc->Unmap(cb.gpu_data, 0)
+			maps[cb_idx] = nil
+		}
 	}
 
+
+	dc->VSSetConstantBuffers(0, u32(len(constant_buffers)), raw_data(constant_buffers))
+	dc->PSSetConstantBuffers(0, u32(len(constant_buffers)), raw_data(constant_buffers))
+
 	dc->RSSetViewports(1, &viewport)
 	dc->RSSetState(s.rasterizer_state)
 
@@ -470,7 +496,8 @@ d3d11_load_shader :: proc(vs_source: string, ps_source: string, desc_allocator :
 	}
 
 	{
-		desc.constant_buffers = make([]Shader_Constant_Buffer_Desc, d3d_desc.ConstantBuffers, desc_allocator)
+		constant_descs: [dynamic]Shader_Constant_Desc
+		d3d_constants: [dynamic]D3D11_Shader_Constant
 		d3d_shd.constant_buffers = make([]D3D11_Shader_Constant_Buffer, d3d_desc.ConstantBuffers, s.allocator)
 
 		for cb_idx in 0..<d3d_desc.ConstantBuffers {
@@ -495,10 +522,7 @@ d3d11_load_shader :: proc(vs_source: string, ps_source: string, desc_allocator :
 			}
 
 			ch(s.device->CreateBuffer(&constant_buffer_desc, nil, &d3d_shd.constant_buffers[cb_idx].gpu_data))
-
-			variables := make([]Shader_Constant_Buffer_Variable_Desc, cb_desc.Variables, desc_allocator)
-			desc.constant_buffers[cb_idx].variables = variables
-			desc.constant_buffers[cb_idx].size = int(cb_desc.Size)
+			d3d_shd.constant_buffers[cb_idx].size = int(cb_desc.Size)
 
 			for var_idx in 0..<cb_desc.Variables {
 				var_info := cb_info->GetVariableByIndex(var_idx)
@@ -511,16 +535,21 @@ d3d11_load_shader :: proc(vs_source: string, ps_source: string, desc_allocator :
 				var_info->GetDesc(&var_desc)
 
 				if var_desc.Name != "" {
-					variables[var_idx] = {
+					append(&constant_descs, Shader_Constant_Desc {
 						name = strings.clone_from_cstring(var_desc.Name, desc_allocator),
-						loc = {
-							buffer_idx = cb_idx,
-							offset = var_desc.StartOffset,
-						},
-					}
+						size = int(var_desc.Size),
+					})
+
+					append(&d3d_constants, D3D11_Shader_Constant {
+						buffer_idx = cb_idx,
+						offset = var_desc.StartOffset,
+					})
 				}
 			}
 		}
+
+		desc.constants = constant_descs[:]
+		d3d_shd.constants = d3d_constants[:]
 	}
 
 	input_layout_desc := make([]d3d11.INPUT_ELEMENT_DESC, len(desc.inputs), frame_allocator)
@@ -562,7 +591,7 @@ d3d11_destroy_shader :: proc(h: Shader_Handle) {
 	shd := hm.get(&s.shaders, h)
 
 	if shd == nil {
-		log.error("Invalid shader %v", h)
+		log.errorf("Invalid shader: %v", h)
 		return
 	}
 
@@ -586,6 +615,12 @@ s: ^D3D11_State
 
 D3D11_Shader_Constant_Buffer :: struct {
 	gpu_data: ^d3d11.IBuffer,
+	size: int,
+}
+
+D3D11_Shader_Constant :: struct {
+	buffer_idx: u32,
+	offset: u32,
 }
 
 D3D11_Shader :: struct {
@@ -594,6 +629,7 @@ D3D11_Shader :: struct {
 	pixel_shader: ^d3d11.IPixelShader,
 	input_layout: ^d3d11.IInputLayout,
 	constant_buffers: []D3D11_Shader_Constant_Buffer,
+	constants: []D3D11_Shader_Constant,
 }
 
 D3D11_State :: struct {
@@ -650,6 +686,7 @@ create_swapchain :: proc(w, h: int) {
 
 	ch(s.device->CreateTexture2D(&depth_buffer_desc, nil, &s.depth_buffer))
 	ch(s.device->CreateDepthStencilView(s.depth_buffer, nil, &s.depth_buffer_view))
+	s.device_context->ClearDepthStencilView(s.depth_buffer_view, {.DEPTH}, 1, 0)
 }
 
 D3D11_Texture :: struct {

+ 2 - 1
render_backend_gl.odin

@@ -1,4 +1,5 @@
-#+build windows, darwin, linux
+#+ignore
+//#+build windows, darwin, linux
 #+private file
 
 package karl2d

+ 2 - 8
render_backend_interface.odin

@@ -1,18 +1,12 @@
 package karl2d
 
-Shader_Constant_Buffer_Desc :: struct {
+Shader_Constant_Desc :: struct {
 	name: string,
 	size: int,
-	variables: []Shader_Constant_Buffer_Variable_Desc,
-}
-
-Shader_Constant_Buffer_Variable_Desc :: struct {
-	name: string,
-	loc: Shader_Constant_Location,
 }
 
 Shader_Desc :: struct {
-	constant_buffers: []Shader_Constant_Buffer_Desc,
+	constants: []Shader_Constant_Desc,
 	inputs: []Shader_Input,
 }