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