Basic vertex and index buffer
This commit is contained in:
@@ -21,9 +21,7 @@ OS :: struct {
|
|||||||
// Constructor / destructor
|
// Constructor / destructor
|
||||||
|
|
||||||
os_init :: proc(settings: base.Settings) {
|
os_init :: proc(settings: base.Settings) {
|
||||||
if !glfw.Init() {
|
assert(cast(bool)glfw.Init(), "[glfw] init failure")
|
||||||
panic("[glfw] init failure")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set window properties
|
// Set window properties
|
||||||
glfw.WindowHint(glfw.CLIENT_API, glfw.NO_API) // do not create OpenGL context
|
glfw.WindowHint(glfw.CLIENT_API, glfw.NO_API) // do not create OpenGL context
|
||||||
|
|||||||
+119
-13
@@ -8,6 +8,16 @@ import "wgpu:wgpu"
|
|||||||
|
|
||||||
import "sindri:base"
|
import "sindri:base"
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
// Types
|
||||||
|
|
||||||
|
Vec3 :: [3]f32
|
||||||
|
|
||||||
|
Vertex :: struct #align (4) {
|
||||||
|
pos: Vec3,
|
||||||
|
col: Vec3,
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
// Variables
|
// Variables
|
||||||
|
|
||||||
@@ -28,6 +38,10 @@ state: struct {
|
|||||||
// ----------------------------------------
|
// ----------------------------------------
|
||||||
capabilities: wgpu.SurfaceCapabilities,
|
capabilities: wgpu.SurfaceCapabilities,
|
||||||
vsync: bool,
|
vsync: bool,
|
||||||
|
// ----------------------------------------
|
||||||
|
vertex_buffer: wgpu.Buffer,
|
||||||
|
index_buffer: wgpu.Buffer,
|
||||||
|
index_count: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
@@ -64,6 +78,9 @@ instance_init :: proc(settings: base.Settings) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
instance_destroy :: proc() {
|
instance_destroy :: proc() {
|
||||||
|
wgpu.BufferRelease(state.vertex_buffer)
|
||||||
|
wgpu.BufferRelease(state.index_buffer)
|
||||||
|
|
||||||
wgpu.RenderPipelineRelease(state.pipeline)
|
wgpu.RenderPipelineRelease(state.pipeline)
|
||||||
wgpu.PipelineLayoutRelease(state.pipeline_layout)
|
wgpu.PipelineLayoutRelease(state.pipeline_layout)
|
||||||
wgpu.ShaderModuleRelease(state.module)
|
wgpu.ShaderModuleRelease(state.module)
|
||||||
@@ -137,18 +154,36 @@ frame :: proc "c" () {
|
|||||||
loadOp = .Clear,
|
loadOp = .Clear,
|
||||||
storeOp = .Store,
|
storeOp = .Store,
|
||||||
depthSlice = wgpu.DEPTH_SLICE_UNDEFINED,
|
depthSlice = wgpu.DEPTH_SLICE_UNDEFINED,
|
||||||
clearValue = {0, 1, 0, 1},
|
clearValue = {55 / 255.0, 73 / 255.0, 73 / 255.0, 1},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
wgpu.RenderPassEncoderSetPipeline(render_pass_encoder, state.pipeline)
|
wgpu.RenderPassEncoderSetPipeline(render_pass_encoder, state.pipeline)
|
||||||
wgpu.RenderPassEncoderDraw(
|
|
||||||
|
wgpu.RenderPassEncoderSetVertexBuffer(
|
||||||
render_pass_encoder,
|
render_pass_encoder,
|
||||||
vertexCount = 3,
|
slot = 0,
|
||||||
instanceCount = 1,
|
buffer = state.vertex_buffer,
|
||||||
firstVertex = 0,
|
offset = 0, // offset into buffer to start from
|
||||||
firstInstance = 0,
|
size = wgpu.WHOLE_SIZE, // x bytes of the buffer to use
|
||||||
|
)
|
||||||
|
|
||||||
|
wgpu.RenderPassEncoderSetIndexBuffer(
|
||||||
|
render_pass_encoder,
|
||||||
|
buffer = state.index_buffer,
|
||||||
|
format = .Uint16, // type of each element in the buffer
|
||||||
|
offset = 0, // offset into buffer to start from
|
||||||
|
size = wgpu.WHOLE_SIZE, // x bytes of the buffer to use
|
||||||
|
)
|
||||||
|
|
||||||
|
wgpu.RenderPassEncoderDrawIndexed(
|
||||||
|
render_pass_encoder,
|
||||||
|
state.index_count,
|
||||||
|
instanceCount = 1, // draw x instance(s) of the mesh
|
||||||
|
firstIndex = 0, // offset into buffer to start from, useful for drawing sub-mesh
|
||||||
|
baseVertex = 0, // value added to index before vertex fetch, useful for multi-mesh vertex buffers
|
||||||
|
firstInstance = 0, // number to start instance index from
|
||||||
)
|
)
|
||||||
|
|
||||||
wgpu.RenderPassEncoderEnd(render_pass_encoder)
|
wgpu.RenderPassEncoderEnd(render_pass_encoder)
|
||||||
@@ -208,17 +243,31 @@ on_device :: proc "c" (
|
|||||||
}
|
}
|
||||||
wgpu.SurfaceConfigure(state.surface, &state.config)
|
wgpu.SurfaceConfigure(state.surface, &state.config)
|
||||||
|
|
||||||
|
// ----------------------------------------
|
||||||
|
// Compile shader
|
||||||
|
|
||||||
shader :: `
|
shader :: `
|
||||||
|
struct VertexInput {
|
||||||
|
@location(0) pos: vec3<f32>,
|
||||||
|
@location(1) col: vec3<f32>,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertexOutput {
|
||||||
|
@builtin(position) position: vec4<f32>,
|
||||||
|
@location(0) col: vec3<f32>,
|
||||||
|
};
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4<f32> {
|
fn vs_main(in: VertexInput) -> VertexOutput {
|
||||||
let x = f32(i32(in_vertex_index) - 1);
|
var out: VertexOutput;
|
||||||
let y = f32(i32(in_vertex_index & 1u) * 2 - 1);
|
out.position = vec4<f32>(in.pos, 1.0);
|
||||||
return vec4<f32>(x, y, 0.0, 1.0);
|
out.col = in.col;
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn fs_main() -> @location(0) vec4<f32> {
|
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
|
return vec4<f32>(in.col, 1.0);
|
||||||
}`
|
}`
|
||||||
|
|
||||||
state.module = wgpu.DeviceCreateShaderModule(
|
state.module = wgpu.DeviceCreateShaderModule(
|
||||||
@@ -231,12 +280,46 @@ on_device :: proc "c" (
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ----------------------------------------
|
||||||
|
// Buffer shape
|
||||||
|
|
||||||
|
// Fill vertex/index buffers
|
||||||
|
fill_buffers_with_quad()
|
||||||
|
|
||||||
|
vertex_attributes := [?]wgpu.VertexAttribute {
|
||||||
|
{
|
||||||
|
format = .Float32x3,
|
||||||
|
offset = cast(u64)offset_of(Vertex, pos),
|
||||||
|
shaderLocation = 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
format = .Float32x3,
|
||||||
|
offset = cast(u64)offset_of(Vertex, col),
|
||||||
|
shaderLocation = 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
vertex_layout := wgpu.VertexBufferLayout {
|
||||||
|
stepMode = .Vertex,
|
||||||
|
arrayStride = size_of(Vertex),
|
||||||
|
attributeCount = len(vertex_attributes),
|
||||||
|
attributes = raw_data(vertex_attributes[:]),
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------
|
||||||
|
// Render pipeline
|
||||||
|
|
||||||
state.pipeline_layout = wgpu.DeviceCreatePipelineLayout(state.device, &{})
|
state.pipeline_layout = wgpu.DeviceCreatePipelineLayout(state.device, &{})
|
||||||
state.pipeline = wgpu.DeviceCreateRenderPipeline(
|
state.pipeline = wgpu.DeviceCreateRenderPipeline(
|
||||||
state.device,
|
state.device,
|
||||||
&{
|
&{
|
||||||
layout = state.pipeline_layout,
|
layout = state.pipeline_layout,
|
||||||
vertex = {module = state.module, entryPoint = "vs_main"},
|
vertex = {
|
||||||
|
module = state.module,
|
||||||
|
entryPoint = "vs_main",
|
||||||
|
bufferCount = 1,
|
||||||
|
buffers = &vertex_layout,
|
||||||
|
},
|
||||||
fragment = &{
|
fragment = &{
|
||||||
module = state.module,
|
module = state.module,
|
||||||
entryPoint = "fs_main",
|
entryPoint = "fs_main",
|
||||||
@@ -290,3 +373,26 @@ pick_present_mode :: proc(vsync: bool) -> wgpu.PresentMode {
|
|||||||
|
|
||||||
return .Fifo // Vsync On
|
return .Fifo // Vsync On
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(private = "file")
|
||||||
|
fill_buffers_with_quad :: proc() {
|
||||||
|
vertices := [?]Vertex {
|
||||||
|
{pos = {-0.5, -0.5, 0}, col = {1, 0, 0}}, // 0 bottom-left red
|
||||||
|
{pos = {+0.5, -0.5, 0}, col = {0, 1, 0}}, // 1 bottom-right green
|
||||||
|
{pos = {+0.5, +0.5, 0}, col = {0, 0, 1}}, // 2 top-right blue
|
||||||
|
{pos = {-0.5, +0.5, 0}, col = {1, 1, 0}}, // 3 top-left yellow
|
||||||
|
}
|
||||||
|
indices := [?]u16{0, 1, 2, 2, 3, 0}
|
||||||
|
|
||||||
|
state.vertex_buffer = wgpu.DeviceCreateBufferWithData(
|
||||||
|
state.device,
|
||||||
|
&{label = "quad vertices", usage = {.Vertex}},
|
||||||
|
vertices[:],
|
||||||
|
)
|
||||||
|
state.index_buffer = wgpu.DeviceCreateBufferWithData(
|
||||||
|
state.device,
|
||||||
|
&{label = "quad indices", usage = {.Index}},
|
||||||
|
indices[:],
|
||||||
|
)
|
||||||
|
state.index_count = cast(u32)len(indices)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user