1 //------------------------------------------------------------------------------ 2 // bufferoffsets.d 3 // 4 // Render separate geometries in vertex- and index-buffers with 5 // buffer offsets. 6 //------------------------------------------------------------------------------ 7 module examples.bufferoffsets; 8 9 private: 10 11 import sg = sokol.gfx; 12 import app = sokol.app; 13 import log = sokol.log; 14 import sglue = sokol.glue; 15 import shd = examples.shaders.bufferoffsets; 16 17 extern (C): 18 @safe: 19 20 struct State 21 { 22 sg.Pipeline pip; 23 sg.Bindings bind; 24 sg.PassAction passAction = {}; 25 } 26 27 struct Vertex 28 { 29 float x = 0.0f, y = 0.0f; 30 float r = 0.0f, g = 0.0f, b = 0.0f; 31 } 32 33 static State state; 34 35 void init() 36 { 37 sg.Desc gfxd = {environment: sglue.environment, 38 logger: {func: &log.func}}; 39 sg.setup(gfxd); 40 41 state.passAction.colors[0].load_action = sg.LoadAction.Clear; 42 state.passAction.colors[0].clear_value.r = 0.5; 43 state.passAction.colors[0].clear_value.g = 0.5; 44 state.passAction.colors[0].clear_value.b = 1.0; 45 state.passAction.colors[0].clear_value.a = 1.0; 46 47 Vertex[7] vertices = [ 48 Vertex(0.0, 0.55, 1.0, 0.0, 0.0), 49 Vertex(0.25, 0.05, 0.0, 1.0, 0.0), 50 Vertex(-0.25, 0.05, 0.0, 0.0, 1.0), 51 52 Vertex(-0.25, -0.05, 0.0, 0.0, 1.0), 53 Vertex(0.25, -0.05, 0.0, 1.0, 0.0), 54 Vertex(0.25, -0.55, 1.0, 0.0, 0.0), 55 Vertex(-0.25, -0.55, 1.0, 1.0, 0.0), 56 ]; 57 58 sg.BufferDesc vbufd = {data: {ptr: vertices.ptr, size: vertices.sizeof},}; 59 state.bind.vertex_buffers[0] = sg.makeBuffer(vbufd); 60 61 ushort[9] indices = [ 62 0, 1, 2, 63 0, 1, 2, 64 0, 2, 3, 65 ]; 66 67 // dfmt off 68 sg.BufferDesc ibufd = { 69 type: sg.BufferType.Indexbuffer, 70 data: {ptr: indices.ptr, size: indices.sizeof}, 71 }; 72 state.bind.index_buffer = sg.makeBuffer(ibufd); 73 74 sg.PipelineDesc pld = { 75 layout: { 76 attrs: [ 77 shd.ATTR_BUFFEROFFSETS_POSITION: {format: sg.VertexFormat.Float2}, 78 shd.ATTR_BUFFEROFFSETS_COLOR0: {format: sg.VertexFormat.Float3}, 79 ], 80 }, 81 shader: sg.makeShader(shd.bufferoffsetsShaderDesc(sg.queryBackend())), 82 index_type: sg.IndexType.Uint16, 83 }; 84 // dfmt on 85 state.pip = sg.makePipeline(pld); 86 } 87 88 void frame() 89 { 90 sg.Pass pass = {action: state.passAction, swapchain: sglue.swapchain()}; 91 sg.beginPass(pass); 92 sg.applyPipeline(state.pip); 93 94 // render the triangle 95 state.bind.vertex_buffer_offsets[0] = 0; 96 state.bind.index_buffer_offset = 0; 97 sg.applyBindings(state.bind); 98 sg.draw(0, 3, 1); 99 100 // render the quad 101 state.bind.vertex_buffer_offsets[0] = 3 * Vertex.sizeof; 102 state.bind.index_buffer_offset = 3 * ushort.sizeof; 103 sg.applyBindings(state.bind); 104 sg.draw(0, 6, 1); 105 106 sg.endPass(); 107 sg.commit(); 108 } 109 110 void cleanup() 111 { 112 sg.shutdown(); 113 } 114 115 // dfmt off 116 void main() 117 { 118 app.Desc runner = { 119 window_title: "bufferoffsets.d", 120 init_cb: &init, 121 frame_cb: &frame, 122 cleanup_cb: &cleanup, 123 width: 800, 124 height: 600, 125 sample_count: 4, 126 icon: {sokol_default: true}, 127 logger: {func: &log.func} 128 }; 129 app.run(runner); 130 } 131 // dfmt on