1 /**
2 Copyright: Copyright (c) 2017-2018 Andrey Penechko.
3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 Authors: Andrey Penechko.
5 */
6 module voxelman.graphics.bufferrenderer;
7 
8 import voxelman.graphics;
9 import voxelman.math;
10 
11 final class BufferRenderer
12 {
13 	Vao vao;
14 	Vbo vbo;
15 	Matrix4f ortho_projection;
16 
17 	SolidShader3d solidShader3d;
18 	TransparentShader3d transparentShader3d;
19 	SolidShader2d solidShader2d;
20 	ColUvShader2d colUvShader2d;
21 
22 	this(IRenderer renderer)
23 	{
24 		vao.gen;
25 		vbo.gen;
26 
27 		solidShader3d.compile(renderer);
28 		transparentShader3d.compile(renderer);
29 		solidShader2d.compile(renderer);
30 		colUvShader2d.compile(renderer);
31 
32 		updateOrtoMatrix(renderer);
33 	}
34 
35 	void updateOrtoMatrix(IRenderer renderer)
36 	{
37 		renderer.setViewport(ivec2(0, 0), renderer.framebufferSize);
38 
39 		enum far = 100_000;
40 		enum near = -100_000;
41 
42 		// (T l, T r, T b, T t, T n, T f)
43 		ortho_projection = orthoMatrix!float(0, renderer.framebufferSize.x, renderer.framebufferSize.y, 0, near, far);
44 	}
45 
46 	void draw(Batch2d batch)
47 	{
48 		solidShader2d.bind;
49 		solidShader2d.setProjection(ortho_projection);
50 
51 		uploadAndDrawBuffer(batch.triBuffer.data, PrimitiveType.TRIANGLES);
52 		uploadAndDrawBuffer(batch.lineBuffer.data, PrimitiveType.LINES);
53 		uploadAndDrawBuffer(batch.pointBuffer.data, PrimitiveType.POINTS);
54 
55 		solidShader2d.unbind;
56 	}
57 
58 	void draw(IRenderer renderer, TexturedBatch2d batch)
59 	{
60 		if (batch.buffer.data.length)
61 		{
62 			auto vertices = batch.buffer.data;
63 			uploadBuffer(vertices);
64 
65 			colUvShader2d.bind;
66 
67 			colUvShader2d.setProjection(ortho_projection);
68 			colUvShader2d.setTexture(0);
69 
70 			size_t start = 0;
71 			foreach (command; batch.commands.data)
72 			{
73 				final switch(command.type)
74 				{
75 					case CommandType.batch:
76 						command.texture.bind;
77 						drawBuffer(PrimitiveType.TRIANGLES, start, command.numVertices);
78 						start += command.numVertices;
79 						break;
80 					case CommandType.clipRect:
81 						renderer.setClipRect(command.clipRect);
82 						break;
83 				}
84 			}
85 
86 			colUvShader2d.unbind;
87 
88 			Texture.unbind(TextureTarget.target2d);
89 		}
90 	}
91 
92 	private void uploadAndDrawBuffer(VertexType)(VertexType[] buffer, PrimitiveType mode)
93 	{
94 		uploadBuffer(buffer);
95 		drawBuffer(mode, 0, buffer.length);
96 	}
97 
98 	private void drawBuffer(PrimitiveType mode, size_t from, size_t count)
99 	{
100 		vao.bind;
101 		vao.drawArrays(mode, cast(int)from, cast(int)count);
102 		vao.unbind;
103 	}
104 
105 	private void uploadBuffer(VertexType)(VertexType[] buffer)
106 	{
107 		vao.bind;
108 			vbo.bind;
109 				vbo.uploadData(buffer, GL_DYNAMIC_DRAW);
110 				VertexType.setAttributes();
111 			vbo.unbind;
112 		vao.unbind;
113 	}
114 }