diff --git a/base/assets/shader_datas.arm b/base/assets/shader_datas.arm index 437456e3..b9cbe474 100644 Binary files a/base/assets/shader_datas.arm and b/base/assets/shader_datas.arm differ diff --git a/base/project.js b/base/project.js index 06ef31a0..4b11b9b9 100644 --- a/base/project.js +++ b/base/project.js @@ -50,7 +50,7 @@ if (!flags.lite) { project.add_tsfiles("sources/ts/iron"); project.add_tsfiles("sources/ts/nodes"); project.add_shaders("shaders/*.glsl"); - project.add_shaders("shaders/draw/*.glsl"); + project.add_shaders("shaders/*.kong"); project.add_shaders("shaders/draw/*.kong"); project.add_assets("assets/*", { destination: "data/{name}" }); project.add_assets("assets/locale/*", { destination: "data/locale/{name}" }); diff --git a/base/shaders/draw/draw_image.frag.glsl b/base/shaders/draw/draw_image.frag.glsl deleted file mode 100644 index 974d36ca..00000000 --- a/base/shaders/draw/draw_image.frag.glsl +++ /dev/null @@ -1,13 +0,0 @@ -#version 450 - -uniform sampler2D tex; - -in vec2 tex_coord; -in vec4 color; -out vec4 frag_color; - -void main() { - vec4 texcolor = texture(tex, tex_coord) * color; - texcolor.rgb = texcolor.rgb * texcolor.a * color.a; - frag_color = texcolor; -} diff --git a/base/shaders/draw/draw_image.kong b/base/shaders/draw/draw_image.kong new file mode 100644 index 00000000..d0c95a92 --- /dev/null +++ b/base/shaders/draw/draw_image.kong @@ -0,0 +1,43 @@ + +#[set(everything)] +const constants: { + P: float4x4; +}; + +#[set(everything)] +const tex: tex2d; + +#[set(everything)] +const tex_sampler: sampler; + +struct vert_in { + pos: float3; + tex: float2; + col: float4; +} + +struct vert_out { + pos: float4; + tex: float2; + col: float4; +} + +fun draw_image_vert(input: vert_in): vert_out { + var output: vert_out; + output.pos = constants.P * float4(input.pos, 1.0); + output.tex = input.tex; + output.col = input.col; + return output; +} + +fun draw_image_frag(input: vert_out): float4 { + var texcolor: float4 = sample(tex, tex_sampler, input.tex) * input.col; + texcolor.rgb = texcolor.rgb * texcolor.a * input.col.a; + return texcolor; +} + +#[pipe] +struct pipe { + vertex = draw_image_vert; + fragment = draw_image_frag; +} diff --git a/base/shaders/draw/draw_image.vert.glsl b/base/shaders/draw/draw_image.vert.glsl deleted file mode 100644 index 0edddc84..00000000 --- a/base/shaders/draw/draw_image.vert.glsl +++ /dev/null @@ -1,15 +0,0 @@ -#version 450 - -uniform mat4 P; - -in vec3 pos; -in vec2 tex; -in vec4 col; -out vec2 tex_coord; -out vec4 color; - -void main() { - gl_Position = mul(vec4(pos, 1.0), P); - tex_coord = tex; - color = col; -} diff --git a/base/shaders/draw/draw_text.frag.glsl b/base/shaders/draw/draw_text.frag.glsl deleted file mode 100644 index 050bd6b0..00000000 --- a/base/shaders/draw/draw_text.frag.glsl +++ /dev/null @@ -1,11 +0,0 @@ -#version 450 - -uniform sampler2D tex; - -in vec2 tex_coord; -in vec4 fragment_color; -out vec4 frag_color; - -void main() { - frag_color = vec4(fragment_color.rgb, texture(tex, tex_coord).r * fragment_color.a); -} diff --git a/base/shaders/draw/draw_text.kong b/base/shaders/draw/draw_text.kong new file mode 100644 index 00000000..2ea004a8 --- /dev/null +++ b/base/shaders/draw/draw_text.kong @@ -0,0 +1,41 @@ + +#[set(everything)] +const constants: { + P: float4x4; +}; + +#[set(everything)] +const tex: tex2d; + +#[set(everything)] +const tex_sampler: sampler; + +struct vert_in { + pos: float3; + tex: float2; + col: float4; +} + +struct vert_out { + pos: float4; + tex: float2; + col: float4; +} + +fun draw_text_vert(input: vert_in): vert_out { + var output: vert_out; + output.pos = constants.P * float4(input.pos, 1.0); + output.tex = input.tex; + output.col = input.col; + return output; +} + +fun draw_text_frag(input: vert_out): float4 { + return float4(input.col.rgb, sample(tex, tex_sampler, input.tex).r * input.col.a); +} + +#[pipe] +struct pipe { + vertex = draw_text_vert; + fragment = draw_text_frag; +} diff --git a/base/shaders/draw/draw_text.vert.glsl b/base/shaders/draw/draw_text.vert.glsl deleted file mode 100644 index e2624c70..00000000 --- a/base/shaders/draw/draw_text.vert.glsl +++ /dev/null @@ -1,15 +0,0 @@ -#version 450 - -uniform mat4 P; - -in vec3 pos; -in vec2 tex; -in vec4 col; -out vec2 tex_coord; -out vec4 fragment_color; - -void main() { - gl_Position = mul(vec4(pos, 1.0), P); - tex_coord = tex; - fragment_color = col; -} diff --git a/base/shaders/world_pass.frag.glsl b/base/shaders/world_pass.frag.glsl deleted file mode 100644 index 4b57199a..00000000 --- a/base/shaders/world_pass.frag.glsl +++ /dev/null @@ -1,15 +0,0 @@ -#version 450 - -#include "std/math.glsl" - -uniform sampler2D envmap; -uniform vec4 envmap_data_world; // angle, sin(angle), cos(angle), strength - -in vec3 normal; -out vec4 frag_color; - -void main() { - vec3 n = normalize(normal); - frag_color.rgb = texture(envmap, envmap_equirect(-n, envmap_data_world.x)).rgb * envmap_data_world.w; - frag_color.a = 0.0; // Mark as non-opaque -} diff --git a/base/shaders/world_pass.kong b/base/shaders/world_pass.kong new file mode 100644 index 00000000..7c1eb507 --- /dev/null +++ b/base/shaders/world_pass.kong @@ -0,0 +1,52 @@ + +#[set(everything)] +const constants: { + SMVP: float4x4; + envmap_data_world: float4; // angle, sin(angle), cos(angle), strength +}; + +#[set(everything)] +const envmap: tex2d; + +#[set(everything)] +const envmap_sampler: sampler; + +const PI: float = 3.1415926535; +const PI2: float = 6.283185307; + +struct vert_in { + pos: float3; + nor: float3; +} + +struct vert_out { + pos: float4; + nor: float3; +} + +fun world_pass_vert(input: vert_in): vert_out { + var output: vert_out; + output.pos = constants.SMVP * float4(input.pos, 1.0); + output.nor = input.nor; + return output; +} + +fun envmap_equirect(normal: float3, angle: float): float2 { + var phi: float = acos(normal.z); + var theta: float = atan2(normal.x, -normal.y) + PI + angle; + return float2(theta / PI2, phi / PI); +} + +fun world_pass_frag(input: vert_out): float4 { + var n: float3 = normalize(input.nor); + var color: float4; + color.rgb = sample(envmap, envmap_sampler, envmap_equirect(-n, constants.envmap_data_world.x)).rgb * constants.envmap_data_world.w; + color.a = 0.0; // Mark as non-opaque + return color; +} + +#[pipe] +struct pipe { + vertex = world_pass_vert; + fragment = world_pass_frag; +} diff --git a/base/shaders/world_pass.vert.glsl b/base/shaders/world_pass.vert.glsl deleted file mode 100644 index 72d2f485..00000000 --- a/base/shaders/world_pass.vert.glsl +++ /dev/null @@ -1,12 +0,0 @@ -#version 450 - -uniform mat4 SMVP; - -in vec3 pos; -in vec3 nor; -out vec3 normal; - -void main() { - normal = nor; - gl_Position = mul(vec4(pos, 1.0), SMVP); -} diff --git a/base/sources/iron_draw.c b/base/sources/iron_draw.c index c0ad3402..c371ba47 100644 --- a/base/sources/iron_draw.c +++ b/base/sources/iron_draw.c @@ -153,10 +153,17 @@ void draw_init(buffer_t *image_vert, buffer_t *image_frag, buffer_t *colored_ver image_pipeline.blend_destination = IRON_GPU_BLEND_INV_SOURCE_ALPHA; image_pipeline.alpha_blend_source = IRON_GPU_BLEND_ONE; image_pipeline.alpha_blend_destination = IRON_GPU_BLEND_INV_SOURCE_ALPHA; + + image_pipeline.kong = true; + iron_gpu_pipeline_compile(&image_pipeline); image_tex_unit = iron_gpu_pipeline_get_texture_unit(&image_pipeline, "tex"); + image_tex_unit.stages[IRON_GPU_SHADER_TYPE_FRAGMENT] = 0; + image_proj_loc = iron_gpu_pipeline_get_constant_location(&image_pipeline, "P"); + image_proj_loc.impl.vertexOffset = 0; + image_proj_loc.impl.fragmentOffset = -1; gpu_vertex_buffer_init(&image_vertex_buffer, DRAW_BUFFER_SIZE * 4, &structure, GPU_USAGE_DYNAMIC); image_rect_verts = gpu_vertex_buffer_lock_all(&image_vertex_buffer); @@ -248,9 +255,17 @@ void draw_init(buffer_t *image_vert, buffer_t *image_frag, buffer_t *colored_ver text_pipeline.blend_destination = IRON_GPU_BLEND_INV_SOURCE_ALPHA; text_pipeline.alpha_blend_source = IRON_GPU_BLEND_SOURCE_ALPHA; text_pipeline.alpha_blend_destination = IRON_GPU_BLEND_INV_SOURCE_ALPHA; + + text_pipeline.kong = true; + iron_gpu_pipeline_compile(&text_pipeline); + text_tex_unit = iron_gpu_pipeline_get_texture_unit(&text_pipeline, "tex"); + text_tex_unit.stages[IRON_GPU_SHADER_TYPE_FRAGMENT] = 0; + text_proj_loc = iron_gpu_pipeline_get_constant_location(&text_pipeline, "P"); + text_proj_loc.impl.vertexOffset = 0; + text_proj_loc.impl.fragmentOffset = -1; iron_gpu_pipeline_init(&text_pipeline_rt); text_pipeline_rt.input_layout = &structure; @@ -260,6 +275,9 @@ void draw_init(buffer_t *image_vert, buffer_t *image_frag, buffer_t *colored_ver text_pipeline_rt.blend_destination = IRON_GPU_BLEND_INV_SOURCE_ALPHA; text_pipeline_rt.alpha_blend_source = IRON_GPU_BLEND_ONE; text_pipeline_rt.alpha_blend_destination = IRON_GPU_BLEND_INV_SOURCE_ALPHA; + + text_pipeline_rt.kong = true; + iron_gpu_pipeline_compile(&text_pipeline_rt); gpu_vertex_buffer_init(&text_vertex_buffer, DRAW_BUFFER_SIZE * 4, &structure, GPU_USAGE_DYNAMIC); diff --git a/base/sources/libs/kong/sources/backends/cstyle.c b/base/sources/libs/kong/sources/backends/cstyle.c index 98e7d7aa..7b73042f 100644 --- a/base/sources/libs/kong/sources/backends/cstyle.c +++ b/base/sources/libs/kong/sources/backends/cstyle.c @@ -24,6 +24,10 @@ void cstyle_write_opcode(char *code, size_t *offset, opcode *o, type_string_func *offset += sprintf(&code[*offset], "%s _%" PRIu64 ";\n", type_string(o->op_var.var.type.type), o->op_var.var.index); } break; + case OPCODE_NEGATE: + indent(code, offset, *indentation); + *offset += sprintf(&code[*offset], "%s _%" PRIu64 " = -_%" PRIu64 ";\n", type_string(o->op_negate.to.type.type), o->op_negate.to.index, o->op_negate.from.index); + break; case OPCODE_NOT: indent(code, offset, *indentation); *offset += sprintf(&code[*offset], "%s _%" PRIu64 " = !_%" PRIu64 ";\n", type_string(o->op_not.to.type.type), o->op_not.to.index, o->op_not.from.index); diff --git a/base/sources/libs/kong/sources/compiler.c b/base/sources/libs/kong/sources/compiler.c index f2e4eee2..fef03233 100644 --- a/base/sources/libs/kong/sources/compiler.c +++ b/base/sources/libs/kong/sources/compiler.c @@ -380,8 +380,16 @@ variable emit_expression(opcodes *code, block *parent, expression *e) { error(context, "not implemented"); case OPERATOR_LESS_EQUAL: error(context, "not implemented"); - case OPERATOR_MINUS: - error(context, "not implemented"); + case OPERATOR_MINUS: { + variable v = emit_expression(code, parent, e->unary.right); + opcode o; + o.type = OPCODE_NEGATE; + o.size = OP_SIZE(o, op_negate); + o.op_negate.from = v; + o.op_negate.to = allocate_variable(v.type, VARIABLE_LOCAL); + emit_op(code, &o); + return o.op_negate.to; + } case OPERATOR_PLUS: error(context, "not implemented"); case OPERATOR_DIVIDE: diff --git a/base/sources/libs/kong/sources/compiler.h b/base/sources/libs/kong/sources/compiler.h index c82201f9..0f4d2b9d 100644 --- a/base/sources/libs/kong/sources/compiler.h +++ b/base/sources/libs/kong/sources/compiler.h @@ -18,6 +18,7 @@ typedef struct opcode { enum { OPCODE_VAR, OPCODE_NOT, + OPCODE_NEGATE, OPCODE_STORE_VARIABLE, OPCODE_SUB_AND_STORE_VARIABLE, OPCODE_ADD_AND_STORE_VARIABLE, @@ -62,6 +63,10 @@ typedef struct opcode { struct { variable var; } op_var; + struct { + variable from; + variable to; + } op_negate; struct { variable from; variable to; diff --git a/base/sources/libs/kong/sources/functions.c b/base/sources/libs/kong/sources/functions.c index 2cf8c1d6..ec81ceb7 100644 --- a/base/sources/libs/kong/sources/functions.c +++ b/base/sources/libs/kong/sources/functions.c @@ -92,6 +92,24 @@ static void add_func_float_float(char *name) { f->block = NULL; } +static void add_func_float_float_float(char *name) { + function_id func = add_function(add_name(name)); + function *f = get_function(func); + init_type_ref(&f->return_type, add_name("float")); + f->return_type.type = find_type_by_ref(&f->return_type); + + f->parameter_names[0] = add_name("a"); + init_type_ref(&f->parameter_types[0], add_name("float")); + f->parameter_types[0].type = find_type_by_ref(&f->parameter_types[0]); + + f->parameter_names[1] = add_name("b"); + init_type_ref(&f->parameter_types[1], add_name("float")); + f->parameter_types[1].type = find_type_by_ref(&f->parameter_types[1]); + + f->parameters_size = 2; + f->block = NULL; +} + static void add_func_float_float2(char *name) { function_id func = add_function(add_name(name)); function *f = get_function(func); @@ -585,6 +603,10 @@ void functions_init(void) { add_func_float3_float3("normalize"); add_func_float_float("sin"); add_func_float_float("cos"); + add_func_float_float("asin"); + add_func_float_float("acos"); + add_func_float_float("atan"); + add_func_float_float_float("atan2"); add_func_float_float2("length"); add_func_uint3("ray_index"); add_func_float3("ray_dimensions"); diff --git a/base/sources/ts/iron/shader_data.ts b/base/sources/ts/iron/shader_data.ts index f039e1cd..65757541 100644 --- a/base/sources/ts/iron/shader_data.ts +++ b/base/sources/ts/iron/shader_data.ts @@ -142,6 +142,13 @@ function shader_context_compile(raw: shader_context_t): shader_context_t { } } else { + + if (starts_with(raw.fragment_shader, "_")) { + raw.fragment_shader = substring(raw.fragment_shader, 1, raw.fragment_shader.length); + raw.vertex_shader = substring(raw.vertex_shader, 1, raw.vertex_shader.length); + raw._.pipe_state.kong = true; + } + ///if arm_embed raw._.pipe_state.fragment_shader = sys_get_shader(raw.fragment_shader); raw._.pipe_state.vertex_shader = sys_get_shader(raw.vertex_shader); @@ -158,20 +165,46 @@ function shader_context_compile(raw: shader_context_t): shader_context_t { return shader_context_finish_compile(raw); } +function shader_context_type_offset(t: string): i32 { + if (t == "int") { + return 4; + } + if (t == "float") { + return 4; + } + if (t == "vec2") { + return 8; + } + if (t == "vec3") { + return 12; + } + if (t == "vec4") { + return 16; + } + if (t == "mat4") { + return 64; + } + if (t == "mat3") { + return 36; + } +} + function shader_context_finish_compile(raw: shader_context_t): shader_context_t { gpu_compile_pipeline(raw._.pipe_state); if (raw.constants != null) { + let offset: i32 = 0; for (let i: i32 = 0; i < raw.constants.length; ++i) { let c: shader_const_t = raw.constants[i]; - shader_context_add_const(raw, c); + shader_context_add_const(raw, c, offset); + offset += shader_context_type_offset(c.type); } } if (raw.texture_units != null) { for (let i: i32 = 0; i < raw.texture_units.length; ++i) { let tu: tex_unit_t = raw.texture_units[i]; - shader_context_add_tex(raw, tu); + shader_context_add_tex(raw, tu, i); } } @@ -343,12 +376,21 @@ function shader_context_get_tex_format(s: string): tex_format_t { return tex_format_t.RGBA32; } -function shader_context_add_const(raw: shader_context_t, c: shader_const_t) { - array_push(raw._.constants, gpu_get_constant_location(raw._.pipe_state, c.name)); +function shader_context_add_const(raw: shader_context_t, c: shader_const_t, offset: i32) { + let cl: iron_gpu_constant_location_t = gpu_get_constant_location(raw._.pipe_state, c.name); + if (raw._.pipe_state.kong) { + let ptr: gpu_constant_location_impl_t = ADDRESS(cl.impl); + ptr.vertexOffset = offset; + ptr.fragmentOffset = offset; + } + array_push(raw._.constants, cl); } -function shader_context_add_tex(raw: shader_context_t, tu: tex_unit_t) { - let unit: any = gpu_get_texture_unit(raw._.pipe_state, tu.name); +function shader_context_add_tex(raw: shader_context_t, tu: tex_unit_t, i: i32) { + let unit: iron_gpu_texture_unit_t = gpu_get_texture_unit(raw._.pipe_state, tu.name); + if (raw._.pipe_state.kong) { + ARRAY_ACCESS(unit.stages, IRON_GPU_SHADER_TYPE_FRAGMENT) = i; + } array_push(raw._.tex_units, unit); }