1 /**
2  * ae.demo.render.main
3  *
4  * License:
5  *   This Source Code Form is subject to the terms of
6  *   the Mozilla Public License, v. 2.0. If a copy of
7  *   the MPL was not distributed with this file, You
8  *   can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * Authors:
11  *   Vladimir Panteleev <ae@cy.md>
12  */
13 
14 module ae.demo.render.main;
15 
16 import std.conv : to;
17 import std.random;
18 
19 import ae.ui.app.application;
20 import ae.ui.app.posix.main;
21 import ae.ui.shell.shell;
22 import ae.ui.shell.sdl2.shell;
23 import ae.ui.video.renderer;
24 import ae.ui.video.sdl2.video;
25 import ae.ui.timer.sdl2.timer;
26 import ae.ui.timer.thread.timer;
27 import ae.utils.fps;
28 import ae.utils.graphics.image;
29 
30 final class MyApplication : Application
31 {
32 	override string getName() { return "Demo/Render"; }
33 	override string getCompanyName() { return "CyberShadow"; }
34 
35 	Shell shell;
36 	Timer timer;
37 	FPSCounter fps;
38 	Renderer.Pixel[] pixels;
39 	bool useOpenGL, switching;
40 	float x=0f, y=0f, dx=0f, dy=0f;
41 	enum DELTA = 1f / 256;
42 	ImageTextureSource[5] imgs;
43 	ImageTextureSource imgT;
44 
45 	this()
46 	{
47 		foreach (x; 0..256)
48 			foreach (y; 0..256)
49 				pixels ~= Renderer.Pixel(x, y, BGRX(cast(ubyte)x, cast(ubyte)y, 0));
50 
51 		foreach (ubyte r; 0..2)
52 		foreach (ubyte g; 0..2)
53 		foreach (ubyte b; 0..2)
54 		pixels ~= Renderer.Pixel(300 + r*3 + b*12, 100 + g*3, BGRX(cast(ubyte)(r*255), cast(ubyte)(g*255), cast(ubyte)(b*255)));
55 	}
56 
57 	void updateFPS(string fps)
58 	{
59 		shell.setCaption((useOpenGL ? "SDL/OpenGL" : "SDL/Software") ~ " - " ~ fps);
60 	}
61 
62 	override void render(Renderer s)
63 	{
64 		fps.tick(&updateFPS);
65 
66 		//pixels ~= Renderer.Pixel(uniform(0, s.width), uniform(0, s.height), BGRX(uniform!ubyte(), uniform!ubyte(), uniform!ubyte()));
67 		s.clear();
68 		s.putPixels(pixels);
69 
70 		s.vline(300, 25,       75, BGRX(255, 0, 0));
71 		s. line(300, 25, 350,  75, BGRX(0, 255, 0));
72 		s.hline(300,     350,  25, BGRX(0, 0, 255));
73 
74 		foreach (uint i, img; imgs)
75 		{
76 			s.draw(i*128, 300, img, 0, 0, img.image.w.to!int, img.image.h.to!int);
77 			s.draw(
78 				i*128 + x+img.image.w/4  , 428 + img.image.h/4  ,
79 				i*128 + x+img.image.w/4*3, 428 + img.image.h/4*3,
80 				img, 0, 0, img.image.w.to!int, img.image.h.to!int);
81 		}
82 
83 		static int offset;
84 		offset++;
85 		auto w = imgT.image.crop(0, 0, imgT.image.w, imgT.image.h).toRef;
86 		for (int l=5; l>=0; l--)
87 		{
88 			checker(w, l, l%2 ? 0 : (offset%60==0?offset+0:offset) >> (3-l/2));
89 			w = w.crop(w.w/4, w.h/4, w.w/4*3, w.h/4*3).toRef;
90 		}
91 		imgT.textureVersion++;
92 		s.draw(400, 50, imgT, 0, 0, imgT.image.w.to!int, imgT.image.h.to!int);
93 	}
94 
95 	void checker(CANVAS)(CANVAS img, int level, int offset)
96 	{
97 		foreach (y; 0..img.h)
98 			foreach (x; 0..img.w)
99 				if (x==0 || y==0 || x==img.w-1 || y==img.h-1)
100 					img[x, y] = BGRX(255, 0, 0);
101 				else
102 				if (level && ((x+offset)/(1<<(level-1))+y/(1<<(level-1)))%2)
103 					img[x, y] = BGRX(255, 255, 255);
104 				else
105 					img[x, y] = BGRX(0, 0, 0);
106 	}
107 
108 	override int run(string[] args)
109 	{
110 		{
111 			enum W = 96, H = 96;
112 
113 			foreach (int i, ref img; imgs)
114 			{
115 				img = new ImageTextureSource;
116 				img.image.size(W, H);
117 				checker(img.image, i, 0);
118 			}
119 
120 			imgT = new ImageTextureSource;
121 			imgT.image.size(W*2, H*2);
122 		}
123 
124 		shell = new SDL2Shell(this);
125 		auto sdl2   = new SDL2Video();
126 	//	auto opengl = new SDLOpenGLVideo();
127 	//	opengl.aa = false;
128 
129 		timer = new SDLTimer();
130 		//timer = new ThreadTimer();
131 		timer.setInterval(AppCallback({ x += dx; y += dy; }), 10);
132 
133 		do
134 		{
135 			switching = false;
136 	//		useOpenGL = !useOpenGL;
137 	//		shell.video = useOpenGL ? opengl : sdl;
138 			shell.video = sdl2;
139 			updateFPS("?");
140 			shell.run();
141 		} while (switching);
142 		sdl2.shutdown();
143 	//	opengl.shutdown();
144 		return 0;
145 	}
146 
147 	override void handleKeyDown(Key key, dchar character)
148 	{
149 		switch (key)
150 		{
151 		case Key.space:
152 			switching = true;
153 			goto case;
154 		case Key.esc:
155 			shell.quit();
156 			break;
157 		case Key.left : dx = -DELTA; break;
158 		case Key.right: dx = +DELTA; break;
159 		case Key.up   : dy = -DELTA; break;
160 		case Key.down : dy = +DELTA; break;
161 		default:
162 			break;
163 		}
164 	}
165 
166 	override void handleKeyUp(Key key)
167 	{
168 		switch (key)
169 		{
170 		case Key.left : dx = 0f; break;
171 		case Key.right: dx = 0f; break;
172 		case Key.up   : dy = 0f; break;
173 		case Key.down : dy = 0f; break;
174 		default:
175 			break;
176 		}
177 	}
178 
179 	override void handleQuit()
180 	{
181 		shell.quit();
182 	}
183 }
184 
185 shared static this()
186 {
187 	createApplication!MyApplication();
188 }