the_application(agg::pix_format_e format, bool flip_y) : agg::platform_support(format, flip_y), m_gamma(5.0, 5.0, 340.0, 12.0, !flip_y), m_mouse_x(200), m_mouse_y(200) { m_gamma.range(0.5, 2.5); m_gamma.value(1.0); m_gamma.label("Gamma = %.3f"); add_ctrl(m_gamma); m_gamma.no_transform(); m_gamma_lut.gamma(m_gamma.value()); m_old_gamma = m_gamma.value(); build_gradient_lut(); }
virtual void on_draw() { pixfmt pixf(rbuf_window()); renderer_base rb(pixf); renderer_solid rs(rb); rb.clear(agg::rgba(1, 1, 1)); // When Gamma changes rebuild the gamma and gradient LUTs //------------------ if(m_old_gamma != m_gamma.value()) { m_gamma_lut.gamma(m_gamma.value()); build_gradient_lut(); m_old_gamma = m_gamma.value(); } // Gradient center. All gradient functions assume the // center being in the origin (0,0) and you can't // change it. But you can apply arbitrary transformations // to the gradient (see below). //------------------ double cx = initial_width() / 2; double cy = initial_height() / 2; double r = 100; // Focal center. Defined in the gradient coordinates, // that is, with respect to the origin (0,0) //------------------ double fx = m_mouse_x - cx; double fy = m_mouse_y - cy; gradient_func_type gradient_func(r, fx, fy); gradient_adaptor_type gradient_adaptor(gradient_func); agg::trans_affine gradient_mtx; // Making the affine matrix. Move to (cx,cy), // apply the resizing transformations and invert // the matrix. Gradients and images always assume the // inverse transformations. //------------------ gradient_mtx.translate(cx, cy); gradient_mtx *= trans_affine_resizing(); gradient_mtx.invert(); interpolator_type span_interpolator(gradient_mtx); span_gradient_type span_gradient(span_interpolator, gradient_adaptor, m_gradient_lut, 0, r); // Form the simple rectangle //------------------ m_rasterizer.reset(); m_rasterizer.move_to_d(0,0); m_rasterizer.line_to_d(width(), 0); m_rasterizer.line_to_d(width(), height()); m_rasterizer.line_to_d(0, height()); // Render the gradient to the whole screen and measure the time //------------------ start_timer(); agg::render_scanlines_aa(m_rasterizer, m_scanline, rb, m_alloc, span_gradient); double tm = elapsed_time(); // Draw the transformed circle that shows the gradient boundary //------------------ agg::ellipse e(cx, cy, r, r); agg::conv_stroke<agg::ellipse> estr(e); agg::conv_transform< agg::conv_stroke< agg::ellipse> > etrans(estr, trans_affine_resizing()); m_rasterizer.add_path(etrans); agg::render_scanlines_aa_solid(m_rasterizer, m_scanline, rb, agg::rgba(1,1,1)); // Show the gradient time //------------------ char buf[64]; agg::gsv_text t; t.size(10.0); agg::conv_stroke<agg::gsv_text> pt(t); pt.width(1.5); sprintf(buf, "%3.2f ms", tm); t.start_point(10.0, 35.0); t.text(buf); m_rasterizer.add_path(pt); agg::render_scanlines_aa_solid(m_rasterizer, m_scanline, rb, agg::rgba(0,0,0)); #if !LINEAR_RGB // Show the controls //------------------ agg::render_ctrl(m_rasterizer, m_scanline, rb, m_gamma); // Apply the inverse gamma to the whole buffer // (transform the colors to the perceptually uniform space) //------------------ pixf.apply_gamma_inv(m_gamma_lut); #endif }