|
Blender
V2.59
|
00001 /* 00002 * $Id: CMP_zcombine.c 35237 2011-02-27 20:13:22Z jesterking $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2006 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): none yet. 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00035 #include "../CMP_util.h" 00036 00037 00038 /* **************** Z COMBINE ******************** */ 00039 /* lazy coder note: node->custom2 is abused to send signal */ 00040 static bNodeSocketType cmp_node_zcombine_in[]= { 00041 { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, 00042 { SOCK_VALUE, 1, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 10000.0f}, 00043 { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, 00044 { SOCK_VALUE, 1, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 10000.0f}, 00045 { -1, 0, "" } 00046 }; 00047 static bNodeSocketType cmp_node_zcombine_out[]= { 00048 { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, 00049 { SOCK_VALUE, 0, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 10000.0f}, 00050 { -1, 0, "" } 00051 }; 00052 00053 static void do_zcombine(bNode *node, float *out, float *src1, float *z1, float *src2, float *z2) 00054 { 00055 float alpha; 00056 float malpha; 00057 00058 if(*z1 <= *z2) { 00059 if (node->custom1) { 00060 // use alpha in combine operation 00061 alpha= src1[3]; 00062 malpha= 1.0f - alpha; 00063 out[0]= malpha*src2[0] + alpha*src1[0]; 00064 out[1]= malpha*src2[1] + alpha*src1[1]; 00065 out[2]= malpha*src2[2] + alpha*src1[2]; 00066 out[3]= malpha*src2[3] + alpha*src1[3]; 00067 } 00068 else { 00069 // do combination based solely on z value 00070 QUATCOPY(out, src1); 00071 } 00072 } 00073 else { 00074 if (node->custom1) { 00075 // use alpha in combine operation 00076 alpha= src2[3]; 00077 malpha= 1.0f - alpha; 00078 out[0]= malpha*src1[0] + alpha*src2[0]; 00079 out[1]= malpha*src1[1] + alpha*src2[1]; 00080 out[2]= malpha*src1[2] + alpha*src2[2]; 00081 out[3]= malpha*src1[3] + alpha*src2[3]; 00082 } 00083 else { 00084 // do combination based solely on z value 00085 QUATCOPY(out, src1); 00086 } 00087 00088 if(node->custom2) 00089 *z1= *z2; 00090 } 00091 } 00092 00093 static void do_zcombine_mask(bNode *node, float *out, float *z1, float *z2) 00094 { 00095 if(*z1 > *z2) { 00096 *out= 1.0f; 00097 if(node->custom2) 00098 *z1= *z2; 00099 } 00100 } 00101 00102 static void do_zcombine_add(bNode *node, float *out, float *col1, float *col2, float *acol) 00103 { 00104 float alpha; 00105 float malpha; 00106 00107 if (node->custom1) { 00108 // use alpha in combine operation, antialiased mask in used here just as hint for the z value 00109 if (*acol>0.0f) { 00110 alpha= col2[3]; 00111 malpha= 1.0f - alpha; 00112 00113 00114 out[0]= malpha*col1[0] + alpha*col2[0]; 00115 out[1]= malpha*col1[1] + alpha*col2[1]; 00116 out[2]= malpha*col1[2] + alpha*col2[2]; 00117 out[3]= malpha*col1[3] + alpha*col2[3]; 00118 } 00119 else { 00120 alpha= col1[3]; 00121 malpha= 1.0f - alpha; 00122 00123 00124 out[0]= malpha*col2[0] + alpha*col1[0]; 00125 out[1]= malpha*col2[1] + alpha*col1[1]; 00126 out[2]= malpha*col2[2] + alpha*col1[2]; 00127 out[3]= malpha*col2[3] + alpha*col1[3]; 00128 } 00129 } 00130 else { 00131 // do combination based solely on z value but with antialiased mask 00132 alpha = *acol; 00133 malpha= 1.0f - alpha; 00134 00135 out[0]= malpha*col1[0] + alpha*col2[0]; 00136 out[1]= malpha*col1[1] + alpha*col2[1]; 00137 out[2]= malpha*col1[2] + alpha*col2[2]; 00138 out[3]= malpha*col1[3] + alpha*col2[3]; 00139 } 00140 } 00141 00142 static void node_composit_exec_zcombine(void *data, bNode *node, bNodeStack **in, bNodeStack **out) 00143 { 00144 RenderData *rd= data; 00145 CompBuf *cbuf= in[0]->data; 00146 CompBuf *zbuf; 00147 00148 /* stack order in: col z col z */ 00149 /* stack order out: col z */ 00150 if(out[0]->hasoutput==0 && out[1]->hasoutput==0) 00151 return; 00152 00153 /* no input image; do nothing now */ 00154 if(in[0]->data==NULL) { 00155 return; 00156 } 00157 00158 if(out[1]->hasoutput) { 00159 /* copy or make a buffer for for the first z value, here we write result in */ 00160 if(in[1]->data) 00161 zbuf= dupalloc_compbuf(in[1]->data); 00162 else { 00163 float *zval; 00164 int tot= cbuf->x*cbuf->y; 00165 00166 zbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); 00167 for(zval= zbuf->rect; tot; tot--, zval++) 00168 *zval= in[1]->vec[0]; 00169 } 00170 /* lazy coder hack */ 00171 node->custom2= 1; 00172 out[1]->data= zbuf; 00173 } 00174 else { 00175 node->custom2= 0; 00176 zbuf= in[1]->data; 00177 } 00178 00179 if(rd->scemode & R_FULL_SAMPLE) { 00180 /* make output size of first input image */ 00181 CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs 00182 00183 composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, zbuf, in[1]->vec, in[2]->data, in[2]->vec, 00184 in[3]->data, in[3]->vec, do_zcombine, CB_RGBA, CB_VAL, CB_RGBA, CB_VAL); 00185 00186 out[0]->data= stackbuf; 00187 } 00188 else { 00189 /* make output size of first input image */ 00190 CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */ 00191 CompBuf *mbuf; 00192 float *fp; 00193 int x; 00194 char *aabuf; 00195 00196 00197 /* make a mask based on comparison, optionally write zvalue */ 00198 mbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); 00199 composit2_pixel_processor(node, mbuf, zbuf, in[1]->vec, in[3]->data, in[3]->vec, do_zcombine_mask, CB_VAL, CB_VAL); 00200 00201 /* convert to char */ 00202 aabuf= MEM_mallocN(cbuf->x*cbuf->y, "aa buf"); 00203 fp= mbuf->rect; 00204 for(x= cbuf->x*cbuf->y-1; x>=0; x--) 00205 if(fp[x]==0.0f) aabuf[x]= 0; 00206 else aabuf[x]= 255; 00207 00208 antialias_tagbuf(cbuf->x, cbuf->y, aabuf); 00209 00210 /* convert to float */ 00211 fp= mbuf->rect; 00212 for(x= cbuf->x*cbuf->y-1; x>=0; x--) 00213 if(aabuf[x]>1) 00214 fp[x]= (1.0f/255.0f)*(float)aabuf[x]; 00215 00216 composit3_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[2]->data, in[2]->vec, mbuf, NULL, 00217 do_zcombine_add, CB_RGBA, CB_RGBA, CB_VAL); 00218 /* free */ 00219 free_compbuf(mbuf); 00220 MEM_freeN(aabuf); 00221 00222 out[0]->data= stackbuf; 00223 } 00224 00225 } 00226 00227 void register_node_type_cmp_zcombine(ListBase *lb) 00228 { 00229 static bNodeType ntype; 00230 00231 node_type_base(&ntype, CMP_NODE_ZCOMBINE, "Z Combine", NODE_CLASS_OP_COLOR, NODE_OPTIONS, 00232 cmp_node_zcombine_in, cmp_node_zcombine_out); 00233 node_type_size(&ntype, 80, 40, 120); 00234 node_type_exec(&ntype, node_composit_exec_zcombine); 00235 00236 nodeRegisterType(lb, &ntype); 00237 } 00238