code cleanup: use booleans and const's for operator vars.
[blender.git] / source / blender / compositor / operations / COM_RenderLayersBaseProg.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_RenderLayersBaseProg.h"
24
25 #include "BLI_listbase.h"
26 #include "DNA_scene_types.h"
27
28 extern "C" {
29         #include "RE_pipeline.h"
30         #include "RE_shader_ext.h"
31         #include "RE_render_ext.h"
32 }
33
34 RenderLayersBaseProg::RenderLayersBaseProg(int renderpass, int elementsize) : NodeOperation()
35 {
36         this->m_renderpass = renderpass;
37         this->setScene(NULL);
38         this->m_inputBuffer = NULL;
39         this->m_elementsize = elementsize;
40         this->m_rd = NULL;
41 }
42
43
44 void RenderLayersBaseProg::initExecution()
45 {
46         Scene *scene = this->getScene();
47         Render *re = (scene) ? RE_GetRender(scene->id.name) : NULL;
48         RenderResult *rr = NULL;
49         
50         if (re)
51                 rr = RE_AcquireResultRead(re);
52         
53         if (rr) {
54                 SceneRenderLayer *srl = (SceneRenderLayer *)BLI_findlink(&scene->r.layers, getLayerId());
55                 if (srl) {
56
57                         RenderLayer *rl = RE_GetRenderLayer(rr, srl->name);
58                         if (rl && rl->rectf) {
59                                 this->m_inputBuffer = RE_RenderLayerGetPass(rl, this->m_renderpass);
60
61                                 if (this->m_inputBuffer == NULL || this->m_renderpass == SCE_PASS_COMBINED) {
62                                         this->m_inputBuffer = rl->rectf;
63                                 }
64                         }
65                 }
66         }
67         if (re) {
68                 RE_ReleaseResult(re);
69                 re = NULL;
70         }
71 }
72
73 void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, PixelSampler sampler)
74 {
75         unsigned int offset;
76         int ix, iy;
77         int width = this->getWidth(), height = this->getHeight();
78
79         switch (sampler) {
80                 case COM_PS_NEAREST:
81                         ix = x;
82                         iy = y;
83                         offset = (iy * width + ix) * this->m_elementsize;
84
85                         if (this->m_elementsize == 1)
86                                 output[0] = this->m_inputBuffer[offset];
87                         else if (this->m_elementsize == 3)
88                                 copy_v3_v3(output, &this->m_inputBuffer[offset]);
89                         else
90                                 copy_v4_v4(output, &this->m_inputBuffer[offset]);
91
92                         break;
93
94                 case COM_PS_BILINEAR:
95                         BLI_bilinear_interpolation_fl(this->m_inputBuffer, output, width, height, this->m_elementsize, x, y);
96                         break;
97
98                 case COM_PS_BICUBIC:
99                         BLI_bicubic_interpolation_fl(this->m_inputBuffer, output, width, height, this->m_elementsize, x, y);
100                         break;
101         }
102
103         if (this->m_elementsize == 1) {
104                 output[1] = 0.0f;
105                 output[2] = 0.0f;
106                 output[3] = 0.0f;
107         }
108         else if (this->m_elementsize == 3) {
109                 output[3] = 1.0f;
110         }
111 }
112
113 void RenderLayersBaseProg::executePixel(float output[4], float x, float y, PixelSampler sampler)
114 {
115         const RenderData *rd = this->m_rd;
116
117         int dx = 0, dy = 0;
118
119         if (rd->mode & R_BORDER && rd->mode & R_CROP) {
120                 /* see comment in executeRegion describing coordinate mapping,
121                  * here it simply goes other way around
122                  */
123                 int full_width  = rd->xsch * rd->size / 100;
124                 int full_height = rd->ysch * rd->size / 100;
125
126                 dx = rd->border.xmin * full_width - (full_width - this->getWidth()) / 2.0f;
127                 dy = rd->border.ymin * full_height - (full_height - this->getHeight()) / 2.0f;
128         }
129
130         int ix = x - dx;
131         int iy = y - dy;
132
133         if (this->m_inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) {
134                 zero_v4(output);
135         }
136         else {
137                 doInterpolation(output, ix, iy, sampler);
138         }
139 }
140
141 void RenderLayersBaseProg::deinitExecution()
142 {
143         this->m_inputBuffer = NULL;
144 }
145
146 void RenderLayersBaseProg::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
147 {
148         Scene *sce = this->getScene();
149         Render *re = (sce) ? RE_GetRender(sce->id.name) : NULL;
150         RenderResult *rr = NULL;
151         
152         resolution[0] = 0;
153         resolution[1] = 0;
154         
155         if (re)
156                 rr = RE_AcquireResultRead(re);
157         
158         if (rr) {
159                 SceneRenderLayer *srl   = (SceneRenderLayer *)BLI_findlink(&sce->r.layers, getLayerId());
160                 if (srl) {
161                         RenderLayer *rl = RE_GetRenderLayer(rr, srl->name);
162                         if (rl && rl->rectf) {
163                                 resolution[0] = rl->rectx;
164                                 resolution[1] = rl->recty;
165                         }
166                 }
167         }
168         
169         if (re)
170                 RE_ReleaseResult(re);
171
172 }
173