4 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version. The Blender
10 * Foundation also sells licenses for use in proprietary software under
11 * the Blender License. See http://www.blender.org/BL/ for information
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24 * All rights reserved.
26 * The Original Code is: all of this file.
28 * Contributor(s): Hos, RPW.
30 * ***** END GPL/BL DUAL LICENSE BLOCK *****
33 /*---------------------------------------------------------------------------*/
35 /*---------------------------------------------------------------------------*/
41 #include "MTC_matrixops.h"
42 #include "MEM_guardedalloc.h"
44 #include "BKE_global.h"
46 #include "DNA_lamp_types.h"
47 #include "DNA_mesh_types.h"
49 #include "radio_types.h"
50 #include "radio.h" /* needs RG, some root data for radiosity */
53 #include "render_intern.h"
54 #include "RE_callbacks.h"
55 #include "old_zbuffer_types.h"
57 /* can be removed when the old renderer disappears */
58 #include "rendercore.h" /* shade_pixel and count_mask */
59 #include "pixelblending.h"
71 #define MIN2(x,y) ( (x)<(y) ? (x) : (y) )
72 /*-----------------------------------------------------------*/
73 /* Globals for this file */
74 /*-----------------------------------------------------------*/
76 extern float centLut[16];
77 extern char *centmask;
79 float *vlzp[32][3], labda[3][2], vez[400], *p[40];
81 float Zmulx; /* Half the screenwidth, in pixels. (used in render.c, */
83 float Zmuly; /* Half the screenheight, in pixels. (used in render.c,*/
85 float Zjitx; /* Jitter offset in x. When jitter is disabled, this */
86 /* should be 0.5. (used in render.c, zbuf.c) */
87 float Zjity; /* Jitter offset in y. When jitter is disabled, this */
88 /* should be 0.5. (used in render.c, zbuf.c) */
90 unsigned int Zvlnr, Zsample;
92 void (*zbuffunc)(float *, float *, float *);
93 void (*zbuflinefunc)(float *, float *);
95 APixstr *APixbuf; /* Zbuffer: linked list of face indices */
96 unsigned short *Acolrow; /* Zbuffer: colour buffer, one line high */
97 int *Arectz; /* Zbuffer: distance buffer, almost obsolete */
98 int Aminy; /* y value of first line in the accu buffer */
99 int Amaxy; /* y value of last line in the accu buffer */
101 APixstrMain apsmfirst;
102 short apsmteller = 0;
104 /*-----------------------------------------------------------*/
106 /*-----------------------------------------------------------*/
108 void fillrect(unsigned int *rect, int x, unsigned int y, unsigned int val)
110 unsigned int len,*drect;
121 /* ************* ACCUMULATION ZBUF ************ */
123 /*-APixstr---------------------(antialised pixel struct)------------------------------*/
125 APixstr *addpsmainA()
135 psm->next= MEM_mallocN(sizeof(APixstrMain), "addpsmainA");
139 psm->ps= MEM_callocN(4096*sizeof(APixstr),"pixstr");
147 APixstrMain *psm, *next;
157 if(psm!= &apsmfirst) MEM_freeN(psm);
166 APixstr *addpsA(void)
168 static APixstr *prev;
171 if((apsmteller & 4095)==0) prev= addpsmainA();
178 /* fills in color, with window coordinate, from Aminy->Amaxy */
179 void zbufinvulAc(float *v1, float *v2, float *v3)
181 APixstr *ap, *apofs, *apn;
182 double x0,y0,z0,x1,y1,z1,x2,y2,z2,xx1;
183 double zxd,zyd,zy0, tmp;
184 float *minv,*maxv,*midv;
186 int my0,my2,sn1,sn2,rectx,zd,*rectzofs;
187 int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2, mask;
192 minv=v1; midv=v2; maxv=v3;
194 else if(v1[1]<v3[1]) {
195 minv=v1; midv=v3; maxv=v2;
198 minv=v3; midv=v1; maxv=v2;
203 minv=v2; midv=v1; maxv=v3;
205 else if(v2[1]<v3[1]) {
206 minv=v2; midv=v3; maxv=v1;
209 minv=v3; midv=v2; maxv=v1;
213 if(minv[1] == maxv[1]) return; /* prevent 'zero' size faces */
217 omsl= floor(midv[1]);
219 if(my2<Aminy || my0> Amaxy) return;
221 if(my0<Aminy) my0= Aminy;
223 /* EDGES : LONGEST */
224 xx1= maxv[1]-minv[1];
225 if(xx1>2.0/65536.0) {
226 z0= (maxv[0]-minv[0])/xx1;
229 dx0= CLAMPIS(tmp, INT_MIN, INT_MAX);
231 tmp= 65536.0*(z0*(my2-minv[1])+minv[0]);
232 xs0= CLAMPIS(tmp, INT_MIN, INT_MAX);
236 xs0= 65536.0*(MIN2(minv[0],maxv[0]));
238 /* EDGES : THE TOP ONE */
239 xx1= maxv[1]-midv[1];
240 if(xx1>2.0/65536.0) {
241 z0= (maxv[0]-midv[0])/xx1;
244 dx1= CLAMPIS(tmp, INT_MIN, INT_MAX);
246 tmp= 65536.0*(z0*(my2-midv[1])+midv[0]);
247 xs1= CLAMPIS(tmp, INT_MIN, INT_MAX);
251 xs1= 65536.0*(MIN2(midv[0],maxv[0]));
253 /* EDGES : BOTTOM ONE */
254 xx1= midv[1]-minv[1];
255 if(xx1>2.0/65536.0) {
256 z0= (midv[0]-minv[0])/xx1;
259 dx2= CLAMPIS(tmp, INT_MIN, INT_MAX);
261 tmp= 65536.0*(z0*(omsl-minv[1])+minv[0]);
262 xs2= CLAMPIS(tmp, INT_MIN, INT_MAX);
266 xs2= 65536.0*(MIN2(minv[0],midv[0]));
281 if(midv[1]==maxv[1]) omsl= my2;
282 if(omsl<Aminy) omsl= Aminy-1; /* to make sure it does the first loop completely */
284 while (my2 > Amaxy) { /* my2 can be larger */
295 xx1= (x0*v1[0]+y0*v1[1])/z0+v1[2];
300 zd= (int)CLAMPIS(zxd, INT_MIN, INT_MAX);
302 /* start-offset in rect */
304 rectzofs= (int *)(Arectz+rectx*(my2-Aminy));
305 apofs= (APixbuf+ rectx*(my2-Aminy));
320 for(y=my2;y>omsl;y--) {
330 if(sn2>=rectx) sn2= rectx-1;
332 zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX);
342 while(apn) { /* loop unrolled */
343 if(apn->p[0]==0) {apn->p[0]= Zvlnr; apn->z[0]= zverg; apn->mask[0]= mask; break; }
344 if(apn->p[0]==Zvlnr) {apn->mask[0]|= mask; break; }
345 if(apn->p[1]==0) {apn->p[1]= Zvlnr; apn->z[1]= zverg; apn->mask[1]= mask; break; }
346 if(apn->p[1]==Zvlnr) {apn->mask[1]|= mask; break; }
347 if(apn->p[2]==0) {apn->p[2]= Zvlnr; apn->z[2]= zverg; apn->mask[2]= mask; break; }
348 if(apn->p[2]==Zvlnr) {apn->mask[2]|= mask; break; }
349 if(apn->p[3]==0) {apn->p[3]= Zvlnr; apn->z[3]= zverg; apn->mask[3]= mask; break; }
350 if(apn->p[3]==Zvlnr) {apn->mask[3]|= mask; break; }
351 if(apn->next==0) apn->next= addpsA();
388 if(sn2>=rectx) sn2= rectx-1;
390 zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX);
400 while(apn) { /* loop unrolled */
401 if(apn->p[0]==0) {apn->p[0]= Zvlnr; apn->z[0]= zverg; apn->mask[0]= mask; break; }
402 if(apn->p[0]==Zvlnr) {apn->mask[0]|= mask; break; }
403 if(apn->p[1]==0) {apn->p[1]= Zvlnr; apn->z[1]= zverg; apn->mask[1]= mask; break; }
404 if(apn->p[1]==Zvlnr) {apn->mask[1]|= mask; break; }
405 if(apn->p[2]==0) {apn->p[2]= Zvlnr; apn->z[2]= zverg; apn->mask[2]= mask; break; }
406 if(apn->p[2]==Zvlnr) {apn->mask[2]|= mask; break; }
407 if(apn->p[3]==0) {apn->p[3]= Zvlnr; apn->z[3]= zverg; apn->mask[3]= mask; break; }
408 if(apn->p[3]==Zvlnr) {apn->mask[3]|= mask; break; }
409 if(apn->next==0) apn->next= addpsA();
425 void zbuflineAc(float *vec1, float *vec2)
429 int start, end, x, y, oldx, oldy, ofs;
437 if(fabs(dx) > fabs(dy)) {
439 /* all lines from left to right */
440 if(vec1[0]<vec2[0]) {
451 end= start+floor(dx);
452 if(end>=R.rectx) end= R.rectx-1;
459 dz= (v2[2]-v1[2])/dx;
461 rectz= (unsigned int *)(Arectz+R.rectx*(oldy-Aminy) +start);
462 ap= (APixbuf+ R.rectx*(oldy-Aminy) +start);
465 if(dy<0) ofs= -R.rectx;
468 for(x= start; x<=end; x++, rectz++, ap++) {
477 if(x>=0 && y>=Aminy && y<=Amaxy) {
481 while(apn) { /* loop unrolled */
482 if(apn->p[0]==0) {apn->p[0]= Zvlnr; apn->z[0]= vergz; apn->mask[0]= mask; break; }
483 if(apn->p[0]==Zvlnr) {apn->mask[0]|= mask; break; }
484 if(apn->p[1]==0) {apn->p[1]= Zvlnr; apn->z[1]= vergz; apn->mask[1]= mask; break; }
485 if(apn->p[1]==Zvlnr) {apn->mask[1]|= mask; break; }
486 if(apn->p[2]==0) {apn->p[2]= Zvlnr; apn->z[2]= vergz; apn->mask[2]= mask; break; }
487 if(apn->p[2]==Zvlnr) {apn->mask[2]|= mask; break; }
488 if(apn->p[3]==0) {apn->p[3]= Zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; }
489 if(apn->p[3]==Zvlnr) {apn->mask[3]|= mask; break; }
490 if(apn->next==0) apn->next= addpsA();
503 /* all lines from top to bottom */
504 if(vec1[1]<vec2[1]) {
515 end= start+floor(dy);
517 if(start>Amaxy || end<Aminy) return;
519 if(end>Amaxy) end= Amaxy;
526 dz= (v2[2]-v1[2])/dy;
528 rectz= (unsigned int *)( Arectz+ (start-Aminy)*R.rectx+ oldx );
529 ap= (APixbuf+ R.rectx*(start-Aminy) +oldx);
535 for(y= start; y<=end; y++, rectz+=R.rectx, ap+=R.rectx) {
544 if(x>=0 && y>=Aminy && x<R.rectx) {
548 while(apn) { /* loop unrolled */
549 if(apn->p[0]==0) {apn->p[0]= Zvlnr; apn->z[0]= vergz; apn->mask[0]= mask; break; }
550 if(apn->p[0]==Zvlnr) {apn->mask[0]|= mask; break; }
551 if(apn->p[1]==0) {apn->p[1]= Zvlnr; apn->z[1]= vergz; apn->mask[1]= mask; break; }
552 if(apn->p[1]==Zvlnr) {apn->mask[1]|= mask; break; }
553 if(apn->p[2]==0) {apn->p[2]= Zvlnr; apn->z[2]= vergz; apn->mask[2]= mask; break; }
554 if(apn->p[2]==Zvlnr) {apn->mask[2]|= mask; break; }
555 if(apn->p[3]==0) {apn->p[3]= Zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; }
556 if(apn->p[3]==Zvlnr) {apn->mask[3]|= mask; break; }
557 if(apn->next==0) apn->next= addpsA();
572 /* ************* NORMAL ZBUFFER ************ */
574 void hoco_to_zco(float *zco, float *hoco)
579 zco[0]= Zmulx*(1.0+hoco[0]/deler)+ Zjitx;
580 zco[1]= Zmuly*(1.0+hoco[1]/deler)+ Zjity;
581 zco[2]= 0x7FFFFFFF *(hoco[2]/deler);
584 void zbufline(vec1, vec2)
587 unsigned int *rectz, *rectp;
588 int start, end, x, y, oldx, oldy, ofs;
596 if(fabs(dx) > fabs(dy)) {
598 /* all lines from left to right */
599 if(vec1[0]<vec2[0]) {
610 end= start+floor(dx);
611 if(end>=R.rectx) end= R.rectx-1;
617 dz= (v2[2]-v1[2])/dx;
619 rectz= R.rectz+ oldy*R.rectx+ start;
620 rectp= R.rectot+ oldy*R.rectx+ start;
622 if(dy<0) ofs= -R.rectx;
625 for(x= start; x<=end; x++, rectz++, rectp++) {
634 if(x>=0 && y>=0 && y<R.recty) {
646 /* all lines from top to bottom */
647 if(vec1[1]<vec2[1]) {
658 end= start+floor(dy);
660 if(end>=R.recty) end= R.recty-1;
666 dz= (v2[2]-v1[2])/dy;
668 rectz= R.rectz+ start*R.rectx+ oldx;
669 rectp= R.rectot+ start*R.rectx+ oldx;
674 for(y= start; y<=end; y++, rectz+=R.rectx, rectp+=R.rectx) {
683 if(x>=0 && y>=0 && x<R.rectx) {
697 void zbufclipwire(VlakRen *vlr)
699 float *f1, *f2, *f3, *f4= 0, deler;
700 int c1, c2, c3, c4, ec, and, or;
702 /* edgecode: 1= draw */
717 and= (c1 & c2 & c3 & c4);
718 or= (c1 | c2 | c3 | c4);
725 if(or) { /* not in the middle */
726 if(and) { /* out completely */
729 else { /* clipping */
734 if( clipline(vez, vez+4)) {
735 hoco_to_zco(vez, vez);
736 hoco_to_zco(vez+4, vez+4);
737 zbuflinefunc(vez, vez+4);
743 if( clipline(vez, vez+4)) {
744 hoco_to_zco(vez, vez);
745 hoco_to_zco(vez+4, vez+4);
746 zbuflinefunc(vez, vez+4);
753 if( clipline(vez, vez+4)) {
754 hoco_to_zco(vez, vez);
755 hoco_to_zco(vez+4, vez+4);
756 zbuflinefunc(vez, vez+4);
762 if( clipline(vez, vez+4)) {
763 hoco_to_zco(vez, vez);
764 hoco_to_zco(vez+4, vez+4);
765 zbuflinefunc(vez, vez+4);
773 if( clipline(vez, vez+4)) {
774 hoco_to_zco(vez, vez);
775 hoco_to_zco(vez+4, vez+4);
776 zbuflinefunc(vez, vez+4);
786 vez[0]= Zmulx*(1.0+f1[0]/deler)+ Zjitx;
787 vez[1]= Zmuly*(1.0+f1[1]/deler)+ Zjity;
788 vez[2]= 0x7FFFFFFF *(f1[2]/deler);
791 vez[4]= Zmulx*(1.0+f2[0]/deler)+ Zjitx;
792 vez[5]= Zmuly*(1.0+f2[1]/deler)+ Zjity;
793 vez[6]= 0x7FFFFFFF *(f2[2]/deler);
796 vez[8]= Zmulx*(1.0+f3[0]/deler)+ Zjitx;
797 vez[9]= Zmuly*(1.0+f3[1]/deler)+ Zjity;
798 vez[10]= 0x7FFFFFFF *(f3[2]/deler);
802 vez[12]= Zmulx*(1.0+f4[0]/deler)+ Zjitx;
803 vez[13]= Zmuly*(1.0+f4[1]/deler)+ Zjity;
804 vez[14]= 0x7FFFFFFF *(f4[2]/deler);
806 if(ec & ME_V3V4) zbuflinefunc(vez+8, vez+12);
807 if(ec & ME_V4V1) zbuflinefunc(vez+12, vez);
810 if(ec & ME_V3V1) zbuflinefunc(vez+8, vez);
813 if(ec & ME_V1V2) zbuflinefunc(vez, vez+4);
814 if(ec & ME_V2V3) zbuflinefunc(vez+4, vez+8);
820 void zbufinvulGLinv(v1,v2,v3)
822 /* fills in R.rectot the value of Zvlnr using R.rectz */
823 /* INVERSE Z COMPARISION: BACKSIDE GETS VISIBLE */
825 double x0,y0,z0,x1,y1,z1,x2,y2,z2,xx1;
826 double zxd,zyd,zy0,tmp;
827 float *minv,*maxv,*midv;
828 unsigned int *rectpofs,*rp;
829 int *rz,zverg,zvlak,x;
830 int my0,my2,sn1,sn2,rectx,zd,*rectzofs;
831 int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2;
836 minv=v1; midv=v2; maxv=v3;
838 else if(v1[1]<v3[1]) {
839 minv=v1; midv=v3; maxv=v2;
842 minv=v3; midv=v1; maxv=v2;
847 minv=v2; midv=v1; maxv=v3;
849 else if(v2[1]<v3[1]) {
850 minv=v2; midv=v3; maxv=v1;
853 minv=v3; midv=v2; maxv=v1;
859 omsl= floor(midv[1]);
861 if(my2<0 || my0> R.recty) return;
865 /* EDGES : LONGEST */
866 xx1= maxv[1]-minv[1];
867 if(xx1>2.0/65536.0) {
868 z0= (maxv[0]-minv[0])/xx1;
871 dx0= CLAMPIS(tmp, INT_MIN, INT_MAX);
873 tmp= 65536.0*(z0*(my2-minv[1])+minv[0]);
874 xs0= CLAMPIS(tmp, INT_MIN, INT_MAX);
878 xs0= 65536.0*(MIN2(minv[0],maxv[0]));
880 /* EDGES : THE TOP ONE */
881 xx1= maxv[1]-midv[1];
882 if(xx1>2.0/65536.0) {
883 z0= (maxv[0]-midv[0])/xx1;
886 dx1= CLAMPIS(tmp, INT_MIN, INT_MAX);
888 tmp= 65536.0*(z0*(my2-midv[1])+midv[0]);
889 xs1= CLAMPIS(tmp, INT_MIN, INT_MAX);
893 xs1= 65536.0*(MIN2(midv[0],maxv[0]));
895 /* EDGES : THE BOTTOM ONE */
896 xx1= midv[1]-minv[1];
897 if(xx1>2.0/65536.0) {
898 z0= (midv[0]-minv[0])/xx1;
901 dx2= CLAMPIS(tmp, INT_MIN, INT_MAX);
903 tmp= 65536.0*(z0*(omsl-minv[1])+minv[0]);
904 xs2= CLAMPIS(tmp, INT_MIN, INT_MAX);
908 xs2= 65536.0*(MIN2(minv[0],midv[0]));
924 if(midv[1]==maxv[1]) omsl= my2;
925 if(omsl<0) omsl= -1; /* then it does the first loop entirely */
927 while (my2 >= R.recty) { /* my2 can be larger */
938 xx1= (x0*v1[0]+y0*v1[1])/z0+v1[2];
943 zd= (int)CLAMPIS(zxd, INT_MIN, INT_MAX);
945 /* start-offset in rect */
947 rectzofs= (int *)(R.rectz+rectx*my2);
948 rectpofs= (R.rectot+rectx*my2);
963 for(y=my2;y>omsl;y--) {
973 if(sn2>=rectx) sn2= rectx-1;
975 zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX);
980 if(zverg> *rz || *rz==0x7FFFFFFF) {
1017 if(sn2>=rectx) sn2= rectx-1;
1019 zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX);
1024 if(zverg> *rz || *rz==0x7FFFFFFF) {
1040 void zbufinvulGL(float *v1, float *v2, float *v3) /* fills in R.rectot the value Zvlnr using R.rectz */
1043 double x1,y1,z1,x2,y2,z2,xx1;
1044 double zxd,zyd,zy0,tmp, zverg, zd;
1045 float *minv,*maxv,*midv;
1046 unsigned int *rectpofs,*rp;
1048 int my0,my2,sn1,sn2,rectx,*rectzofs;
1049 int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2;
1053 if(v2[1]<v3[1]) { minv=v1; midv=v2; maxv=v3; }
1054 else if(v1[1]<v3[1]) { minv=v1; midv=v3; maxv=v2; }
1055 else { minv=v3; midv=v1; maxv=v2; }
1058 if(v1[1]<v3[1]) { minv=v2; midv=v1; maxv=v3; }
1059 else if(v2[1]<v3[1]) { minv=v2; midv=v3; maxv=v1; }
1060 else { minv=v3; midv=v2; maxv=v1; }
1063 if(minv[1] == maxv[1]) return; /* no zero sized faces */
1066 my2= floor(maxv[1]);
1067 omsl= floor(midv[1]);
1069 if(my2<0 || my0> R.recty) return;
1073 /* EDGES : THE LONGEST */
1074 xx1= maxv[1]-minv[1];
1075 if(xx1>2.0/65536.0) {
1076 z0= (maxv[0]-minv[0])/xx1;
1079 dx0= CLAMPIS(tmp, INT_MIN, INT_MAX);
1081 tmp= 65536.0*(z0*(my2-minv[1]) + minv[0]);
1082 xs0= CLAMPIS(tmp, INT_MIN, INT_MAX);
1086 xs0= 65536.0*(MIN2(minv[0],maxv[0]));
1088 /* EDGES : THE TOP ONE */
1089 xx1= maxv[1]-midv[1];
1090 if(xx1>2.0/65536.0) {
1091 z0= (maxv[0]-midv[0])/xx1;
1094 dx1= CLAMPIS(tmp, INT_MIN, INT_MAX);
1096 tmp= 65536.0*(z0*(my2-midv[1])+midv[0]);
1097 xs1= CLAMPIS(tmp, INT_MIN, INT_MAX);
1101 xs1= 65536.0*(MIN2(midv[0],maxv[0]));
1103 /* EDGES : BOTTOM ONE */
1104 xx1= midv[1]-minv[1];
1105 if(xx1>2.0/65536.0) {
1106 z0= (midv[0]-minv[0])/xx1;
1109 dx2= CLAMPIS(tmp, INT_MIN, INT_MAX);
1111 tmp= 65536.0*(z0*(omsl-minv[1])+minv[0]);
1112 xs2= CLAMPIS(tmp, INT_MIN, INT_MAX);
1116 xs2= 65536.0*(MIN2(minv[0],midv[0]));
1132 if(midv[1]==maxv[1]) omsl= my2;
1133 if(omsl<0) omsl= -1; /* then it takes the first loop entirely */
1135 while (my2 >= R.recty) { /* my2 can be larger */
1146 xx1= (x0*v1[0]+y0*v1[1])/z0+v1[2];
1153 /* start-offset in rect */
1155 rectzofs= (int *)(R.rectz+rectx*my2);
1156 rectpofs= (R.rectot+rectx*my2);
1171 for(y=my2;y>omsl;y--) {
1173 /* endian insensitive */
1182 if(sn2>=rectx) sn2= rectx-1;
1227 if(sn2>=rectx) sn2= rectx-1;
1251 void zbufinvulGL_onlyZ(float *v1, float *v2, float *v3) /* only fills in R.rectz */
1253 double x0,y0,z0,x1,y1,z1,x2,y2,z2,xx1;
1254 double zxd,zyd,zy0,tmp;
1255 float *minv,*maxv,*midv;
1257 int my0,my2,sn1,sn2,rectx,zd,*rectzofs;
1258 int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2;
1267 else if(v1[1]<v3[1]) {
1284 else if(v2[1]<v3[1]) {
1297 my2= floor(maxv[1]);
1298 omsl= floor(midv[1]);
1300 if(my2<0 || my0> R.recty) return;
1304 /* EDGES : LONGEST */
1305 xx1= maxv[1]-minv[1];
1307 z0= (maxv[0]-minv[0])/xx1;
1310 dx0= CLAMPIS(tmp, INT_MIN, INT_MAX);
1312 tmp= 65536.0*(z0*(my2-minv[1])+minv[0]);
1313 xs0= CLAMPIS(tmp, INT_MIN, INT_MAX);
1317 xs0= 65536.0*(MIN2(minv[0],maxv[0]));
1320 xx1= maxv[1]-midv[1];
1322 z0= (maxv[0]-midv[0])/xx1;
1325 dx1= CLAMPIS(tmp, INT_MIN, INT_MAX);
1327 tmp= 65536.0*(z0*(my2-midv[1])+midv[0]);
1328 xs1= CLAMPIS(tmp, INT_MIN, INT_MAX);
1332 xs1= 65536.0*(MIN2(midv[0],maxv[0]));
1334 /* EDGES : BOTTOM */
1335 xx1= midv[1]-minv[1];
1337 z0= (midv[0]-minv[0])/xx1;
1340 dx2= CLAMPIS(tmp, INT_MIN, INT_MAX);
1342 tmp= 65536.0*(z0*(omsl-minv[1])+minv[0]);
1343 xs2= CLAMPIS(tmp, INT_MIN, INT_MAX);
1347 xs2= 65536.0*(MIN2(minv[0],midv[0]));
1363 if(midv[1]==maxv[1]) omsl= my2;
1364 if(omsl<0) omsl= -1; /* then it takes first loop entirely */
1366 while (my2 >= R.recty) { /* my2 can be larger */
1377 xx1= (x0*v1[0]+y0*v1[1])/z0+v1[2];
1382 zd= (int)CLAMPIS(zxd, INT_MIN, INT_MAX);
1384 /* start-offset in rect */
1386 rectzofs= (int *)(R.rectz+rectx*my2);
1400 for(y=my2;y>omsl;y--) {
1410 if(sn2>=rectx) sn2= rectx-1;
1412 zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX);
1451 if(sn2>=rectx) sn2= rectx-1;
1453 zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX);
1471 void print3floats(float *v1, float *v2, float *v3)
1473 printf("1 %f %f %f %f\n", v1[0], v1[1], v1[2], v1[3]);
1474 printf("2 %f %f %f %f\n", v2[0], v2[1], v2[2], v2[3]);
1475 printf("3 %f %f %f %f\n", v3[0], v3[1], v3[2], v3[3]);
1478 static short cliptestf(float p, float q, float *u1, float *u2)
1487 else if(r>*u1) *u1=r;
1496 else if(r<*u2) *u2=r;
1499 else if(q<0.0) return 0;
1504 int RE_testclip(float *v)
1506 float abs4; /* WATCH IT: this function should do the same as cliptestf, otherwise troubles in zbufclip()*/
1511 if(v[2]< -abs4) c=16; /* this used to be " if(v[2]<0) ", see clippz() */
1512 else if(v[2]> abs4) c+= 32;
1514 if( v[0]>abs4) c+=2;
1515 else if( v[0]< -abs4) c+=1;
1517 if( v[1]>abs4) c+=4;
1518 else if( v[1]< -abs4) c+=8;
1524 static void clipp(float *v1, float *v2, int b1, int *b2, int *b3, int a)
1526 float da,db,u1=0.0,u2=1.0;
1534 /* according the original article by Liang&Barsky, for clipping of
1535 * homeginic coordinates with viewplane, the value of "0" is used instead of "-w" .
1536 * This differs from the other clipping cases (like left or top) and I considered
1537 * it to be not so 'homogenic'. But later it has proven to be an error,
1538 * who would have thought that of L&B!
1541 if(cliptestf(-da-db, v1[3]+v1[a], &u1,&u2)) {
1542 if(cliptestf(da-db, v1[3]-v1[a], &u1,&u2)) {
1548 else labda[b1][1]=1.0; /* u2 */
1552 } else labda[b1][0]=0.0;
1557 static int clipline(float *v1, float *v2) /* return 0: do not draw */
1559 float dz,dw, u1=0.0, u2=1.0;
1565 /* this 1.01 is for clipping x and y just a tinsy larger. that way it is
1566 filled in with zbufwire correctly when rendering in parts. otherwise
1567 you see line endings at edges... */
1569 if(cliptestf(-dz-dw, v1[3]+v1[2], &u1,&u2)) {
1570 if(cliptestf(dz-dw, v1[3]-v1[2], &u1,&u2)) {
1573 dz= 1.01*(v2[3]-v1[3]);
1576 if(cliptestf(-dx-dz, v1[0]+v13, &u1,&u2)) {
1577 if(cliptestf(dx-dz, v13-v1[0], &u1,&u2)) {
1581 if(cliptestf(-dy-dz, v1[1]+v13, &u1,&u2)) {
1582 if(cliptestf(dy-dz, v13-v1[1], &u1,&u2)) {
1608 static void maakvertpira(float *v1, float *v2, int *b1, int b2, int *clve)
1620 adr[0]= v1[0]+l1*(v2[0]-v1[0]);
1621 adr[1]= v1[1]+l1*(v2[1]-v1[1]);
1622 adr[2]= v1[2]+l1*(v2[2]-v1[2]);
1623 adr[3]= v1[3]+l1*(v2[3]-v1[3]);
1632 adr[0]= v1[0]+l2*(v2[0]-v1[0]);
1633 adr[1]= v1[1]+l2*(v2[1]-v1[1]);
1634 adr[2]= v1[2]+l2*(v2[2]-v1[2]);
1635 adr[3]= v1[3]+l2*(v2[3]-v1[3]);
1641 /* ------------------------------------------------------------------------- */
1643 void RE_projectverto(float *v1, float *adr)
1645 /* calcs homogenic coord of vertex v1 */
1651 adr[0]= x*R.winmat[0][0] + z*R.winmat[2][0];
1652 adr[1]= y*R.winmat[1][1]+ z*R.winmat[2][1];
1653 adr[2]= z*R.winmat[2][2] + R.winmat[3][2];
1654 adr[3]= z*R.winmat[2][3] + R.winmat[3][3];
1658 /* ------------------------------------------------------------------------- */
1660 void projectvert(float *v1, float *adr)
1662 /* calcs homogenic coord of vertex v1 */
1668 adr[0]= x*R.winmat[0][0]+ y*R.winmat[1][0]+ z*R.winmat[2][0]+ R.winmat[3][0];
1669 adr[1]= x*R.winmat[0][1]+ y*R.winmat[1][1]+ z*R.winmat[2][1]+ R.winmat[3][1];
1670 adr[2]= x*R.winmat[0][2]+ y*R.winmat[1][2]+ z*R.winmat[2][2]+ R.winmat[3][2];
1671 adr[3]= x*R.winmat[0][3]+ y*R.winmat[1][3]+ z*R.winmat[2][3]+ R.winmat[3][3];
1675 void zbufclip(float *f1, float *f2, float *f3, int c1, int c2, int c3)
1679 if(c1 | c2 | c3) { /* not in middle */
1680 if(c1 & c2 & c3) { /* completely out */
1682 } else { /* clipping */
1683 int arg, v, b, clipflag[3], b1, b2, b3, c4, clve=3, clvlo, clvl=1;
1685 vez[0]= f1[0]; vez[1]= f1[1]; vez[2]= f1[2]; vez[3]= f1[3];
1686 vez[4]= f2[0]; vez[5]= f2[1]; vez[6]= f2[2]; vez[7]= f2[3];
1687 vez[8]= f3[0]; vez[9]= f3[1]; vez[10]= f3[2];vez[11]= f3[3];
1693 clipflag[0]= ( (c1 & 48) | (c2 & 48) | (c3 & 48) );
1694 if(clipflag[0]==0) { /* othwerwise it needs to be calculated again, after the first (z) clip */
1695 clipflag[1]= ( (c1 & 3) | (c2 & 3) | (c3 & 3) );
1696 clipflag[2]= ( (c1 & 12) | (c2 & 12) | (c3 & 12) );
1705 for(v=0; v<clvlo; v++) {
1707 if(vlzp[v][0]!=0) { /* face is still there */
1708 b2= b3 =0; /* clip flags */
1711 else if (b==1) arg= 0;
1714 clipp(vlzp[v][0],vlzp[v][1],0,&b2,&b3, arg);
1715 clipp(vlzp[v][1],vlzp[v][2],1,&b2,&b3, arg);
1716 clipp(vlzp[v][2],vlzp[v][0],2,&b2,&b3, arg);
1718 if(b2==0 && b3==1) {
1719 /* completely 'in' */;
1722 /* completely 'out' */;
1725 maakvertpira(vlzp[v][0],vlzp[v][1],&b1,0,&clve);
1726 maakvertpira(vlzp[v][1],vlzp[v][2],&b1,1,&clve);
1727 maakvertpira(vlzp[v][2],vlzp[v][0],&b1,2,&clve);
1729 /* after front clip done: now set clip flags */
1731 clipflag[1]= clipflag[2]= 0;
1733 for(b3=0; b3<clve; b3++) {
1734 c4= RE_testclip(f1);
1735 clipflag[1] |= (c4 & 3);
1736 clipflag[2] |= (c4 & 12);
1743 for(b3=3; b3<=b1; b3++) {
1744 vlzp[clvl][0]= p[0];
1745 vlzp[clvl][1]= p[b3-2];
1746 vlzp[clvl][2]= p[b3-1];
1756 /* warning, this should never happen! */
1757 if(clve>38) printf("clip overflow: clve clvl %d %d\n",clve,clvl);
1759 /* perspective division */
1761 for(c1=0;c1<clve;c1++) {
1763 f1[0]= Zmulx*(1.0+f1[0]/deler)+ Zjitx;
1764 f1[1]= Zmuly*(1.0+f1[1]/deler)+ Zjity;
1765 f1[2]= 0x7FFFFFFF *(f1[2]/deler);
1768 for(b=1;b<clvl;b++) {
1770 zbuffunc(vlzp[b][0],vlzp[b][1],vlzp[b][2]);
1777 /* perspective division: HCS to ZCS */
1780 vez[0]= Zmulx*(1.0+f1[0]/deler)+ Zjitx;
1781 vez[1]= Zmuly*(1.0+f1[1]/deler)+ Zjity;
1782 vez[2]= 0x7FFFFFFF *(f1[2]/deler);
1785 vez[4]= Zmulx*(1.0+f2[0]/deler)+ Zjitx;
1786 vez[5]= Zmuly*(1.0+f2[1]/deler)+ Zjity;
1787 vez[6]= 0x7FFFFFFF *(f2[2]/deler);
1790 vez[8]= Zmulx*(1.0+f3[0]/deler)+ Zjitx;
1791 vez[9]= Zmuly*(1.0+f3[1]/deler)+ Zjity;
1792 vez[10]= 0x7FFFFFFF *(f3[2]/deler);
1794 zbuffunc(vez,vez+4,vez+8);
1797 /* ***************** ZBUFFER MAIN ROUTINES **************** */
1800 void zbufferall(void)
1805 short transp=0, env=0, wire=0;
1807 Zmulx= ((float)R.rectx)/2.0;
1808 Zmuly= ((float)R.recty)/2.0;
1810 fillrect(R.rectz, R.rectx, R.recty, 0x7FFFFFFF);
1814 zbuffunc= zbufinvulGL;
1815 zbuflinefunc= zbufline;
1817 for(v=0;v<R.totvlak;v++) {
1819 if((v & 255)==0) vlr= R.blovl[v>>8];
1822 if(vlr->flag & R_VISIBLE) {
1825 transp= ma->mode & MA_ZTRA;
1826 env= (ma->mode & MA_ENV);
1827 wire= (ma->mode & MA_WIRE);
1829 if(ma->mode & MA_ZINV) zbuffunc= zbufinvulGLinv;
1830 else zbuffunc= zbufinvulGL;
1837 if(wire) zbufclipwire(vlr);
1839 zbufclip(vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip);
1841 if(Zvlnr) Zvlnr+= 0x800000;
1842 zbufclip(vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v3->clip, vlr->v4->clip);
1850 static int hashlist_projectvert(float *v1, float *hoco)
1852 static VertBucket bucket[256], *buck;
1855 memset(bucket, 0, 256*sizeof(VertBucket));
1859 buck= &bucket[ (((long)v1)/16) & 255 ];
1860 if(buck->vert==v1) {
1861 COPY_16(hoco, buck->hoco);
1865 projectvert(v1, hoco);
1866 buck->clip = RE_testclip(hoco);
1868 COPY_16(buck->hoco, hoco);
1872 /* used for booth radio 'tool' as during render */
1873 void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem)
1877 int c1, c2, c3, c4= 0;
1878 unsigned int *rectoto, *rectzo;
1881 if(rg_totelem==0) return;
1883 hashlist_projectvert(0, 0);
1895 Zmulx= ((float)R.rectx)/2.0;
1896 Zmuly= ((float)R.recty)/2.0;
1898 /* needed for projectvert */
1899 MTC_Mat4MulMat4(R.winmat, vw->viewmat, vw->winmat);
1901 fillrect(R.rectz, R.rectx, R.recty, 0x7FFFFFFF);
1902 fillrect(R.rectot, R.rectx, R.recty, 0xFFFFFF);
1904 zbuffunc= zbufinvulGL;
1906 if(rg_elem) { /* radio tool */
1910 re+= (rg_totelem-1);
1911 for(a= rg_totelem-1; a>=0; a--, re--) {
1913 if( (rn->f & RAD_SHOOT)==0 ) { /* no shootelement */
1915 if( rn->f & RAD_TWOSIDED) Zvlnr= a;
1916 else if( rn->f & RAD_BACKFACE) Zvlnr= 0xFFFFFF;
1919 c1= hashlist_projectvert(rn->v1, hoco[0]);
1920 c2= hashlist_projectvert(rn->v2, hoco[1]);
1921 c3= hashlist_projectvert(rn->v3, hoco[2]);
1924 c4= hashlist_projectvert(rn->v4, hoco[3]);
1927 zbufclip(hoco[0], hoco[1], hoco[2], c1, c2, c3);
1929 zbufclip(hoco[0], hoco[2], hoco[3], c1, c3, c4);
1934 else { /* radio render */
1939 for(a=0; a<R.totvlak; a++) {
1940 if((a & 255)==0) vlr= R.blovl[a>>8]; else vlr++;
1944 if( (rf->flag & RAD_SHOOT)==0 ) { /* no shootelement */
1946 if( rf->flag & RAD_TWOSIDED) Zvlnr= totface;
1947 else if( rf->flag & RAD_BACKFACE) Zvlnr= 0xFFFFFF; /* receives no energy, but is zbuffered */
1948 else Zvlnr= totface;
1950 c1= hashlist_projectvert(vlr->v1->co, hoco[0]);
1951 c2= hashlist_projectvert(vlr->v2->co, hoco[1]);
1952 c3= hashlist_projectvert(vlr->v3->co, hoco[2]);
1955 c4= hashlist_projectvert(vlr->v4->co, hoco[3]);
1958 zbufclip(hoco[0], hoco[1], hoco[2], c1, c2, c3);
1960 zbufclip(hoco[0], hoco[2], hoco[3], c1, c3, c4);
1976 void zbuffershad(LampRen *lar)
1980 int a, ok=1, lay= -1;
1982 if(lar->mode & LA_LAYER) lay= lar->lay;
1984 Zmulx= ((float)R.rectx)/2.0;
1985 Zmuly= ((float)R.recty)/2.0;
1988 fillrect(R.rectz,R.rectx,R.recty,0x7FFFFFFE);
1990 zbuffunc= zbufinvulGL_onlyZ;
1992 for(a=0;a<R.totvlak;a++) {
1994 if((a & 255)==0) vlr= R.blovl[a>>8];
2000 if((ma->mode & MA_TRACEBLE)==0) ok= 0;
2003 if(ok && (vlr->flag & R_VISIBLE) && (vlr->lay & lay)) {
2004 zbufclip(vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip);
2005 if(vlr->v4) zbufclip(vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v3->clip, vlr->v4->clip);
2012 /* ******************** ABUF ************************* */
2015 void bgnaccumbuf(void)
2018 Acolrow= MEM_mallocN(4*sizeof(short)*R.rectx, "Acolrow");
2019 Arectz= MEM_mallocN(sizeof(int)*ABUFPART*R.rectx, "Arectz");
2020 APixbuf= MEM_mallocN(ABUFPART*R.rectx*sizeof(APixstr), "APixbuf");
2029 /* ------------------------------------------------------------------------ */
2031 void endaccumbuf(void)
2040 /* ------------------------------------------------------------------------ */
2042 void copyto_abufz(int sample)
2048 memcpy(Arectz, R.rectz+ R.rectx*Aminy, 4*R.rectx*(Amaxy-Aminy+1));
2050 if( (R.r.mode & R_OSA)==0 || sample==0) return;
2053 rd= (R.rectdaps+ R.rectx*Aminy);
2055 sample= (1<<sample);
2057 for(y=Aminy; y<=Amaxy; y++) {
2058 for(x=0; x<R.rectx; x++) {
2060 if( IS_A_POINTER_CODE(*rd)) {
2061 ps= (PixStr *) POINTER_FROM_CODE(*rd);
2064 if(sample & ps->mask) {
2078 /* ------------------------------------------------------------------------ */
2082 float vec[3], hoco[4], mul, zval, fval;
2087 Zmulx= ((float)R.rectx)/2.0;
2088 Zmuly= ((float)R.recty)/2.0;
2090 /* clear APixstructs */
2091 len= sizeof(APixstr)*R.rectx*ABUFPART;
2092 memset(APixbuf, 0, len);
2094 zbuffunc= zbufinvulAc;
2095 zbuflinefunc= zbuflineAc;
2097 for(Zsample=0; Zsample<R.osa || R.osa==0; Zsample++) {
2099 copyto_abufz(Zsample); /* init zbuffer */
2101 if(R.r.mode & R_OSA) {
2102 Zjitx= -jit[Zsample][0]-0.5;
2103 Zjity= -jit[Zsample][1]-0.5;
2106 for(v=0; v<R.totvlak; v++) {
2108 Zvlr= R.blovl[v>>8];
2114 if(ma->mode & (MA_ZTRA)) {
2116 /* a little advantage for transp rendering (a z offset) */
2117 if( ma->zoffs != 0.0) {
2119 zval= mul*(1.0+Zvlr->v1->ho[2]/Zvlr->v1->ho[3]);
2121 VECCOPY(vec, Zvlr->v1->co);
2122 /* z is negative, otherwise its being clipped */
2124 RE_projectverto(vec, hoco);
2125 fval= mul*(1.0+hoco[2]/hoco[3]);
2127 Azvoordeel= (int) fabs(zval - fval );
2133 if(Zvlr->flag & R_VISIBLE) {
2135 if(ma->mode & (MA_WIRE)) zbufclipwire(Zvlr);
2137 zbufclip(Zvlr->v1->ho, Zvlr->v2->ho, Zvlr->v3->ho, Zvlr->v1->clip, Zvlr->v2->clip, Zvlr->v3->clip);
2140 zbufclip(Zvlr->v1->ho, Zvlr->v3->ho, Zvlr->v4->ho, Zvlr->v1->clip, Zvlr->v3->clip, Zvlr->v4->clip);
2145 if(RE_local_test_break()) break;
2148 if((R.r.mode & R_OSA)==0) break;
2149 if(RE_local_test_break()) break;
2154 int vergzvlak(const void *a1, const void *a2)
2156 const int *x1=a1, *x2=a2;
2158 if( x1[0] < x2[0] ) return 1;
2159 else if( x1[0] > x2[0]) return -1;
2163 void shadetrapixel(float x, float y, int vlak, int mask, unsigned short *shortcol)
2166 if( (vlak & 0x7FFFFF) > R.totvlak) {
2167 printf("error in shadetrapixel nr: %d\n", (vlak & 0x7FFFFF));
2170 if(R.r.mode & R_OSA) {
2171 int intcol[4]={0,0,0,0};
2174 for(a=0; a<R.osa; a++) {
2176 shadepixel_short(x+jit[a][0], y+jit[a][1], vlak, 1<<a, shortcol);
2177 intcol[0]+= shortcol[0];
2178 intcol[1]+= shortcol[1];
2179 intcol[2]+= shortcol[2];
2180 intcol[3]+= shortcol[3];
2184 shortcol[0]= intcol[0]/tot;
2185 shortcol[1]= intcol[1]/tot;
2186 shortcol[2]= intcol[2]/tot;
2187 shortcol[3]= intcol[3]/tot;
2189 else shadepixel_short(x, y, vlak, mask, shortcol);
2192 extern unsigned short usegamtab;
2193 void abufsetrow(int y)
2197 int x, part, a, b, zrow[100][3], totvlak, alpha[32], tempgam, nr, intcol[4];
2199 unsigned short *col, shortcol[4], tempcol[4], sampcol[16*4], *scol;
2203 printf("abufsetrow: osa too large\n");
2209 R.flag &= ~R_LAMPHALO;
2212 if(R.r.mode & R_OSA ) {
2214 for(a=0; a<=R.osa; a++) {
2218 /* does a pixbuf has to be created? */
2219 if(y<Aminy || y>Amaxy) {
2221 Aminy= part*ABUFPART;
2222 Amaxy= Aminy+ABUFPART-1;
2223 if(Amaxy>=R.recty) Amaxy= R.recty-1;
2230 memset(col, 0, 2*4*R.rectx);
2231 ap= APixbuf+R.rectx*(y-Aminy);
2236 for(x=0; x<R.rectx; x++, col+=4, ap++) {
2242 for(a=0; a<4; a++) {
2244 zrow[totvlak][0]= apn->z[a];
2245 zrow[totvlak][1]= apn->p[a];
2246 zrow[totvlak][2]= apn->mask[a];
2248 if(totvlak>99) totvlak= 99;
2256 shadetrapixel((float)x, (float)y, ap->p[0], ap->mask[0], shortcol);
2258 nr= count_mask(ap->mask[0]);
2259 if( (R.r.mode & R_OSA) && nr<R.osa) {
2261 col[0]= (shortcol[0]*a)>>16;
2262 col[1]= (shortcol[1]*a)>>16;
2263 col[2]= (shortcol[2]*a)>>16;
2264 col[3]= (shortcol[3]*a)>>16;
2267 col[0]= shortcol[0];
2268 col[1]= shortcol[1];
2269 col[2]= shortcol[2];
2270 col[3]= shortcol[3];
2276 if(zrow[0][0] < zrow[1][0]) {
2277 a= zrow[0][0]; zrow[0][0]= zrow[1][0]; zrow[1][0]= a;
2278 a= zrow[0][1]; zrow[0][1]= zrow[1][1]; zrow[1][1]= a;
2279 a= zrow[0][2]; zrow[0][2]= zrow[1][2]; zrow[1][2]= a;
2283 else { /* totvlak>2 */
2284 qsort(zrow, totvlak, sizeof(int)*3, vergzvlak);
2287 /* join when pixels are adjacent */
2292 shadetrapixel((float)x, (float)y, zrow[totvlak][1], 0xFFFF, shortcol);
2294 a= count_mask(zrow[totvlak][2]);
2295 if( (R.r.mode & R_OSA ) && a<R.osa) {
2297 memset(sampcol, 0, 4*2*R.osa);
2298 sval= addtosampcol(sampcol, shortcol, zrow[totvlak][2]);
2300 /* sval==0: alpha completely full */
2301 while( (sval != 0) && (totvlak>0) ) {
2302 a= count_mask(zrow[totvlak-1][2]);
2306 shadetrapixel((float)x, (float)y, zrow[totvlak][1], zrow[totvlak][2], shortcol);
2307 sval= addtosampcol(sampcol, shortcol, zrow[totvlak][2]);
2310 intcol[0]= scol[0]; intcol[1]= scol[1];
2311 intcol[2]= scol[2]; intcol[3]= scol[3];
2313 for(a=1; a<R.osa; a++, scol+=4) {
2314 intcol[0]+= scol[0]; intcol[1]+= scol[1];
2315 intcol[2]+= scol[2]; intcol[3]+= scol[3];
2317 tempcol[0]= intcol[0]/R.osa;
2318 tempcol[1]= intcol[1]/R.osa;
2319 tempcol[2]= intcol[2]/R.osa;
2320 tempcol[3]= intcol[3]/R.osa;
2322 addAlphaUnderShort(col, tempcol);
2327 shortcol[0]= (shortcol[0]*a)>>16;
2328 shortcol[1]= (shortcol[1]*a)>>16;
2329 shortcol[2]= (shortcol[2]*a)>>16;
2330 shortcol[3]= (shortcol[3]*a)>>16;
2331 addAlphaUnderShort(col, shortcol);
2334 else addAlphaUnderShort(col, shortcol);
2336 if(col[3]>=0xFFF0) break;