1 module evael.graphics.models.Model;
2 
3 import evael.system.Asset;
4 
5 import evael.graphics.Drawable;
6 import evael.graphics.models.BoundingBox;
7 import evael.graphics.GraphicsDevice;
8 import evael.graphics.Vertex;
9 import evael.graphics.shaders.Shader;
10 
11 import evael.utils.Math;
12 
13 /**
14  * Model.
15  */
16 class Model : Drawable, IAsset
17 {
18 	/// Buffer for instancing
19 	protected uint[] m_instancingBuffers;
20 
21 	/// Instances count
22 	protected uint m_instancesCount;
23 
24 	/// Shader
25 	protected Shader m_shader;
26 
27 	/**
28 	 * Model constructor.
29 	 */
30 	@nogc
31 	public this(GraphicsDevice graphicsDevice) nothrow
32 	{
33 		super(graphicsDevice);
34 
35 		this.m_vao = this.m_graphicsDevice.generateVAO();		
36 	}
37 
38 	/**
39 	 * Model destructor.
40 	 */
41 	public void dispose()
42 	{
43 		
44 	}
45 
46 	/**
47 	 * Initializes instancing data.
48 	 * Params:
49 	 *		instancesCount : instances count for the next draw call
50 	 *		buffersCount : vbos count to generate for instances data
51 	 */
52 	public void initializeInstancing(in uint instancesCount, in int buffersCount) nothrow
53 	{
54 		if(this.m_instancingBuffers == null)
55 		{
56 			this.m_instancingBuffers = this.m_graphicsDevice.generateBuffers(BufferType.VertexBuffer, buffersCount);
57 		}
58 
59 		this.m_instancesCount = instancesCount;
60 	}
61 
62 	/**
63 	 * Sets buffer data for buffer at position index.
64 	 * Params:
65 	 *		index : buffer index
66 	 *		data : data to send
67 	 */
68 	@nogc
69 	public void setInstancingBufferData(T)(in int index, void* data) nothrow
70 	{
71 		assert(index < this.m_instancingBuffers.length, "Invalid instancing buffer index");
72 
73 		this.m_graphicsDevice.allocVertexBufferData(this.m_instancingBuffers[index], this.m_instancesCount * T.sizeof, data, BufferUsage.DynamicDraw);
74 	}
75 
76 	/**
77 	 * Updates buffer data for buffer at position index.
78 	 * Params:
79 	 *		index : buffer index
80 	 *		offset : offset in the buffer
81 	 *		data : data to send
82 	 */
83 	@nogc
84 	public void updateInstancingBufferData(in int index, in uint offset, in uint size, void* data) nothrow
85 	{
86 		assert(index < this.m_instancingBuffers.length, "Invalid instancing buffer index");
87 
88 		this.m_graphicsDevice.sendVertexBufferData(this.m_instancingBuffers[index], offset, size, data);
89 	}
90 
91 
92 	public uint getInstancingBuffer(in int index)
93 	{
94 		assert(index < this.m_instancingBuffers.length, "Invalid instancing buffer index");
95 		
96 		return this.m_instancingBuffers[index];
97 	}
98 
99 	/**
100 	 * Draws all instances, depends on model impl
101 	 */
102 	abstract public void drawInstances(in bool bindTexture = true);
103 
104 	@nogc 
105 	@property nothrow
106 	{
107 		public uint vao()
108 		{
109 			return this.m_vao;
110 		}
111 
112 		public uint instancesCount()
113 		{
114 			return this.m_instancesCount;
115 		}
116 
117 		public bool availableInstances()
118 		{
119 			return this.m_instancesCount > 0;
120 		}
121 	}
122 }