Add outline pass to cubes

This commit is contained in:
Hugo Mårdbrink 2025-08-27 00:16:42 +02:00
parent 1852cf3a7f
commit 2ee22c118c
10 changed files with 425 additions and 108 deletions

View file

@ -1,5 +1,6 @@
build-shaders: build-shaders:
./sokol-shdc -i shaders/src/shader.glsl -o shaders/out/shader.odin -l metal_macos -f sokol_odin ./sokol-shdc -i shaders/src/cube.glsl -o shaders/out/cube.odin -l metal_macos -f sokol_odin
./sokol-shdc -i shaders/src/outline.glsl -o shaders/out/outline.odin -l metal_macos -f sokol_odin
build: build-shaders build: build-shaders
odin build . -use-single-module odin build . -use-single-module

View file

@ -0,0 +1,28 @@
package program_config
import sg "../sokol/gfx"
// Application
WINDOW_TITLE :: "ECS Test"
// Behaviour
SPAWN_INTERVAL :: 0.2 // in seconds
GRAVITY_CONSTANT :: -2.5
SPAWN_AREA :: 50 // one side
Y_DESPAWN_CUTOFF :: -15
// Colors
BACKGROUND_COLOR :: sg.Color{ 1.0000, 0.9725, 0.9059, 1 }
CUBE_COLORS := [][4]f32{
{ 0.6235, 0.7725, 0.9098, 1 },
{ 0.9216, 0.6392, 0.6392, 1 },
{ 0.7137, 0.8431, 0.6588, 1 },
{ 0.7059, 0.6549, 0.8392, 1 },
{ 1.0000, 0.8980, 0.6000, 1 },
}
BORDER_COLOR :: [4]f32{ 0, 0, 0, 1 }
// User
MOVEMENT_SPEED :: 3.0
LOOK_SENSITIVITY :: 0.15
START_POSITION :: [3]f32{ 30, 0, 60 }

View file

@ -37,7 +37,8 @@ MeshComponent :: struct {
} }
MaterialID :: enum { MaterialID :: enum {
Grid, Cube,
Outline,
} }
MaterialComponent :: struct { MaterialComponent :: struct {

View file

@ -2,6 +2,8 @@ package ecs
import "core:log" import "core:log"
import program_config "../config"
PhysicsSystem :: struct { PhysicsSystem :: struct {
using base: SystemBase, using base: SystemBase,
} }
@ -18,7 +20,7 @@ physics_system_update :: proc(physics_system: ^PhysicsSystem, coordinator: ^Coor
transform.position += rigid_body.velocity * dt transform.position += rigid_body.velocity * dt
rigid_body.velocity += gravity.force * dt rigid_body.velocity += gravity.force * dt
if transform.position.y < -15 { if transform.position.y < program_config.Y_DESPAWN_CUTOFF {
append(&entities_to_delete, entity) append(&entities_to_delete, entity)
} }
} }

View file

@ -20,6 +20,8 @@ import sa "../sokol/app"
import sh "../sokol/helpers" import sh "../sokol/helpers"
import sg "../sokol/gfx" import sg "../sokol/gfx"
import program_config "../config"
import shaders "../shaders/out" import shaders "../shaders/out"
VertexData :: struct { VertexData :: struct {
@ -48,14 +50,46 @@ RenderSystem :: struct {
} }
@(private) @(private)
init_grid_material :: proc(render_system: ^RenderSystem) { init_outline_material :: proc(render_system: ^RenderSystem) {
shader := sg.make_shader(shaders.main_shader_desc(sg.query_backend())) shader := sg.make_shader(shaders.outline_shader_desc(sg.query_backend()))
pipeline := sg.make_pipeline({ pipeline := sg.make_pipeline({
shader = shader, shader = shader,
layout = { layout = {
attrs = { attrs = {
shaders.ATTR_main_pos = { format = .FLOAT3 }, shaders.ATTR_outline_pos = { format = .FLOAT3 },
shaders.ATTR_main_uv = { format = .FLOAT2 }, shaders.ATTR_outline_uv = { format = .FLOAT2 },
},
},
index_type = .UINT16,
cull_mode = .FRONT,
depth = {
pixel_format = .DEFAULT,
write_enabled = true,
bias = 0.001,
bias_clamp = 0.0,
bias_slope_scale = 1.0,
compare = .LESS_EQUAL,
},
})
sampler := sg.make_sampler({})
render_system.materials[.Outline] = Material{
shader = shader,
pipeline = pipeline,
sampler = sampler,
}
}
@(private)
init_cube_material :: proc(render_system: ^RenderSystem) {
shader := sg.make_shader(shaders.cube_shader_desc(sg.query_backend()))
pipeline := sg.make_pipeline({
shader = shader,
layout = {
attrs = {
shaders.ATTR_cube_pos = { format = .FLOAT3 },
shaders.ATTR_cube_uv = { format = .FLOAT2 },
}, },
}, },
index_type = .UINT16, index_type = .UINT16,
@ -93,7 +127,7 @@ init_grid_material :: proc(render_system: ^RenderSystem) {
sampler := sg.make_sampler({}) sampler := sg.make_sampler({})
render_system.materials[.Grid] = Material{ render_system.materials[.Cube] = Material{
shader = shader, shader = shader,
pipeline = pipeline, pipeline = pipeline,
image = image, image = image,
@ -178,7 +212,9 @@ render_system_init :: proc(render_system: ^RenderSystem, camera_entity: EntityID
render_system.camera_entity = camera_entity render_system.camera_entity = camera_entity
init_cube_mesh(render_system) init_cube_mesh(render_system)
init_grid_material(render_system) init_cube_material(render_system)
init_outline_material(render_system)
} }
render_system_delete :: proc(render_system: ^RenderSystem, coordinator: ^Coordinator) { render_system_delete :: proc(render_system: ^RenderSystem, coordinator: ^Coordinator) {
@ -186,11 +222,16 @@ render_system_delete :: proc(render_system: ^RenderSystem, coordinator: ^Coordin
sg.destroy_buffer(cube_mesh.index_buffer) sg.destroy_buffer(cube_mesh.index_buffer)
sg.destroy_buffer(cube_mesh.vertex_buffer) sg.destroy_buffer(cube_mesh.vertex_buffer)
grid_material := render_system.materials[.Grid] cube_material := render_system.materials[.Cube]
sg.destroy_image(grid_material.image) sg.destroy_image(cube_material.image)
sg.destroy_sampler(grid_material.sampler) sg.destroy_sampler(cube_material.sampler)
sg.destroy_pipeline(grid_material.pipeline) sg.destroy_pipeline(cube_material.pipeline)
sg.destroy_shader(grid_material.shader) sg.destroy_shader(cube_material.shader)
outline_material := render_system.materials[.Outline]
sg.destroy_sampler(outline_material.sampler)
sg.destroy_pipeline(outline_material.pipeline)
sg.destroy_shader(outline_material.shader)
delete(render_system.materials) delete(render_system.materials)
delete(render_system.meshes) delete(render_system.meshes)
@ -198,24 +239,55 @@ render_system_delete :: proc(render_system: ^RenderSystem, coordinator: ^Coordin
sg.shutdown() sg.shutdown()
} }
render_system_update :: proc(render_system: ^RenderSystem, coordinator: ^Coordinator, dt: f32) { @(private)
camera := coordinator_get_component(CameraComponent, coordinator, render_system.camera_entity) CLEAR_SCREEN_ACTION :: sg.Pass_Action{
colors = {
proj := linalg.matrix4_perspective_f32(70, sa.widthf() / sa.heightf(), 0.001, 1000) 0 = {
view := linalg.matrix4_look_at_f32(camera.position, camera.target, { 0, 1, 0 } ) load_action = .CLEAR,
clear_value = program_config.BACKGROUND_COLOR,
BACKGROUND_COLOR :: sg.Color{ 0, 0, 0, 1 }
CLEAR_SCREEN_ACTION :: sg.Pass_Action{
colors = {
0 = {
load_action = .CLEAR,
clear_value = BACKGROUND_COLOR,
}
} }
} }
}
sg.begin_pass({ swapchain = sh.glue_swapchain(), action = CLEAR_SCREEN_ACTION }) outline_pass :: proc(render_system: ^RenderSystem, coordinator: ^Coordinator, proj: Mat4, view: Mat4) {
for entity in render_system.entities {
transform := coordinator_get_component(TransformComponent, coordinator, entity)
mesh_id := coordinator_get_component(MeshComponent, coordinator, entity).mesh_id
mesh := render_system.meshes[mesh_id]
scale_mat := linalg.matrix4_scale_f32(transform.scale * 1.2)
rot_mat := linalg.matrix4_from_yaw_pitch_roll_f32(
transform.rotation.y,
transform.rotation.x,
transform.rotation.z
)
pos_mat := linalg.matrix4_translate_f32(transform.position)
model := pos_mat * rot_mat * scale_mat
mvp := proj * view * model
outline_material := render_system.materials[.Outline]
sg.apply_pipeline(outline_material.pipeline)
sg.apply_bindings({
vertex_buffers = { 0 = mesh.vertex_buffer },
index_buffer = mesh.index_buffer,
})
sg.apply_uniforms(shaders.UB_VsParamsOutline, sg_range(&shaders.Vsparamsoutline{
mvp = mvp,
}))
sg.apply_uniforms(shaders.UB_FsParamsOutline, sg_range(&shaders.Fsparamsoutline{
col = program_config.BORDER_COLOR,
}))
sg.draw(0, 36, 1)
}
}
cube_pass :: proc(render_system: ^RenderSystem, coordinator: ^Coordinator, proj: Mat4, view: Mat4) {
for entity in render_system.entities { for entity in render_system.entities {
transform := coordinator_get_component(TransformComponent, coordinator, entity) transform := coordinator_get_component(TransformComponent, coordinator, entity)
@ -246,15 +318,26 @@ render_system_update :: proc(render_system: ^RenderSystem, coordinator: ^Coordin
index_buffer = mesh.index_buffer, index_buffer = mesh.index_buffer,
}) })
sg.apply_uniforms(shaders.UB_VsParams, sg_range(&shaders.Vsparams{ sg.apply_uniforms(shaders.UB_VsParamsCube, sg_range(&shaders.Vsparamscube{
mvp = mvp, mvp = mvp,
col = color.color, col = color.color,
})) }))
sg.draw(0, 36, 1) sg.draw(0, 36, 1)
} }
}
render_system_update :: proc(render_system: ^RenderSystem, coordinator: ^Coordinator) {
camera := coordinator_get_component(CameraComponent, coordinator, render_system.camera_entity)
proj := linalg.matrix4_perspective_f32(70, sa.widthf() / sa.heightf(), 0.001, 1000)
view := linalg.matrix4_look_at_f32(camera.position, camera.target, { 0, 1, 0 } )
sg.begin_pass({ swapchain = sh.glue_swapchain(), action = CLEAR_SCREEN_ACTION })
outline_pass(render_system, coordinator, proj, view)
cube_pass(render_system, coordinator, proj, view)
sg.end_pass() sg.end_pass()
sg.commit() sg.commit()
} }

View file

@ -21,10 +21,11 @@ import sa "sokol/app"
import sh "sokol/helpers" import sh "sokol/helpers"
import "ecs" import "ecs"
import program_config "config"
Vec2 :: [2]f32 Vec2 :: ecs.Vec2
Vec3 :: [3]f32 Vec3 :: ecs.Vec3
Vec4 :: [4]f32 Vec4 :: ecs.Vec4
Globals :: struct { Globals :: struct {
coordinator: ecs.Coordinator, coordinator: ecs.Coordinator,
@ -34,6 +35,7 @@ Globals :: struct {
render_system: ^ecs.RenderSystem, render_system: ^ecs.RenderSystem,
time_since_cube: f32, time_since_cube: f32,
current_color: i32,
} }
g: ^Globals g: ^Globals
@ -50,7 +52,7 @@ main :: proc() {
default_context = context default_context = context
sa.run({ sa.run({
window_title = "ECS Test", window_title = program_config.WINDOW_TITLE,
allocator = sa.Allocator(sh.allocator(&default_context)), allocator = sa.Allocator(sh.allocator(&default_context)),
logger = sa.Logger(sh.logger(&default_context)), logger = sa.Logger(sh.logger(&default_context)),
@ -80,14 +82,14 @@ frame_cb:: proc "c" () {
dt := f32(sa.frame_duration()) dt := f32(sa.frame_duration())
g.time_since_cube += dt g.time_since_cube += dt
if g.time_since_cube >= 0.2 { if g.time_since_cube >= program_config.SPAWN_INTERVAL {
create_cube()
g.time_since_cube = 0 g.time_since_cube = 0
create_cube()
} }
ecs.physics_system_update(g.physics_system, &g.coordinator, dt) ecs.physics_system_update(g.physics_system, &g.coordinator, dt)
ecs.camera_system_update(g.camera_system, &g.coordinator, dt) ecs.camera_system_update(g.camera_system, &g.coordinator, dt)
ecs.render_system_update(g.render_system, &g.coordinator, dt) ecs.render_system_update(g.render_system, &g.coordinator)
ecs.input_system_mouse_reset(g.input_system, &g.coordinator) ecs.input_system_mouse_reset(g.input_system, &g.coordinator)
} }
@ -115,7 +117,7 @@ create_cube :: proc() {
&g.coordinator, &g.coordinator,
entity, entity,
ecs.GravityComponent{ ecs.GravityComponent{
ecs.Vec3{ 0.0, -2.5, 0.0 } ecs.Vec3{ 0.0, program_config.GRAVITY_CONSTANT, 0.0 }
}) })
ecs.coordinator_add_component( ecs.coordinator_add_component(
ecs.RigidBodyComponent, ecs.RigidBodyComponent,
@ -131,25 +133,23 @@ create_cube :: proc() {
entity, entity,
ecs.TransformComponent{ ecs.TransformComponent{
position = Vec3{ position = Vec3{
f32(rand.int_max(50)), f32(rand.int_max(program_config.SPAWN_AREA)),
10, 10,
f32(rand.int_max(50)), f32(rand.int_max(program_config.SPAWN_AREA)),
}, },
rotation = ecs.Vec3{0.0, 0.0, 0.0}, rotation = ecs.Vec3{ 0.0, 0.0, 0.0 },
scale = ecs.Vec3{1.0, 1.0, 1.0}, scale = ecs.Vec3{ 1.0, 1.0, 1.0 },
}) })
ecs.coordinator_add_component( ecs.coordinator_add_component(
ecs.ColorComponent, ecs.ColorComponent,
&g.coordinator, &g.coordinator,
entity, entity,
ecs.ColorComponent{ ecs.ColorComponent{
color = Vec4{ color = program_config.CUBE_COLORS[g.current_color]
rand.float32_uniform(0,1),
rand.float32_uniform(0,1),
rand.float32_uniform(0,1),
rand.float32_uniform(0,1),
},
}) })
g.current_color += 1
g.current_color %= i32(len(program_config.CUBE_COLORS))
ecs.coordinator_add_component( ecs.coordinator_add_component(
ecs.MeshComponent, ecs.MeshComponent,
&g.coordinator, &g.coordinator,
@ -162,7 +162,7 @@ create_cube :: proc() {
&g.coordinator, &g.coordinator,
entity, entity,
ecs.MaterialComponent{ ecs.MaterialComponent{
material_id = .Grid material_id = .Cube
}) })
} }
@ -208,12 +208,12 @@ create_scene :: proc() {
&g.coordinator, &g.coordinator,
user_entity, user_entity,
ecs.CameraComponent{ ecs.CameraComponent{
position = { 30, 0, 60 }, position = program_config.START_POSITION,
target = { 0, 0, 1 }, target = { 0, 0, 1 },
look = { 0, 0 }, look = { 0, 0 },
movement_speed = 3.0, movement_speed = program_config.MOVEMENT_SPEED,
look_sensitivity = 0.15, look_sensitivity = program_config.LOOK_SENSITIVITY,
}) })
ecs.coordinator_add_component( ecs.coordinator_add_component(

View file

@ -6,21 +6,21 @@ import sg "../../sokol/gfx"
Generated by sokol-shdc (https://github.com/floooh/sokol-tools) Generated by sokol-shdc (https://github.com/floooh/sokol-tools)
Cmdline: Cmdline:
sokol-shdc -i shaders/src/shader.glsl -o shaders/out/shader.odin -l metal_macos -f sokol_odin sokol-shdc -i shaders/src/cube.glsl -o shaders/out/cube.odin -l metal_macos -f sokol_odin
Overview: Overview:
========= =========
Shader program: 'main': Shader program: 'cube':
Get shader desc: main_shader_desc(sg.query_backend()) Get shader desc: cube_shader_desc(sg.query_backend())
Vertex Shader: vs Vertex Shader: vs_cube
Fragment Shader: fs Fragment Shader: fs_cube
Attributes: Attributes:
ATTR_main_pos => 0 ATTR_cube_pos => 0
ATTR_main_uv => 1 ATTR_cube_uv => 1
Bindings: Bindings:
Uniform block 'VsParams': Uniform block 'VsParamsCube':
Odin struct: Vsparams Odin struct: Vsparamscube
Bind slot: UB_VsParams => 0 Bind slot: UB_VsParamsCube => 0
Image 'tex': Image 'tex':
Image type: ._2D Image type: ._2D
Sample type: .FLOAT Sample type: .FLOAT
@ -30,12 +30,12 @@ import sg "../../sokol/gfx"
Type: .FILTERING Type: .FILTERING
Bind slot: SMP_smp => 0 Bind slot: SMP_smp => 0
*/ */
ATTR_main_pos :: 0 ATTR_cube_pos :: 0
ATTR_main_uv :: 1 ATTR_cube_uv :: 1
UB_VsParams :: 0 UB_VsParamsCube :: 0
IMG_tex :: 0 IMG_tex :: 0
SMP_smp :: 0 SMP_smp :: 0
Vsparams :: struct #align(16) { Vsparamscube :: struct #align(16) {
using _: struct #packed { using _: struct #packed {
mvp: Mat4, mvp: Mat4,
col: [4]f32, col: [4]f32,
@ -47,7 +47,7 @@ Vsparams :: struct #align(16) {
using namespace metal; using namespace metal;
struct VsParams struct VsParamsCube
{ {
float4x4 mvp; float4x4 mvp;
float4 col; float4 col;
@ -66,7 +66,7 @@ Vsparams :: struct #align(16) {
float2 uv [[attribute(1)]]; float2 uv [[attribute(1)]];
}; };
vertex main0_out main0(main0_in in [[stage_in]], constant VsParams& _19 [[buffer(0)]]) vertex main0_out main0(main0_in in [[stage_in]], constant VsParamsCube& _19 [[buffer(0)]])
{ {
main0_out out = {}; main0_out out = {};
out.gl_Position = _19.mvp * float4(in.pos, 1.0); out.gl_Position = _19.mvp * float4(in.pos, 1.0);
@ -77,44 +77,45 @@ Vsparams :: struct #align(16) {
*/ */
@(private="file") @(private="file")
vs_source_metal_macos := [585]u8 { vs_cube_source_metal_macos := [593]u8 {
0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x20,0x3c,0x6d,0x65,0x74,0x61,0x6c,0x5f, 0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x20,0x3c,0x6d,0x65,0x74,0x61,0x6c,0x5f,
0x73,0x74,0x64,0x6c,0x69,0x62,0x3e,0x0a,0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65, 0x73,0x74,0x64,0x6c,0x69,0x62,0x3e,0x0a,0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,
0x20,0x3c,0x73,0x69,0x6d,0x64,0x2f,0x73,0x69,0x6d,0x64,0x2e,0x68,0x3e,0x0a,0x0a, 0x20,0x3c,0x73,0x69,0x6d,0x64,0x2f,0x73,0x69,0x6d,0x64,0x2e,0x68,0x3e,0x0a,0x0a,
0x75,0x73,0x69,0x6e,0x67,0x20,0x6e,0x61,0x6d,0x65,0x73,0x70,0x61,0x63,0x65,0x20, 0x75,0x73,0x69,0x6e,0x67,0x20,0x6e,0x61,0x6d,0x65,0x73,0x70,0x61,0x63,0x65,0x20,
0x6d,0x65,0x74,0x61,0x6c,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x56, 0x6d,0x65,0x74,0x61,0x6c,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x56,
0x73,0x50,0x61,0x72,0x61,0x6d,0x73,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c, 0x73,0x50,0x61,0x72,0x61,0x6d,0x73,0x43,0x75,0x62,0x65,0x0a,0x7b,0x0a,0x20,0x20,
0x6f,0x61,0x74,0x34,0x78,0x34,0x20,0x6d,0x76,0x70,0x3b,0x0a,0x20,0x20,0x20,0x20, 0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x78,0x34,0x20,0x6d,0x76,0x70,0x3b,0x0a,
0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x63,0x6f,0x6c,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a, 0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x63,0x6f,0x6c,0x3b,0x0a,
0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,
0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x63,0x6f,
0x6c,0x6f,0x72,0x20,0x5b,0x5b,0x75,0x73,0x65,0x72,0x28,0x6c,0x6f,0x63,0x6e,0x30,
0x29,0x5d,0x5d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,0x20,
0x74,0x65,0x78,0x5f,0x63,0x6f,0x6f,0x72,0x64,0x20,0x5b,0x5b,0x75,0x73,0x65,0x72,
0x28,0x6c,0x6f,0x63,0x6e,0x31,0x29,0x5d,0x5d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,
0x6c,0x6f,0x61,0x74,0x34,0x20,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,
0x6e,0x20,0x5b,0x5b,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x5d,0x5d,0x3b,0x0a,
0x7d,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30, 0x7d,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,
0x5f,0x69,0x6e,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x33, 0x5f,0x6f,0x75,0x74,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,
0x20,0x70,0x6f,0x73,0x20,0x5b,0x5b,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65, 0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x5b,0x5b,0x75,0x73,0x65,0x72,0x28,0x6c,
0x28,0x30,0x29,0x5d,0x5d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74, 0x6f,0x63,0x6e,0x30,0x29,0x5d,0x5d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,
0x32,0x20,0x75,0x76,0x20,0x5b,0x5b,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65, 0x61,0x74,0x32,0x20,0x74,0x65,0x78,0x5f,0x63,0x6f,0x6f,0x72,0x64,0x20,0x5b,0x5b,
0x28,0x31,0x29,0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x76,0x65,0x72,0x74,0x65, 0x75,0x73,0x65,0x72,0x28,0x6c,0x6f,0x63,0x6e,0x31,0x29,0x5d,0x5d,0x3b,0x0a,0x20,
0x78,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x20,0x6d,0x61,0x69,0x6e, 0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x67,0x6c,0x5f,0x50,0x6f,0x73,
0x30,0x28,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x20,0x69,0x6e,0x20,0x5b,0x5b, 0x69,0x74,0x69,0x6f,0x6e,0x20,0x5b,0x5b,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,
0x73,0x74,0x61,0x67,0x65,0x5f,0x69,0x6e,0x5d,0x5d,0x2c,0x20,0x63,0x6f,0x6e,0x73, 0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x6d,
0x74,0x61,0x6e,0x74,0x20,0x56,0x73,0x50,0x61,0x72,0x61,0x6d,0x73,0x26,0x20,0x5f, 0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,
0x31,0x39,0x20,0x5b,0x5b,0x62,0x75,0x66,0x66,0x65,0x72,0x28,0x30,0x29,0x5d,0x5d, 0x6f,0x61,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x5b,0x5b,0x61,0x74,0x74,0x72,0x69,
0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75, 0x62,0x75,0x74,0x65,0x28,0x30,0x29,0x5d,0x5d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,
0x74,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x7b,0x7d,0x3b,0x0a,0x20,0x20,0x20,0x20, 0x6c,0x6f,0x61,0x74,0x32,0x20,0x75,0x76,0x20,0x5b,0x5b,0x61,0x74,0x74,0x72,0x69,
0x6f,0x75,0x74,0x2e,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20, 0x62,0x75,0x74,0x65,0x28,0x31,0x29,0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x76,
0x3d,0x20,0x5f,0x31,0x39,0x2e,0x6d,0x76,0x70,0x20,0x2a,0x20,0x66,0x6c,0x6f,0x61, 0x65,0x72,0x74,0x65,0x78,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x20,
0x74,0x34,0x28,0x69,0x6e,0x2e,0x70,0x6f,0x73,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b, 0x6d,0x61,0x69,0x6e,0x30,0x28,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x20,0x69,
0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d, 0x6e,0x20,0x5b,0x5b,0x73,0x74,0x61,0x67,0x65,0x5f,0x69,0x6e,0x5d,0x5d,0x2c,0x20,
0x20,0x5f,0x31,0x39,0x2e,0x63,0x6f,0x6c,0x3b,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75, 0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x56,0x73,0x50,0x61,0x72,0x61,0x6d,
0x74,0x2e,0x74,0x65,0x78,0x5f,0x63,0x6f,0x6f,0x72,0x64,0x20,0x3d,0x20,0x69,0x6e, 0x73,0x43,0x75,0x62,0x65,0x26,0x20,0x5f,0x31,0x39,0x20,0x5b,0x5b,0x62,0x75,0x66,
0x2e,0x75,0x76,0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20, 0x66,0x65,0x72,0x28,0x30,0x29,0x5d,0x5d,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,
0x6f,0x75,0x74,0x3b,0x0a,0x7d,0x0a,0x0a,0x00, 0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,
0x7b,0x7d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x67,0x6c,0x5f,0x50,
0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x5f,0x31,0x39,0x2e,0x6d,0x76,
0x70,0x20,0x2a,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x69,0x6e,0x2e,0x70,0x6f,
0x73,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,
0x2e,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x5f,0x31,0x39,0x2e,0x63,0x6f,0x6c,
0x3b,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x74,0x65,0x78,0x5f,0x63,0x6f,
0x6f,0x72,0x64,0x20,0x3d,0x20,0x69,0x6e,0x2e,0x75,0x76,0x3b,0x0a,0x20,0x20,0x20,
0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x75,0x74,0x3b,0x0a,0x7d,0x0a,0x0a,
0x00,
} }
/* /*
#include <metal_stdlib> #include <metal_stdlib>
@ -142,7 +143,7 @@ vs_source_metal_macos := [585]u8 {
*/ */
@(private="file") @(private="file")
fs_source_metal_macos := [450]u8 { fs_cube_source_metal_macos := [450]u8 {
0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x20,0x3c,0x6d,0x65,0x74,0x61,0x6c,0x5f, 0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x20,0x3c,0x6d,0x65,0x74,0x61,0x6c,0x5f,
0x73,0x74,0x64,0x6c,0x69,0x62,0x3e,0x0a,0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65, 0x73,0x74,0x64,0x6c,0x69,0x62,0x3e,0x0a,0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,
0x20,0x3c,0x73,0x69,0x6d,0x64,0x2f,0x73,0x69,0x6d,0x64,0x2e,0x68,0x3e,0x0a,0x0a, 0x20,0x3c,0x73,0x69,0x6d,0x64,0x2f,0x73,0x69,0x6d,0x64,0x2e,0x68,0x3e,0x0a,0x0a,
@ -173,14 +174,14 @@ fs_source_metal_macos := [450]u8 {
0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x75,0x74,0x3b,0x0a,0x7d,0x0a, 0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x75,0x74,0x3b,0x0a,0x7d,0x0a,
0x0a,0x00, 0x0a,0x00,
} }
main_shader_desc :: proc (backend: sg.Backend) -> sg.Shader_Desc { cube_shader_desc :: proc (backend: sg.Backend) -> sg.Shader_Desc {
desc: sg.Shader_Desc desc: sg.Shader_Desc
desc.label = "main_shader" desc.label = "cube_shader"
#partial switch backend { #partial switch backend {
case .METAL_MACOS: case .METAL_MACOS:
desc.vertex_func.source = transmute(cstring)&vs_source_metal_macos desc.vertex_func.source = transmute(cstring)&vs_cube_source_metal_macos
desc.vertex_func.entry = "main0" desc.vertex_func.entry = "main0"
desc.fragment_func.source = transmute(cstring)&fs_source_metal_macos desc.fragment_func.source = transmute(cstring)&fs_cube_source_metal_macos
desc.fragment_func.entry = "main0" desc.fragment_func.entry = "main0"
desc.attrs[0].base_type = .FLOAT desc.attrs[0].base_type = .FLOAT
desc.attrs[1].base_type = .FLOAT desc.attrs[1].base_type = .FLOAT

170
shaders/out/outline.odin Normal file
View file

@ -0,0 +1,170 @@
package shaders
import sg "../../sokol/gfx"
/*
#version:1# (machine generated, don't edit!)
Generated by sokol-shdc (https://github.com/floooh/sokol-tools)
Cmdline:
sokol-shdc -i shaders/src/outline.glsl -o shaders/out/outline.odin -l metal_macos -f sokol_odin
Overview:
=========
Shader program: 'outline':
Get shader desc: outline_shader_desc(sg.query_backend())
Vertex Shader: vs_outline
Fragment Shader: fs_outline
Attributes:
ATTR_outline_pos => 0
ATTR_outline_uv => 1
Bindings:
Uniform block 'VsParamsOutline':
Odin struct: Vsparamsoutline
Bind slot: UB_VsParamsOutline => 0
Uniform block 'FsParamsOutline':
Odin struct: Fsparamsoutline
Bind slot: UB_FsParamsOutline => 1
*/
ATTR_outline_pos :: 0
ATTR_outline_uv :: 1
UB_VsParamsOutline :: 0
UB_FsParamsOutline :: 1
Vsparamsoutline :: struct #align(16) {
using _: struct #packed {
mvp: Mat4,
},
}
Fsparamsoutline :: struct #align(16) {
using _: struct #packed {
col: [4]f32,
},
}
/*
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct VsParamsOutline
{
float4x4 mvp;
};
struct main0_out
{
float4 gl_Position [[position]];
};
struct main0_in
{
float3 pos [[attribute(0)]];
};
vertex main0_out main0(main0_in in [[stage_in]], constant VsParamsOutline& _19 [[buffer(0)]])
{
main0_out out = {};
out.gl_Position = _19.mvp * float4(in.pos, 1.0);
return out;
}
*/
@(private="file")
vs_outline_source_metal_macos := [427]u8 {
0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x20,0x3c,0x6d,0x65,0x74,0x61,0x6c,0x5f,
0x73,0x74,0x64,0x6c,0x69,0x62,0x3e,0x0a,0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,
0x20,0x3c,0x73,0x69,0x6d,0x64,0x2f,0x73,0x69,0x6d,0x64,0x2e,0x68,0x3e,0x0a,0x0a,
0x75,0x73,0x69,0x6e,0x67,0x20,0x6e,0x61,0x6d,0x65,0x73,0x70,0x61,0x63,0x65,0x20,
0x6d,0x65,0x74,0x61,0x6c,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x56,
0x73,0x50,0x61,0x72,0x61,0x6d,0x73,0x4f,0x75,0x74,0x6c,0x69,0x6e,0x65,0x0a,0x7b,
0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x78,0x34,0x20,0x6d,0x76,
0x70,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x6d,0x61,
0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,
0x6f,0x61,0x74,0x34,0x20,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,
0x20,0x5b,0x5b,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x5d,0x5d,0x3b,0x0a,0x7d,
0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,
0x69,0x6e,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x33,0x20,
0x70,0x6f,0x73,0x20,0x5b,0x5b,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28,
0x30,0x29,0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x76,0x65,0x72,0x74,0x65,0x78,
0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,
0x28,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x20,0x69,0x6e,0x20,0x5b,0x5b,0x73,
0x74,0x61,0x67,0x65,0x5f,0x69,0x6e,0x5d,0x5d,0x2c,0x20,0x63,0x6f,0x6e,0x73,0x74,
0x61,0x6e,0x74,0x20,0x56,0x73,0x50,0x61,0x72,0x61,0x6d,0x73,0x4f,0x75,0x74,0x6c,
0x69,0x6e,0x65,0x26,0x20,0x5f,0x31,0x39,0x20,0x5b,0x5b,0x62,0x75,0x66,0x66,0x65,
0x72,0x28,0x30,0x29,0x5d,0x5d,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x6d,0x61,
0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x7b,0x7d,
0x3b,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x67,0x6c,0x5f,0x50,0x6f,0x73,
0x69,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x5f,0x31,0x39,0x2e,0x6d,0x76,0x70,0x20,
0x2a,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x69,0x6e,0x2e,0x70,0x6f,0x73,0x2c,
0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,
0x6e,0x20,0x6f,0x75,0x74,0x3b,0x0a,0x7d,0x0a,0x0a,0x00,
}
/*
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct FsParamsOutline
{
float4 col;
};
struct main0_out
{
float4 frag_color [[color(0)]];
};
fragment main0_out main0(constant FsParamsOutline& _12 [[buffer(0)]])
{
main0_out out = {};
out.frag_color = _12.col;
return out;
}
*/
@(private="file")
fs_outline_source_metal_macos := [322]u8 {
0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x20,0x3c,0x6d,0x65,0x74,0x61,0x6c,0x5f,
0x73,0x74,0x64,0x6c,0x69,0x62,0x3e,0x0a,0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,
0x20,0x3c,0x73,0x69,0x6d,0x64,0x2f,0x73,0x69,0x6d,0x64,0x2e,0x68,0x3e,0x0a,0x0a,
0x75,0x73,0x69,0x6e,0x67,0x20,0x6e,0x61,0x6d,0x65,0x73,0x70,0x61,0x63,0x65,0x20,
0x6d,0x65,0x74,0x61,0x6c,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x46,
0x73,0x50,0x61,0x72,0x61,0x6d,0x73,0x4f,0x75,0x74,0x6c,0x69,0x6e,0x65,0x0a,0x7b,
0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x63,0x6f,0x6c,0x3b,
0x0a,0x7d,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x6d,0x61,0x69,0x6e,
0x30,0x5f,0x6f,0x75,0x74,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,
0x74,0x34,0x20,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x5b,0x5b,
0x63,0x6f,0x6c,0x6f,0x72,0x28,0x30,0x29,0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,
0x66,0x72,0x61,0x67,0x6d,0x65,0x6e,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,
0x75,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x28,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,
0x74,0x20,0x46,0x73,0x50,0x61,0x72,0x61,0x6d,0x73,0x4f,0x75,0x74,0x6c,0x69,0x6e,
0x65,0x26,0x20,0x5f,0x31,0x32,0x20,0x5b,0x5b,0x62,0x75,0x66,0x66,0x65,0x72,0x28,
0x30,0x29,0x5d,0x5d,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x6d,0x61,0x69,0x6e,
0x30,0x5f,0x6f,0x75,0x74,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x7b,0x7d,0x3b,0x0a,
0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,
0x6f,0x72,0x20,0x3d,0x20,0x5f,0x31,0x32,0x2e,0x63,0x6f,0x6c,0x3b,0x0a,0x20,0x20,
0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x75,0x74,0x3b,0x0a,0x7d,0x0a,
0x0a,0x00,
}
outline_shader_desc :: proc (backend: sg.Backend) -> sg.Shader_Desc {
desc: sg.Shader_Desc
desc.label = "outline_shader"
#partial switch backend {
case .METAL_MACOS:
desc.vertex_func.source = transmute(cstring)&vs_outline_source_metal_macos
desc.vertex_func.entry = "main0"
desc.fragment_func.source = transmute(cstring)&fs_outline_source_metal_macos
desc.fragment_func.entry = "main0"
desc.attrs[0].base_type = .FLOAT
desc.attrs[1].base_type = .FLOAT
desc.uniform_blocks[0].stage = .VERTEX
desc.uniform_blocks[0].layout = .STD140
desc.uniform_blocks[0].size = 64
desc.uniform_blocks[0].msl_buffer_n = 0
desc.uniform_blocks[1].stage = .FRAGMENT
desc.uniform_blocks[1].layout = .STD140
desc.uniform_blocks[1].size = 16
desc.uniform_blocks[1].msl_buffer_n = 0
}
return desc
}

View file

@ -3,11 +3,11 @@
@ctype mat4 Mat4 @ctype mat4 Mat4
@vs vs @vs vs_cube
in vec3 pos; in vec3 pos;
in vec2 uv; in vec2 uv;
layout(binding = 0) uniform VsParams { layout(binding = 0) uniform VsParamsCube {
mat4 mvp; mat4 mvp;
vec4 col; vec4 col;
}; };
@ -23,7 +23,7 @@ void main() {
@end @end
@fs fs @fs fs_cube
in vec4 color; in vec4 color;
in vec2 tex_coord; in vec2 tex_coord;
@ -38,4 +38,4 @@ void main() {
@end @end
@program main vs fs @program cube vs_cube fs_cube

31
shaders/src/outline.glsl Normal file
View file

@ -0,0 +1,31 @@
@header package shaders
@header import sg "../../sokol/gfx"
@ctype mat4 Mat4
@vs vs_outline
in vec3 pos;
in vec2 uv;
layout(binding = 0) uniform VsParamsOutline {
mat4 mvp;
};
void main() {
gl_Position = mvp * vec4(pos, 1);
}
@end
@fs fs_outline
layout(binding = 1) uniform FsParamsOutline {
vec4 col;
};
out vec4 frag_color;
void main() {
frag_color = col;
}
@end
@program outline vs_outline fs_outline