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:
./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
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 {
Grid,
Cube,
Outline,
}
MaterialComponent :: struct {

View file

@ -2,6 +2,8 @@ package ecs
import "core:log"
import program_config "../config"
PhysicsSystem :: struct {
using base: SystemBase,
}
@ -18,7 +20,7 @@ physics_system_update :: proc(physics_system: ^PhysicsSystem, coordinator: ^Coor
transform.position += rigid_body.velocity * 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)
}
}

View file

@ -20,6 +20,8 @@ import sa "../sokol/app"
import sh "../sokol/helpers"
import sg "../sokol/gfx"
import program_config "../config"
import shaders "../shaders/out"
VertexData :: struct {
@ -48,14 +50,46 @@ RenderSystem :: struct {
}
@(private)
init_grid_material :: proc(render_system: ^RenderSystem) {
shader := sg.make_shader(shaders.main_shader_desc(sg.query_backend()))
init_outline_material :: proc(render_system: ^RenderSystem) {
shader := sg.make_shader(shaders.outline_shader_desc(sg.query_backend()))
pipeline := sg.make_pipeline({
shader = shader,
layout = {
attrs = {
shaders.ATTR_main_pos = { format = .FLOAT3 },
shaders.ATTR_main_uv = { format = .FLOAT2 },
shaders.ATTR_outline_pos = { format = .FLOAT3 },
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,
@ -93,7 +127,7 @@ init_grid_material :: proc(render_system: ^RenderSystem) {
sampler := sg.make_sampler({})
render_system.materials[.Grid] = Material{
render_system.materials[.Cube] = Material{
shader = shader,
pipeline = pipeline,
image = image,
@ -178,7 +212,9 @@ render_system_init :: proc(render_system: ^RenderSystem, camera_entity: EntityID
render_system.camera_entity = camera_entity
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) {
@ -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.vertex_buffer)
grid_material := render_system.materials[.Grid]
sg.destroy_image(grid_material.image)
sg.destroy_sampler(grid_material.sampler)
sg.destroy_pipeline(grid_material.pipeline)
sg.destroy_shader(grid_material.shader)
cube_material := render_system.materials[.Cube]
sg.destroy_image(cube_material.image)
sg.destroy_sampler(cube_material.sampler)
sg.destroy_pipeline(cube_material.pipeline)
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.meshes)
@ -198,24 +239,55 @@ render_system_delete :: proc(render_system: ^RenderSystem, coordinator: ^Coordin
sg.shutdown()
}
render_system_update :: proc(render_system: ^RenderSystem, coordinator: ^Coordinator, dt: f32) {
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 } )
BACKGROUND_COLOR :: sg.Color{ 0, 0, 0, 1 }
@(private)
CLEAR_SCREEN_ACTION :: sg.Pass_Action{
colors = {
0 = {
load_action = .CLEAR,
clear_value = BACKGROUND_COLOR,
clear_value = program_config.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 {
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,
})
sg.apply_uniforms(shaders.UB_VsParams, sg_range(&shaders.Vsparams{
sg.apply_uniforms(shaders.UB_VsParamsCube, sg_range(&shaders.Vsparamscube{
mvp = mvp,
col = color.color,
}))
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.commit()
}

View file

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

View file

@ -6,21 +6,21 @@ import sg "../../sokol/gfx"
Generated by sokol-shdc (https://github.com/floooh/sokol-tools)
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:
=========
Shader program: 'main':
Get shader desc: main_shader_desc(sg.query_backend())
Vertex Shader: vs
Fragment Shader: fs
Shader program: 'cube':
Get shader desc: cube_shader_desc(sg.query_backend())
Vertex Shader: vs_cube
Fragment Shader: fs_cube
Attributes:
ATTR_main_pos => 0
ATTR_main_uv => 1
ATTR_cube_pos => 0
ATTR_cube_uv => 1
Bindings:
Uniform block 'VsParams':
Odin struct: Vsparams
Bind slot: UB_VsParams => 0
Uniform block 'VsParamsCube':
Odin struct: Vsparamscube
Bind slot: UB_VsParamsCube => 0
Image 'tex':
Image type: ._2D
Sample type: .FLOAT
@ -30,12 +30,12 @@ import sg "../../sokol/gfx"
Type: .FILTERING
Bind slot: SMP_smp => 0
*/
ATTR_main_pos :: 0
ATTR_main_uv :: 1
UB_VsParams :: 0
ATTR_cube_pos :: 0
ATTR_cube_uv :: 1
UB_VsParamsCube :: 0
IMG_tex :: 0
SMP_smp :: 0
Vsparams :: struct #align(16) {
Vsparamscube :: struct #align(16) {
using _: struct #packed {
mvp: Mat4,
col: [4]f32,
@ -47,7 +47,7 @@ Vsparams :: struct #align(16) {
using namespace metal;
struct VsParams
struct VsParamsCube
{
float4x4 mvp;
float4 col;
@ -66,7 +66,7 @@ Vsparams :: struct #align(16) {
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 = {};
out.gl_Position = _19.mvp * float4(in.pos, 1.0);
@ -77,44 +77,45 @@ Vsparams :: struct #align(16) {
*/
@(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,
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,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,
0x6f,0x61,0x74,0x34,0x78,0x34,0x20,0x6d,0x76,0x70,0x3b,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,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,
0x73,0x50,0x61,0x72,0x61,0x6d,0x73,0x43,0x75,0x62,0x65,0x0a,0x7b,0x0a,0x20,0x20,
0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x78,0x34,0x20,0x6d,0x76,0x70,0x3b,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,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,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,
0x32,0x20,0x75,0x76,0x20,0x5b,0x5b,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,
0x28,0x31,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,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,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,
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,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,0x20,0x20,0x20,0x20,0x66,
0x6c,0x6f,0x61,0x74,0x32,0x20,0x75,0x76,0x20,0x5b,0x5b,0x61,0x74,0x74,0x72,0x69,
0x62,0x75,0x74,0x65,0x28,0x31,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,0x43,0x75,0x62,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,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>
@ -142,7 +143,7 @@ vs_source_metal_macos := [585]u8 {
*/
@(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,
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,
@ -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,
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.label = "main_shader"
desc.label = "cube_shader"
#partial switch backend {
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.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.attrs[0].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
@vs vs
@vs vs_cube
in vec3 pos;
in vec2 uv;
layout(binding = 0) uniform VsParams {
layout(binding = 0) uniform VsParamsCube {
mat4 mvp;
vec4 col;
};
@ -23,7 +23,7 @@ void main() {
@end
@fs fs
@fs fs_cube
in vec4 color;
in vec2 tex_coord;
@ -38,4 +38,4 @@ void main() {
@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