211 lines
No EOL
6.1 KiB
Odin
211 lines
No EOL
6.1 KiB
Odin
package main
|
|
|
|
import sdl "vendor:sdl3"
|
|
import "core:math/linalg"
|
|
import "core:mem"
|
|
|
|
frag_shader_code := #load("shader.spv.frag")
|
|
vert_shader_code := #load("shader.spv.vert")
|
|
|
|
main :: proc() {
|
|
ok := sdl.Init({.VIDEO}); assert(ok)
|
|
|
|
sdl.SetLogPriorities(.VERBOSE)
|
|
|
|
window := sdl.CreateWindow("Pain and Suffering and Pleasure", 800, 500, nil)
|
|
|
|
device := sdl.CreateGPUDevice({.SPIRV}, true, nil)
|
|
|
|
ok = sdl.ClaimWindowForGPUDevice(device, window); assert(ok)
|
|
|
|
vert_shader := sdl.CreateGPUShader(device, {
|
|
code_size = len(vert_shader_code),
|
|
code = raw_data(vert_shader_code),
|
|
entrypoint = "main",
|
|
format = {.SPIRV},
|
|
stage = .VERTEX,
|
|
num_uniform_buffers = 1,
|
|
})
|
|
|
|
frag_shader := sdl.CreateGPUShader(device, {
|
|
code_size = len(frag_shader_code),
|
|
code = raw_data(frag_shader_code),
|
|
entrypoint = "main",
|
|
format = {.SPIRV},
|
|
stage = .FRAGMENT,
|
|
num_uniform_buffers = 0,
|
|
})
|
|
|
|
Vec3 :: [3]f32
|
|
|
|
Vertex_Data :: struct {
|
|
pos: Vec3,
|
|
color: sdl.FColor,
|
|
}
|
|
|
|
size : f32= 1
|
|
|
|
vertices := []Vertex_Data {
|
|
{ pos = {-size, size, 1}, color = {1,0,0,1} },
|
|
{pos = {size, size, 1}, color = {0,1,1,1}},
|
|
{pos={-size,-size, 1}, color = {1,0,1,1}},
|
|
{pos={size,-size, 1}, color = {1,0,1,1}},
|
|
}
|
|
|
|
vertices_byte_size := len(vertices) * size_of(vertices[0])
|
|
|
|
indicies := []u16 {
|
|
0,1,2,
|
|
2,1,3
|
|
}
|
|
|
|
indices_byte_size := len(indicies) * size_of(indicies[0])
|
|
vertex_buf := sdl.CreateGPUBuffer(device, {
|
|
usage = {.VERTEX},
|
|
size = u32(vertices_byte_size),
|
|
})
|
|
|
|
index_buf := sdl.CreateGPUBuffer(device, {
|
|
usage = {.INDEX},
|
|
size = u32(vertices_byte_size),
|
|
})
|
|
|
|
transfer_buf := sdl.CreateGPUTransferBuffer(device, {
|
|
usage = .UPLOAD,
|
|
size = u32(vertices_byte_size + indices_byte_size),
|
|
})
|
|
|
|
transfer_mem := transmute([^]byte)sdl.MapGPUTransferBuffer(device, transfer_buf, false)
|
|
mem.copy(transfer_mem, raw_data(vertices), vertices_byte_size)
|
|
mem.copy(transfer_mem[vertices_byte_size:], raw_data(indicies), indices_byte_size)
|
|
sdl.UnmapGPUTransferBuffer(device, transfer_buf)
|
|
|
|
copy_buffer := sdl.AcquireGPUCommandBuffer(device)
|
|
copy_pass := sdl.BeginGPUCopyPass(copy_buffer)
|
|
|
|
sdl.UploadToGPUBuffer(copy_pass, {
|
|
transfer_buffer = transfer_buf,
|
|
}, {
|
|
buffer = vertex_buf,
|
|
size = u32(vertices_byte_size),
|
|
}, false)
|
|
|
|
sdl.UploadToGPUBuffer(copy_pass, {
|
|
transfer_buffer = transfer_buf, offset = u32(vertices_byte_size)
|
|
}, {
|
|
buffer = index_buf,
|
|
size = u32(indices_byte_size)
|
|
}, false)
|
|
|
|
sdl.EndGPUCopyPass(copy_pass)
|
|
|
|
ok = sdl.SubmitGPUCommandBuffer(copy_buffer); assert(ok)
|
|
|
|
sdl.ReleaseGPUTransferBuffer(device, transfer_buf)
|
|
|
|
|
|
vertex_attrs := []sdl.GPUVertexAttribute {
|
|
{
|
|
location = 0,
|
|
format = .FLOAT3,
|
|
offset = u32(offset_of(Vertex_Data, pos)),
|
|
},
|
|
{
|
|
location = 1,
|
|
format = .FLOAT4,
|
|
offset = u32(offset_of(Vertex_Data, color)),
|
|
}
|
|
}
|
|
|
|
pipeline := sdl.CreateGPUGraphicsPipeline(device, {
|
|
vertex_shader = vert_shader,
|
|
fragment_shader = frag_shader,
|
|
primitive_type = .TRIANGLELIST,
|
|
vertex_input_state = {
|
|
num_vertex_buffers = 1,
|
|
vertex_buffer_descriptions = &(sdl.GPUVertexBufferDescription{
|
|
slot = 0,
|
|
pitch = size_of(Vertex_Data),
|
|
}),
|
|
num_vertex_attributes = u32(len(vertex_attrs)),
|
|
vertex_attributes = raw_data(vertex_attrs),
|
|
},
|
|
target_info = {
|
|
num_color_targets = 1,
|
|
color_target_descriptions = &(sdl.GPUColorTargetDescription{
|
|
format = sdl.GetGPUSwapchainTextureFormat(device, window)
|
|
})
|
|
}
|
|
})
|
|
|
|
defer sdl.ReleaseGPUShader(device, frag_shader)
|
|
defer sdl.ReleaseGPUShader(device, vert_shader)
|
|
|
|
win_size: [2]i32
|
|
ok = sdl.GetWindowSize(window, &win_size.x, &win_size.y); assert(ok)
|
|
|
|
rotation_speed := linalg.to_radians(f32(90))
|
|
|
|
rotation := f32(0.62)
|
|
|
|
proj := linalg.matrix4_perspective_f32(linalg.to_radians(f32(70)), f32(win_size.x) / f32(win_size.y), 0.0001, 1000)
|
|
|
|
|
|
UBO :: struct {
|
|
mvp: matrix[4,4]f32
|
|
}
|
|
|
|
last_ticks := sdl.GetTicks()
|
|
|
|
|
|
for {
|
|
new_ticks := sdl.GetTicks()
|
|
delta_time := f32(new_ticks - last_ticks) / 1000
|
|
last_ticks = new_ticks
|
|
event: sdl.Event
|
|
for sdl.PollEvent(&event) {
|
|
#partial switch(event.type) {
|
|
case .QUIT:
|
|
return
|
|
case .KEY_DOWN:
|
|
#partial switch(event.key.scancode) {
|
|
case .ESCAPE:
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
buffer := sdl.AcquireGPUCommandBuffer(device)
|
|
|
|
texture: ^sdl.GPUTexture
|
|
|
|
ok = sdl.WaitAndAcquireGPUSwapchainTexture(buffer, window, &texture, nil, nil); assert(ok)
|
|
|
|
rotation += rotation_speed * delta_time
|
|
model_mat := linalg.matrix4_translate_f32({0,0,-5}) * linalg.matrix4_rotate_f32(rotation, {0,1,0})
|
|
|
|
ubo := UBO {mvp = proj * model_mat}
|
|
|
|
if texture != nil {
|
|
color_target := sdl.GPUColorTargetInfo{
|
|
texture = texture,
|
|
load_op = .CLEAR,
|
|
clear_color = {0,0.2,0.4,1},
|
|
store_op = .STORE,
|
|
}
|
|
render_pass := sdl.BeginGPURenderPass(buffer, &color_target, 1, nil)
|
|
|
|
sdl.BindGPUGraphicsPipeline(render_pass, pipeline)
|
|
sdl.BindGPUVertexBuffers(render_pass, 0, &(sdl.GPUBufferBinding{
|
|
buffer = vertex_buf,
|
|
|
|
}),1)
|
|
sdl.BindGPUIndexBuffer(render_pass, {buffer = index_buf}, ._16BIT)
|
|
sdl.PushGPUVertexUniformData(buffer, 0, &ubo, size_of(ubo))
|
|
sdl.DrawGPUIndexedPrimitives(render_pass, 6, 1, 0, 0 ,0)
|
|
sdl.EndGPURenderPass(render_pass)
|
|
}
|
|
|
|
ok = sdl.SubmitGPUCommandBuffer(buffer); assert(ok)
|
|
}
|
|
} |