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.renderqueue;
7 
8 import voxelman.graphics;
9 import voxelman.math;
10 
11 final class RenderQueue
12 {
13 	ResourceManager resourceManager;
14 	Texture atlasTexture;
15 	IRenderer renderer;
16 
17 	BufferRenderer bufferRenderer;
18 	Batch2d batch;
19 	TexturedBatch2d texBatch;
20 	TextStyle[] defaultTextStyles;
21 
22 	this(ResourceManager resMan, IRenderer renderer)
23 	{
24 		resourceManager = resMan;
25 		this.renderer = renderer;
26 		this.atlasTexture = new Texture(TextureTarget.target2d, TextureFormat.rgba);
27 		bufferRenderer = new BufferRenderer(renderer);
28 		defaultTextStyles = [TextStyle(Colors.black)];
29 	}
30 
31 	void reuploadTexture()
32 	{
33 		atlasTexture.loadFromImage(resourceManager.texAtlas.bitmap);
34 	}
35 
36 	enum minDepth2d = -100_000;
37 	enum maxDepth2d = 100_000;
38 
39 	void beginFrame()
40 	{
41 		irect clipRect = irect(ivec2(0,0), renderer.framebufferSize);
42 		texBatch.reset(clipRect);
43 		batch.reset();
44 	}
45 
46 	void endFrame()
47 	{}
48 
49 	void drawFrame()
50 	{
51 		renderer.alphaBlending = true;
52 		renderer.rectClipping = true;
53 		renderer.depthTest = true;
54 		bufferRenderer.updateOrtoMatrix(renderer);
55 		bufferRenderer.draw(renderer, texBatch);
56 		bufferRenderer.draw(batch);
57 		renderer.rectClipping = false;
58 	}
59 
60 	void draw(AnimationInstance animation, vec2 target, float depth, Color4ub color = Colors.white)
61 	{
62 		auto sprite = animation.currentFrameSprite;
63 		vec2 targetRectPos = target - vec2(animation.origin * animation.scale);
64 		texBatch.putRect(
65 			frect(targetRectPos, vec2(sprite.atlasRect.size) * animation.scale),
66 			frect(sprite.atlasRect),
67 			depth,
68 			color,
69 			atlasTexture);
70 	}
71 
72 	void draw(Sprite sprite, vec2 target, float depth, Color4ub color = Colors.white)
73 	{
74 		texBatch.putRect(
75 			frect(target, vec2(sprite.atlasRect.size)),
76 			frect(sprite.atlasRect),
77 			depth,
78 			color,
79 			atlasTexture);
80 	}
81 
82 	void draw(SpriteInstance sprite, vec2 target, float depth, Color4ub color = Colors.white)
83 	{
84 		vec2 targetRectPos = target - vec2(sprite.origin * sprite.scale);
85 		texBatch.putRect(
86 			frect(targetRectPos, vec2(sprite.sprite.atlasRect.size) * sprite.scale),
87 			frect(sprite.sprite.atlasRect),
88 			depth,
89 			color,
90 			atlasTexture);
91 	}
92 
93 	void drawTexRect(frect target, frect source, float depth, Color4ub color = Colors.white)
94 	{
95 		texBatch.putRect(target, source, depth, color, atlasTexture);
96 	}
97 
98 	void drawRectFill(vec2 pos, vec2 size, float depth, Color4ub color)
99 	{
100 		texBatch.putRect(frect(pos, size), frect(resourceManager.whitePixelPos, vec2(1,1)), depth, color, atlasTexture);
101 	}
102 
103 	void drawRectLine(vec2 pos, vec2 size, float depth, Color4ub color)
104 	{
105 		texBatch.putRect(frect(pos.x, pos.y, size.x, 1), frect(resourceManager.whitePixelPos, vec2(1,1)), depth, color, atlasTexture);
106 		texBatch.putRect(frect(pos.x, pos.y+1, 1, size.y-2), frect(resourceManager.whitePixelPos, vec2(1,1)), depth, color, atlasTexture);
107 		texBatch.putRect(frect(pos.x, pos.y+size.y-1, size.x, 1), frect(resourceManager.whitePixelPos, vec2(1,1)), depth, color, atlasTexture);
108 		texBatch.putRect(frect(pos.x+size.x-1, pos.y+1, 1, size.y-2), frect(resourceManager.whitePixelPos, vec2(1,1)), depth, color, atlasTexture);
109 	}
110 
111 	void pushClipRect(irect rect) {
112 		texBatch.pushClipRect(rect);
113 	}
114 	void popClipRect() {
115 		texBatch.popClipRect();
116 	}
117 
118 	FontRef defaultFont()
119 	{
120 		return resourceManager.fontManager.defaultFont;
121 	}
122 
123 	TextMesherParams defaultText()
124 	{
125 		TextMesherParams params;
126 		params.sink = TextRectSink(&texBatch, atlasTexture);
127 		params.depth = 0;
128 		params.font = defaultFont;
129 		params.styles = defaultTextStyles;
130 		return params;
131 	}
132 
133 	TextMesherParams startTextAt(vec2 origin)
134 	{
135 		auto params = defaultText();
136 		params.origin = origin;
137 		return params;
138 	}
139 
140 	void print(vec2 pos, Color4ub color, int scale, const(char[]) str)
141 	{
142 		auto params = startTextAt(pos);
143 		params.color = color;
144 		params.scale = scale;
145 		params.meshText(str);
146 	}
147 
148 	void print(vec2 pos, Color4ub color, int scale, int depth, const(char[]) str)
149 	{
150 		auto params = startTextAt(pos);
151 		params.color = color;
152 		params.scale = scale;
153 		params.depth = depth;
154 		params.meshText(str);
155 	}
156 
157 	void print(Args...)(vec2 pos, Color4ub color, int scale, const(char[]) fmt, Args args)
158 	{
159 		auto params = startTextAt(pos);
160 		params.color = color;
161 		params.scale = scale;
162 		params.meshText(fmt, args);
163 	}
164 
165 	void print(Args...)(vec2 pos, Color4ub color, const(char[]) fmt, Args args)
166 	{
167 		this.print(pos, color, 1, fmt, args);
168 	}
169 
170 	void print(Args...)(vec2 pos, const(char[]) fmt, Args args)
171 	{
172 		this.print(pos, Colors.black, 1, fmt, args);
173 	}
174 }