diff --git a/src/display/nr-filter-specularlighting.cpp b/src/display/nr-filter-specularlighting.cpp
index 677f93dded1f355c39c02c59dc459aeecdaca389..6a6ce38a8199284dcd40ef6f27991b094d725e1b 100644 (file)
#include "display/nr-light.h"
#include "libnr/nr-blit.h"
#include "libnr/nr-pixblock.h"
-#include "libnr/nr-matrix.h"
#include "libnr/nr-rect-l.h"
#include "color.h"
-namespace NR {
+namespace Inkscape {
+namespace Filters {
FilterSpecularLighting::FilterSpecularLighting()
{
//to get the expected formula
#define COMPUTE_INTER(inter, H, N, ks, speculaExponent) \
do {\
- gdouble scal = scalar_product((N), (H)); \
+ gdouble scal = NR::scalar_product((N), (H)); \
if (scal <= 0)\
(inter) = 0;\
else\
@@ -80,13 +80,13 @@ int FilterSpecularLighting::render(FilterSlot &slot, FilterUnits const &units) {
int dx = 1; //TODO setup
int dy = 1; //TODO setup
//surface scale
- Matrix trans = units.get_matrix_primitiveunits2pb();
+ Geom::Matrix trans = units.get_matrix_primitiveunits2pb();
gdouble ss = surfaceScale * trans[0];
gdouble ks = specularConstant; //diffuse lighting constant
- Fvector L, N, LC, H;
+ NR::Fvector L, N, LC, H;
gdouble inter;
- nr_pixblock_setup_fast(out, in->mode,
+ nr_pixblock_setup_fast(out, NR_PIXBLOCK_MODE_R8G8B8A8N,
in->area.x0, in->area.y0, in->area.x1, in->area.y1,
true);
unsigned char *data_i = NR_PIXBLOCK_PX (in);
@@ -99,16 +99,17 @@ int FilterSpecularLighting::render(FilterSlot &slot, FilterUnits const &units) {
DistantLight *dl = new DistantLight(light.distant, lighting_color);
dl->light_vector(L);
dl->light_components(LC);
- normalized_sum(H, L, EYE_VECTOR);
+ NR::normalized_sum(H, L, NR::EYE_VECTOR);
//finish the work
for (i = 0, j = 0; i < w*h; i++) {
- compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
+ NR::compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
COMPUTE_INTER(inter, N, H, ks, specularExponent);
- data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_RED]);
+ data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_RED]); // CLAMP includes rounding!
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_GREEN]);
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_BLUE]);
- data_o[j++] = MAX(MAX(data_o[j-3], data_o[j-2]), data_o[j-1]);
+ data_o[j] = MAX(MAX(data_o[j-3], data_o[j-2]), data_o[j-1]);
+ ++j;
}
out->empty = FALSE;
delete dl;
@@ -124,18 +125,19 @@ int FilterSpecularLighting::render(FilterSlot &slot, FilterUnits const &units) {
// pixblock coordinates
//finish the work
for (i = 0, j = 0; i < w*h; i++) {
- compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
+ NR::compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
pl->light_vector(L,
i % w + x0,
i / w + y0,
ss * (double) data_i[4*i+3]/ 255);
- normalized_sum(H, L, EYE_VECTOR);
+ NR::normalized_sum(H, L, NR::EYE_VECTOR);
COMPUTE_INTER(inter, N, H, ks, specularExponent);
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_RED]);
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_GREEN]);
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_BLUE]);
- data_o[j++] = MAX(MAX(data_o[j-3], data_o[j-2]), data_o[j-1]);
+ data_o[j] = MAX(MAX(data_o[j-3], data_o[j-2]), data_o[j-1]);
+ ++j;
}
out->empty = FALSE;
delete pl;
@@ -150,19 +152,20 @@ int FilterSpecularLighting::render(FilterSlot &slot, FilterUnits const &units) {
// pixblock coordinates
//finish the work
for (i = 0, j = 0; i < w*h; i++) {
- compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
+ NR::compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
sl->light_vector(L,
i % w + x0,
i / w + y0,
ss * (double) data_i[4*i+3]/ 255);
sl->light_components(LC, L);
- normalized_sum(H, L, EYE_VECTOR);
+ NR::normalized_sum(H, L, NR::EYE_VECTOR);
COMPUTE_INTER(inter, N, H, ks, specularExponent);
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_RED]);
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_GREEN]);
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_BLUE]);
- data_o[j++] = MAX(MAX(data_o[j-3], data_o[j-2]), data_o[j-1]);
+ data_o[j] = MAX(MAX(data_o[j-3], data_o[j-2]), data_o[j-1]);
+ ++j;
}
out->empty = FALSE;
delete sl;
@@ -185,11 +188,25 @@ int FilterSpecularLighting::render(FilterSlot &slot, FilterUnits const &units) {
return 0;
}
+void FilterSpecularLighting::area_enlarge(NRRectL &area, Geom::Matrix const &trans)
+{
+ // TODO: support kernelUnitLength
+ double scalex = std::fabs(trans[0]) + std::fabs(trans[1]);
+ double scaley = std::fabs(trans[2]) + std::fabs(trans[3]);
+
+ //FIXME: no +2 should be there!... (noticable only for big scales at big zoom factor)
+ area.x0 -= (int)(scalex) + 2;
+ area.x1 += (int)(scalex) + 2;
+ area.y0 -= (int)(scaley) + 2;
+ area.y1 += (int)(scaley) + 2;
+}
+
FilterTraits FilterSpecularLighting::get_input_traits() {
return TRAIT_PARALLER;
}
-} /* namespace NR */
+} /* namespace Filters */
+} /* namespace Inkscape */
/*
Local Variables: