1 /**
2  * Copyright:       Copyright (C) 2018 Gabriel Gheorghe, All Rights Reserved
3  * Authors:         $(Gabriel Gheorghe)
4  * License:         $(LINK2 https://www.gnu.org/licenses/gpl-3.0.txt, GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007)
5  * Source
6  * Documentation:
7  * Coverage:
8  */
9 module liberty.core.model;
10 import liberty.graphics.util : RenderUtil;
11 import liberty.graphics.video.vertex : VertexSpec;
12 import liberty.graphics.video.vao : VertexArray;
13 import liberty.graphics.video.buffer : VideoBuffer, BufferTarget;
14 import liberty.graphics.material : Material, Materials;
15 import liberty.graphics.renderer : Vertex, DataUsage;
16 import liberty.math : Vector2F, Vector3F;
17 import liberty.core.utils : Singleton, IService;
18 ///
19 struct Mesh {
20 	///
21 	VertexArray vao;
22 	///
23     VideoBuffer vbo;
24     ///
25     VideoBuffer ibo;
26     ///
27     void clear() {
28         vao.destroy();
29         vbo.destroy();
30         ibo.destroy();
31     }
32 }
33 ///
34 final class Model(VERTEX) {
35 	private {
36 		VertexSpec!VERTEX _vertexSpec;
37 		Mesh _mesh;
38 		Material _material;
39 	}
40 	///
41 	this(VERTEX[] vboArray, uint[] indices, Material material = Materials.get.defaultMaterial) {
42 		_material = material;
43 		_vertexSpec = RenderUtil.get.createVertexSpec!VERTEX(_material.shader);
44         _mesh.vao = RenderUtil.get.createVertexArray();
45         _mesh.vbo = RenderUtil.get.createBuffer(BufferTarget.Array, DataUsage.StaticDraw, vboArray[]);
46         _mesh.ibo = RenderUtil.get.createBuffer(BufferTarget.ElementArray, DataUsage.StaticDraw);
47         _mesh.vao.bind();
48         _mesh.vbo.bind();
49         _mesh.ibo.data = indices;
50         _vertexSpec.use();
51         _mesh.vao.unbind();
52 	}
53 	///
54 	~this() {
55 		_mesh.clear();
56 		_vertexSpec.destroy();
57 	}
58 	///
59 	Mesh mesh() {
60 		return _mesh;
61 	}
62 	///
63 	Material material() {
64 		return _material;
65 	}
66 	///
67 	void mesh(Mesh mesh) pure nothrow {
68 		_mesh = mesh;
69 	}
70 	///
71 	void material(Material material) pure nothrow {
72 		_material = material;
73 	}
74 }
75 ///
76 final class Models : Singleton!Models {
77 	///
78 	Model!Vertex rectangleModel;
79 	///
80 	Model!Vertex cubeModel;
81 	///
82 	void load() {
83 		/* Create rectangleModel */
84 		Vertex[4] rectangleVertices;
85 		rectangleVertices[0] = Vertex(Vector3F( 0.5f,  0.5f, 0.0f), Vector2F(1.0f, 1.0f));
86         rectangleVertices[1] = Vertex(Vector3F( 0.5f, -0.5f, 0.0f), Vector2F(1.0f, 0.0f));
87         rectangleVertices[2] = Vertex(Vector3F(-0.5f, -0.5f, 0.0f), Vector2F(0.0f, 0.0f));
88         rectangleVertices[3] = Vertex(Vector3F(-0.5f,  0.5f, 0.0f), Vector2F(0.0f, 1.0f));
89 		uint[] rectangleIndices = [
90 			0, 1, 3,
91 			1, 2, 3
92 		];
93 		rectangleModel = new Model!Vertex(rectangleVertices, rectangleIndices);
94 		/* Create cubeModel */
95 		Vertex[8] cubeVertices;
96 		cubeVertices[0] = Vertex(Vector3F(-0.5, -0.5, -0.5), Vector2F(0, 0));
97         cubeVertices[1] = Vertex(Vector3F(0.5, -0.5, -0.5), Vector2F(1, 0));
98         cubeVertices[2] = Vertex(Vector3F(0.5, 0.5, -0.5), Vector2F(1, 1));
99         cubeVertices[3] = Vertex(Vector3F(-0.5, 0.5, -0.5), Vector2F(0, 1));
100         cubeVertices[4] = Vertex(Vector3F(-0.5, -0.5, 0.5), Vector2F(0, 1));
101         cubeVertices[5] = Vertex(Vector3F(0.5, -0.5, 0.5), Vector2F(1, 0));
102         cubeVertices[6] = Vertex(Vector3F(0.5, 0.5, 0.5), Vector2F(0, 0));
103         cubeVertices[7] = Vertex(Vector3F(-0.5, 0.5, 0.5), Vector2F(1, 1));
104 		uint[] cubeIndices = [
105 	         0, 1, 3, 3, 1, 2,
106 	         1, 5, 2, 2, 5, 6,
107 	         5, 4, 6, 6, 4, 7,
108 	         4, 0, 7, 7, 0, 3,
109 	         3, 2, 7, 7, 2, 6,
110 	         4, 5, 0, 0, 5, 1
111 	     ];
112         cubeModel = new Model!Vertex(cubeVertices, cubeIndices);
113 	}
114 }