1 #include <stdio.h>
2 #include "agg_basics.h"
3 #include "agg_rendering_buffer.h"
4 #include "agg_rasterizer_scanline_aa.h"
5 #include "agg_scanline_u.h"
6 #include "agg_scanline_p.h"
7 #include "agg_renderer_scanline.h"
8 #include "agg_span_allocator.h"
9 #include "agg_span_gouraud_rgba.h"
10 #include "agg_span_gouraud_gray.h"
11 #include "agg_span_solid.h"
12 #include "platform/agg_platform_support.h"
13
14 #include "ctrl/agg_slider_ctrl.h"
15
16
17 //#define AGG_GRAY8
18 #define AGG_BGR24
19 //#define AGG_RGB24
20 //#define AGG_BGRA32
21 //#define AGG_RGBA32
22 //#define AGG_ARGB32
23 //#define AGG_ABGR32
24 //#define AGG_RGB565
25 //#define AGG_RGB555
26 #include "pixel_formats.h"
27
28 enum flip_y_e { flip_y = true };
29
30
31 #include "agg_math.h"
32 #include "agg_dda_line.h"
33
34
35 class the_application : public agg::platform_support
36 {
37 double m_x[3];
38 double m_y[3];
39 double m_dx;
40 double m_dy;
41 int m_idx;
42
43 agg::slider_ctrl<agg::rgba> m_dilation;
44 agg::slider_ctrl<agg::rgba> m_gamma;
45 agg::slider_ctrl<agg::rgba> m_alpha;
46
47
48 public:
the_application(agg::pix_format_e format,bool flip_y)49 the_application(agg::pix_format_e format, bool flip_y) :
50 agg::platform_support(format, flip_y),
51 m_idx(-1),
52 m_dilation(5, 5, 400-5, 11, !flip_y),
53 m_gamma (5, 5+15, 400-5, 11+15, !flip_y),
54 m_alpha (5, 5+30, 400-5, 11+30, !flip_y)
55
56 {
57 m_x[0] = 57; m_y[0] = 60;
58 m_x[1] = 369; m_y[1] = 170;
59 m_x[2] = 143; m_y[2] = 310;
60
61 add_ctrl(m_dilation);
62 add_ctrl(m_gamma);
63 add_ctrl(m_alpha);
64
65 m_dilation.label("Dilation=%3.2f");
66 m_gamma.label("Linear gamma=%3.2f");
67 m_alpha.label("Opacity=%3.2f");
68
69 m_dilation.value(0.175);
70 m_gamma.value(0.809);
71 m_alpha.value(1.0);
72 }
73
74
75 template<class Scanline, class Ras>
render_gouraud(Scanline & sl,Ras & ras)76 void render_gouraud(Scanline& sl, Ras& ras)
77 {
78 double alpha = m_alpha.value();
79 double brc = 1;
80
81 typedef agg::renderer_base<pixfmt> base_ren_type;
82 #ifdef AGG_GRAY8
83 typedef agg::span_gouraud_gray<color_type> span_gen_type;
84 #else
85 typedef agg::span_gouraud_rgba<color_type> span_gen_type;
86 #endif
87 typedef agg::span_allocator<color_type> span_alloc_type;
88
89 pixfmt pf(rbuf_window());
90 base_ren_type ren_base(pf);
91
92 span_alloc_type span_alloc;
93 span_gen_type span_gen;
94
95 ras.gamma(agg::gamma_linear(0.0, m_gamma.value()));
96
97 double d = m_dilation.value();
98
99 // Single triangle
100 //span_gen.colors(agg::rgba(1, 0, 0, alpha),
101 // agg::rgba(0, 1, 0, alpha),
102 // agg::rgba(0, 0, 1, alpha));
103 //span_gen.triangle(m_x[0], m_y[0], m_x[1], m_y[1], m_x[2], m_y[2], d);
104 //ras.add_path(span_gen);
105 //agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
106
107
108 // Six triangles
109 double xc = (m_x[0] + m_x[1] + m_x[2]) / 3.0;
110 double yc = (m_y[0] + m_y[1] + m_y[2]) / 3.0;
111
112 double x1 = (m_x[1] + m_x[0]) / 2 - (xc - (m_x[1] + m_x[0]) / 2);
113 double y1 = (m_y[1] + m_y[0]) / 2 - (yc - (m_y[1] + m_y[0]) / 2);
114
115 double x2 = (m_x[2] + m_x[1]) / 2 - (xc - (m_x[2] + m_x[1]) / 2);
116 double y2 = (m_y[2] + m_y[1]) / 2 - (yc - (m_y[2] + m_y[1]) / 2);
117
118 double x3 = (m_x[0] + m_x[2]) / 2 - (xc - (m_x[0] + m_x[2]) / 2);
119 double y3 = (m_y[0] + m_y[2]) / 2 - (yc - (m_y[0] + m_y[2]) / 2);
120
121 span_gen.colors(agg::rgba(1, 0, 0, alpha),
122 agg::rgba(0, 1, 0, alpha),
123 agg::rgba(brc, brc, brc, alpha));
124 span_gen.triangle(m_x[0], m_y[0], m_x[1], m_y[1], xc, yc, d);
125 ras.add_path(span_gen);
126 agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
127
128
129 span_gen.colors(agg::rgba(0, 1, 0, alpha),
130 agg::rgba(0, 0, 1, alpha),
131 agg::rgba(brc, brc, brc, alpha));
132 span_gen.triangle(m_x[1], m_y[1], m_x[2], m_y[2], xc, yc, d);
133 ras.add_path(span_gen);
134 agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
135
136
137 span_gen.colors(agg::rgba(0, 0, 1, alpha),
138 agg::rgba(1, 0, 0, alpha),
139 agg::rgba(brc, brc, brc, alpha));
140 span_gen.triangle(m_x[2], m_y[2], m_x[0], m_y[0], xc, yc, d);
141 ras.add_path(span_gen);
142 agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
143
144
145 brc = 1-brc;
146 span_gen.colors(agg::rgba(1, 0, 0, alpha),
147 agg::rgba(0, 1, 0, alpha),
148 agg::rgba(brc, brc, brc, alpha));
149 span_gen.triangle(m_x[0], m_y[0], m_x[1], m_y[1], x1, y1, d);
150 ras.add_path(span_gen);
151 agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
152
153
154 span_gen.colors(agg::rgba(0, 1, 0, alpha),
155 agg::rgba(0, 0, 1, alpha),
156 agg::rgba(brc, brc, brc, alpha));
157 span_gen.triangle(m_x[1], m_y[1], m_x[2], m_y[2], x2, y2, d);
158 ras.add_path(span_gen);
159 agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
160
161
162 span_gen.colors(agg::rgba(0, 0, 1, alpha),
163 agg::rgba(1, 0, 0, alpha),
164 agg::rgba(brc, brc, brc, alpha));
165 span_gen.triangle(m_x[2], m_y[2], m_x[0], m_y[0], x3, y3, d);
166 ras.add_path(span_gen);
167 agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
168 }
169
170
171
172
173
174
175
176
on_draw()177 virtual void on_draw()
178 {
179 typedef agg::renderer_base<pixfmt> base_ren_type;
180
181 pixfmt pf(rbuf_window());
182 base_ren_type ren_base(pf);
183 ren_base.clear(agg::rgba(1,1,1));
184
185 agg::scanline_u8 sl;
186 agg::rasterizer_scanline_aa<> ras;
187
188 render_gouraud(sl, ras);
189
190 ras.gamma(agg::gamma_none());
191 agg::render_ctrl(ras, sl, ren_base, m_dilation);
192 agg::render_ctrl(ras, sl, ren_base, m_gamma);
193 agg::render_ctrl(ras, sl, ren_base, m_alpha);
194 }
195
196
on_mouse_button_down(int x,int y,unsigned flags)197 virtual void on_mouse_button_down(int x, int y, unsigned flags)
198 {
199 unsigned i;
200 if(flags & agg::mouse_right)
201 {
202 agg::scanline_u8 sl;
203 agg::rasterizer_scanline_aa<> ras;
204 start_timer();
205 for(i = 0; i < 100; i++)
206 {
207 render_gouraud(sl, ras);
208 }
209 char buf[100];
210 sprintf(buf, "Time=%2.2f ms", elapsed_time());
211 message(buf);
212 }
213
214 if(flags & agg::mouse_left)
215 {
216 for (i = 0; i < 3; i++)
217 {
218 if(sqrt( (x-m_x[i]) * (x-m_x[i]) + (y-m_y[i]) * (y-m_y[i]) ) < 10.0)
219 {
220 m_dx = x - m_x[i];
221 m_dy = y - m_y[i];
222 m_idx = i;
223 break;
224 }
225 }
226 if(i == 3)
227 {
228 if(agg::point_in_triangle(m_x[0], m_y[0],
229 m_x[1], m_y[1],
230 m_x[2], m_y[2],
231 x, y))
232 {
233 m_dx = x - m_x[0];
234 m_dy = y - m_y[0];
235 m_idx = 3;
236 }
237
238 }
239 }
240 }
241
242
on_mouse_move(int x,int y,unsigned flags)243 virtual void on_mouse_move(int x, int y, unsigned flags)
244 {
245 if(flags & agg::mouse_left)
246 {
247 if(m_idx == 3)
248 {
249 double dx = x - m_dx;
250 double dy = y - m_dy;
251 m_x[1] -= m_x[0] - dx;
252 m_y[1] -= m_y[0] - dy;
253 m_x[2] -= m_x[0] - dx;
254 m_y[2] -= m_y[0] - dy;
255 m_x[0] = dx;
256 m_y[0] = dy;
257 force_redraw();
258 return;
259 }
260
261 if(m_idx >= 0)
262 {
263 m_x[m_idx] = x - m_dx;
264 m_y[m_idx] = y - m_dy;
265 force_redraw();
266 }
267 }
268 else
269 {
270 on_mouse_button_up(x, y, flags);
271 }
272 }
273
on_mouse_button_up(int x,int y,unsigned flags)274 virtual void on_mouse_button_up(int x, int y, unsigned flags)
275 {
276 m_idx = -1;
277 }
278
279
on_key(int x,int y,unsigned key,unsigned flags)280 virtual void on_key(int x, int y, unsigned key, unsigned flags)
281 {
282 double dx = 0;
283 double dy = 0;
284 switch(key)
285 {
286 case agg::key_left: dx = -0.1; break;
287 case agg::key_right: dx = 0.1; break;
288 case agg::key_up: dy = 0.1; break;
289 case agg::key_down: dy = -0.1; break;
290 }
291 m_x[0] += dx;
292 m_y[0] += dy;
293 m_x[1] += dx;
294 m_y[1] += dy;
295 force_redraw();
296 }
297
298
299 };
300
301
agg_main(int argc,char * argv[])302 int agg_main(int argc, char* argv[])
303 {
304 the_application app(pix_format, flip_y);
305 app.caption("AGG Example. Gouraud Shading");
306
307 if(app.init(400, 320, agg::window_resize))
308 {
309 return app.run();
310 }
311 return 1;
312 }
313
314
315