index 736055f32b96167d7836b3174ebbb1c5f084d9d2..32896712cb64c206acf5368cbd800957b67d90b8 100644 (file)
#include "display/nr-filter-diffuselighting.h"
#include "display/nr-filter-getalpha.h"
#include "display/nr-filter-slot.h"
+#include "display/nr-filter-units.h"
+#include "display/nr-filter-utils.h"
#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"
-#include "round.h"
namespace NR {
if ((inter) < 0) (inter) = 0; \
}while(0)
-int FilterDiffuseLighting::render(FilterSlot &slot, Matrix const &trans) {
- NRPixBlock *in = filter_get_alpha(slot.get(_input));
+
+int FilterDiffuseLighting::render(FilterSlot &slot, FilterUnits const &units) {
+ NRPixBlock *in = slot.get(_input);
+ if (!in) {
+ g_warning("Missing source image for feDiffuseLighting (in=%d)", _input);
+ return 1;
+ }
+
NRPixBlock *out = new NRPixBlock;
int w = in->area.x1 - in->area.x0;
int dx = 1; //TODO setup
int dy = 1; //TODO setup
//surface scale
- //TODO for the time being, assumes userSpaceOnUse
+ Matrix trans = units.get_matrix_primitiveunits2pb();
gdouble ss = surfaceScale * trans[0];
gdouble kd = diffuseConstant; //diffuse lighting constant
compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
COMPUTE_INTER(inter, N, L, kd);
- data_o[j++] = (unsigned char) round(inter * LC[LIGHT_RED]);
- data_o[j++] = (unsigned char) round(inter * LC[LIGHT_GREEN]);
- data_o[j++] = (unsigned char) round(inter * LC[LIGHT_BLUE]);
+ 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++] = 255;
}
out->empty = FALSE;
PointLight *pl = new PointLight(light.point, lighting_color, trans);
pl->light_components(LC);
//TODO we need a reference to the filter to determine primitiveUnits
- //slot._arena_item->filter seems to be ok on simple examples
- //for now assume userSpaceOnUse
//if objectBoundingBox is used, use a different matrix for light_vector
+ // UPDATE: trans is now correct matrix from primitiveUnits to
+ // 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);
ss * (double) data_i[4*i+3]/ 255);
COMPUTE_INTER(inter, N, L, kd);
- data_o[j++] = (unsigned char) round(inter * LC[LIGHT_RED]);
- data_o[j++] = (unsigned char) round(inter * LC[LIGHT_GREEN]);
- data_o[j++] = (unsigned char) round(inter * LC[LIGHT_BLUE]);
+ 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++] = 255;
}
out->empty = FALSE;
{
SpotLight *sl = new SpotLight(light.spot, lighting_color, trans);
//TODO we need a reference to the filter to determine primitiveUnits
- //slot._arena_item->filter seems to be ok on simple examples
- //for now assume userSpaceOnUse
//if objectBoundingBox is used, use a different matrix for light_vector
+ // UPDATE: trans is now correct matrix from primitiveUnits to
+ // 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);
sl->light_components(LC, L);
COMPUTE_INTER(inter, N, L, kd);
- data_o[j++] = (unsigned char) round(inter * LC[LIGHT_RED]);
- data_o[j++] = (unsigned char) round(inter * LC[LIGHT_GREEN]);
- data_o[j++] = (unsigned char) round(inter * LC[LIGHT_BLUE]);
+ 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++] = 255;
}
out->empty = FALSE;
//finishing
slot.set(_output, out);
- delete in;
+ //nr_pixblock_release(in);
+ //delete in;
return 0;
}
+FilterTraits FilterDiffuseLighting::get_input_traits() {
+ return TRAIT_PARALLER;
+}
+
} /* namespace NR */
/*