1 module canvas.backend.common;
2 import canvas.color;
3 import canvas.math;
4 
5 // Enums:
6 
7 enum ShaderType {
8 	Fragment,
9 	Vertex,
10 }
11 
12 enum DrawMode {
13 	Triangles,
14 	TriangleFan,
15 	TriangleStrip,
16 }
17 
18 enum MeshUsage {
19 
20 	/** Signals that the mesh will not be modified often */
21 	Static,
22 
23 	/** Signals that the mesh will be modified often */
24 	Dynamic,
25 
26 }
27 
28 enum AttributeType {
29 	Float,
30 	FVec2,
31 	FVec3,
32 	FVec4,
33 	Int,
34 	IVec2,
35 	IVec3,
36 	IVec4,
37 }
38 
39 size_t byteLength(AttributeType type) {
40 	final switch (type) {
41 		case AttributeType.Float: return float.sizeof;
42 		case AttributeType.FVec2: return FVec2.sizeof;
43 		case AttributeType.FVec3: return FVec3.sizeof;
44 		case AttributeType.FVec4: return FVec4.sizeof;
45 		case AttributeType.Int: return int.sizeof;
46 		case AttributeType.IVec2: return IVec2.sizeof;
47 		case AttributeType.IVec3: return IVec3.sizeof;
48 		case AttributeType.IVec4: return IVec4.sizeof;
49 	}
50 }
51 
52 enum StencilFunction {
53 	Always,
54 	Never,
55 	Lt,
56 	Le,
57 	Gt,
58 	Ge,
59 	Eq,
60 	Neq,
61 }
62 
63 enum StencilOp {
64 	Nop,
65 	Zero,
66 	Set,
67 	Inc,
68 	Dec,
69 	IncWrap,
70 	DecWrap,
71 	Inv,
72 }
73 
74 // Structs:
75 
76 struct ShaderSource {
77 	ShaderType type;
78 	string source;
79 }
80 
81 struct Attribute {
82 	string name;
83 	AttributeType type;
84 	size_t byteOffset;
85 }
86 
87 struct VertexFormat {
88 	Attribute[] attributes;
89 	size_t stride;
90 
91 	void add(string name, AttributeType type) {
92 		// TODO: bind to input based on name; currently uses order
93 		attributes ~= Attribute(name, type, stride);
94 		stride += type.byteLength;
95 	}
96 }
97 
98 struct Stencil {
99 
100 	StencilFunction func = StencilFunction.Always;
101 	StencilOp stencilFail = StencilOp.Nop;
102 	StencilOp depthFail = StencilOp.Nop;
103 	StencilOp pass = StencilOp.Nop;
104 	ubyte refValue = 0;
105 	ubyte writeMask = 0xFF;
106 	ubyte readMask = 0xFF;
107 }
108 
109 struct BlendingFunction {
110 	enum Factor {
111 		Zero,
112 		One,
113 		SrcColor,
114 		DstColor,
115 		SrcAlpha,
116 		DstAlpha,
117 		ConstColor,
118 		ConstAlpha,
119 		OneMinusSrcColor,
120 		OneMinusDstColor,
121 		OneMinusSrcAlpha,
122 		OneMinusDstAlpha,
123 		OneMinusConstColor,
124 		OneMinusConstAlpha,
125 	}
126 
127 	enum Operation {
128 		Add,
129 		SrcMinusDst,
130 		DstMinusSrc,
131 		Min,
132 		Max,
133 	}
134 
135 	Operation op;
136 	Factor sfactor;
137 	Factor dfactor;
138 	FVec4 constant = FVec4(0, 0, 0, 0);
139 }
140 
141 enum BlendingFunctions : BlendingFunction {
142 	Normal = BlendingFunction(
143 		BlendingFunction.Operation.Add,
144 		BlendingFunction.Factor.SrcAlpha,
145 		BlendingFunction.Factor.OneMinusSrcAlpha,
146 	),
147 	Overwrite = BlendingFunction(
148 		BlendingFunction.Operation.Add,
149 		BlendingFunction.Factor.One,
150 		BlendingFunction.Factor.Zero,
151 	),
152 	Add = BlendingFunction(
153 		BlendingFunction.Operation.Add,
154 		BlendingFunction.Factor.One,
155 		BlendingFunction.Factor.One,
156 	),
157 }
158 
159 // Resources:
160 
161 abstract class Shader {
162 
163 	/**
164 
165 	Releases all resources used by the shader
166 
167 	Calling any method on the shader, including $(REF dispose), after it has been disposed is undefined behavior
168 
169 	*/
170 	void dispose();
171 
172 	void setUniform(string name, float value);
173 	void setUniform(string name, int value);
174 	void setUniform(string name, FVec2 value);
175 	void setUniform(string name, FVec3 value);
176 	void setUniform(string name, FVec4 value);
177 	void setUniform(string name, Color value);
178 	void setUniform(string name, IVec2 value);
179 	void setUniform(string name, IVec3 value);
180 	void setUniform(string name, IVec4 value);
181 	void setUniform(string name, FMat3 value);
182 	void setUniform(string name, Texture value);
183 
184 }
185 
186 abstract class Mesh {
187 
188 	/**
189 
190 	Releases all resources used by the mesh
191 
192 	Calling any method on the mesh, including $(REF dispose), after it has been disposed is undefined behavior
193 
194 	*/
195 	void dispose();
196 
197 	void upload(void[] data);
198 
199 }
200 
201 abstract class Texture {
202 
203 	/**
204 
205 	Releases all resources used by the texture
206 
207 	Calling any method on the texture, including $(REF dispose), after it has been disposed is undefined behavior
208 
209 	*/
210 	void dispose();
211 
212 	IVec2 size();
213 
214 }
215 
216 abstract class Framebuffer : Texture {}
217 
218 abstract class CanvasBackend {
219 
220 	/** Releases all resources created under this backend */
221 	void dispose();
222 
223 	/** Creates a new shader from the given sources */
224 	Shader shader(ShaderSource[] sources);
225 
226 	Mesh mesh(VertexFormat format, MeshUsage usage);
227 
228 	Framebuffer framebuffer(IVec2 size);
229 
230 	Texture texture(IVec2 size, const(void)[] data);
231 
232 	/**
233 
234 	Sets the current rendering target
235 
236 	Pass in $(D null) to draw onto the main window
237 
238 	*/
239 	void renderTarget(Framebuffer framebuffer);
240 
241 	/** Gets the current rendering target, or $(D null) */
242 	Framebuffer renderTarget();
243 
244 	/** Clears the color buffer with the given color */
245 	void clearColor(Color color);
246 
247 	/** Clears the stencil buffer with the given value */
248 	void clearStencil(ubyte value);
249 
250 	void stencil(Stencil value);
251 
252 	void stencilSeparate(Stencil front, Stencil back);
253 
254 	/** Gets the color channel blending function */
255 	BlendingFunction colorBlend();
256 
257 	/** Gets the alpha channel blending function */
258 	BlendingFunction alphaBlend();
259 
260 	/** Same as $(REF colorBlend) */
261 	BlendingFunction blend();
262 
263 	void blend(BlendingFunction value);
264 
265 	void blend(BlendingFunction color, BlendingFunction alpha);
266 
267 	/** Sets the viewport rectangle */
268 	void viewport(IVec2 location, IVec2 size);
269 
270 	void colorWriteMask(bool r, bool g, bool b, bool a);
271 
272 	void draw(DrawMode mode, Shader shader, Mesh mesh, size_t startVertex, size_t numVertices);
273 
274 }