Fix various compiler warnings.
[blender-staging.git] / source / blender / compositor / operations / COM_RenderLayersProg.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
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.
8  *
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.
13  *
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.
17  *
18  * Contributor: 
19  *              Jeroen Bakker 
20  *              Monique Dewanchand
21  */
22
23 #include "COM_RenderLayersProg.h"
24
25 #include "BLI_listbase.h"
26 #include "BKE_scene.h"
27 #include "DNA_scene_types.h"
28
29 extern "C" {
30 #  include "RE_pipeline.h"
31 #  include "RE_shader_ext.h"
32 #  include "RE_render_ext.h"
33 }
34
35 /* ******** Render Layers Base Prog ******** */
36
37 RenderLayersBaseProg::RenderLayersBaseProg(int renderpass, int elementsize) : NodeOperation()
38 {
39         this->m_renderpass = renderpass;
40         this->setScene(NULL);
41         this->m_inputBuffer = NULL;
42         this->m_elementsize = elementsize;
43         this->m_rd = NULL;
44 }
45
46
47 void RenderLayersBaseProg::initExecution()
48 {
49         Scene *scene = this->getScene();
50         Render *re = (scene) ? RE_GetRender(scene->id.name) : NULL;
51         RenderResult *rr = NULL;
52         
53         if (re)
54                 rr = RE_AcquireResultRead(re);
55         
56         if (rr) {
57                 SceneRenderLayer *srl = (SceneRenderLayer *)BLI_findlink(&scene->r.layers, getLayerId());
58                 if (srl) {
59
60                         RenderLayer *rl = RE_GetRenderLayer(rr, srl->name);
61                         if (rl) {
62                                 this->m_inputBuffer = RE_RenderLayerGetPass(rl, this->m_renderpass, this->m_viewName);
63                                 if (this->m_inputBuffer == NULL && this->m_renderpass == SCE_PASS_COMBINED) {
64                                         this->m_inputBuffer = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, this->m_viewName);
65                                 }
66                         }
67                 }
68         }
69         if (re) {
70                 RE_ReleaseResult(re);
71                 re = NULL;
72         }
73 }
74
75 void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, PixelSampler sampler)
76 {
77         unsigned int offset;
78         int width = this->getWidth(), height = this->getHeight();
79
80         switch (sampler) {
81                 case COM_PS_NEAREST: {
82                         int ix = x;
83                         int iy = y;
84                         if (ix < 0 || iy < 0 || ix >= width || iy >= height) {
85                                 if (this->m_elementsize == 1)
86                                         output[0] = 0.0f;
87                                 else if (this->m_elementsize == 3)
88                                         zero_v3(output);
89                                 else
90                                         zero_v4(output);
91                                 break;
92                                 
93                         }
94
95                         offset = (iy * width + ix) * this->m_elementsize;
96
97                         if (this->m_elementsize == 1)
98                                 output[0] = this->m_inputBuffer[offset];
99                         else if (this->m_elementsize == 3)
100                                 copy_v3_v3(output, &this->m_inputBuffer[offset]);
101                         else
102                                 copy_v4_v4(output, &this->m_inputBuffer[offset]);
103                         break;
104                 }
105
106                 case COM_PS_BILINEAR:
107                         BLI_bilinear_interpolation_fl(this->m_inputBuffer, output, width, height, this->m_elementsize, x, y);
108                         break;
109
110                 case COM_PS_BICUBIC:
111                         BLI_bicubic_interpolation_fl(this->m_inputBuffer, output, width, height, this->m_elementsize, x, y);
112                         break;
113         }
114 }
115
116 void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
117 {
118 #if 0
119         const RenderData *rd = this->m_rd;
120
121         int dx = 0, dy = 0;
122
123         if (rd->mode & R_BORDER && rd->mode & R_CROP) {
124                 /* see comment in executeRegion describing coordinate mapping,
125                  * here it simply goes other way around
126                  */
127                 int full_width  = rd->xsch * rd->size / 100;
128                 int full_height = rd->ysch * rd->size / 100;
129
130                 dx = rd->border.xmin * full_width - (full_width - this->getWidth()) / 2.0f;
131                 dy = rd->border.ymin * full_height - (full_height - this->getHeight()) / 2.0f;
132         }
133
134         int ix = x - dx;
135         int iy = y - dy;
136 #endif
137
138 #ifndef NDEBUG
139         {
140                 const DataType data_type = this->getOutputSocket()->getDataType();
141                 int actual_element_size = this->m_elementsize;
142                 int expected_element_size;
143                 if (data_type == COM_DT_VALUE) {
144                         expected_element_size = 1;
145                 }
146                 else if (data_type == COM_DT_VECTOR) {
147                         expected_element_size = 3;
148                 }
149                 else if (data_type == COM_DT_COLOR) {
150                         expected_element_size = 4;
151                 }
152                 else {
153                         expected_element_size = 0;
154                         BLI_assert(!"Something horribly wrong just happened");
155                 }
156                 BLI_assert(expected_element_size == actual_element_size);
157         }
158 #endif
159
160         if (this->m_inputBuffer == NULL) {
161                 int elemsize = this->m_elementsize;
162                 if (elemsize == 1) {
163                         output[0] = 0.0f;
164                 }
165                 else if (elemsize == 3) {
166                         zero_v3(output);
167                 }
168                 else {
169                         BLI_assert(elemsize == 4);
170                         zero_v4(output);
171                 }
172         }
173         else {
174                 doInterpolation(output, x, y, sampler);
175         }
176 }
177
178 void RenderLayersBaseProg::deinitExecution()
179 {
180         this->m_inputBuffer = NULL;
181 }
182
183 void RenderLayersBaseProg::determineResolution(unsigned int resolution[2], unsigned int /*preferredResolution*/[2])
184 {
185         Scene *sce = this->getScene();
186         Render *re = (sce) ? RE_GetRender(sce->id.name) : NULL;
187         RenderResult *rr = NULL;
188         
189         resolution[0] = 0;
190         resolution[1] = 0;
191         
192         if (re)
193                 rr = RE_AcquireResultRead(re);
194         
195         if (rr) {
196                 SceneRenderLayer *srl   = (SceneRenderLayer *)BLI_findlink(&sce->r.layers, getLayerId());
197                 if (srl) {
198                         RenderLayer *rl = RE_GetRenderLayer(rr, srl->name);
199                         if (rl) {
200                                 resolution[0] = rl->rectx;
201                                 resolution[1] = rl->recty;
202                         }
203                 }
204         }
205         
206         if (re)
207                 RE_ReleaseResult(re);
208
209 }
210
211 /* ******** Render Layers AO Operation ******** */
212
213 RenderLayersAOOperation::RenderLayersAOOperation() : RenderLayersBaseProg(SCE_PASS_AO, 3)
214 {
215         this->addOutputSocket(COM_DT_COLOR);
216 }
217
218
219 void RenderLayersAOOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
220 {
221         float *inputBuffer = this->getInputBuffer();
222         if (inputBuffer == NULL) {
223                 zero_v3(output);
224         }
225         else {
226                 doInterpolation(output, x, y, sampler);
227         }
228         output[3] = 1.0f;
229 }
230
231 /* ******** Render Layers Alpha Operation ******** */
232
233 RenderLayersAlphaProg::RenderLayersAlphaProg() : RenderLayersBaseProg(SCE_PASS_COMBINED, 4)
234 {
235         this->addOutputSocket(COM_DT_VALUE);
236 }
237
238 void RenderLayersAlphaProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
239 {
240         float *inputBuffer = this->getInputBuffer();
241
242         if (inputBuffer == NULL) {
243                 output[0] = 0.0f;
244         }
245         else {
246                 float temp[4];
247                 doInterpolation(temp, x, y, sampler);
248                 output[0] = temp[3];
249         }
250 }
251
252 /* ******** Render Layers Color Operation ******** */
253
254 RenderLayersColorOperation::RenderLayersColorOperation() : RenderLayersBaseProg(SCE_PASS_RGBA, 4)
255 {
256         this->addOutputSocket(COM_DT_COLOR);
257 }
258
259 /* ******** Render Layers Cycles Operation ******** */
260
261 RenderLayersCyclesOperation::RenderLayersCyclesOperation(int pass) : RenderLayersBaseProg(pass, 3)
262 {
263         this->addOutputSocket(COM_DT_VECTOR);
264 }
265
266 /* ******** Render Layers Depth Operation ******** */
267
268 RenderLayersDepthProg::RenderLayersDepthProg() : RenderLayersBaseProg(SCE_PASS_Z, 1)
269 {
270         this->addOutputSocket(COM_DT_VALUE);
271 }
272
273 void RenderLayersDepthProg::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/)
274 {
275         int ix = x;
276         int iy = y;
277         float *inputBuffer = this->getInputBuffer();
278
279         if (inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) {
280                 output[0] = 0.0f;
281         }
282         else {
283                 unsigned int offset = (iy * this->getWidth() + ix);
284                 output[0] = inputBuffer[offset];
285         }
286 }
287
288 /* ******** Render Layers Diffuse Operation ******** */
289
290 RenderLayersDiffuseOperation::RenderLayersDiffuseOperation() : RenderLayersBaseProg(SCE_PASS_DIFFUSE, 3)
291 {
292         this->addOutputSocket(COM_DT_VECTOR);
293 }
294
295 /* ******** Render Layers Emit Operation ******** */
296
297 RenderLayersEmitOperation::RenderLayersEmitOperation() : RenderLayersBaseProg(SCE_PASS_EMIT, 3)
298 {
299         this->addOutputSocket(COM_DT_VECTOR);
300 }
301
302 /* ******** Render Layers Environment Operation ******** */
303
304 RenderLayersEnvironmentOperation::RenderLayersEnvironmentOperation() : RenderLayersBaseProg(SCE_PASS_ENVIRONMENT, 3)
305 {
306         this->addOutputSocket(COM_DT_VECTOR);
307 }
308
309 /* ******** Render Layers Image Operation ******** */
310
311 RenderLayersColorProg::RenderLayersColorProg() : RenderLayersBaseProg(SCE_PASS_COMBINED, 4)
312 {
313         this->addOutputSocket(COM_DT_COLOR);
314 }
315
316 /* ******** Render Layers Indirect Operation ******** */
317
318 RenderLayersIndirectOperation::RenderLayersIndirectOperation() : RenderLayersBaseProg(SCE_PASS_INDIRECT, 3)
319 {
320         this->addOutputSocket(COM_DT_VECTOR);
321 }
322
323 /* ******** Render Layers Material Index Operation ******** */
324
325 RenderLayersMaterialIndexOperation::RenderLayersMaterialIndexOperation() : RenderLayersBaseProg(SCE_PASS_INDEXMA, 1)
326 {
327         this->addOutputSocket(COM_DT_VALUE);
328 }
329
330 /* ******** Render Layers Mist Operation ******** */
331
332 RenderLayersMistOperation::RenderLayersMistOperation() : RenderLayersBaseProg(SCE_PASS_MIST, 1)
333 {
334         this->addOutputSocket(COM_DT_VALUE);
335 }
336
337 /* ******** Render Layers Normal Operation ******** */
338
339 RenderLayersNormalOperation::RenderLayersNormalOperation() : RenderLayersBaseProg(SCE_PASS_NORMAL, 3)
340 {
341         this->addOutputSocket(COM_DT_VECTOR);
342 }
343
344 /* ******** Render Layers Object Index Operation ******** */
345
346 RenderLayersObjectIndexOperation::RenderLayersObjectIndexOperation() : RenderLayersBaseProg(SCE_PASS_INDEXOB, 1)
347 {
348         this->addOutputSocket(COM_DT_VALUE);
349 }
350
351 /* ******** Render Layers Reflection Operation ******** */
352
353 RenderLayersReflectionOperation::RenderLayersReflectionOperation() : RenderLayersBaseProg(SCE_PASS_REFLECT, 3)
354 {
355         this->addOutputSocket(COM_DT_VECTOR);
356 }
357
358 /* ******** Render Layers Refraction Operation ******** */
359
360 RenderLayersRefractionOperation::RenderLayersRefractionOperation() : RenderLayersBaseProg(SCE_PASS_REFRACT, 3)
361 {
362         this->addOutputSocket(COM_DT_VECTOR);
363 }
364
365 /* ******** Render Layers Shadow Operation ******** */
366
367 RenderLayersShadowOperation::RenderLayersShadowOperation() : RenderLayersBaseProg(SCE_PASS_SHADOW, 3)
368 {
369         this->addOutputSocket(COM_DT_VECTOR);
370 }
371
372 /* ******** Render Layers Specular Operation ******** */
373
374 RenderLayersSpecularOperation::RenderLayersSpecularOperation() : RenderLayersBaseProg(SCE_PASS_SPEC, 3)
375 {
376         this->addOutputSocket(COM_DT_VECTOR);
377 }
378
379 /* ******** Render Layers Speed Operation ******** */
380
381 RenderLayersSpeedOperation::RenderLayersSpeedOperation() : RenderLayersBaseProg(SCE_PASS_VECTOR, 4)
382 {
383         this->addOutputSocket(COM_DT_COLOR);
384 }
385
386 /* ******** Render Layers UV Operation ******** */
387
388 RenderLayersUVOperation::RenderLayersUVOperation() : RenderLayersBaseProg(SCE_PASS_UV, 3)
389 {
390         this->addOutputSocket(COM_DT_VECTOR);
391 }
392
393 /* ******** Debug Render Layers Cycles Operation ******** */
394
395 #ifdef WITH_CYCLES_DEBUG
396
397 RenderLayersCyclesDebugOperation::RenderLayersCyclesDebugOperation(
398         int pass,
399         int debug_pass_type)
400         : RenderLayersBaseProg(pass, RE_debug_pass_num_channels_get(debug_pass_type))
401 {
402         switch (m_elementsize) {
403                 case 1:
404                         this->addOutputSocket(COM_DT_VALUE);
405                         break;
406                 case 3:
407                         this->addOutputSocket(COM_DT_VECTOR);
408                         break;
409                 case 4:
410                         this->addOutputSocket(COM_DT_COLOR);
411                         break;
412                 default:
413                         BLI_assert(!"Unkown debug pass type element size.");
414         }
415 }
416
417 #endif