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