1 /**
2     RenderingDevice buffer abstraction.
3 
4     Copyright © 2025, Inochi2D Project
5     Distributed under the 2-Clause BSD License, see LICENSE file.
6     
7     Authors: Luna Nielsen
8 */
9 module inochi2d.godot.render.buffer;
10 import inochi2d.godot.render;
11 import godot.rendering_device;
12 import godot.variant;
13 import godot.globals;
14 import godot;
15 import numem;
16 
17 /**
18     Buffer creation flags.
19 */
20 alias BufferCreationFlags = RenderingDevice.BufferCreationBits;
21 
22 /**
23     Index buffer formats.
24 */
25 alias IndexBufferFormat = RenderingDevice.IndexBufferFormat;
26 
27 /**
28     Base class for RenderingDevice buffers.
29 */
30 abstract class RDBuffer : RDObject {
31 private:
32 @nogc:
33     size_t size_;
34 
35 protected:
36 
37     /**
38         Constructs a new RDBuffer.
39 
40         Params:
41             device =    The rendering device that owns this object.
42             rid =       The render id of this object.
43             size =      Size of the buffer in bytes.
44     */
45     this(RenderingDevice device, RID rid, size_t size) {
46         super(device, rid);
47         this.size_ = size;
48     }
49 
50 public:
51 
52     /**
53         Size of the buffer in bytes.
54     */
55     final @property size_t size() => size_;
56 
57     /**
58         Updates the contents of the buffer.
59 
60         Params:
61             data =      The data to upload to the GPU
62             offset =    The offset into the buffer to upload the data.
63         
64         Returns:
65             $(D GDError.OK) on success,
66             $(D GDError) status code on failure.
67     */
68     final GDError update(void[] data, int offset) {
69         auto p_data = PackedArray!(ubyte)(cast(ubyte[])data);
70         auto p_error = device.bufferUpdate(rid, offset, cast(uint)data.length, p_data);
71         gd_delete(p_data);
72         return p_error;
73     }
74 }
75 
76 /**
77     An index buffer.
78 */
79 class RDIndexBuffer : RDBuffer {
80 public:
81 @nogc:
82 
83     this(RenderingDevice device, IndexBufferFormat format, uint indexCount, BufferCreationFlags flags) {
84         size_t p_size = (16 * (format+1))*indexCount;
85         super(device, device.indexBufferCreate(indexCount, format, PackedArray!(ubyte).init, false, flags), p_size);
86     }
87 }
88 
89 /**
90     A vertex buffer.
91 */
92 class RDVertexBuffer : RDBuffer {
93 public:
94 @nogc:
95 
96     this(RenderingDevice device, size_t sizeInBytes, BufferCreationFlags flags) {
97         super(device, device.vertexBufferCreate(cast(int)sizeInBytes, PackedArray!(ubyte).init, flags), sizeInBytes);
98     }
99 }
100 
101 /**
102     A uniform buffer.
103 */
104 class RDUniformBuffer : RDBuffer {
105 public:
106 @nogc:
107 
108     this(RenderingDevice device, size_t sizeInBytes, BufferCreationFlags flags) {
109         super(device, device.uniformBufferCreate(cast(int)sizeInBytes, PackedArray!(ubyte).init, flags), sizeInBytes);
110     }
111 }