2 * Copyright 2011, Blender Foundation.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include "integrator.h"
25 #include "util_algorithm.h"
26 #include "util_foreach.h"
32 static bool compare_pass_order(const Pass& a, const Pass& b)
34 if(a.components == b.components)
35 return (a.type < b.type);
36 return (a.components > b.components);
39 void Pass::add(PassType type, vector<Pass>& passes)
45 pass.exposure = false;
69 case PASS_MATERIAL_ID:
73 case PASS_DIFFUSE_COLOR:
76 case PASS_GLOSSY_COLOR:
79 case PASS_TRANSMISSION_COLOR:
82 case PASS_DIFFUSE_INDIRECT:
86 case PASS_GLOSSY_INDIRECT:
90 case PASS_TRANSMISSION_INDIRECT:
94 case PASS_DIFFUSE_DIRECT:
98 case PASS_GLOSSY_DIRECT:
100 pass.exposure = true;
102 case PASS_TRANSMISSION_DIRECT:
104 pass.exposure = true;
109 pass.exposure = true;
111 case PASS_BACKGROUND:
113 pass.exposure = true;
117 pass.exposure = true;
121 passes.push_back(pass);
123 /* order from by components, to ensure alignment so passes with size 4
124 come first and then passes with size 1 */
125 sort(passes.begin(), passes.end(), compare_pass_order);
128 bool Pass::equals(const vector<Pass>& A, const vector<Pass>& B)
130 if(A.size() != B.size())
133 for(int i = 0; i < A.size(); i++)
134 if(A[i].type != B[i].type)
145 Pass::add(PASS_COMBINED, passes);
153 void Film::device_update(Device *device, DeviceScene *dscene)
158 KernelFilm *kfilm = &dscene->data.film;
161 kfilm->exposure = exposure;
162 kfilm->pass_flag = 0;
163 kfilm->pass_stride = 0;
164 kfilm->use_light_pass = 0;
166 foreach(Pass& pass, passes) {
167 kfilm->pass_flag |= pass.type;
171 kfilm->pass_combined = kfilm->pass_stride;
174 kfilm->pass_depth = kfilm->pass_stride;
177 kfilm->pass_normal = kfilm->pass_stride;
180 kfilm->pass_uv = kfilm->pass_stride;
183 kfilm->pass_object_id = kfilm->pass_stride;
185 case PASS_MATERIAL_ID:
186 kfilm->pass_material_id = kfilm->pass_stride;
188 case PASS_DIFFUSE_COLOR:
189 kfilm->pass_diffuse_color = kfilm->pass_stride;
190 kfilm->use_light_pass = 1;
192 case PASS_GLOSSY_COLOR:
193 kfilm->pass_glossy_color = kfilm->pass_stride;
194 kfilm->use_light_pass = 1;
196 case PASS_TRANSMISSION_COLOR:
197 kfilm->pass_transmission_color = kfilm->pass_stride;
198 kfilm->use_light_pass = 1;
200 case PASS_DIFFUSE_INDIRECT:
201 kfilm->pass_diffuse_indirect = kfilm->pass_stride;
202 kfilm->use_light_pass = 1;
204 case PASS_GLOSSY_INDIRECT:
205 kfilm->pass_glossy_indirect = kfilm->pass_stride;
206 kfilm->use_light_pass = 1;
208 case PASS_TRANSMISSION_INDIRECT:
209 kfilm->pass_transmission_indirect = kfilm->pass_stride;
210 kfilm->use_light_pass = 1;
212 case PASS_DIFFUSE_DIRECT:
213 kfilm->pass_diffuse_direct = kfilm->pass_stride;
214 kfilm->use_light_pass = 1;
216 case PASS_GLOSSY_DIRECT:
217 kfilm->pass_glossy_direct = kfilm->pass_stride;
218 kfilm->use_light_pass = 1;
220 case PASS_TRANSMISSION_DIRECT:
221 kfilm->pass_transmission_direct = kfilm->pass_stride;
222 kfilm->use_light_pass = 1;
226 kfilm->pass_emission = kfilm->pass_stride;
227 kfilm->use_light_pass = 1;
229 case PASS_BACKGROUND:
230 kfilm->pass_background = kfilm->pass_stride;
231 kfilm->use_light_pass = 1;
233 kfilm->pass_ao = kfilm->pass_stride;
234 kfilm->use_light_pass = 1;
239 kfilm->pass_stride += pass.components;
242 kfilm->pass_stride = align_up(kfilm->pass_stride, 4);
247 void Film::device_free(Device *device, DeviceScene *dscene)
251 bool Film::modified(const Film& film)
253 return !(exposure == film.exposure
254 && Pass::equals(passes, film.passes));
257 void Film::tag_update(Scene *scene)
259 scene->integrator->tag_update(scene);