浏览代码

GL shader loading WIP and default shaders

Karl Zylinski 4 月之前
父节点
当前提交
e83b4f72b0
共有 6 个文件被更改,包括 124 次插入14 次删除
  1. 12 0
      default_shader_fragment.glsl
  2. 16 0
      default_shader_vertex.glsl
  3. 3 4
      karl2d.odin
  4. 12 0
      render_backend_d3d11.odin
  5. 78 10
      render_backend_gl.odin
  6. 3 0
      render_backend_interface.odin

+ 12 - 0
default_shader_fragment.glsl

@@ -0,0 +1,12 @@
+#version 330
+in vec2 frag_uv;
+in vec4 frag_color;
+out vec4 final_color;
+
+uniform sampler2D tex;
+
+void main()
+{
+    vec4 c = texture(tex, frag_uv);
+    final_color = c * frag_color;
+}

+ 16 - 0
default_shader_vertex.glsl

@@ -0,0 +1,16 @@
+#version 330
+in vec2 position;
+in vec2 uv;
+in vec4 color;
+
+out vec2 frag_uv;
+out vec4 frag_color;
+
+uniform mat4 mvp;
+
+void main()
+{
+    frag_uv = uv;
+    frag_color = color;
+    gl_Position = mvp*vec4(position, 0.0, 1.0);
+}

+ 3 - 4
karl2d.odin

@@ -65,7 +65,7 @@ init :: proc(window_width: int, window_height: int, window_title: string,
 	slice.fill(white_rect[:], 255)
 	s.shape_drawing_texture = rb.load_texture(white_rect[:], 16, 16, .RGBA_8_Norm)
 
-	s.default_shader = load_shader(string(DEFAULT_SHADER_SOURCE))
+	s.default_shader = load_shader(rb.default_shader_vertex_source(), rb.default_shader_fragment_source())
 	s.batch_shader = s.default_shader
 	/*if font, font_err := load_default_font(); font_err == .OK {
 		s.default_font = font
@@ -780,8 +780,8 @@ get_default_font :: proc() -> Font_Handle {
 // SHADERS //
 //---------//
 
-load_shader :: proc(shader_source: string, layout_formats: []Pixel_Format = {}) -> Shader {
-	handle, desc := rb.load_shader(shader_source, shader_source, s.frame_allocator, layout_formats)
+load_shader :: proc(vertex_shader_source: string, fragment_shader_source: string, layout_formats: []Pixel_Format = {}) -> Shader {
+	handle, desc := rb.load_shader(vertex_shader_source, fragment_shader_source, s.frame_allocator, layout_formats)
 
 	if handle == SHADER_NONE {
 		log.error("Failed loading shader")
@@ -1447,7 +1447,6 @@ batch_vertex :: proc(v: Vec2, uv: Vec2, color: Color) {
 
 
 VERTEX_BUFFER_MAX :: 1000000
-DEFAULT_SHADER_SOURCE :: #load("shader.hlsl")
 
 @(private="file")
 s: ^State

+ 12 - 0
render_backend_d3d11.odin

@@ -21,6 +21,8 @@ RENDER_BACKEND_INTERFACE_D3D11 :: Render_Backend_Interface {
 	destroy_texture = d3d11_destroy_texture,
 	load_shader = d3d11_load_shader,
 	destroy_shader = d3d11_destroy_shader,
+	default_shader_vertex_source = d3d11_default_shader_vertex_source,
+	default_shader_fragment_source = d3d11_default_shader_fragment_source,
 }
 
 import d3d11 "vendor:directx/d3d11"
@@ -730,4 +732,14 @@ log_messages :: proc(loc := #caller_location) {
 	}
 
 	iq->ClearStoredMessages()
+}
+
+DEFAULT_SHADER_SOURCE :: #load("shader.hlsl")
+
+d3d11_default_shader_vertex_source :: proc() -> string {
+	return string(DEFAULT_SHADER_SOURCE)
+}
+
+d3d11_default_shader_fragment_source :: proc() -> string {
+	return string(DEFAULT_SHADER_SOURCE)
 }

+ 78 - 10
render_backend_gl.odin

@@ -21,6 +21,9 @@ RENDER_BACKEND_INTERFACE_GL :: Render_Backend_Interface {
 	destroy_texture = gl_destroy_texture,
 	load_shader = gl_load_shader,
 	destroy_shader = gl_destroy_shader,
+
+	default_shader_vertex_source = gl_default_shader_vertex_source,
+	default_shader_fragment_source = gl_default_shader_fragment_source,
 }
 
 import "base:runtime"
@@ -148,36 +151,91 @@ compile_shader_from_source :: proc(shader_data: string, shader_type: gl.Shader_T
 	gl.CompileShader(shader_id)
 
 	result: i32
-	if result == 0 {
-		gl.GetShaderiv(shader_id, gl.COMPILE_STATUS, &result)
+	gl.GetShaderiv(shader_id, gl.COMPILE_STATUS, &result)
+		
+	if result != 1 {
 		info_len: i32
 		gl.GetShaderInfoLog(shader_id, i32(len(err_buf)), &info_len, raw_data(err_buf))
 		err_msg^ = string(err_buf[:info_len])
+		gl.DeleteShader(shader_id)
 		return 0, false
 	}
 
 	return shader_id, true
 }
 
+link_shader :: proc(vs_shader: u32, fs_shader: u32, err_buf: []u8, err_msg: ^string) -> (program_id: u32, ok: bool) {
+	program_id = gl.CreateProgram()
+	gl.AttachShader(program_id, vs_shader)
+	gl.AttachShader(program_id, fs_shader)
+	gl.LinkProgram(program_id)
+
+	result: i32
+	gl.GetProgramiv(program_id, gl.LINK_STATUS, &result)
+
+	if result != 1 {
+		info_len: i32
+		gl.GetProgramInfoLog(program_id, i32(len(err_buf)), &info_len, raw_data(err_buf))
+		err_msg^ = string(err_buf[:info_len])
+		gl.DeleteProgram(program_id)
+		return 0, false
+	}
+
+	return program_id, true
+}
+
 gl_load_shader :: proc(vs_source: string, fs_source: string, desc_allocator := frame_allocator, layout_formats: []Pixel_Format = {}) -> (handle: Shader_Handle, desc: Shader_Desc) {
 	@static err: [1024]u8
 	err_msg: string
 	vs_shader, vs_shader_ok := compile_shader_from_source(vs_source, gl.Shader_Type.VERTEX_SHADER, err[:], &err_msg)
 
-	if vs_shader_ok  {
-		log.info(err_msg)
+	if !vs_shader_ok  {
+		log.error(err_msg)
+		return {}, {}
 	}
 	
 	fs_shader, fs_shader_ok := compile_shader_from_source(fs_source, gl.Shader_Type.FRAGMENT_SHADER, err[:], &err_msg)
 
 	if !fs_shader_ok {
-		log.info(err_msg)
+		log.error(err_msg)
+		return {}, {}
+	}
+
+	program, program_ok := link_shader(vs_shader, fs_shader, err[:], &err_msg)
+
+	if !program_ok {
+		log.error(err_msg)
+		return {}, {}
 	}
 
-	program := gl.CreateProgram()
-	gl.AttachShader(program, vs_shader)
-	gl.AttachShader(program, fs_shader)
-	gl.LinkProgram(program)
+	{
+		num_attribs: i32
+		gl.GetProgramiv(program, gl.ACTIVE_ATTRIBUTES, &num_attribs)
+		desc.inputs = make([]Shader_Input, num_attribs, desc_allocator)
+
+		attrib_name_buf: [256]u8
+
+		for i in 0..<num_attribs {
+			attrib_name_len: i32
+			attrib_size: i32
+			attrib_type: u32
+			gl.GetActiveAttrib(program, u32(i), i32(len(attrib_name_buf)), &attrib_name_len, &attrib_size, &attrib_type, raw_data(attrib_name_buf[:]))
+
+			type: Shader_Input_Type
+
+			switch attrib_type {
+				case gl.FLOAT: type = .F32
+				case gl.FLOAT_VEC2: type = .Vec2
+				case gl.FLOAT_VEC3: type = .Vec3
+				case gl.FLOAT_VEC4: type = .Vec4
+				case: log.errorf("Unknwon type: %v", attrib_type)
+			}
+
+			// olic constants GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4, GL_FLOAT_MAT2, GL_FLOAT_MAT3, GL_FLOAT_MAT4, GL_FLOAT_MAT2x3, GL_FLOAT_MAT2x4, GL_FLOAT_MAT3x2, GL_FLOAT_MAT3x4, GL_FLOAT_MAT4x2, GL_FLOAT_MAT4x3, GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4, GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT_VEC4, GL_DOUBLE, GL_DOUBLE_VEC2, GL_DOUBLE_VEC3, GL_DOUBLE_VEC4, GL_DOUBLE_MAT2, GL_DOUBLE_MAT3, GL_DOUBLE_MAT4, GL_DOUBLE_MAT2x3, GL_DOUBLE_MAT2x4, GL_DOUBLE_MAT3x2, GL_DOUBLE_MAT3x4, GL_DOUBLE_MAT4x2, or GL_DOUBLE_MAT4x3 may be retur
+
+			//log.info(i, attrib_name_len, attrib_size, attrib_type, string(attrib_name_buf[:attrib_name_len]))
+		}
+	}
 
 	shader := GL_Shader {
 		program = program,
@@ -190,4 +248,14 @@ gl_load_shader :: proc(vs_source: string, fs_source: string, desc_allocator := f
 
 gl_destroy_shader :: proc(h: Shader_Handle) {
 	
-}
+}
+
+gl_default_shader_vertex_source :: proc() -> string {
+	return #load("default_shader_vertex.glsl")
+}
+
+
+gl_default_shader_fragment_source :: proc() -> string {
+	return #load("default_shader_fragment.glsl")
+}
+

+ 3 - 0
render_backend_interface.odin

@@ -38,4 +38,7 @@ Render_Backend_Interface :: struct {
 	get_swapchain_height: proc() -> int,
 
 	batch_vertex: proc(v: Vec2, uv: Vec2, color: Color),
+
+	default_shader_vertex_source: proc() -> string,
+	default_shader_fragment_source: proc() -> string,
 }