Two colorful triangles
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
sdlgpu
|
||||||
|
shaders/*.spv.*
|
17
build.sh
Executable file
17
build.sh
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
for i in shaders/src/*; do
|
||||||
|
filename=$(basename $i)
|
||||||
|
basename=$(printf $filename | cut -d. -f1)
|
||||||
|
ext=$(printf $filename | cut -d. -f3)
|
||||||
|
glslc "$i" -o shaders/${basename}.spv.${ext}
|
||||||
|
done
|
||||||
|
# glslc shader.glsl.vert -o shader.spv.vert
|
||||||
|
# glslc shader.glsl.frag -o shader.spv.frag
|
||||||
|
|
||||||
|
odin build src -debug -out:sdlgpu
|
||||||
|
|
||||||
|
./sdlgpu
|
9
shaders/src/shader.glsl.frag
Normal file
9
shaders/src/shader.glsl.frag
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#version 460
|
||||||
|
|
||||||
|
|
||||||
|
layout(location=0) in vec3 color;
|
||||||
|
layout(location=0) out vec4 frag_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
frag_color = vec4(color, 1);
|
||||||
|
}
|
16
shaders/src/shader.glsl.vert
Normal file
16
shaders/src/shader.glsl.vert
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#version 460
|
||||||
|
|
||||||
|
layout(set=1, binding=0) uniform UBO {
|
||||||
|
mat4 mvp;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(location=0) in vec3 position;
|
||||||
|
layout(location=1) in vec3 color;
|
||||||
|
|
||||||
|
layout(location=0) out vec3 out_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = mvp * vec4(position, 1);
|
||||||
|
out_color = color;
|
||||||
|
}
|
||||||
|
|
195
src/main.odin
Normal file
195
src/main.odin
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "core:log"
|
||||||
|
import "core:math/linalg"
|
||||||
|
import "core:mem"
|
||||||
|
import sdl "vendor:sdl3"
|
||||||
|
|
||||||
|
frag_shader_code := #load("../shaders/shader.spv.frag")
|
||||||
|
vert_shader_code := #load("../shaders/shader.spv.vert")
|
||||||
|
|
||||||
|
main :: proc() {
|
||||||
|
context.logger = log.create_console_logger()
|
||||||
|
|
||||||
|
sdl.SetLogPriorities(.VERBOSE)
|
||||||
|
|
||||||
|
ok := sdl.Init({.VIDEO});assert(ok)
|
||||||
|
|
||||||
|
window := sdl.CreateWindow("hi sdl", 800, 400, {});assert(window != nil)
|
||||||
|
|
||||||
|
gpu := sdl.CreateGPUDevice({.SPIRV}, true, nil);assert(gpu != nil)
|
||||||
|
|
||||||
|
ok = sdl.ClaimWindowForGPUDevice(gpu, window);assert(ok)
|
||||||
|
|
||||||
|
vert_shader := load_shader(gpu, vert_shader_code, .VERTEX, 1)
|
||||||
|
frag_shader := load_shader(gpu, frag_shader_code, .FRAGMENT, 0)
|
||||||
|
|
||||||
|
Vec3 :: [3]f32
|
||||||
|
Vertex :: struct {
|
||||||
|
pos: Vec3,
|
||||||
|
col: Vec3,
|
||||||
|
}
|
||||||
|
vertices := []Vertex {
|
||||||
|
{{-0.5, 0, 0}, {1, 0, 0}},
|
||||||
|
{{0, 1.0, 0}, {0, 1, 0}},
|
||||||
|
{{0.5, 0, 0}, {0, 0, 1}},
|
||||||
|
{{0.5, 0, 0}, {1, 1, 0}},
|
||||||
|
{{0, -0.5, 0}, {0, 1, 1}},
|
||||||
|
{{-0.5, -0, 0}, {1, 0, 1}},
|
||||||
|
}
|
||||||
|
vertices_byte_size := len(vertices) * size_of(vertices[0])
|
||||||
|
vertex_attrs := []sdl.GPUVertexAttribute {
|
||||||
|
{location = 0, format = .FLOAT3, offset = 0}, // Position
|
||||||
|
{location = 1, format = .FLOAT3, offset = size_of(Vec3)}, // Color
|
||||||
|
}
|
||||||
|
vertex_buf := sdl.CreateGPUBuffer(
|
||||||
|
gpu,
|
||||||
|
sdl.GPUBufferCreateInfo{usage = {.VERTEX}, size = u32(vertices_byte_size)},
|
||||||
|
)
|
||||||
|
|
||||||
|
transfer_buf := sdl.CreateGPUTransferBuffer(
|
||||||
|
gpu,
|
||||||
|
sdl.GPUTransferBufferCreateInfo{usage = .UPLOAD, size = u32(vertices_byte_size)},
|
||||||
|
)
|
||||||
|
{ // Copy verticies to the transfer buffer
|
||||||
|
|
||||||
|
transfer_mem := sdl.MapGPUTransferBuffer(
|
||||||
|
gpu,
|
||||||
|
transfer_buf,
|
||||||
|
false,
|
||||||
|
);assert(transfer_mem != nil)
|
||||||
|
defer sdl.UnmapGPUTransferBuffer(gpu, transfer_buf)
|
||||||
|
|
||||||
|
mem.copy(transfer_mem, raw_data(vertices), vertices_byte_size)
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Upload buffer to gpu
|
||||||
|
copy_cmd_buf := sdl.AcquireGPUCommandBuffer(gpu)
|
||||||
|
defer {ok = sdl.SubmitGPUCommandBuffer(copy_cmd_buf);assert(ok)}
|
||||||
|
copy_pass := sdl.BeginGPUCopyPass(copy_cmd_buf)
|
||||||
|
defer sdl.EndGPUCopyPass(copy_pass)
|
||||||
|
|
||||||
|
sdl.UploadToGPUBuffer(
|
||||||
|
copy_pass,
|
||||||
|
{transfer_buffer = transfer_buf},
|
||||||
|
{buffer = vertex_buf, size = u32(vertices_byte_size)},
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
sdl.ReleaseGPUTransferBuffer(gpu, transfer_buf)
|
||||||
|
|
||||||
|
pipeline := sdl.CreateGPUGraphicsPipeline(
|
||||||
|
gpu,
|
||||||
|
{
|
||||||
|
vertex_shader = vert_shader,
|
||||||
|
fragment_shader = frag_shader,
|
||||||
|
vertex_input_state = {
|
||||||
|
num_vertex_buffers = 1,
|
||||||
|
vertex_buffer_descriptions = &sdl.GPUVertexBufferDescription {
|
||||||
|
slot = 0,
|
||||||
|
pitch = size_of(Vertex),
|
||||||
|
},
|
||||||
|
num_vertex_attributes = u32(len(vertex_attrs)),
|
||||||
|
vertex_attributes = raw_data(vertex_attrs),
|
||||||
|
},
|
||||||
|
primitive_type = .TRIANGLELIST,
|
||||||
|
target_info = {
|
||||||
|
num_color_targets = 1,
|
||||||
|
color_target_descriptions = &(sdl.GPUColorTargetDescription {
|
||||||
|
format = sdl.GetGPUSwapchainTextureFormat(gpu, window),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
sdl.ReleaseGPUShader(gpu, vert_shader)
|
||||||
|
sdl.ReleaseGPUShader(gpu, frag_shader)
|
||||||
|
|
||||||
|
wsize := [2]i32{}
|
||||||
|
ok = sdl.GetWindowSize(window, &wsize.x, &wsize.y);assert(ok)
|
||||||
|
|
||||||
|
rotation := f32(0)
|
||||||
|
|
||||||
|
proj := linalg.matrix4_perspective_f32(
|
||||||
|
linalg.to_radians(f32(30)),
|
||||||
|
f32(wsize.x) / f32(wsize.y),
|
||||||
|
0.001,
|
||||||
|
1000,
|
||||||
|
)
|
||||||
|
|
||||||
|
UBO :: struct {
|
||||||
|
mvp: matrix[4, 4]f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
last_ticks := sdl.GetTicks()
|
||||||
|
|
||||||
|
loop: for {
|
||||||
|
new_ticks := sdl.GetTicks()
|
||||||
|
delta := f32(new_ticks - last_ticks) / 1000
|
||||||
|
last_ticks = new_ticks
|
||||||
|
ev: sdl.Event
|
||||||
|
for sdl.PollEvent(&ev) {
|
||||||
|
#partial switch ev.type {
|
||||||
|
case .QUIT:
|
||||||
|
break loop
|
||||||
|
case .KEY_DOWN:
|
||||||
|
if ev.key.scancode == .ESCAPE do break loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cmd_buf := sdl.AcquireGPUCommandBuffer(gpu)
|
||||||
|
swaptex: ^sdl.GPUTexture
|
||||||
|
ok = sdl.WaitAndAcquireGPUSwapchainTexture(cmd_buf, window, &swaptex, nil, nil);assert(ok)
|
||||||
|
|
||||||
|
rotation += 1 * delta
|
||||||
|
|
||||||
|
model_mat :=
|
||||||
|
linalg.matrix4_translate_f32({0, 0, -5}) *
|
||||||
|
linalg.matrix4_rotate_f32(rotation, {0, 1, 0})
|
||||||
|
ubo := UBO{proj * model_mat}
|
||||||
|
|
||||||
|
if swaptex != nil {
|
||||||
|
color_target := sdl.GPUColorTargetInfo {
|
||||||
|
texture = swaptex,
|
||||||
|
load_op = .CLEAR,
|
||||||
|
clear_color = {0.3, 0.1, 0.7, 1},
|
||||||
|
store_op = .STORE,
|
||||||
|
}
|
||||||
|
|
||||||
|
render_pass := sdl.BeginGPURenderPass(cmd_buf, &color_target, 1, nil)
|
||||||
|
sdl.BindGPUGraphicsPipeline(render_pass, pipeline)
|
||||||
|
sdl.BindGPUVertexBuffers(
|
||||||
|
render_pass,
|
||||||
|
0,
|
||||||
|
&(sdl.GPUBufferBinding{buffer = vertex_buf}),
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
sdl.PushGPUVertexUniformData(cmd_buf, 0, &ubo, size_of(ubo))
|
||||||
|
sdl.DrawGPUPrimitives(render_pass, u32(len(vertices)), 1, 0, 0)
|
||||||
|
sdl.EndGPURenderPass(render_pass)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = sdl.SubmitGPUCommandBuffer(cmd_buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
load_shader :: proc(
|
||||||
|
gpu: ^sdl.GPUDevice,
|
||||||
|
code: []u8,
|
||||||
|
stage: sdl.GPUShaderStage,
|
||||||
|
num_uniforms: u32,
|
||||||
|
) -> ^sdl.GPUShader {
|
||||||
|
shader := sdl.CreateGPUShader(
|
||||||
|
gpu,
|
||||||
|
sdl.GPUShaderCreateInfo {
|
||||||
|
code_size = len(code),
|
||||||
|
code = raw_data(code),
|
||||||
|
entrypoint = "main",
|
||||||
|
format = {.SPIRV},
|
||||||
|
stage = stage,
|
||||||
|
num_uniform_buffers = num_uniforms,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return shader
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user