2
* feDiffuseLighting renderer
5
* Niko Kiirala <niko@kiirala.com>
6
* Jean-Rene Reinhard <jr@komite.net>
8
* Copyright (C) 2007 authors
10
* Released under GNU GPL, read the file 'COPYING' for more information
13
#include <glib/gmessages.h>
15
#include "display/nr-3dutils.h"
16
#include "display/nr-arena-item.h"
17
#include "display/nr-filter-diffuselighting.h"
18
#include "display/nr-filter-getalpha.h"
19
#include "display/nr-filter-slot.h"
20
#include "display/nr-filter-units.h"
21
#include "display/nr-filter-utils.h"
22
#include "display/nr-light.h"
23
#include "libnr/nr-blit.h"
24
#include "libnr/nr-pixblock.h"
25
#include "libnr/nr-matrix.h"
26
#include "libnr/nr-rect-l.h"
31
FilterDiffuseLighting::FilterDiffuseLighting()
33
light_type = NO_LIGHT;
36
lighting_color = 0xffffffff;
39
FilterPrimitive * FilterDiffuseLighting::create() {
40
return new FilterDiffuseLighting();
43
FilterDiffuseLighting::~FilterDiffuseLighting()
46
#define COMPUTE_INTER(inter, N, L, kd) \
48
(inter) = (kd) * scalar_product((N), (L)); \
49
if ((inter) < 0) (inter) = 0; \
53
int FilterDiffuseLighting::render(FilterSlot &slot, FilterUnits const &units) {
54
NRPixBlock *in = slot.get(_input);
56
g_warning("Missing source image for feDiffuseLighting (in=%d)", _input);
60
NRPixBlock *out = new NRPixBlock;
62
int w = in->area.x1 - in->area.x0;
63
int h = in->area.y1 - in->area.y0;
67
//As long as FilterRes and kernel unit is not supported we hardcode the
69
int dx = 1; //TODO setup
70
int dy = 1; //TODO setup
72
Matrix trans = units.get_matrix_primitiveunits2pb();
73
gdouble ss = surfaceScale * trans[0];
74
gdouble kd = diffuseConstant; //diffuse lighting constant
79
nr_pixblock_setup_fast(out, in->mode,
80
in->area.x0, in->area.y0, in->area.x1, in->area.y1,
82
unsigned char *data_i = NR_PIXBLOCK_PX (in);
83
unsigned char *data_o = NR_PIXBLOCK_PX (out);
84
//No light, nothing to do
87
//the light vector is constant
89
DistantLight *dl = new DistantLight(light.distant, lighting_color);
91
dl->light_components(LC);
93
for (i = 0, j = 0; i < w*h; i++) {
94
compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
95
COMPUTE_INTER(inter, N, L, kd);
97
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_RED]);
98
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_GREEN]);
99
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_BLUE]);
108
PointLight *pl = new PointLight(light.point, lighting_color, trans);
109
pl->light_components(LC);
110
//TODO we need a reference to the filter to determine primitiveUnits
111
//if objectBoundingBox is used, use a different matrix for light_vector
112
// UPDATE: trans is now correct matrix from primitiveUnits to
113
// pixblock coordinates
115
for (i = 0, j = 0; i < w*h; i++) {
116
compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
120
ss * (double) data_i[4*i+3]/ 255);
121
COMPUTE_INTER(inter, N, L, kd);
123
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_RED]);
124
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_GREEN]);
125
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_BLUE]);
134
SpotLight *sl = new SpotLight(light.spot, lighting_color, trans);
135
//TODO we need a reference to the filter to determine primitiveUnits
136
//if objectBoundingBox is used, use a different matrix for light_vector
137
// UPDATE: trans is now correct matrix from primitiveUnits to
138
// pixblock coordinates
140
for (i = 0, j = 0; i < w*h; i++) {
141
compute_surface_normal(N, ss, in, i / w, i % w, dx, dy);
145
ss * (double) data_i[4*i+3]/ 255);
146
sl->light_components(LC, L);
147
COMPUTE_INTER(inter, N, L, kd);
149
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_RED]);
150
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_GREEN]);
151
data_o[j++] = CLAMP_D_TO_U8(inter * LC[LIGHT_BLUE]);
158
//else unknown light source, doing nothing
162
if (light_type != NO_LIGHT)
163
g_warning("unknown light source %d", light_type);
164
for (i = 0; i < w*h; i++) {
172
slot.set(_output, out);
173
//nr_pixblock_release(in);
178
FilterTraits FilterDiffuseLighting::get_input_traits() {
179
return TRAIT_PARALLER;
187
c-file-style:"stroustrup"
188
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
193
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :