Kaynağa Gözat

Ported a shader example from raylib and added missing wrapper procs

Karl Zylinski 7 ay önce
ebeveyn
işleme
8f5d637f6d

+ 66 - 0
examples/raylib_ports/shaders_texture_waves/shaders_texture_waves.odin

@@ -0,0 +1,66 @@
+// Based on https://github.com/raysan5/raylib/blob/master/examples/shaders/shaders_texture_waves.c
+
+package raylib_example_shaders_texture_waves
+
+import k2 "../../.."
+import "core:time"
+
+SCREEN_WIDTH :: 800
+SCREEN_HEIGHT :: 450
+
+main :: proc() {
+    k2.init(SCREEN_WIDTH, SCREEN_HEIGHT, "Karl2D: texture waves (raylib [shaders] example - texture waves)")
+
+    texture := k2.load_texture_from_file("space.png")
+    shader := k2.load_shader("", "wave.fs")
+
+    seconds_loc := k2.get_shader_location(shader, "seconds")
+    freq_x_loc := k2.get_shader_location(shader, "freqX")
+    freq_y_loc := k2.get_shader_location(shader, "freqY")
+    amp_x_loc := k2.get_shader_location(shader, "ampX")
+    amp_y_loc := k2.get_shader_location(shader, "ampY")
+    speed_x_loc := k2.get_shader_location(shader, "speedX")
+    speed_y_loc := k2.get_shader_location(shader, "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_value(shader, k2.get_shader_location(shader, "size"), screen_size)
+    k2.set_shader_value(shader, freq_x_loc, freq_x)
+    k2.set_shader_value(shader, freq_y_loc, freq_y)
+    k2.set_shader_value(shader, amp_x_loc, amp_x)
+    k2.set_shader_value(shader, amp_y_loc, amp_y)
+    k2.set_shader_value(shader, speed_x_loc, speed_x)
+    k2.set_shader_value(shader, speed_y_loc, speed_y)
+
+    seconds: f32
+
+    last_frame_time := time.now()
+
+    for !k2.window_should_close() {
+    	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_value(shader, seconds_loc, seconds)
+		k2.set_shader(shader)
+
+		k2.draw_texture(texture, {0, 0})
+		k2.draw_texture(texture, {f32(texture.width), 0})
+
+		k2.set_shader(nil)
+		k2.present()
+    }
+
+    k2.destroy_shader(shader)
+    k2.destroy_texture(texture)
+
+    k2.shutdown()
+}

BIN
examples/raylib_ports/shaders_texture_waves/space.png


+ 37 - 0
examples/raylib_ports/shaders_texture_waves/wave.fs

@@ -0,0 +1,37 @@
+#version 330
+
+// Input vertex attributes (from vertex shader)
+in vec2 fragTexCoord;
+in vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// Output fragment color
+out vec4 finalColor;
+
+uniform float seconds;
+
+uniform vec2 size;
+
+uniform float freqX;
+uniform float freqY;
+uniform float ampX;
+uniform float ampY;
+uniform float speedX;
+uniform float speedY;
+
+void main() {
+    float pixelWidth = 1.0/size.x;
+    float pixelHeight = 1.0/size.y;
+    float aspect = pixelHeight/pixelWidth;
+    float boxLeft = 0.0;
+    float boxTop = 0.0;
+
+    vec2 p = fragTexCoord;
+    p.x += cos((fragTexCoord.y - boxTop)*freqX/(pixelWidth*750.0) + (seconds*speedX))*ampX*pixelWidth;
+    p.y += sin((fragTexCoord.x - boxLeft)*freqY*aspect/(pixelHeight*750.0) + (seconds*speedY))*ampY*pixelHeight;
+
+    finalColor = texture(texture0, p)*colDiffuse*fragColor;
+}

+ 22 - 0
karl2d.odin

@@ -44,6 +44,7 @@ destroy_texture: proc(tex: Texture) : _destroy_texture
 
 set_camera: proc(camera: Maybe(Camera)) : _set_camera
 set_scissor_rect: proc(scissor_rect: Maybe(Rect)) : _set_scissor_rect
+set_shader: proc(shader: Maybe(Shader)) : _set_shader
 
 draw_texture: proc(tex: Texture, pos: Vec2, tint := WHITE) : _draw_texture
 draw_texture_rect: proc(tex: Texture, rect: Rect, pos: Vec2, tint := WHITE) : _draw_texture_rect
@@ -53,6 +54,20 @@ draw_rect_outline: proc(rect: Rect, thickness: f32, color: Color) : _draw_rectan
 draw_circle: proc(center: Vec2, radius: f32, color: Color) : _draw_circle
 draw_line: proc(start: Vec2, end: Vec2, thickness: f32, color: Color) : _draw_line
 
+
+load_shader: proc(vertex_shader_filename: string, fragment_shader_filename: string) -> Shader : _load_shader
+destroy_shader: proc(shader: Shader) : _destroy_shader
+
+get_shader_location: proc(shader: Shader, uniform_name: string) -> int : _get_shader_location
+
+set_shader_value_f32: proc(shader: Shader, loc: int, val: f32) : _set_shader_value_f32
+set_shader_value_vec2: proc(shader: Shader, loc: int, val: Vec2) : _set_shader_value_vec2
+
+set_shader_value :: proc {
+	set_shader_value_f32,
+	set_shader_value_vec2,
+}
+
 // WARNING: Not proper text rendering yet... No font support etc
 draw_text: proc(text: string, pos: Vec2, font_size: f32, color: Color) : _draw_text
 
@@ -86,6 +101,7 @@ Texture :: struct {
 	width: int,
 	height: int,
 }
+
 Camera :: struct {
 	target: Vec2,
 	origin: Vec2,
@@ -113,6 +129,12 @@ MAGENTA :: Color { 255, 0, 255, 255 }
 DARKGRAY :: Color{ 80, 80, 80, 255 }
 GREEN :: Color{ 0, 228, 48, 255 }
 
+// This is plain raylib shader for now, until I rewrite the shader system
+Shader :: struct {
+	id: u32,
+	locs: []i32,
+}
+
 // Based on Raylib / GLFW
 Keyboard_Key :: enum {
 	None            = 0,

+ 43 - 0
karl2d_raylib.odin

@@ -5,6 +5,7 @@ import "raylib/rlgl"
 import "core:log"
 import "core:strings"
 import "base:runtime"
+import "core:slice"
 
 _init :: proc(width: int, height: int, title: string,
               allocator := context.allocator, loc := #caller_location) -> ^State {
@@ -244,6 +245,14 @@ _set_scissor_rect :: proc(scissor_rect: Maybe(Rect)) {
 	}
 }
 
+_set_shader :: proc(shader: Maybe(Shader)) {
+	if s, s_ok := shader.?; s_ok {
+		rlgl.SetShader(s.id, raw_data(s.locs))
+	} else {
+		rlgl.SetShader(rlgl.GetShaderIdDefault(), rlgl.GetShaderLocsDefault())
+	}
+}
+
 _process_events :: proc() {
 	rl.PollInputEvents()
 }
@@ -259,6 +268,40 @@ _present :: proc(do_flush := true) {
 	rl.SwapScreenBuffer()
 }
 
+_load_shader :: proc(vs: string, fs: string) -> Shader {
+	s := rl.LoadShader(temp_cstring(vs), temp_cstring(fs))
+
+	return {
+		id = s.id,
+		locs = slice.from_ptr(s.locs, 32),
+	}
+}
+
+_destroy_shader :: proc(shader: Shader) {
+	rl.UnloadShader(rl_shader(shader))
+}
+
+_get_shader_location :: proc(shader: Shader, uniform_name: string) -> int {
+	return int(rl.GetShaderLocation(rl_shader(shader), temp_cstring(uniform_name)))
+}
+
+_set_shader_value_f32 :: proc(shader: Shader, loc: int, val: f32) {
+	val := val
+	rl.SetShaderValue(rl_shader(shader), loc, &val, .FLOAT)
+}
+
+_set_shader_value_vec2 :: proc(shader: Shader, loc: int, val: Vec2) {
+	val := val
+	rl.SetShaderValue(rl_shader(shader), loc, &val, .VEC2)
+}
+
+rl_shader :: proc(s: Shader) -> rl.Shader {
+	return {
+		id = s.id,
+		locs = raw_data(s.locs),
+	}
+}
+
 temp_cstring :: proc(str: string) -> cstring {
 	return strings.clone_to_cstring(str, context.temp_allocator)
 }