315 lines
8.7 KiB
C++
315 lines
8.7 KiB
C++
|
#include <stdio.h>
|
||
|
#include "agg_basics.h"
|
||
|
#include "agg_rendering_buffer.h"
|
||
|
#include "agg_rasterizer_scanline_aa.h"
|
||
|
#include "agg_scanline_u.h"
|
||
|
#include "agg_scanline_p.h"
|
||
|
#include "agg_renderer_scanline.h"
|
||
|
#include "agg_span_allocator.h"
|
||
|
#include "agg_span_gouraud_rgba.h"
|
||
|
#include "agg_span_gouraud_gray.h"
|
||
|
#include "agg_span_solid.h"
|
||
|
#include "platform/agg_platform_support.h"
|
||
|
|
||
|
#include "ctrl/agg_slider_ctrl.h"
|
||
|
|
||
|
|
||
|
//#define AGG_GRAY8
|
||
|
#define AGG_BGR24
|
||
|
//#define AGG_RGB24
|
||
|
//#define AGG_BGRA32
|
||
|
//#define AGG_RGBA32
|
||
|
//#define AGG_ARGB32
|
||
|
//#define AGG_ABGR32
|
||
|
//#define AGG_RGB565
|
||
|
//#define AGG_RGB555
|
||
|
#include "pixel_formats.h"
|
||
|
|
||
|
enum flip_y_e { flip_y = true };
|
||
|
|
||
|
|
||
|
#include "agg_math.h"
|
||
|
#include "agg_dda_line.h"
|
||
|
|
||
|
|
||
|
class the_application : public agg::platform_support
|
||
|
{
|
||
|
double m_x[3];
|
||
|
double m_y[3];
|
||
|
double m_dx;
|
||
|
double m_dy;
|
||
|
int m_idx;
|
||
|
|
||
|
agg::slider_ctrl<agg::rgba> m_dilation;
|
||
|
agg::slider_ctrl<agg::rgba> m_gamma;
|
||
|
agg::slider_ctrl<agg::rgba> m_alpha;
|
||
|
|
||
|
|
||
|
public:
|
||
|
the_application(agg::pix_format_e format, bool flip_y) :
|
||
|
agg::platform_support(format, flip_y),
|
||
|
m_idx(-1),
|
||
|
m_dilation(5, 5, 400-5, 11, !flip_y),
|
||
|
m_gamma (5, 5+15, 400-5, 11+15, !flip_y),
|
||
|
m_alpha (5, 5+30, 400-5, 11+30, !flip_y)
|
||
|
|
||
|
{
|
||
|
m_x[0] = 57; m_y[0] = 60;
|
||
|
m_x[1] = 369; m_y[1] = 170;
|
||
|
m_x[2] = 143; m_y[2] = 310;
|
||
|
|
||
|
add_ctrl(m_dilation);
|
||
|
add_ctrl(m_gamma);
|
||
|
add_ctrl(m_alpha);
|
||
|
|
||
|
m_dilation.label("Dilation=%3.2f");
|
||
|
m_gamma.label("Linear gamma=%3.2f");
|
||
|
m_alpha.label("Opacity=%3.2f");
|
||
|
|
||
|
m_dilation.value(0.175);
|
||
|
m_gamma.value(0.809);
|
||
|
m_alpha.value(1.0);
|
||
|
}
|
||
|
|
||
|
|
||
|
template<class Scanline, class Ras>
|
||
|
void render_gouraud(Scanline& sl, Ras& ras)
|
||
|
{
|
||
|
double alpha = m_alpha.value();
|
||
|
double brc = 1;
|
||
|
|
||
|
typedef agg::renderer_base<pixfmt> base_ren_type;
|
||
|
#ifdef AGG_GRAY8
|
||
|
typedef agg::span_gouraud_gray<color_type> span_gen_type;
|
||
|
#else
|
||
|
typedef agg::span_gouraud_rgba<color_type> span_gen_type;
|
||
|
#endif
|
||
|
typedef agg::span_allocator<color_type> span_alloc_type;
|
||
|
|
||
|
pixfmt pf(rbuf_window());
|
||
|
base_ren_type ren_base(pf);
|
||
|
|
||
|
span_alloc_type span_alloc;
|
||
|
span_gen_type span_gen;
|
||
|
|
||
|
ras.gamma(agg::gamma_linear(0.0, m_gamma.value()));
|
||
|
|
||
|
double d = m_dilation.value();
|
||
|
|
||
|
// Single triangle
|
||
|
//span_gen.colors(agg::rgba(1, 0, 0, alpha),
|
||
|
// agg::rgba(0, 1, 0, alpha),
|
||
|
// agg::rgba(0, 0, 1, alpha));
|
||
|
//span_gen.triangle(m_x[0], m_y[0], m_x[1], m_y[1], m_x[2], m_y[2], d);
|
||
|
//ras.add_path(span_gen);
|
||
|
//agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
|
||
|
|
||
|
|
||
|
// Six triangles
|
||
|
double xc = (m_x[0] + m_x[1] + m_x[2]) / 3.0;
|
||
|
double yc = (m_y[0] + m_y[1] + m_y[2]) / 3.0;
|
||
|
|
||
|
double x1 = (m_x[1] + m_x[0]) / 2 - (xc - (m_x[1] + m_x[0]) / 2);
|
||
|
double y1 = (m_y[1] + m_y[0]) / 2 - (yc - (m_y[1] + m_y[0]) / 2);
|
||
|
|
||
|
double x2 = (m_x[2] + m_x[1]) / 2 - (xc - (m_x[2] + m_x[1]) / 2);
|
||
|
double y2 = (m_y[2] + m_y[1]) / 2 - (yc - (m_y[2] + m_y[1]) / 2);
|
||
|
|
||
|
double x3 = (m_x[0] + m_x[2]) / 2 - (xc - (m_x[0] + m_x[2]) / 2);
|
||
|
double y3 = (m_y[0] + m_y[2]) / 2 - (yc - (m_y[0] + m_y[2]) / 2);
|
||
|
|
||
|
span_gen.colors(agg::rgba(1, 0, 0, alpha),
|
||
|
agg::rgba(0, 1, 0, alpha),
|
||
|
agg::rgba(brc, brc, brc, alpha));
|
||
|
span_gen.triangle(m_x[0], m_y[0], m_x[1], m_y[1], xc, yc, d);
|
||
|
ras.add_path(span_gen);
|
||
|
agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
|
||
|
|
||
|
|
||
|
span_gen.colors(agg::rgba(0, 1, 0, alpha),
|
||
|
agg::rgba(0, 0, 1, alpha),
|
||
|
agg::rgba(brc, brc, brc, alpha));
|
||
|
span_gen.triangle(m_x[1], m_y[1], m_x[2], m_y[2], xc, yc, d);
|
||
|
ras.add_path(span_gen);
|
||
|
agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
|
||
|
|
||
|
|
||
|
span_gen.colors(agg::rgba(0, 0, 1, alpha),
|
||
|
agg::rgba(1, 0, 0, alpha),
|
||
|
agg::rgba(brc, brc, brc, alpha));
|
||
|
span_gen.triangle(m_x[2], m_y[2], m_x[0], m_y[0], xc, yc, d);
|
||
|
ras.add_path(span_gen);
|
||
|
agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
|
||
|
|
||
|
|
||
|
brc = 1-brc;
|
||
|
span_gen.colors(agg::rgba(1, 0, 0, alpha),
|
||
|
agg::rgba(0, 1, 0, alpha),
|
||
|
agg::rgba(brc, brc, brc, alpha));
|
||
|
span_gen.triangle(m_x[0], m_y[0], m_x[1], m_y[1], x1, y1, d);
|
||
|
ras.add_path(span_gen);
|
||
|
agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
|
||
|
|
||
|
|
||
|
span_gen.colors(agg::rgba(0, 1, 0, alpha),
|
||
|
agg::rgba(0, 0, 1, alpha),
|
||
|
agg::rgba(brc, brc, brc, alpha));
|
||
|
span_gen.triangle(m_x[1], m_y[1], m_x[2], m_y[2], x2, y2, d);
|
||
|
ras.add_path(span_gen);
|
||
|
agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
|
||
|
|
||
|
|
||
|
span_gen.colors(agg::rgba(0, 0, 1, alpha),
|
||
|
agg::rgba(1, 0, 0, alpha),
|
||
|
agg::rgba(brc, brc, brc, alpha));
|
||
|
span_gen.triangle(m_x[2], m_y[2], m_x[0], m_y[0], x3, y3, d);
|
||
|
ras.add_path(span_gen);
|
||
|
agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
virtual void on_draw()
|
||
|
{
|
||
|
typedef agg::renderer_base<pixfmt> base_ren_type;
|
||
|
|
||
|
pixfmt pf(rbuf_window());
|
||
|
base_ren_type ren_base(pf);
|
||
|
ren_base.clear(agg::rgba(1,1,1));
|
||
|
|
||
|
agg::scanline_u8 sl;
|
||
|
agg::rasterizer_scanline_aa<> ras;
|
||
|
|
||
|
render_gouraud(sl, ras);
|
||
|
|
||
|
ras.gamma(agg::gamma_none());
|
||
|
agg::render_ctrl(ras, sl, ren_base, m_dilation);
|
||
|
agg::render_ctrl(ras, sl, ren_base, m_gamma);
|
||
|
agg::render_ctrl(ras, sl, ren_base, m_alpha);
|
||
|
}
|
||
|
|
||
|
|
||
|
virtual void on_mouse_button_down(int x, int y, unsigned flags)
|
||
|
{
|
||
|
unsigned i;
|
||
|
if(flags & agg::mouse_right)
|
||
|
{
|
||
|
agg::scanline_u8 sl;
|
||
|
agg::rasterizer_scanline_aa<> ras;
|
||
|
start_timer();
|
||
|
for(i = 0; i < 100; i++)
|
||
|
{
|
||
|
render_gouraud(sl, ras);
|
||
|
}
|
||
|
char buf[100];
|
||
|
sprintf(buf, "Time=%2.2f ms", elapsed_time());
|
||
|
message(buf);
|
||
|
}
|
||
|
|
||
|
if(flags & agg::mouse_left)
|
||
|
{
|
||
|
for (i = 0; i < 3; i++)
|
||
|
{
|
||
|
if(sqrt( (x-m_x[i]) * (x-m_x[i]) + (y-m_y[i]) * (y-m_y[i]) ) < 10.0)
|
||
|
{
|
||
|
m_dx = x - m_x[i];
|
||
|
m_dy = y - m_y[i];
|
||
|
m_idx = i;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if(i == 3)
|
||
|
{
|
||
|
if(agg::point_in_triangle(m_x[0], m_y[0],
|
||
|
m_x[1], m_y[1],
|
||
|
m_x[2], m_y[2],
|
||
|
x, y))
|
||
|
{
|
||
|
m_dx = x - m_x[0];
|
||
|
m_dy = y - m_y[0];
|
||
|
m_idx = 3;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
virtual void on_mouse_move(int x, int y, unsigned flags)
|
||
|
{
|
||
|
if(flags & agg::mouse_left)
|
||
|
{
|
||
|
if(m_idx == 3)
|
||
|
{
|
||
|
double dx = x - m_dx;
|
||
|
double dy = y - m_dy;
|
||
|
m_x[1] -= m_x[0] - dx;
|
||
|
m_y[1] -= m_y[0] - dy;
|
||
|
m_x[2] -= m_x[0] - dx;
|
||
|
m_y[2] -= m_y[0] - dy;
|
||
|
m_x[0] = dx;
|
||
|
m_y[0] = dy;
|
||
|
force_redraw();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if(m_idx >= 0)
|
||
|
{
|
||
|
m_x[m_idx] = x - m_dx;
|
||
|
m_y[m_idx] = y - m_dy;
|
||
|
force_redraw();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
on_mouse_button_up(x, y, flags);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
virtual void on_mouse_button_up(int x, int y, unsigned flags)
|
||
|
{
|
||
|
m_idx = -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
virtual void on_key(int x, int y, unsigned key, unsigned flags)
|
||
|
{
|
||
|
double dx = 0;
|
||
|
double dy = 0;
|
||
|
switch(key)
|
||
|
{
|
||
|
case agg::key_left: dx = -0.1; break;
|
||
|
case agg::key_right: dx = 0.1; break;
|
||
|
case agg::key_up: dy = 0.1; break;
|
||
|
case agg::key_down: dy = -0.1; break;
|
||
|
}
|
||
|
m_x[0] += dx;
|
||
|
m_y[0] += dy;
|
||
|
m_x[1] += dx;
|
||
|
m_y[1] += dy;
|
||
|
force_redraw();
|
||
|
}
|
||
|
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
int agg_main(int argc, char* argv[])
|
||
|
{
|
||
|
the_application app(pix_format, flip_y);
|
||
|
app.caption("AGG Example. Gouraud Shading");
|
||
|
|
||
|
if(app.init(400, 320, agg::window_resize))
|
||
|
{
|
||
|
return app.run();
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
|