diff --git a/.github/workflows/sokol_shader_examples.yml b/.github/workflows/sokol_shader_examples.yml index 2a09015c46..084fa47758 100644 --- a/.github/workflows/sokol_shader_examples.yml +++ b/.github/workflows/sokol_shader_examples.yml @@ -37,6 +37,7 @@ jobs: examples/sokol/03_march_tracing_glsl/rt_glsl \ examples/sokol/04_multi_shader_glsl/rt_glsl_puppy \ examples/sokol/04_multi_shader_glsl/rt_glsl_march \ + examples/sokol/05_instancing_glsl/rt_glsl_instancing \ ; do \ echo "compiling shader $f.glsl ..."; \ sokol-tools-bin-pre-feb2021-api-changes/bin/linux/sokol-shdc --input $f.glsl --output $f.h --slang glsl330 ; \ diff --git a/cmd/tools/modules/testing/common.v b/cmd/tools/modules/testing/common.v index 4ae40a95db..0420e58c2e 100644 --- a/cmd/tools/modules/testing/common.v +++ b/cmd/tools/modules/testing/common.v @@ -134,6 +134,7 @@ pub fn new_test_session(_vargs string) TestSession { skip_files << 'examples/sokol/02_cubes_glsl/cube_glsl.v' skip_files << 'examples/sokol/03_march_tracing_glsl/rt_glsl.v' skip_files << 'examples/sokol/04_multi_shader_glsl/rt_glsl.v' + skip_files << 'examples/sokol/05_instancing_glsl/rt_glsl.v' } if testing.github_job != 'ubuntu-tcc' { skip_files << 'examples/wkhtmltopdf.v' // needs installation of wkhtmltopdf from https://github.com/wkhtmltopdf/packaging/releases diff --git a/examples/sokol/01_cubes/cube.v b/examples/sokol/01_cubes/cube.v index cd202ba12b..e40b7af7ee 100644 --- a/examples/sokol/01_cubes/cube.v +++ b/examples/sokol/01_cubes/cube.v @@ -402,6 +402,7 @@ fn my_event_manager(mut ev gg.Event, mut app App) { * Main * ******************************************************************************/ +[console] // is needed for easier diagnostics on windows fn main() { // App init mut app := &App{ diff --git a/examples/sokol/02_cubes_glsl/cube_glsl.v b/examples/sokol/02_cubes_glsl/cube_glsl.v index 130470d916..4c47fd11c0 100644 --- a/examples/sokol/02_cubes_glsl/cube_glsl.v +++ b/examples/sokol/02_cubes_glsl/cube_glsl.v @@ -58,8 +58,8 @@ mut: texture C.sg_image init_flag bool frame_count int - mouse_x int = -1 - mouse_y int = -1 + mouse_x int = -1 + mouse_y int = -1 // glsl cube_pip_glsl C.sg_pipeline cube_bind C.sg_bindings @@ -119,9 +119,9 @@ fn update_text_texture(sg_img C.sg_image, w int, h int, buf byteptr) { fn draw_triangle() { sgl.defaults() sgl.begin_triangles() - sgl.v2f_c3b(0.0, 0.5, 255, 0, 0) - sgl.v2f_c3b(-0.5, -0.5, 0, 0, 255) - sgl.v2f_c3b(0.5, -0.5, 0, 255, 0) + sgl.v2f_c3b( 0.0, 0.5, 255, 0 , 0 ) + sgl.v2f_c3b(-0.5, -0.5, 0, 0 , 255) + sgl.v2f_c3b( 0.5, -0.5, 0, 255, 0 ) sgl.end() } @@ -132,35 +132,35 @@ fn cube() { sgl.c3f(1.0, 0.0, 0.0) // edge coord // x,y,z, texture cord: u,v - sgl.v3f_t2f(-1.0, 1.0, -1.0, -1.0, 1.0) - sgl.v3f_t2f(1.0, 1.0, -1.0, 1.0, 1.0) - sgl.v3f_t2f(1.0, -1.0, -1.0, 1.0, -1.0) + sgl.v3f_t2f(-1.0, 1.0, -1.0, -1.0, 1.0) + sgl.v3f_t2f( 1.0, 1.0, -1.0, 1.0, 1.0) + sgl.v3f_t2f( 1.0, -1.0, -1.0, 1.0, -1.0) sgl.v3f_t2f(-1.0, -1.0, -1.0, -1.0, -1.0) sgl.c3f(0.0, 1.0, 0.0) - sgl.v3f_t2f(-1.0, -1.0, 1.0, -1.0, 1.0) - sgl.v3f_t2f(1.0, -1.0, 1.0, 1.0, 1.0) - sgl.v3f_t2f(1.0, 1.0, 1.0, 1.0, -1.0) - sgl.v3f_t2f(-1.0, 1.0, 1.0, -1.0, -1.0) + sgl.v3f_t2f(-1.0, -1.0, 1.0, -1.0, 1.0) + sgl.v3f_t2f( 1.0, -1.0, 1.0, 1.0, 1.0) + sgl.v3f_t2f( 1.0, 1.0, 1.0, 1.0, -1.0) + sgl.v3f_t2f(-1.0, 1.0, 1.0, -1.0, -1.0) sgl.c3f(0.0, 0.0, 1.0) - sgl.v3f_t2f(-1.0, -1.0, 1.0, -1.0, 1.0) - sgl.v3f_t2f(-1.0, 1.0, 1.0, 1.0, 1.0) - sgl.v3f_t2f(-1.0, 1.0, -1.0, 1.0, -1.0) + sgl.v3f_t2f(-1.0, -1.0, 1.0, -1.0, 1.0) + sgl.v3f_t2f(-1.0, 1.0, 1.0, 1.0, 1.0) + sgl.v3f_t2f(-1.0, 1.0, -1.0, 1.0, -1.0) sgl.v3f_t2f(-1.0, -1.0, -1.0, -1.0, -1.0) sgl.c3f(1.0, 0.5, 0.0) - sgl.v3f_t2f(1.0, -1.0, 1.0, -1.0, 1.0) - sgl.v3f_t2f(1.0, -1.0, -1.0, 1.0, 1.0) - sgl.v3f_t2f(1.0, 1.0, -1.0, 1.0, -1.0) - sgl.v3f_t2f(1.0, 1.0, 1.0, -1.0, -1.0) + sgl.v3f_t2f(1.0, -1.0, 1.0, -1.0, 1.0) + sgl.v3f_t2f(1.0, -1.0, -1.0, 1.0, 1.0) + sgl.v3f_t2f(1.0, 1.0, -1.0, 1.0, -1.0) + sgl.v3f_t2f(1.0, 1.0, 1.0, -1.0, -1.0) sgl.c3f(0.0, 0.5, 1.0) - sgl.v3f_t2f(1.0, -1.0, -1.0, -1.0, 1.0) - sgl.v3f_t2f(1.0, -1.0, 1.0, 1.0, 1.0) - sgl.v3f_t2f(-1.0, -1.0, 1.0, 1.0, -1.0) + sgl.v3f_t2f( 1.0, -1.0, -1.0, -1.0, 1.0) + sgl.v3f_t2f( 1.0, -1.0, 1.0, 1.0, 1.0) + sgl.v3f_t2f(-1.0, -1.0, 1.0, 1.0, -1.0) sgl.v3f_t2f(-1.0, -1.0, -1.0, -1.0, -1.0) sgl.c3f(1.0, 0.0, 0.5) - sgl.v3f_t2f(-1.0, 1.0, -1.0, -1.0, 1.0) - sgl.v3f_t2f(-1.0, 1.0, 1.0, 1.0, 1.0) - sgl.v3f_t2f(1.0, 1.0, 1.0, 1.0, -1.0) - sgl.v3f_t2f(1.0, 1.0, -1.0, -1.0, -1.0) + sgl.v3f_t2f(-1.0, 1.0, -1.0, -1.0, 1.0) + sgl.v3f_t2f(-1.0, 1.0, 1.0, 1.0, 1.0) + sgl.v3f_t2f( 1.0, 1.0, 1.0, 1.0, -1.0) + sgl.v3f_t2f( 1.0, 1.0, -1.0, -1.0, -1.0) sgl.end() } @@ -189,7 +189,7 @@ fn draw_cubes(app App) { sgl.translate(0.0, 0.0, 3.0) sgl.scale(0.5, 0.5, 0.5) sgl.rotate(-3.0 * sgl.rad(2 * rot[0]), 1.0, 0.0, 0.0) - sgl.rotate(3.0 * sgl.rad(2 * rot[1]), 0.0, 0.0, 1.0) + sgl.rotate( 3.0 * sgl.rad(2 * rot[1]), 0.0, 0.0, 1.0) cube() sgl.pop_matrix() sgl.pop_matrix() @@ -201,35 +201,35 @@ fn cube_texture(r f32, g f32, b f32) { sgl.c3f(r, g, b) // edge coord // x,y,z, texture cord: u,v - sgl.v3f_t2f(-1.0, 1.0, -1.0, 0.0, 0.25) - sgl.v3f_t2f(1.0, 1.0, -1.0, 0.25, 0.25) - sgl.v3f_t2f(1.0, -1.0, -1.0, 0.25, 0.0) - sgl.v3f_t2f(-1.0, -1.0, -1.0, 0.0, 0.0) + sgl.v3f_t2f(-1.0, 1.0, -1.0, 0.0 , 0.25) + sgl.v3f_t2f( 1.0, 1.0, -1.0, 0.25, 0.25) + sgl.v3f_t2f( 1.0, -1.0, -1.0, 0.25, 0.0 ) + sgl.v3f_t2f(-1.0, -1.0, -1.0, 0.0 , 0.0 ) sgl.c3f(r, g, b) - sgl.v3f_t2f(-1.0, -1.0, 1.0, 0.0, 0.25) - sgl.v3f_t2f(1.0, -1.0, 1.0, 0.25, 0.25) - sgl.v3f_t2f(1.0, 1.0, 1.0, 0.25, 0.0) - sgl.v3f_t2f(-1.0, 1.0, 1.0, 0.0, 0.0) + sgl.v3f_t2f(-1.0, -1.0, 1.0, 0.0 , 0.25) + sgl.v3f_t2f( 1.0, -1.0, 1.0, 0.25, 0.25) + sgl.v3f_t2f( 1.0, 1.0, 1.0, 0.25, 0.0 ) + sgl.v3f_t2f(-1.0, 1.0, 1.0, 0.0 , 0.0 ) sgl.c3f(r, g, b) - sgl.v3f_t2f(-1.0, -1.0, 1.0, 0.0, 0.25) - sgl.v3f_t2f(-1.0, 1.0, 1.0, 0.25, 0.25) - sgl.v3f_t2f(-1.0, 1.0, -1.0, 0.25, 0.0) - sgl.v3f_t2f(-1.0, -1.0, -1.0, 0.0, 0.0) + sgl.v3f_t2f(-1.0, -1.0, 1.0, 0.0 , 0.25) + sgl.v3f_t2f(-1.0, 1.0, 1.0, 0.25, 0.25) + sgl.v3f_t2f(-1.0, 1.0, -1.0, 0.25, 0.0 ) + sgl.v3f_t2f(-1.0, -1.0, -1.0, 0.0 , 0.0 ) sgl.c3f(r, g, b) - sgl.v3f_t2f(1.0, -1.0, 1.0, 0.0, 0.25) - sgl.v3f_t2f(1.0, -1.0, -1.0, 0.25, 0.25) - sgl.v3f_t2f(1.0, 1.0, -1.0, 0.25, 0.0) - sgl.v3f_t2f(1.0, 1.0, 1.0, 0.0, 0.0) + sgl.v3f_t2f(1.0, -1.0, 1.0, 0.0 , 0.25) + sgl.v3f_t2f(1.0, -1.0, -1.0, 0.25, 0.25) + sgl.v3f_t2f(1.0, 1.0, -1.0, 0.25, 0.0 ) + sgl.v3f_t2f(1.0, 1.0, 1.0, 0.0 , 0.0 ) sgl.c3f(r, g, b) - sgl.v3f_t2f(1.0, -1.0, -1.0, 0.0, 0.25) - sgl.v3f_t2f(1.0, -1.0, 1.0, 0.25, 0.25) - sgl.v3f_t2f(-1.0, -1.0, 1.0, 0.25, 0.0) - sgl.v3f_t2f(-1.0, -1.0, -1.0, 0.0, 0.0) + sgl.v3f_t2f( 1.0, -1.0, -1.0, 0.0 , 0.25) + sgl.v3f_t2f( 1.0, -1.0, 1.0, 0.25, 0.25) + sgl.v3f_t2f(-1.0, -1.0, 1.0, 0.25, 0.0 ) + sgl.v3f_t2f(-1.0, -1.0, -1.0, 0.0 , 0.0 ) sgl.c3f(r, g, b) - sgl.v3f_t2f(-1.0, 1.0, -1.0, 0.0, 0.25) - sgl.v3f_t2f(-1.0, 1.0, 1.0, 0.25, 0.25) - sgl.v3f_t2f(1.0, 1.0, 1.0, 0.25, 0.0) - sgl.v3f_t2f(1.0, 1.0, -1.0, 0.0, 0.0) + sgl.v3f_t2f(-1.0, 1.0, -1.0, 0.0 , 0.25) + sgl.v3f_t2f(-1.0, 1.0, 1.0, 0.25, 0.25) + sgl.v3f_t2f( 1.0, 1.0, 1.0, 0.25, 0.0 ) + sgl.v3f_t2f( 1.0, 1.0, -1.0, 0.0 , 0.0 ) sgl.end() } @@ -251,8 +251,8 @@ struct Vertex_t { color u32 // u u16 // v u16 - u f32 - v f32 + u f32 + v f32 } fn init_cube_glsl(mut app App) { @@ -261,30 +261,36 @@ fn init_cube_glsl(mut app App) { d := f32(1.0) // 0.05) c := u32(0xFFFFFF_FF) // color RGBA8 vertices := [ - Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, - Vertex_t{1.0, -1.0, -1.0, c, d, 0}, - Vertex_t{1.0, 1.0, -1.0, c, d, d}, - Vertex_t{-1.0, 1.0, -1.0, c, 0, d}, - Vertex_t{-1.0, -1.0, 1.0, c, 0, 0}, - Vertex_t{1.0, -1.0, 1.0, c, d, 0}, - Vertex_t{1.0, 1.0, 1.0, c, d, d}, - Vertex_t{-1.0, 1.0, 1.0, c, 0, d}, - Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, - Vertex_t{-1.0, 1.0, -1.0, c, d, 0}, - Vertex_t{-1.0, 1.0, 1.0, c, d, d}, - Vertex_t{-1.0, -1.0, 1.0, c, 0, d}, - Vertex_t{1.0, -1.0, -1.0, c, 0, 0}, - Vertex_t{1.0, 1.0, -1.0, c, d, 0}, - Vertex_t{1.0, 1.0, 1.0, c, d, d}, - Vertex_t{1.0, -1.0, 1.0, c, 0, d}, - Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, - Vertex_t{-1.0, -1.0, 1.0, c, d, 0}, - Vertex_t{1.0, -1.0, 1.0, c, d, d}, - Vertex_t{1.0, -1.0, -1.0, c, 0, d}, - Vertex_t{-1.0, 1.0, -1.0, c, 0, 0}, - Vertex_t{-1.0, 1.0, 1.0, c, d, 0}, - Vertex_t{1.0, 1.0, 1.0, c, d, d}, - Vertex_t{1.0, 1.0, -1.0, c, 0, d}, + // Face 0 + Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{ 1.0, -1.0, -1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, -1.0, c, d, d}, + Vertex_t{-1.0, 1.0, -1.0, c, 0, d}, + // Face 1 + Vertex_t{-1.0, -1.0, 1.0, c, 0, 0}, + Vertex_t{ 1.0, -1.0, 1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, 1.0, c, d, d}, + Vertex_t{-1.0, 1.0, 1.0, c, 0, d}, + // Face 2 + Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{-1.0, 1.0, -1.0, c, d, 0}, + Vertex_t{-1.0, 1.0, 1.0, c, d, d}, + Vertex_t{-1.0, -1.0, 1.0, c, 0, d}, + // Face 3 + Vertex_t{ 1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{ 1.0, 1.0, -1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, 1.0, c, d, d}, + Vertex_t{ 1.0, -1.0, 1.0, c, 0, d}, + // Face 4 + Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{-1.0, -1.0, 1.0, c, d, 0}, + Vertex_t{ 1.0, -1.0, 1.0, c, d, d}, + Vertex_t{ 1.0, -1.0, -1.0, c, 0, d}, + // Face 5 + Vertex_t{-1.0, 1.0, -1.0, c, 0, 0}, + Vertex_t{-1.0, 1.0, 1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, 1.0, c, d, d}, + Vertex_t{ 1.0, 1.0, -1.0, c, 0, d}, ] mut vert_buffer_desc := C.sg_buffer_desc{} @@ -296,44 +302,14 @@ fn init_cube_glsl(mut app App) { vert_buffer_desc.label = 'cube-vertices'.str vbuf := gfx.make_buffer(&vert_buffer_desc) - // create an index buffer for the cube + /* create an index buffer for the cube */ indices := [ - u16(0), - 1, - 2, - 0, - 2, - 3, - 6, - 5, - 4, - 7, - 6, - 4, - 8, - 9, - 10, - 8, - 10, - 11, - 14, - 13, - 12, - 15, - 14, - 12, - 16, - 17, - 18, - 16, - 18, - 19, - 22, - 21, - 20, - 23, - 22, - 20, + u16(0), 1, 2, 0, 2, 3, + 6, 5, 4, 7, 6, 4, + 8, 9, 10, 8, 10, 11, + 14, 13, 12, 15, 14, 12, + 16, 17, 18, 16, 18, 19, + 22, 21, 20, 23, 22, 20 ] mut index_buffer_desc := C.sg_buffer_desc{} @@ -352,9 +328,9 @@ fn init_cube_glsl(mut app App) { pipdesc.layout.buffers[0].stride = int(sizeof(Vertex_t)) // the constants [C.ATTR_vs_pos, C.ATTR_vs_color0, C.ATTR_vs_texcoord0] are generated bysokol-shdc - pipdesc.layout.attrs[C.ATTR_vs_pos].format = .float3 // x,y,z as f32 - pipdesc.layout.attrs[C.ATTR_vs_color0].format = .ubyte4n // color as u32 - pipdesc.layout.attrs[C.ATTR_vs_texcoord0].format = .float2 // u,v as f32 + pipdesc.layout.attrs[C.ATTR_vs_pos ].format = .float3 // x,y,z as f32 + pipdesc.layout.attrs[C.ATTR_vs_color0 ].format = .ubyte4n // color as u32 + pipdesc.layout.attrs[C.ATTR_vs_texcoord0].format = .float2 // u,v as f32 // pipdesc.layout.attrs[C.ATTR_vs_texcoord0].format = .short2n // u,v as u16 pipdesc.shader = shader @@ -434,18 +410,18 @@ fn draw_texture_cubes(app App) { sgl.rotate(sgl.rad(rot[1]), 0.0, 1.0, 0.0) cube_texture(1, 1, 1) sgl.push_matrix() - sgl.translate(0.0, 0.0, 3.0) - sgl.scale(0.5, 0.5, 0.5) - sgl.rotate(-2.0 * sgl.rad(rot[0]), 1.0, 0.0, 0.0) - sgl.rotate(-2.0 * sgl.rad(rot[1]), 0.0, 1.0, 0.0) - cube_texture(1, 1, 1) - sgl.push_matrix() - sgl.translate(0.0, 0.0, 3.0) - sgl.scale(0.5, 0.5, 0.5) - sgl.rotate(-3.0 * sgl.rad(2 * rot[0]), 1.0, 0.0, 0.0) - sgl.rotate(3.0 * sgl.rad(2 * rot[1]), 0.0, 0.0, 1.0) - cube_texture(1, 1, 1) - sgl.pop_matrix() + sgl.translate(0.0, 0.0, 3.0) + sgl.scale(0.5, 0.5, 0.5) + sgl.rotate(-2.0 * sgl.rad(rot[0]), 1.0, 0.0, 0.0) + sgl.rotate(-2.0 * sgl.rad(rot[1]), 0.0, 1.0, 0.0) + cube_texture(1,1,1) + sgl.push_matrix() + sgl.translate(0.0, 0.0, 3.0) + sgl.scale(0.5, 0.5, 0.5) + sgl.rotate(-3.0 * sgl.rad(2*rot[0]), 1.0, 0.0, 0.0) + sgl.rotate(3.0 * sgl.rad(2*rot[1]), 0.0, 0.0, 1.0) + cube_texture(1,1,1) + sgl.pop_matrix() sgl.pop_matrix() sgl.disable_texture() @@ -549,15 +525,15 @@ fn my_init(mut app App) { } // low right corner else if x == 7 && y == 7 { - tmp_txt[i] = byte(0) + tmp_txt[i + 0] = byte(0) tmp_txt[i + 1] = byte(0xFF) tmp_txt[i + 2] = byte(0) tmp_txt[i + 3] = byte(0xFF) } else { col := if ((x + y) & 1) == 1 { 0xFF } else { 128 } - tmp_txt[i] = byte(col) // red - tmp_txt[i + 1] = byte(col) // green - tmp_txt[i + 2] = byte(col) // blue + tmp_txt[i + 0] = byte(col) // red + tmp_txt[i + 1] = byte(col) // green + tmp_txt[i + 2] = byte(col) // blue tmp_txt[i + 3] = byte(0xFF) // alpha } i += 4 @@ -599,7 +575,7 @@ fn my_event_manager(mut ev gg.Event, mut app App) { * Main * ******************************************************************************/ -[console] +[console] // is needed for easier diagnostics on windows fn main() { // App init mut app := &App{ diff --git a/examples/sokol/03_march_tracing_glsl/rt_glsl.v b/examples/sokol/03_march_tracing_glsl/rt_glsl.v index eaae531354..47e2a41805 100644 --- a/examples/sokol/03_march_tracing_glsl/rt_glsl.v +++ b/examples/sokol/03_march_tracing_glsl/rt_glsl.v @@ -68,7 +68,9 @@ mut: ticks i64 } -// Texture functions +/****************************************************************************** +* Texture functions +******************************************************************************/ fn create_texture(w int, h int, buf byteptr) C.sg_image { sz := w * h * 4 mut img_desc := C.sg_image_desc{ @@ -108,9 +110,9 @@ fn update_text_texture(sg_img C.sg_image, w int, h int, buf byteptr) { C.sg_update_image(sg_img, &tmp_sbc) } -// Draw functions - -/* +/****************************************************************************** +* Draw functions +****************************************************************************** Cube vertex buffer with packed vertex formats for color and texture coords. Note that a vertex format which must be portable across all backends must only use the normalized integer formats @@ -138,30 +140,36 @@ fn init_cube_glsl(mut app App) { d := f32(1.0) c := u32(0xFFFFFF_FF) // color RGBA8 vertices := [ - Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, - Vertex_t{1.0, -1.0, -1.0, c, d, 0}, - Vertex_t{1.0, 1.0, -1.0, c, d, d}, - Vertex_t{-1.0, 1.0, -1.0, c, 0, d}, - Vertex_t{-1.0, -1.0, 1.0, c, 0, 0}, - Vertex_t{1.0, -1.0, 1.0, c, d, 0}, - Vertex_t{1.0, 1.0, 1.0, c, d, d}, - Vertex_t{-1.0, 1.0, 1.0, c, 0, d}, - Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, - Vertex_t{-1.0, 1.0, -1.0, c, d, 0}, - Vertex_t{-1.0, 1.0, 1.0, c, d, d}, - Vertex_t{-1.0, -1.0, 1.0, c, 0, d}, - Vertex_t{1.0, -1.0, -1.0, c, 0, 0}, - Vertex_t{1.0, 1.0, -1.0, c, d, 0}, - Vertex_t{1.0, 1.0, 1.0, c, d, d}, - Vertex_t{1.0, -1.0, 1.0, c, 0, d}, - Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, - Vertex_t{-1.0, -1.0, 1.0, c, d, 0}, - Vertex_t{1.0, -1.0, 1.0, c, d, d}, - Vertex_t{1.0, -1.0, -1.0, c, 0, d}, - Vertex_t{-1.0, 1.0, -1.0, c, 0, 0}, - Vertex_t{-1.0, 1.0, 1.0, c, d, 0}, - Vertex_t{1.0, 1.0, 1.0, c, d, d}, - Vertex_t{1.0, 1.0, -1.0, c, 0, d}, + // Face 0 + Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{ 1.0, -1.0, -1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, -1.0, c, d, d}, + Vertex_t{-1.0, 1.0, -1.0, c, 0, d}, + // Face 1 + Vertex_t{-1.0, -1.0, 1.0, c, 0, 0}, + Vertex_t{ 1.0, -1.0, 1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, 1.0, c, d, d}, + Vertex_t{-1.0, 1.0, 1.0, c, 0, d}, + // Face 2 + Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{-1.0, 1.0, -1.0, c, d, 0}, + Vertex_t{-1.0, 1.0, 1.0, c, d, d}, + Vertex_t{-1.0, -1.0, 1.0, c, 0, d}, + // Face 3 + Vertex_t{ 1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{ 1.0, 1.0, -1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, 1.0, c, d, d}, + Vertex_t{ 1.0, -1.0, 1.0, c, 0, d}, + // Face 4 + Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{-1.0, -1.0, 1.0, c, d, 0}, + Vertex_t{ 1.0, -1.0, 1.0, c, d, d}, + Vertex_t{ 1.0, -1.0, -1.0, c, 0, d}, + // Face 5 + Vertex_t{-1.0, 1.0, -1.0, c, 0, 0}, + Vertex_t{-1.0, 1.0, 1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, 1.0, c, d, d}, + Vertex_t{ 1.0, 1.0, -1.0, c, 0, d}, ] mut vert_buffer_desc := C.sg_buffer_desc{} @@ -174,7 +182,7 @@ fn init_cube_glsl(mut app App) { // create an index buffer for the cube indices := [ - 0, 1, 2, 0, 2, 3, + u16(0), 1, 2, 0, 2, 3, 6, 5, 4, 7, 6, 4, 8, 9, 10, 8, 10, 11, 14, 13, 12, 15, 14, 12, @@ -183,13 +191,13 @@ fn init_cube_glsl(mut app App) { ] mut index_buffer_desc := C.sg_buffer_desc{} - unsafe { C.memset(&index_buffer_desc, 0, sizeof(index_buffer_desc)) } - index_buffer_desc.size = indices.len * int(sizeof(int)) + unsafe {C.memset(&index_buffer_desc, 0, sizeof(index_buffer_desc))} + index_buffer_desc.size = indices.len * int(sizeof(u16)) index_buffer_desc.content = byteptr(indices.data) - index_buffer_desc.@type = .indexbuffer - index_buffer_desc.label = 'cube-indices'.str + index_buffer_desc.@type = .indexbuffer + index_buffer_desc.label = "cube-indices".str ibuf := gfx.make_buffer(&index_buffer_desc) - + // create shader shader := gfx.make_shader(C.rt_shader_desc()) @@ -198,13 +206,13 @@ fn init_cube_glsl(mut app App) { pipdesc.layout.buffers[0].stride = int(sizeof(Vertex_t)) // the constants [C.ATTR_vs_pos, C.ATTR_vs_color0, C.ATTR_vs_texcoord0] are generated by sokol-shdc - pipdesc.layout.attrs[C.ATTR_vs_pos].format = .float3 // x,y,z as f32 - pipdesc.layout.attrs[C.ATTR_vs_color0].format = .ubyte4n // color as u32 - pipdesc.layout.attrs[C.ATTR_vs_texcoord0].format = .float2 // u,v as f32 + pipdesc.layout.attrs[C.ATTR_vs_pos ].format = .float3 // x,y,z as f32 + pipdesc.layout.attrs[C.ATTR_vs_color0 ].format = .ubyte4n // color as u32 + pipdesc.layout.attrs[C.ATTR_vs_texcoord0].format = .float2 // u,v as f32 // pipdesc.layout.attrs[C.ATTR_vs_texcoord0].format = .short2n // u,v as u16 pipdesc.shader = shader - pipdesc.index_type = .uint32 + pipdesc.index_type = .uint16 pipdesc.depth_stencil = C.sg_depth_stencil_state{ depth_write_enabled: true @@ -222,18 +230,23 @@ fn init_cube_glsl(mut app App) { println('GLSL init DONE!') } +[inline] +fn vec4(x f32, y f32, z f32, w f32) m4.Vec4 { + return m4.Vec4{e:[x, y, z, w]!} +} + fn calc_tr_matrices(w f32, h f32, rx f32, ry f32, in_scale f32) m4.Mat4 { - proj := m4.perspective(60, w / h, 0.01, 10.0) - view := m4.look_at(m4.Vec4{ e: [f32(0.0), 0.0, 6, 0]! }, m4.Vec4{ e: [f32(0), 0, 0, 0]! }, m4.Vec4{ e: [f32(0), 1.0, 0, 0]! }) + proj := m4.perspective(60, w/h, 0.01, 10.0) + view := m4.look_at(vec4(f32(0.0) ,0 , 6, 0), vec4(f32(0), 0, 0, 0), vec4(f32(0), 1, 0, 0)) view_proj := view * proj - rxm := m4.rotate(m4.rad(rx), m4.Vec4{ e: [f32(1), 0, 0, 0]! }) - rym := m4.rotate(m4.rad(ry), m4.Vec4{ e: [f32(0), 1, 0, 0]! }) + rxm := m4.rotate(m4.rad(rx), vec4(f32(1), 0, 0, 0)) + rym := m4.rotate(m4.rad(ry), vec4(f32(0), 1, 0, 0)) - model := rym * rxm - scale_m := m4.scale(m4.Vec4{ e: [in_scale, in_scale, in_scale, 1]! }) + model := rym * rxm + scale_m := m4.scale(vec4(in_scale, in_scale, in_scale, 1)) - res := (scale_m * model) * view_proj + res := (scale_m * model) * view_proj return res } @@ -258,22 +271,22 @@ fn draw_cube_glsl(app App) { gfx.apply_bindings(app.cube_bind) // Uniforms - // + // *** vertex shadeer uniforms *** // passing the view matrix as uniform // res is a 4x4 matrix of f32 thus: 4*16 byte of size gfx.apply_uniforms(C.SG_SHADERSTAGE_VS, C.SLOT_vs_params, &tr_matrix, 4 * 16) - // fragment shader uniforms + // *** fragment shader uniforms *** time_ticks := f32(time.ticks() - app.ticks) / 1000 mut tmp_fs_params := [ f32(ws.width), - ws.height * ratio, /* x,y resolution to pass to FS */ - app.mouse_x, /* mouse x */ - ws.height - app.mouse_y * 2, /* mouse y scaled */ - time_ticks, /* time as f32 */ - app.frame_count, /* frame count */ + ws.height * ratio, // x,y resolution to pass to FS + app.mouse_x, // mouse x + ws.height - app.mouse_y * 2, // mouse y scaled + time_ticks, // time as f32 + app.frame_count, // frame count 0, - 0 /* padding bytes , see "fs_params" struct paddings in rt_glsl.h */, + 0 // padding bytes , see "fs_params" struct paddings in rt_glsl.h ]! gfx.apply_uniforms(C.SG_SHADERSTAGE_FS, C.SLOT_fs_params, &tmp_fs_params, int(sizeof(tmp_fs_params))) @@ -303,7 +316,9 @@ fn frame(mut app App) { app.frame_count++ } -// Init / Cleanup +/****************************************************************************** +* Init / Cleanup +******************************************************************************/ fn my_init(mut app App) { // set max vertices, // for a large number of the same type of object it is better use the instances!! @@ -326,22 +341,22 @@ fn my_init(mut app App) { x := (i & 0xFF) >> 5 // 8 cell // upper left corner if x == 0 && y == 0 { - tmp_txt[i] = byte(0xFF) + tmp_txt[i + 0] = byte(0xFF) tmp_txt[i + 1] = byte(0) tmp_txt[i + 2] = byte(0) tmp_txt[i + 3] = byte(0xFF) } // low right corner else if x == 7 && y == 7 { - tmp_txt[i] = byte(0) + tmp_txt[i + 0] = byte(0) tmp_txt[i + 1] = byte(0xFF) tmp_txt[i + 2] = byte(0) tmp_txt[i + 3] = byte(0xFF) } else { col := if ((x + y) & 1) == 1 { 0xFF } else { 128 } - tmp_txt[i] = byte(col) // red - tmp_txt[i + 1] = byte(col) // green - tmp_txt[i + 2] = byte(col) // blue + tmp_txt[i + 0] = byte(col) // red + tmp_txt[i + 1] = byte(col) // green + tmp_txt[i + 2] = byte(col) // blue tmp_txt[i + 3] = byte(0xFF) // alpha } i += 4 @@ -360,7 +375,9 @@ fn cleanup(mut app App) { gfx.shutdown() } -// events handling: +/****************************************************************************** +* events handling +******************************************************************************/ fn my_event_manager(mut ev gg.Event, mut app App) { if ev.typ == .mouse_move { app.mouse_x = int(ev.mouse_x) @@ -375,8 +392,10 @@ fn my_event_manager(mut ev gg.Event, mut app App) { } } -// [console] is needed for easier diagnostics on windows -[console] +/****************************************************************************** +* Main +******************************************************************************/ +[console] // is needed for easier diagnostics on windows fn main() { // App init mut app := &App{ diff --git a/examples/sokol/04_multi_shader_glsl/rt_glsl.v b/examples/sokol/04_multi_shader_glsl/rt_glsl.v index fb7a5f7518..909d85f41b 100644 --- a/examples/sokol/04_multi_shader_glsl/rt_glsl.v +++ b/examples/sokol/04_multi_shader_glsl/rt_glsl.v @@ -42,13 +42,10 @@ import sokol.sgl import time // GLSL Include and functions - #flag -I @VROOT/. #include "rt_glsl_march.h" #Please use sokol-shdc to generate the necessary rt_glsl_march.h file from rt_glsl_march.glsl (see the instructions at the top of this file) #include "rt_glsl_puppy.h" #Please use sokol-shdc to generate the necessary rt_glsl_puppy.h file from rt_glsl_puppy.glsl (see the instructions at the top of this file) - fn C.rt_march_shader_desc() &C.sg_shader_desc - fn C.rt_puppy_shader_desc() &C.sg_shader_desc const ( @@ -63,12 +60,12 @@ mut: texture C.sg_image init_flag bool frame_count int - mouse_x int = -1 - mouse_y int = -1 - mouse_down bool + mouse_x int = -1 + mouse_y int = -1 + mouse_down bool // glsl - cube_pip_glsl C.sg_pipeline - cube_bind C.sg_bindings + cube_pip_glsl C.sg_pipeline + cube_bind C.sg_bindings pipe map[string]C.sg_pipeline bind map[string]C.sg_bindings // time @@ -76,9 +73,7 @@ mut: } /****************************************************************************** -* * Texture functions -* ******************************************************************************/ fn create_texture(w int, h int, buf byteptr) C.sg_image { sz := w * h * 4 @@ -120,11 +115,8 @@ fn update_text_texture(sg_img C.sg_image, w int, h int, buf byteptr) { } /****************************************************************************** -* * Draw functions -* -******************************************************************************/ -/* +****************************************************************************** Cube vertex buffer with packed vertex formats for color and texture coords. Note that a vertex format which must be portable across all backends must only use the normalized integer formats @@ -134,7 +126,6 @@ Cube vertex buffer with packed vertex formats for color and texture coords. formats to floating point inputs (only to integer inputs), and WebGL2 / GLES2 don't support integer vertex shader inputs. */ - struct Vertex_t { x f32 y f32 @@ -153,30 +144,36 @@ fn init_cube_glsl_m(mut app App) { d := f32(1.0) c := u32(0xFFFFFF_FF) // color RGBA8 vertices := [ - Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, - Vertex_t{1.0, -1.0, -1.0, c, d, 0}, - Vertex_t{1.0, 1.0, -1.0, c, d, d}, - Vertex_t{-1.0, 1.0, -1.0, c, 0, d}, - Vertex_t{-1.0, -1.0, 1.0, c, 0, 0}, - Vertex_t{1.0, -1.0, 1.0, c, d, 0}, - Vertex_t{1.0, 1.0, 1.0, c, d, d}, - Vertex_t{-1.0, 1.0, 1.0, c, 0, d}, - Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, - Vertex_t{-1.0, 1.0, -1.0, c, d, 0}, - Vertex_t{-1.0, 1.0, 1.0, c, d, d}, - Vertex_t{-1.0, -1.0, 1.0, c, 0, d}, - Vertex_t{1.0, -1.0, -1.0, c, 0, 0}, - Vertex_t{1.0, 1.0, -1.0, c, d, 0}, - Vertex_t{1.0, 1.0, 1.0, c, d, d}, - Vertex_t{1.0, -1.0, 1.0, c, 0, d}, - Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, - Vertex_t{-1.0, -1.0, 1.0, c, d, 0}, - Vertex_t{1.0, -1.0, 1.0, c, d, d}, - Vertex_t{1.0, -1.0, -1.0, c, 0, d}, - Vertex_t{-1.0, 1.0, -1.0, c, 0, 0}, - Vertex_t{-1.0, 1.0, 1.0, c, d, 0}, - Vertex_t{1.0, 1.0, 1.0, c, d, d}, - Vertex_t{1.0, 1.0, -1.0, c, 0, d}, + // Face 0 + Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{ 1.0, -1.0, -1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, -1.0, c, d, d}, + Vertex_t{-1.0, 1.0, -1.0, c, 0, d}, + // Face 1 + Vertex_t{-1.0, -1.0, 1.0, c, 0, 0}, + Vertex_t{ 1.0, -1.0, 1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, 1.0, c, d, d}, + Vertex_t{-1.0, 1.0, 1.0, c, 0, d}, + // Face 2 + Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{-1.0, 1.0, -1.0, c, d, 0}, + Vertex_t{-1.0, 1.0, 1.0, c, d, d}, + Vertex_t{-1.0, -1.0, 1.0, c, 0, d}, + // Face 3 + Vertex_t{ 1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{ 1.0, 1.0, -1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, 1.0, c, d, d}, + Vertex_t{ 1.0, -1.0, 1.0, c, 0, d}, + // Face 4 + Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{-1.0, -1.0, 1.0, c, d, 0}, + Vertex_t{ 1.0, -1.0, 1.0, c, d, d}, + Vertex_t{ 1.0, -1.0, -1.0, c, 0, d}, + // Face 5 + Vertex_t{-1.0, 1.0, -1.0, c, 0, 0}, + Vertex_t{-1.0, 1.0, 1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, 1.0, c, d, d}, + Vertex_t{ 1.0, 1.0, -1.0, c, 0, d}, ] mut vert_buffer_desc := C.sg_buffer_desc{} @@ -187,31 +184,16 @@ fn init_cube_glsl_m(mut app App) { vert_buffer_desc.label = 'cube-vertices'.str vbuf := gfx.make_buffer(&vert_buffer_desc) - // create an index buffer for the cube + /* create an index buffer for the cube */ indices := [ - u16(0), - 1, - 2, - 0, - 2, - 3, - 6, - 5, - 4, - 7, - 6, - 4, - 8, - 9, - 10, - 8, - 10, - 11, - /* - u16(14), 13, 12, 15, 14, 12, + u16(0), 1, 2, 0, 2, 3, + 6, 5, 4, 7, 6, 4, + 8, 9, 10, 8, 10, 11, +/* + u16(14), 13, 12, 15, 14, 12, 16, 17, 18, 16, 18, 19, 22, 21, 20, 23, 22, 20 - */ +*/ ] mut index_buffer_desc := C.sg_buffer_desc{} @@ -230,8 +212,8 @@ fn init_cube_glsl_m(mut app App) { pipdesc.layout.buffers[0].stride = int(sizeof(Vertex_t)) // the constants [C.ATTR_vs_m_pos, C.ATTR_vs_m_color0, C.ATTR_vs_m_texcoord0] are generated by sokol-shdc - pipdesc.layout.attrs[C.ATTR_vs_m_pos].format = .float3 // x,y,z as f32 - pipdesc.layout.attrs[C.ATTR_vs_m_color0].format = .ubyte4n // color as u32 + pipdesc.layout.attrs[C.ATTR_vs_m_pos ].format = .float3 // x,y,z as f32 + pipdesc.layout.attrs[C.ATTR_vs_m_color0 ].format = .ubyte4n // color as u32 pipdesc.layout.attrs[C.ATTR_vs_m_texcoord0].format = .float2 // u,v as f32 // pipdesc.layout.attrs[C.ATTR_vs_m_texcoord0].format = .short2n // u,v as u16 @@ -266,30 +248,36 @@ fn init_cube_glsl_p(mut app App) { d := f32(1.0) c := u32(0xFFFFFF_FF) // color RGBA8 vertices := [ - Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, - Vertex_t{1.0, -1.0, -1.0, c, d, 0}, - Vertex_t{1.0, 1.0, -1.0, c, d, d}, - Vertex_t{-1.0, 1.0, -1.0, c, 0, d}, - Vertex_t{-1.0, -1.0, 1.0, c, 0, 0}, - Vertex_t{1.0, -1.0, 1.0, c, d, 0}, - Vertex_t{1.0, 1.0, 1.0, c, d, d}, - Vertex_t{-1.0, 1.0, 1.0, c, 0, d}, - Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, - Vertex_t{-1.0, 1.0, -1.0, c, d, 0}, - Vertex_t{-1.0, 1.0, 1.0, c, d, d}, - Vertex_t{-1.0, -1.0, 1.0, c, 0, d}, - Vertex_t{1.0, -1.0, -1.0, c, 0, 0}, - Vertex_t{1.0, 1.0, -1.0, c, d, 0}, - Vertex_t{1.0, 1.0, 1.0, c, d, d}, - Vertex_t{1.0, -1.0, 1.0, c, 0, d}, - Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, - Vertex_t{-1.0, -1.0, 1.0, c, d, 0}, - Vertex_t{1.0, -1.0, 1.0, c, d, d}, - Vertex_t{1.0, -1.0, -1.0, c, 0, d}, - Vertex_t{-1.0, 1.0, -1.0, c, 0, 0}, - Vertex_t{-1.0, 1.0, 1.0, c, d, 0}, - Vertex_t{1.0, 1.0, 1.0, c, d, d}, - Vertex_t{1.0, 1.0, -1.0, c, 0, d}, + // Face 0 + Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{ 1.0, -1.0, -1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, -1.0, c, d, d}, + Vertex_t{-1.0, 1.0, -1.0, c, 0, d}, + // Face 1 + Vertex_t{-1.0, -1.0, 1.0, c, 0, 0}, + Vertex_t{ 1.0, -1.0, 1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, 1.0, c, d, d}, + Vertex_t{-1.0, 1.0, 1.0, c, 0, d}, + // Face 2 + Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{-1.0, 1.0, -1.0, c, d, 0}, + Vertex_t{-1.0, 1.0, 1.0, c, d, d}, + Vertex_t{-1.0, -1.0, 1.0, c, 0, d}, + // Face 3 + Vertex_t{ 1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{ 1.0, 1.0, -1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, 1.0, c, d, d}, + Vertex_t{ 1.0, -1.0, 1.0, c, 0, d}, + // Face 4 + Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{-1.0, -1.0, 1.0, c, d, 0}, + Vertex_t{ 1.0, -1.0, 1.0, c, d, d}, + Vertex_t{ 1.0, -1.0, -1.0, c, 0, d}, + // Face 5 + Vertex_t{-1.0, 1.0, -1.0, c, 0, 0}, + Vertex_t{-1.0, 1.0, 1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, 1.0, c, d, d}, + Vertex_t{ 1.0, 1.0, -1.0, c, 0, d}, ] mut vert_buffer_desc := C.sg_buffer_desc{} @@ -300,31 +288,17 @@ fn init_cube_glsl_p(mut app App) { vert_buffer_desc.label = 'cube-vertices'.str vbuf := gfx.make_buffer(&vert_buffer_desc) - // create an index buffer for the cube + /* create an index buffer for the cube */ indices := [ - /* - u16(0), 1, 2, 0, 2, 3, +/* + u16(0), 1, 2, 0, 2, 3, 6, 5, 4, 7, 6, 4, 8, 9, 10, 8, 10, 11, - */ - u16(14), - 13, - 12, - 15, - 14, - 12, - 16, - 17, - 18, - 16, - 18, - 19, - 22, - 21, - 20, - 23, - 22, - 20, +*/ + u16(14), 13, 12, 15, 14, 12, + 16, 17, 18, 16, 18, 19, + 22, 21, 20, 23, 22, 20 + ] mut index_buffer_desc := C.sg_buffer_desc{} @@ -343,9 +317,9 @@ fn init_cube_glsl_p(mut app App) { pipdesc.layout.buffers[0].stride = int(sizeof(Vertex_t)) // the constants [C.ATTR_vs_p_pos, C.ATTR_vs_p_color0, C.ATTR_vs_p_texcoord0] are generated by sokol-shdc - pipdesc.layout.attrs[C.ATTR_vs_p_pos].format = .float3 // x,y,z as f32 - pipdesc.layout.attrs[C.ATTR_vs_p_color0].format = .ubyte4n // color as u32 - pipdesc.layout.attrs[C.ATTR_vs_p_texcoord0].format = .float2 // u,v as f32 + pipdesc.layout.attrs[C.ATTR_vs_p_pos ].format = .float3 // x,y,z as f32 + pipdesc.layout.attrs[C.ATTR_vs_p_color0 ].format = .ubyte4n // color as u32 + pipdesc.layout.attrs[C.ATTR_vs_p_texcoord0].format = .float2 // u,v as f32 // pipdesc.layout.attrs[C.ATTR_vs_p_texcoord0].format = .short2n // u,v as u16 pipdesc.shader = shader @@ -372,26 +346,23 @@ fn init_cube_glsl_p(mut app App) { println('GLSL Puppy init DONE!') } +[inline] +fn vec4(x f32, y f32, z f32, w f32) m4.Vec4 { + return m4.Vec4{e:[x, y, z, w]!} +} + fn calc_tr_matrices(w f32, h f32, rx f32, ry f32, in_scale f32) m4.Mat4 { - proj := m4.perspective(60, w / h, 0.01, 10.0) - view := m4.look_at(m4.Vec4{ e: [f32(0.0), 0.0, 6, 0]! }, m4.Vec4{ - e: [f32(0), 0, 0, 0]! - }, m4.Vec4{ - e: [f32(0), 1.0, 0, 0]! - }) + proj := m4.perspective(60, w/h, 0.01, 10.0) + view := m4.look_at(vec4(f32(0.0) ,0 , 6, 0), vec4(f32(0), 0, 0, 0), vec4(f32(0), 1, 0, 0)) view_proj := view * proj - rxm := m4.rotate(m4.rad(rx), m4.Vec4{ - e: [f32(1), 0, 0, 0]! - }) - rym := m4.rotate(m4.rad(ry), m4.Vec4{ - e: [f32(0), 1, 0, 0]! - }) + rxm := m4.rotate(m4.rad(rx), vec4(f32(1), 0, 0, 0)) + rym := m4.rotate(m4.rad(ry), vec4(f32(0), 1, 0, 0)) - model := rym * rxm - scale_m := m4.scale(m4.Vec4{ e: [in_scale, in_scale, in_scale, 1]! }) + model := rym * rxm + scale_m := m4.scale(vec4(in_scale, in_scale, in_scale, 1)) - res := (scale_m * model) * view_proj + res := (scale_m * model) * view_proj return res } @@ -412,26 +383,25 @@ fn draw_cube_glsl_m(app App) { gfx.apply_pipeline(app.pipe['march']) gfx.apply_bindings(app.bind['march']) - //*************** // Uniforms - //*************** + // *** vertex shadeer uniforms *** // passing the view matrix as uniform // res is a 4x4 matrix of f32 thus: 4*16 byte of size gfx.apply_uniforms(C.SG_SHADERSTAGE_VS, C.SLOT_vs_params_m, &tr_matrix, 4 * 16) - // fragment shader uniforms + // *** fragment shader uniforms *** time_ticks := f32(time.ticks() - app.ticks) / 1000 mut tmp_fs_params := [ f32(ws.width), - ws.height * ratio, /* x,y resolution to pass to FS */ + ws.height * ratio, // x,y resolution to pass to FS 0, - 0, /* dont send mouse position */ + 0, // dont send mouse position /* app.mouse_x, // mouse x */ /* ws.height - app.mouse_y*2, // mouse y scaled */ - time_ticks, /* time as f32 */ - app.frame_count, /* frame count */ + time_ticks, // time as f32 + app.frame_count, // frame count 0, - 0 /* padding bytes , see "fs_params" struct paddings in rt_glsl.h */, + 0 // padding bytes , see "fs_params" struct paddings in rt_glsl.h ]! gfx.apply_uniforms(C.SG_SHADERSTAGE_FS, C.SLOT_fs_params_m, &tmp_fs_params, int(sizeof(tmp_fs_params))) @@ -457,26 +427,25 @@ fn draw_cube_glsl_p(app App) { gfx.apply_pipeline(app.pipe['puppy']) gfx.apply_bindings(app.bind['puppy']) - //*************** // Uniforms - //*************** + // *** vertex shadeer uniforms *** // passing the view matrix as uniform // res is a 4x4 matrix of f32 thus: 4*16 byte of size gfx.apply_uniforms(C.SG_SHADERSTAGE_VS, C.SLOT_vs_params_p, &tr_matrix, 4 * 16) - // fragment shader uniforms + // *** fragment shader uniforms *** time_ticks := f32(time.ticks() - app.ticks) / 1000 mut tmp_fs_params := [ f32(ws.width), - ws.height * ratio, /* x,y resolution to pass to FS */ + ws.height * ratio, // x,y resolution to pass to FS 0, - 0, /* dont send mouse position */ + 0, // dont send mouse position /* app.mouse_x, // mouse x */ /* ws.height - app.mouse_y*2, // mouse y scaled */ - time_ticks, /* time as f32 */ - app.frame_count, /* frame count */ + time_ticks, // time as f32 + app.frame_count, // frame count 0, - 0 /* padding bytes , see "fs_params" struct paddings in rt_glsl.h */, + 0 // padding bytes , see "fs_params" struct paddings in rt_glsl.h ]! gfx.apply_uniforms(C.SG_SHADERSTAGE_FS, C.SLOT_fs_params_p, &tmp_fs_params, int(sizeof(tmp_fs_params))) @@ -533,9 +502,7 @@ fn frame(mut app App) { } /****************************************************************************** -* * Init / Cleanup -* ******************************************************************************/ fn my_init(mut app App) { // set max vertices, @@ -559,22 +526,22 @@ fn my_init(mut app App) { x := (i & 0xFF) >> 5 // 8 cell // upper left corner if x == 0 && y == 0 { - tmp_txt[i] = byte(0xFF) + tmp_txt[i + 0] = byte(0xFF) tmp_txt[i + 1] = byte(0) tmp_txt[i + 2] = byte(0) tmp_txt[i + 3] = byte(0xFF) } // low right corner else if x == 7 && y == 7 { - tmp_txt[i] = byte(0) + tmp_txt[i + 0] = byte(0) tmp_txt[i + 1] = byte(0xFF) tmp_txt[i + 2] = byte(0) tmp_txt[i + 3] = byte(0xFF) } else { col := if ((x + y) & 1) == 1 { 0xFF } else { 128 } - tmp_txt[i] = byte(col) // red - tmp_txt[i + 1] = byte(col) // green - tmp_txt[i + 2] = byte(col) // blue + tmp_txt[i + 0] = byte(col) // red + tmp_txt[i + 1] = byte(col) // green + tmp_txt[i + 2] = byte(col) // blue tmp_txt[i + 3] = byte(0xFF) // alpha } i += 4 @@ -594,9 +561,7 @@ fn cleanup(mut app App) { } /****************************************************************************** -* -* event -* +* events handling ******************************************************************************/ fn my_event_manager(mut ev gg.Event, mut app App) { if ev.typ == .mouse_down { @@ -619,11 +584,9 @@ fn my_event_manager(mut ev gg.Event, mut app App) { } /****************************************************************************** -* * Main -* ******************************************************************************/ -[console] +[console] // is needed for easier diagnostics on windows fn main() { // App init mut app := &App{ @@ -635,7 +598,7 @@ fn main() { height: win_height use_ortho: true // This is needed for 2D drawing create_window: true - window_title: '3D Ray Marching Cube' + window_title: '3D Dual shader Cube - click and rotate with the mouse' user_data: app bg_color: bg_color frame_fn: frame diff --git a/examples/sokol/05_instancing_glsl/rt_glsl.v b/examples/sokol/05_instancing_glsl/rt_glsl.v new file mode 100644 index 0000000000..469bd38557 --- /dev/null +++ b/examples/sokol/05_instancing_glsl/rt_glsl.v @@ -0,0 +1,505 @@ +/********************************************************************** +* +* Sokol 3d cube multishader demo +* +* Copyright (c) 2021 Dario Deledda. All rights reserved. +* Use of this source code is governed by an MIT license +* that can be found in the LICENSE file. +* +* HOW TO COMPILE SHADERS: +* - download the sokol shader convertor tool from https://github.com/floooh/sokol-tools-bin/archive/pre-feb2021-api-changes.tar.gz +* ( also look at https://github.com/floooh/sokol-tools/blob/master/docs/sokol-shdc.md ) +* - compile the .glsl shared file with: +* linux : sokol-shdc --input rt_glsl_instancing.glsl --output rt_glsl_instancing.h --slang glsl330 +* windows: sokol-shdc.exe --input rt_glsl_instancing.glsl --output rt_glsl_instancing.h --slang glsl330 +* +* --slang parameter can be: +* - glsl330: desktop GL +* - glsl100: GLES2 / WebGL +* - glsl300es: GLES3 / WebGL2 +* - hlsl4: D3D11 +* - hlsl5: D3D11 +* - metal_macos: Metal on macOS +* - metal_ios: Metal on iOS device +* - metal_sim: Metal on iOS simulator +* - wgpu: WebGPU +* +* you can have multiple platforms at the same time passing parameters like this: --slang glsl330:hlsl5:metal_macos +* for further infos have a look at the sokol shader tool docs. +* +* TODO: +* - frame counter +**********************************************************************/ +import gg +import gg.m4 +import gx +import math + +import sokol.gfx +//import sokol.sgl + +import time + +const ( + win_width = 800 + win_height = 800 + bg_color = gx.white + num_inst = 16384 +) + +struct App { +mut: + gg &gg.Context + texture C.sg_image + init_flag bool + frame_count int + + mouse_x int = -1 + mouse_y int = -1 + mouse_down bool + + // glsl + cube_pip_glsl C.sg_pipeline + cube_bind C.sg_bindings + + pipe map[string]C.sg_pipeline + bind map[string]C.sg_bindings + + // time + ticks i64 + + // instances + inst_pos [num_inst]m4.Vec4 + + // camera + camera_x f32 + camera_z f32 +} + +/****************************************************************************** +* GLSL Include and functions +******************************************************************************/ +#flag -I @VROOT/. +#include "rt_glsl_instancing.h" #Please use sokol-shdc to generate the necessary rt_glsl_march.h file from rt_glsl_march.glsl (see the instructions at the top of this file) +fn C.instancing_shader_desc() &C.sg_shader_desc + +/****************************************************************************** +* Texture functions +******************************************************************************/ +fn create_texture(w int, h int, buf byteptr) C.sg_image{ + sz := w * h * 4 + mut img_desc := C.sg_image_desc{ + width: w + height: h + num_mipmaps: 0 + min_filter: .linear + mag_filter: .linear + //usage: .dynamic + wrap_u: .clamp_to_edge + wrap_v: .clamp_to_edge + label: &byte(0) + d3d11_texture: 0 + } + // comment if .dynamic is enabled + img_desc.content.subimage[0][0] = C.sg_subimage_content{ + ptr: buf + size: sz + } + + sg_img := C.sg_make_image(&img_desc) + return sg_img +} + +fn destroy_texture(sg_img C.sg_image){ + C.sg_destroy_image(sg_img) +} + +// Use only if usage: .dynamic is enabled +fn update_text_texture(sg_img C.sg_image, w int, h int, buf byteptr){ + sz := w * h * 4 + mut tmp_sbc := C.sg_image_content{} + tmp_sbc.subimage[0][0] = C.sg_subimage_content { + ptr: buf + size: sz + } + C.sg_update_image(sg_img, &tmp_sbc) +} + +/****************************************************************************** +* Draw functions +****************************************************************************** + Cube vertex buffer with packed vertex formats for color and texture coords. + Note that a vertex format which must be portable across all + backends must only use the normalized integer formats + (BYTE4N, UBYTE4N, SHORT2N, SHORT4N), which can be converted + to floating point formats in the vertex shader inputs. + The reason is that D3D11 cannot convert from non-normalized + formats to floating point inputs (only to integer inputs), + and WebGL2 / GLES2 don't support integer vertex shader inputs. +*/ + +struct Vertex_t { + x f32 + y f32 + z f32 + color u32 + + //u u16 // for compatibility with D3D11 + //v u16 // for compatibility with D3D11 + u f32 + v f32 +} + +// march shader init +fn init_cube_glsl_i(mut app App) { + /* cube vertex buffer */ + //d := u16(32767) // for compatibility with D3D11, 32767 stand for 1 + d := f32(1.0) + c := u32(0xFFFFFF_FF) // color RGBA8 + vertices := [ + // Face 0 + Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{ 1.0, -1.0, -1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, -1.0, c, d, d}, + Vertex_t{-1.0, 1.0, -1.0, c, 0, d}, + // Face 1 + Vertex_t{-1.0, -1.0, 1.0, c, 0, 0}, + Vertex_t{ 1.0, -1.0, 1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, 1.0, c, d, d}, + Vertex_t{-1.0, 1.0, 1.0, c, 0, d}, + // Face 2 + Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{-1.0, 1.0, -1.0, c, d, 0}, + Vertex_t{-1.0, 1.0, 1.0, c, d, d}, + Vertex_t{-1.0, -1.0, 1.0, c, 0, d}, + // Face 3 + Vertex_t{ 1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{ 1.0, 1.0, -1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, 1.0, c, d, d}, + Vertex_t{ 1.0, -1.0, 1.0, c, 0, d}, + // Face 4 + Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{-1.0, -1.0, 1.0, c, d, 0}, + Vertex_t{ 1.0, -1.0, 1.0, c, d, d}, + Vertex_t{ 1.0, -1.0, -1.0, c, 0, d}, + // Face 5 + Vertex_t{-1.0, 1.0, -1.0, c, 0, 0}, + Vertex_t{-1.0, 1.0, 1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, 1.0, c, d, d}, + Vertex_t{ 1.0, 1.0, -1.0, c, 0, d}, + ] + + mut vert_buffer_desc := C.sg_buffer_desc{} + unsafe {C.memset(&vert_buffer_desc, 0, sizeof(vert_buffer_desc))} + vert_buffer_desc.size = vertices.len * int(sizeof(Vertex_t)) + vert_buffer_desc.content = byteptr(vertices.data) + vert_buffer_desc.@type = .vertexbuffer + vert_buffer_desc.label = "cube-vertices".str + vbuf := gfx.make_buffer(&vert_buffer_desc) + + /* create an instance buffer for the cube */ + mut inst_buffer_desc := C.sg_buffer_desc{} + unsafe {C.memset(&inst_buffer_desc, 0, sizeof(inst_buffer_desc))} + inst_buffer_desc.size = num_inst * int(sizeof(m4.Vec4)) + inst_buffer_desc.@type = .vertexbuffer + inst_buffer_desc.usage = .stream + inst_buffer_desc.label = "instance-data".str + inst_buf := gfx.make_buffer(&inst_buffer_desc) + + + /* create an index buffer for the cube */ + indices := [ + u16(0), 1, 2, 0, 2, 3, + 6, 5, 4, 7, 6, 4, + 8, 9, 10, 8, 10, 11, + 14, 13, 12, 15, 14, 12, + 16, 17, 18, 16, 18, 19, + 22, 21, 20, 23, 22, 20 + ] + + mut index_buffer_desc := C.sg_buffer_desc{} + unsafe {C.memset(&index_buffer_desc, 0, sizeof(index_buffer_desc))} + index_buffer_desc.size = indices.len * int(sizeof(u16)) + index_buffer_desc.content = byteptr(indices.data) + index_buffer_desc.@type = .indexbuffer + index_buffer_desc.label = "cube-indices".str + ibuf := gfx.make_buffer(&index_buffer_desc) + + /* create shader */ + shader := gfx.make_shader(C.instancing_shader_desc()) + + mut pipdesc := C.sg_pipeline_desc{} + unsafe {C.memset(&pipdesc, 0, sizeof(pipdesc))} + pipdesc.layout.buffers[0].stride = int(sizeof(Vertex_t)) + + // the constants [C.ATTR_vs_m_pos, C.ATTR_vs_m_color0, C.ATTR_vs_m_texcoord0] are generated by sokol-shdc + pipdesc.layout.attrs[C.ATTR_vs_i_pos ].format = .float3 // x,y,z as f32 + pipdesc.layout.attrs[C.ATTR_vs_i_pos ].buffer_index = 0 + pipdesc.layout.attrs[C.ATTR_vs_i_color0 ].format = .ubyte4n // color as u32 + pipdesc.layout.attrs[C.ATTR_vs_i_pos ].buffer_index = 0 + pipdesc.layout.attrs[C.ATTR_vs_i_texcoord0].format = .float2 // u,v as f32 + pipdesc.layout.attrs[C.ATTR_vs_i_pos ].buffer_index = 0 + + // instancing + // the constant ATTR_vs_i_inst_pos is generated by sokol-shdc + pipdesc.layout.buffers[1].stride = int(sizeof(m4.Vec4)) + pipdesc.layout.buffers[1].step_func = .per_instance // we will pass a single parameter for each instance!! + pipdesc.layout.attrs[C.ATTR_vs_i_inst_pos ].format = .float4 + pipdesc.layout.attrs[C.ATTR_vs_i_inst_pos ].buffer_index = 1 + + pipdesc.shader = shader + pipdesc.index_type = .uint16 + + pipdesc.depth_stencil = C.sg_depth_stencil_state{ + depth_write_enabled: true + depth_compare_func : gfx.CompareFunc(C.SG_COMPAREFUNC_LESS_EQUAL) + } + pipdesc.rasterizer = C.sg_rasterizer_state { + cull_mode: .back + } + pipdesc.label = "glsl_shader pipeline".str + + mut bind := C.sg_bindings{} + unsafe {C.memset(&bind, 0, sizeof(bind))} + bind.vertex_buffers[0] = vbuf // vertex buffer + bind.vertex_buffers[1] = inst_buf // instance buffer + bind.index_buffer = ibuf + bind.fs_images[C.SLOT_tex] = app.texture + app.bind['inst'] = bind + app.pipe['inst'] = gfx.make_pipeline(&pipdesc) + + println("GLSL March init DONE!") +} + +fn calc_tr_matrices(w f32, h f32, rx f32, ry f32, in_scale f32) m4.Mat4{ + proj := m4.perspective(60, w/h, 0.01, 4000.0) + view := m4.look_at(m4.Vec4{e:[f32(0.0),100,6,0]!}, m4.Vec4{e:[f32(0),0,0,0]!}, m4.Vec4{e:[f32(0),1.0,0,0]!}) + view_proj := view * proj + + rxm := m4.rotate(m4.rad(rx), m4.Vec4{e:[f32(1),0,0,0]!}) + rym := m4.rotate(m4.rad(ry), m4.Vec4{e:[f32(0),1,0,0]!}) + + model := rym * rxm + scale_m := m4.scale(m4.Vec4{e:[in_scale, in_scale, in_scale, 1]!}) + + res := (scale_m * model)* view_proj + return res +} + +// triangles draw +fn draw_cube_glsl_i(mut app App){ + if app.init_flag == false { + return + } + + ws := gg.window_size() + //ratio := f32(ws.width) / ws.height + dw := f32(ws.width / 2) + dh := f32(ws.height / 2) + + rot := [f32(app.mouse_y), f32(app.mouse_x)] + tr_matrix := calc_tr_matrices(dw, dh, rot[0], rot[1], 2.3) + + gfx.apply_pipeline(app.pipe['inst']) + gfx.apply_bindings(app.bind['inst']) + + //*************** + // Instancing + //*************** + // passing the instancing to the vs + time_ticks := f32(time.ticks() - app.ticks) / 1000 + cube_size := 2 + sz := 128 // field size dimension + cx := 64 // x center for the cubes + cz := 64 // z center for the cubes + //frame := (app.frame_count/4) % 100 + for index in 0..num_inst { + x := f32(index % sz) + z := f32(index / sz) + // simply waves + y := f32(math.cos((x+time_ticks)/2.0)*math.sin(z/2.0))*2 + // sombrero function + //r := ((x-cx)*(x-cx)+(z-cz)*(z-cz))/(sz/2) + //y := f32(math.sin(r+time_ticks)*4.0) + spare_param := f32(index % 10) + app.inst_pos[index] = m4.Vec4{e:[f32((x - cx - app.camera_x) * cube_size),y ,f32( (z - cz - app.camera_z) * cube_size),spare_param]!} + } + gfx.update_buffer(app.bind['inst'].vertex_buffers[1], &app.inst_pos , num_inst * int(sizeof(m4.Vec4)) ) + + // Uniforms + // *** vertex shadeer uniforms *** + // passing the view matrix as uniform + // res is a 4x4 matrix of f32 thus: 4*16 byte of size + gfx.apply_uniforms(C.SG_SHADERSTAGE_VS, C.SLOT_vs_params_i, &tr_matrix, 4*16 ) + +/* + // *** fragment shader uniforms *** + time_ticks := f32(time.ticks() - app.ticks) / 1000 + mut tmp_fs_params := [ + f32(ws.width), ws.height * ratio, // x,y resolution to pass to FS + 0,0, // dont send mouse position + //app.mouse_x, // mouse x + //ws.height - app.mouse_y*2, // mouse y scaled + time_ticks, // time as f32 + app.frame_count, // frame count + 0,0 // padding bytes , see "fs_params" struct paddings in rt_glsl.h + ]! + gfx.apply_uniforms(C.SG_SHADERSTAGE_FS, C.SLOT_fs_params_i, &tmp_fs_params, int(sizeof(tmp_fs_params))) +*/ + // 3 vertices for triangle * 2 triangles per face * 6 faces = 36 vertices to draw for num_inst times + gfx.draw(0, (3 * 2) * 6, num_inst) +} + + +fn draw_start_glsl(app App){ + if app.init_flag == false { + return + } + + ws := gg.window_size() + //ratio := f32(ws.width) / ws.height + //dw := f32(ws.width / 2) + //dh := f32(ws.height / 2) + + gfx.apply_viewport(0, 0, ws.width, ws.height, true) +} + +fn draw_end_glsl(app App){ + gfx.end_pass() + gfx.commit() +} + +fn frame(mut app App) { + ws := gg.window_size() + + // clear + mut color_action := C.sg_color_attachment_action{ + action: gfx.Action(C.SG_ACTION_CLEAR) + } + color_action.val[0] = 0 + color_action.val[1] = 0 + color_action.val[2] = 0 + color_action.val[3] = 1.0 + mut pass_action := C.sg_pass_action{} + pass_action.colors[0] = color_action + gfx.begin_default_pass(&pass_action, ws.width, ws.height) + + draw_start_glsl(app) + draw_cube_glsl_i(mut app) + draw_end_glsl(app) + app.frame_count++ +} + +/****************************************************************************** +* Init / Cleanup +******************************************************************************/ +fn my_init(mut app App) { + // create chessboard texture 256*256 RGBA + w := 256 + h := 256 + sz := w * h * 4 + tmp_txt := unsafe { malloc(sz) } + mut i := 0 + for i < sz { + unsafe { + y := (i >> 0x8) >> 5 // 8 cell + x := (i & 0xFF) >> 5 // 8 cell + // upper left corner + if x == 0 && y == 0 { + tmp_txt[i + 0] = byte(0xFF) + tmp_txt[i + 1] = byte(0) + tmp_txt[i + 2] = byte(0) + tmp_txt[i + 3] = byte(0xFF) + } + // low right corner + else if x == 7 && y == 7 { + tmp_txt[i + 0] = byte(0) + tmp_txt[i + 1] = byte(0xFF) + tmp_txt[i + 2] = byte(0) + tmp_txt[i + 3] = byte(0xFF) + } else { + col := if ((x + y) & 1) == 1 { 0xFF } else { 128 } + tmp_txt[i + 0] = byte(col) // red + tmp_txt[i + 1] = byte(col) // green + tmp_txt[i + 2] = byte(col) // blue + tmp_txt[i + 3] = byte(0xFF) // alpha + } + i += 4 + } + } + unsafe { + app.texture = create_texture(w, h, tmp_txt) + free(tmp_txt) + } + + // glsl + init_cube_glsl_i(mut app) + app.init_flag = true +} + +fn cleanup(mut app App) { + gfx.shutdown() +} + +/****************************************************************************** +* events handling +******************************************************************************/ +fn my_event_manager(mut ev gg.Event, mut app App) { + if ev.typ == .mouse_down{ + app.mouse_down = true + } + if ev.typ == .mouse_up{ + app.mouse_down = false + } + if app.mouse_down == true && ev.typ == .mouse_move { + app.mouse_x = int(ev.mouse_x) + app.mouse_y = int(ev.mouse_y) + } + if ev.typ == .touches_began || ev.typ == .touches_moved { + if ev.num_touches > 0 { + touch_point := ev.touches[0] + app.mouse_x = int(touch_point.pos_x) + app.mouse_y = int(touch_point.pos_y) + } + } + + // keyboard + if ev.typ == .key_down { + step := f32(1.0) + match ev.key_code { + .w { app.camera_z += step } + .s { app.camera_z -= step } + .a { app.camera_x -= step } + .d { app.camera_x += step } + else{} + } + } +} + +/****************************************************************************** +* Main +******************************************************************************/ +[console] // is needed for easier diagnostics on windows +fn main(){ + // App init + mut app := &App{ + gg: 0 + } + + app.gg = gg.new_context({ + width: win_width + height: win_height + use_ortho: true // This is needed for 2D drawing + create_window: true + window_title: 'Instancing Cube' + user_data: app + bg_color: bg_color + frame_fn: frame + init_fn: my_init + cleanup_fn: cleanup + event_fn: my_event_manager + }) + + app.ticks = time.ticks() + app.gg.run() +} diff --git a/examples/sokol/05_instancing_glsl/rt_glsl_instancing.glsl b/examples/sokol/05_instancing_glsl/rt_glsl_instancing.glsl new file mode 100644 index 0000000000..0e780b3f68 --- /dev/null +++ b/examples/sokol/05_instancing_glsl/rt_glsl_instancing.glsl @@ -0,0 +1,64 @@ +//------------------------------------------------------------------------------ +// Shader code for texcube-sapp sample. +// +// NOTE: This source file also uses the '#pragma sokol' form of the +// custom tags. +//------------------------------------------------------------------------------ +//#pragma sokol @ctype mat4 hmm_mat4 + +#pragma sokol @vs vs_i +uniform vs_params_i { + mat4 mvp; +}; + +in vec4 pos; +in vec4 color0; +in vec2 texcoord0; + +in vec4 inst_pos; + +out vec4 color; +out vec4 color_inst; +out vec2 uv; + +const vec4 palette[10] = vec4[10]( + vec4(1,0,0,1), + vec4(0,1,0,1), + vec4(0,0,1,1), + vec4(1,1,0,1), + vec4(0,1,1,1), + vec4(1,1,1,1), + vec4(0,0,0,1), + vec4(0.2,0.2,0.2,1), + vec4(0.3,0.3,0.3,1), + vec4(0.9,0.9,0.9,1) +); + +void main() { + vec4 delta_pos = vec4(inst_pos.xyz,0); + float w = inst_pos.w; + color_inst = palette[int(w)]; + gl_Position = mvp * (pos + delta_pos); + color = color0; + uv = texcoord0/4; +} +#pragma sokol @end + +#pragma sokol @fs fs_i +uniform sampler2D tex; + +in vec4 color; +in vec4 color_inst; +in vec2 uv; +out vec4 frag_color; + +void main() { + vec4 c = color; + vec4 txt = texture(tex, uv); + c = txt * c * color_inst; + frag_color = c ; +} + +#pragma sokol @end + +#pragma sokol @program instancing vs_i fs_i diff --git a/examples/sokol/05_instancing_glsl/v.mod b/examples/sokol/05_instancing_glsl/v.mod new file mode 100644 index 0000000000..e69de29bb2