~ubuntu-branches/ubuntu/gutsy/blender/gutsy-security

« back to all changes in this revision

Viewing changes to source/blender/render/intern/source/vanillaRenderPipe.c

  • Committer: Bazaar Package Importer
  • Author(s): Florian Ernst
  • Date: 2005-11-06 12:40:03 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051106124003-3pgs7tcg5rox96xg
Tags: 2.37a-1.1
* Non-maintainer upload.
* Split out parts of 01_SConstruct_debian.dpatch again: root_build_dir
  really needs to get adjusted before the clean target runs - closes: #333958,
  see #288882 for reference

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
 *
32
32
 * 28-06-2000 nzc
33
33
 *
34
 
 * $Id: vanillaRenderPipe.c,v 1.7 2004/04/24 12:02:39 ton Exp $
 
34
 * $Id: vanillaRenderPipe.c,v 1.21 2005/06/08 12:51:03 ton Exp $
35
35
 *
36
36
 */
37
37
 
56
56
#include "DNA_camera_types.h"
57
57
#include "DNA_object_types.h"
58
58
#include "BKE_global.h"
 
59
#include "BKE_utildefines.h"
 
60
 
 
61
#include "BLI_arithb.h"
 
62
#include "BLI_rand.h"
59
63
 
60
64
/* local includes (from the render module) */
61
65
#include "RE_callbacks.h"
62
66
#include "render.h"       /* all kinds of stuff                              */
63
 
#include "render_intern.h"
64
67
#include "zbuf.h"         /* for vergzvlak, zbufclip, zbufclipwire           */
65
68
#include "edgeRender.h"   /* all edge rendering stuff                        */
66
69
#include "pixelshading.h" /* painting the pixels                             */
74
77
 
75
78
/* own includes */
76
79
#include "vanillaRenderPipe.h"
77
 
#include "vanillaRenderPipe_int.h"
78
 
 
79
 
#ifdef HAVE_CONFIG_H
80
 
#include <config.h>
81
 
#endif
82
 
 
83
 
/* crud */
84
 
#define MIN2(x,y)               ( (x)<(y) ? (x) : (y) )
 
80
 
 
81
#include "SDL_thread.h"
 
82
 
 
83
/* threshold for alpha                                                       */
 
84
#define RE_FULL_ALPHA_FLOAT 0.9998
85
85
 
86
86
/* ------------------------------------------------------------------------- */
87
87
/* Debug defines: disable all for production level code.                     */
109
109
 
110
110
extern float Zmulx, Zmuly;   /* Some kind of scale?                          */
111
111
 
112
 
extern unsigned int Zvlnr;           /* Face rendering pointer and counter: these    */
113
 
extern VlakRen *Zvlr;        /* are used for 'caching' render results.       */
114
 
 
115
 
 /* These function pointers are used for z buffer filling.    */
116
 
extern void (*zbuffunc)(float *, float *, float *);
117
 
extern void (*zbuflinefunc)(float *, float *);
118
 
 
119
112
extern char cmask[256];      /* When a pixel is supersampled, we must        */
120
113
extern char *centmask;       /* compute its colour on a point _on_ the face. */
121
114
                             /* These two are used to compute an offset to   */
122
115
                             /* guarantee we use valid coordinates.          */
123
116
 
124
 
/* unsorted */
125
 
extern float fmask[256];
126
 
extern unsigned short usegamtab, shortcol[4], 
127
 
        *mask1[9], *mask2[9],/*   *igamtab1, */ *igamtab2/*,   *gamtab */;
128
 
 
129
117
extern RE_APixstrExt *APixbufExt;/*Zbuffer: linked list of face, halo indices*/
130
118
 
131
119
/* Globals : --------------------------------------------------------------- */
 
120
                                                           /* we use 2 x three lines, for gaussian sample     */
 
121
RE_COLBUFTYPE *AColourBuffer0; /* Buffer for colours of 1 line of pixels      */
 
122
RE_COLBUFTYPE *AColourBuffer1; /* Buffer for colours of 1 line of pixels      */
 
123
RE_COLBUFTYPE *AColourBuffer2; /* Buffer for colours of 1 line of pixels      */
 
124
RE_COLBUFTYPE *AColourBuffer1a; /* Buffer for colours of 1 line of pixels      */
 
125
RE_COLBUFTYPE *AColourBuffer2a; /* Buffer for colours of 1 line of pixels      */
 
126
RE_COLBUFTYPE *AColourBuffer3; /* Buffer for colours of 1 line of pixels      */
132
127
 
133
 
RE_COLBUFTYPE *AColourBuffer; /* Buffer for colours of 1 line of pixels      */
134
128
static int     Aminy;         /* y value of first line in the accu buffer    */
135
129
static int     Amaxy;         /* y value of last line in the accu buffer     */
136
130
                              /* -also used to clip when zbuffering          */
137
131
 
138
132
/* Buffer width refers to the size of the buffers we build. Image size is    */
139
133
/* the same as R.rectx, R.recty.                                             */
140
 
static int     imageHeight;   /* image size in pixels in y direction         */
141
 
static int     imageWidth;    /* image size in pixels in x direction         */
142
 
static int     bufferHeight;  /* image size in pixels in y direction         */
143
 
static int     bufferWidth;   /* image size in pixels in x direction         */
144
134
static int     zBufferWidth;  /* special width because zbuffer needs to be   */
145
135
                              /* wider */
146
136
 
152
142
int            osaNr;         /* The oversample number. I keep it            */
153
143
                              /* separately here, because I treat no OSA     */
154
144
                              /* as if it were osa=1.                        */
155
 
RE_COLBUFTYPE  collector[4];  /* used throughout as pixel colour accu        */
156
 
RE_COLBUFTYPE  sampcol[RE_MAX_OSA_COUNT * 4]; /* subpixel accu buffer        */
157
 
 
158
 
/* ------------------------------------------------------------------------- */
159
 
/* Local (for now) */
160
 
/*  void integrateStack(struct RE_faceField* stack, */
161
 
/*                                      int ptr, */
162
 
/*                                      float x,  */
163
 
/*                                      float y,  */
164
 
/*                                      int osaNr); */
165
 
void integratePerSubStack(struct RE_faceField* stack,
166
 
                                                  int ptr,
167
 
                                                  float x, 
168
 
                                                  float y, 
169
 
                                                  int osaNr);
170
 
 
171
 
/* ------------------------------------------------------------------------- */
172
 
 
173
 
void zBufShadeAdvanced()
174
 
{
175
 
    int      y, keepLooping = 1;
176
 
    float xjit = 0.0, yjit = 0.0;
177
 
 
178
 
    Zjitx=Zjity= -0.5; /* jitter preset: 0.5 pixel */
179
 
 
180
 
        /* EDGE: for edge rendering we should compute a larger buffer, but this  */
181
 
        /* may require modifications at a deeper level. For now, we just         */
182
 
        /* 'ignore' edge pixels.                                                 */
183
 
        imageHeight  = R.recty;
184
 
        imageWidth   = R.rectx;
185
 
        bufferHeight = R.recty;
186
 
        bufferWidth  = R.rectx;
187
 
   
188
 
    /* Set osaNr. Treat 'no osa' as 'osa = 1' */
189
 
    if(R.r.mode & R_OSA) {
190
 
                osaNr = R.osa;
191
 
                if(osaNr > 16) { /* check was moved from calcZBufLine */
192
 
                        printf("zBufShadeAdvanced> osa too large (internal error)\n");
193
 
                        G.afbreek= 1;
194
 
                        return;
195
 
                }
196
 
    } else {
197
 
        /* little hack */
198
 
        osaNr = 1;
199
 
        xjit = jit[0][0];
200
 
        yjit = jit[0][1];
201
 
        jit[0][0] = 0.45;
202
 
        jit[0][1] = 0.45;        
203
 
    }
204
 
 
205
 
    RE_setwindowclip(0, -1); /* just to be sure, reset the view matrix       */
206
 
 
207
 
        initRenderBuffers(bufferWidth);
208
 
 
209
 
        /* ugh! should be converted sooner!! */
210
 
        switch (R.r.alphamode) {
211
 
        case R_ALPHAKEY:        
212
 
                setSkyBlendingMode(RE_ALPHA_KEY);
213
 
                break;
214
 
        case R_ALPHAPREMUL:     
215
 
                setSkyBlendingMode(RE_ALPHA_PREMUL);
216
 
                break;
217
 
/* not there... this is the default case */
218
 
/*      case R_ALPHASKY:         */
219
 
/*              setSkyBlendingMode(RE_ALPHA_SKY); */
220
 
/*              break; */
221
 
        default:
222
 
                setSkyBlendingMode(RE_ALPHA_SKY);               
223
 
        }
224
 
        
225
 
    y = 0;
226
 
    while ( (y < bufferHeight) && keepLooping) {
227
 
                calcZBufLine(y);
228
 
 
229
 
                renderZBufLine(y);
230
 
                transferColourBufferToOutput(y);
231
 
                
232
 
                if(y & 1) RE_local_render_display(y-1, y, imageWidth, imageHeight, R.rectot);           
233
 
 
234
 
                if(RE_local_test_break()) keepLooping = 0;
235
 
                y++; 
236
 
    }
237
 
        freeRenderBuffers();
238
 
 
239
 
        /* Edge rendering is done purely as a post-effect                        */
240
 
        if(R.r.mode & R_EDGE) {
241
 
                addEdges((char*)R.rectot, imageWidth, imageHeight,
242
 
                         osaNr,
243
 
                         R.r.edgeint, R.r.same_mat_redux,
244
 
                         G.compat, G.notonlysolid,
245
 
                         R.r.edgeR, R.r.edgeG, R.r.edgeB);
246
 
        }
247
 
 
248
 
        add_halo_flare(); /* from rendercore */
249
 
        
250
 
        if (!(R.r.mode & R_OSA)) {
251
 
                jit[0][0] = xjit;
252
 
                jit[0][1] = yjit; 
253
 
        }
254
 
    
255
 
} /* end of void zbufshadeAdvanced() */
256
 
 
257
 
/* ------------------------------------------------------------------------- */
258
 
 
259
 
void initRenderBuffers(int bwidth) 
260
 
{
261
 
 
 
145
 
 
146
/* ------------------------------------------------------------------------- */
 
147
 
 
148
/**
 
149
* Z buffer initializer, for new pipeline.
 
150
 * <LI>
 
151
 * <IT> AColourBuffer : colour buffer for one line
 
152
 * <IT> APixbufExt    : pixel data buffer for one line, depth RE_ZBUFLEN 
 
153
 * </LI>
 
154
 */
 
155
static void initRenderBuffers(int bwidth) 
 
156
{
 
157
        /* bwidth+4, as in rendercore.c. I think it's too much, but yah (ton) */
 
158
    AColourBuffer0 = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow");
 
159
    AColourBuffer1 = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow");
 
160
    AColourBuffer2 = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow");
 
161
    AColourBuffer1a = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow");
 
162
    AColourBuffer2a = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow");
 
163
    AColourBuffer3 = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow");
 
164
        
262
165
    /* The +1 is needed because the fill-functions use a +1 offset when      */
263
166
    /* filling in pixels. Mind that also the buffer-clearing function needs  */
264
167
    /* this offset (done in calcZBufLine).                                   */
265
168
        /* The offset is wrong: it shouldn't be there. I need to fix this still. */
266
 
    AColourBuffer = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * bwidth, 
267
 
                            "Acolrow");
268
169
        zBufferWidth = bwidth + 1;
269
170
        initZbuffer(bwidth + 1);
270
171
 
271
172
    Aminy= -1000; /* indices of lines in the z buffer: no lines buffered     */
272
173
    Amaxy= -1000;
273
174
 
274
 
        /* Use slider when the gamma button is pressed. */
275
 
        if (R.r.mode & R_GAMMA) {               
276
 
                makeGammaTables(R.r.gamma);
277
 
                setDoGamma(1);
278
 
        } else {
279
 
                /*
280
 
                  Needed for spotlights! Maybe a separate gammatable would be
281
 
                  required here
282
 
                */
283
 
                makeGammaTables(1.0);
284
 
                setDoGamma(0);
285
 
        }
286
175
 
287
 
} /* End of void initZBuffers(void) */
 
176
288
177
 
289
178
/* ------------------------------------------------------------------------- */
 
179
/**
 
180
 * Z buffer destructor, frees stuff from initZBuffers().
 
181
 */
290
182
 
291
 
void freeRenderBuffers(void) {  
292
 
    if (AColourBuffer) MEM_freeN(AColourBuffer);
 
183
static void freeRenderBuffers(void) {   
 
184
    if (AColourBuffer0) MEM_freeN(AColourBuffer0);
 
185
    if (AColourBuffer1) MEM_freeN(AColourBuffer1);
 
186
    if (AColourBuffer2) MEM_freeN(AColourBuffer2);
 
187
    if (AColourBuffer1a) MEM_freeN(AColourBuffer1a);
 
188
    if (AColourBuffer2a) MEM_freeN(AColourBuffer2a);
 
189
    if (AColourBuffer3) MEM_freeN(AColourBuffer3);
293
190
        freeZbuffer();
294
 
} /* End of void freeZBuffers(void) */
295
 
 
296
 
/* ------------------------------------------------------------------------- */
297
 
 
298
 
void calcZBufLine(int y)
299
 
{
300
 
 
301
 
    int part;
302
 
    int keepLooping = 1;
303
 
 
304
 
    if(y<0) return;
305
 
 
306
 
        /* zbuffer fix: here? */
307
 
        Zmulx= ((float) bufferWidth)/2.0;
308
 
        Zmuly= ((float) bufferHeight)/2.0;
309
 
 
310
 
        
311
 
        /* use these buffer fill functions */    
312
 
        zbuffunc     = zBufferFillFace;
313
 
        zbuflinefunc = zBufferFillEdge;
314
 
            
315
 
    /* (FORALL y: Aminy =< y =< Amaxy: y is buffered)                        */
316
 
    if( (y < Aminy) || (y > Amaxy)) {
317
 
        /* prepare buffer */
318
 
        part  = (y/RE_ZBUFLEN);     /* These two lines are mystifying me...  */
319
 
        Aminy = part * RE_ZBUFLEN;  /* Possibly for rounding things?         */
320
 
        Amaxy = Aminy + RE_ZBUFLEN - 1;
321
 
/*          if(Amaxy >= R.recty) Amaxy = R.recty-1; */
322
 
        if(Amaxy >= bufferHeight) Amaxy = bufferHeight - 1;
323
 
                resetZbuffer();
324
 
        
325
 
        Zsample = 0; /* Zsample is used internally !                         */
326
 
        while ( (Zsample < osaNr) && keepLooping ) {
327
 
            /* Apply jitter to this pixel. The jitter offsets are globals.   */
328
 
            /* They are added in zbufclip()                                  */
329
 
            /* Negative: these offsets are added to the vertex coordinates   */
330
 
            /* so it equals translating viewpoint over the positive vector.  */
331
 
            Zjitx= -jit[Zsample][0];
332
 
            Zjity= -jit[Zsample][1];
333
 
 
334
 
            keepLooping = fillZBufDistances();
335
 
            
336
 
            if(RE_local_test_break()) keepLooping = 0;
337
 
            Zsample++;
338
 
        }
339
 
    };
340
 
    
341
 
} /*End of void calcZBufLine(int y) */
342
 
 
343
 
/* ------------------------------------------------------------------------- */
344
 
 
345
 
int countAndSortPixelFaces(int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE], 
 
191
 
192
/* ------------------------------------------------------------------------- */
 
193
 
 
194
/**
 
195
 * New fill function for z buffer, for edge-only rendering.
 
196
 */
 
197
static void zBufferFillFace(unsigned int zvlnr, float *v1, float *v2, float *v3)  
 
198
{
 
199
        /* Coordinates of the vertices are specified in ZCS */
 
200
        VlakRen *vlr;
 
201
        int apteller, apoffsetteller;
 
202
        double z0; /* used as temp var*/
 
203
        double xx1;
 
204
        double zxd,zyd,zy0, tmp;
 
205
        float *minv,*maxv,*midv;
 
206
        register int zverg,zvlak,x;
 
207
        int my0,my2,sn1,sn2,rectx,zd;
 
208
        int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2, mask;
 
209
        int obtype;
 
210
        /* These used to be doubles.  We may want to change them back if the     */
 
211
        /* loss of accuracy proves to be a problem? There does not seem to be    */
 
212
        /* any performance issues here, so I'll just keep the doubles.           */
 
213
        /*      float vec0[3], vec1[3], vec2[3]; */
 
214
        double vec0[3], vec1[3], vec2[3];
 
215
        
 
216
        vlr= RE_findOrAddVlak( (zvlnr-1) & 0x7FFFFF);
 
217
        if(vlr->mat->mode & MA_ZTRA) obtype= RE_POLY;
 
218
        else obtype= RE_POLY|RE_SOLID;
 
219
        
 
220
        /* MIN MAX */
 
221
        /* sort vertices for min mid max y value */
 
222
        if(v1[1]<v2[1]) {
 
223
                if(v2[1]<v3[1])      { minv=v1; midv=v2; maxv=v3;}
 
224
                else if(v1[1]<v3[1]) { minv=v1; midv=v3; maxv=v2;}
 
225
                else                 { minv=v3; midv=v1; maxv=v2;}
 
226
        }
 
227
        else {
 
228
                if(v1[1]<v3[1])          { minv=v2; midv=v1; maxv=v3;}
 
229
                else if(v2[1]<v3[1]) { minv=v2; midv=v3; maxv=v1;}
 
230
                else                 { minv=v3; midv=v2; maxv=v1;}
 
231
        }
 
232
 
 
233
        if(minv[1] == maxv[1]) return;  /* security to remove 'zero' size faces */
 
234
 
 
235
        my0  = ceil(minv[1]);
 
236
        my2  = floor(maxv[1]);
 
237
        omsl = floor(midv[1]);
 
238
 
 
239
        /* outside the current z buffer slice: clip whole face */
 
240
        if( (my2 < Aminy) || (my0 > Amaxy)) return;
 
241
 
 
242
        if(my0<Aminy) my0= Aminy;
 
243
 
 
244
        /* EDGES : THE LONGEST */
 
245
        xx1= maxv[1]-minv[1];
 
246
        if(xx1>2.0/65536.0) {
 
247
                z0= (maxv[0]-minv[0])/xx1;
 
248
                
 
249
                tmp= (-65536.0*z0);
 
250
                dx0= CLAMPIS(tmp, INT_MIN, INT_MAX);
 
251
                
 
252
                tmp= 65536.0*(z0*(my2-minv[1])+minv[0]);
 
253
                xs0= CLAMPIS(tmp, INT_MIN, INT_MAX);
 
254
        }
 
255
        else {
 
256
                dx0= 0;
 
257
                xs0= 65536.0*(MIN2(minv[0],maxv[0]));
 
258
        }
 
259
        /* EDGES : THE TOP ONE */
 
260
        xx1= maxv[1]-midv[1];
 
261
        if(xx1>2.0/65536.0) {
 
262
                z0= (maxv[0]-midv[0])/xx1;
 
263
                
 
264
                tmp= (-65536.0*z0);
 
265
                dx1= CLAMPIS(tmp, INT_MIN, INT_MAX);
 
266
                
 
267
                tmp= 65536.0*(z0*(my2-midv[1])+midv[0]);
 
268
                xs1= CLAMPIS(tmp, INT_MIN, INT_MAX);
 
269
        }
 
270
        else {
 
271
                dx1= 0;
 
272
                xs1= 65536.0*(MIN2(midv[0],maxv[0]));
 
273
        }
 
274
        /* EDGES : THE BOTTOM ONE */
 
275
        xx1= midv[1]-minv[1];
 
276
        if(xx1>2.0/65536.0) {
 
277
                z0= (midv[0]-minv[0])/xx1;
 
278
                
 
279
                tmp= (-65536.0*z0);
 
280
                dx2= CLAMPIS(tmp, INT_MIN, INT_MAX);
 
281
                
 
282
                tmp= 65536.0*(z0*(omsl-minv[1])+minv[0]);
 
283
                xs2= CLAMPIS(tmp, INT_MIN, INT_MAX);
 
284
        }
 
285
        else {
 
286
                dx2= 0;
 
287
                xs2= 65536.0*(MIN2(minv[0],midv[0]));
 
288
        }
 
289
 
 
290
        /* ZBUF DX DY */
 
291
        /* xyz_1 = v_1 - v_2 */
 
292
        MTC_diff3DFF(vec1, v1, v2);
 
293
        /* xyz_2 = v_2 - v_3 */
 
294
        MTC_diff3DFF(vec2, v2, v3);
 
295
        /* xyz_0 = xyz_1 cross xyz_2 */
 
296
        MTC_cross3Double(vec0, vec1, vec2);
 
297
 
 
298
        /* cross product of two of the sides is 0 => this face is too small */
 
299
        if(vec0[2]==0.0) return;
 
300
 
 
301
        if(midv[1] == maxv[1]) omsl= my2;
 
302
        if(omsl < Aminy) omsl= Aminy-1;  /* make sure it takes the first loop entirely */
 
303
 
 
304
        while (my2 > Amaxy) {  /* my2 can be larger */
 
305
                xs0+=dx0;
 
306
                if (my2<=omsl) {
 
307
                        xs2+= dx2;
 
308
                }
 
309
                else{
 
310
                        xs1+= dx1;
 
311
                }
 
312
                my2--;
 
313
        }
 
314
 
 
315
        xx1= (vec0[0]*v1[0]+vec0[1]*v1[1])/vec0[2]+v1[2];
 
316
 
 
317
        zxd= -vec0[0]/vec0[2];
 
318
        zyd= -vec0[1]/vec0[2];
 
319
        zy0= my2*zyd+xx1;
 
320
        zd= (int)CLAMPIS(zxd, INT_MIN, INT_MAX);
 
321
 
 
322
        /* start-ofset in rect */
 
323
        /*      rectx= R.rectx;  */
 
324
        /* I suspect this var needs very careful setting... When edge rendering  */
 
325
        /* is on, this is strange */
 
326
        rectx = zBufferWidth;
 
327
        apoffsetteller = rectx*(my2-Aminy);
 
328
 
 
329
        mask= 1<<Zsample;
 
330
        zvlak= zvlnr;
 
331
 
 
332
        xs3= 0;         /* flag */
 
333
        if(dx0>dx1) {
 
334
                MTC_swapInt(&xs0, &xs1);
 
335
                MTC_swapInt(&dx0, &dx1);
 
336
                xs3= 1; /* flag */
 
337
 
 
338
        }
 
339
 
 
340
        for(y=my2;y>omsl;y--) {
 
341
 
 
342
                sn1= xs0>>16;
 
343
                xs0+= dx0;
 
344
 
 
345
                sn2= xs1>>16;
 
346
                xs1+= dx1;
 
347
 
 
348
                sn1++;
 
349
 
 
350
                if(sn2>=rectx) sn2= rectx-1;
 
351
                if(sn1<0) sn1= 0;
 
352
                zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX);
 
353
                apteller = apoffsetteller + sn1;
 
354
                x= sn2-sn1;
 
355
                
 
356
                zverg-= Azvoordeel;
 
357
                
 
358
                while(x>=0) {
 
359
                        insertObject(apteller, zvlnr, obtype, zverg, mask);
 
360
                        zverg+= zd;
 
361
                        apteller++;
 
362
                        x--;
 
363
                }
 
364
                zy0-= zyd;
 
365
                apoffsetteller -= rectx;
 
366
        }
 
367
 
 
368
        if(xs3) {
 
369
                xs0= xs1;
 
370
                dx0= dx1;
 
371
        }
 
372
        if(xs0>xs2) {
 
373
                xs3= xs0;
 
374
                xs0= xs2;
 
375
                xs2= xs3;
 
376
                xs3= dx0;
 
377
                dx0= dx2;
 
378
                dx2= xs3;
 
379
        }
 
380
 
 
381
        for(; y>=my0; y--) {
 
382
 
 
383
                sn1= xs0>>16;
 
384
                xs0+= dx0;
 
385
 
 
386
                sn2= xs2>>16;
 
387
                xs2+= dx2;
 
388
 
 
389
                sn1++;
 
390
 
 
391
                if(sn2>=rectx) sn2= rectx-1;
 
392
                if(sn1<0) sn1= 0;
 
393
                zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX);
 
394
                apteller = apoffsetteller + sn1;
 
395
                x= sn2-sn1;
 
396
      
 
397
                zverg-= Azvoordeel;
 
398
      
 
399
                while(x>=0) {
 
400
                        insertObject(apteller, zvlnr, obtype, zverg, mask);
 
401
                        zverg+= zd;
 
402
                        apteller++;
 
403
                        x--;
 
404
                }
 
405
                
 
406
                zy0-=zyd;
 
407
                apoffsetteller -= rectx;
 
408
        }
 
409
 
410
/* ------------------------------------------------------------------------- */
 
411
 
 
412
static void zBufferFillEdge(unsigned int zvlnr, float *vec1, float *vec2)
 
413
{
 
414
        int apteller;
 
415
        int start, end, x, y, oldx, oldy, ofs;
 
416
        int dz, vergz, mask, maxtest=0;
 
417
        float dx, dy;
 
418
        float v1[3], v2[3];
 
419
        
 
420
        dx= vec2[0]-vec1[0];
 
421
        dy= vec2[1]-vec1[1];
 
422
        
 
423
        if(fabs(dx) > fabs(dy)) {
 
424
                
 
425
                /* all lines from left to right */
 
426
                if(vec1[0]<vec2[0]) {
 
427
                        VECCOPY(v1, vec1);
 
428
                        VECCOPY(v2, vec2);
 
429
                }
 
430
                else {
 
431
                        VECCOPY(v2, vec1);
 
432
                        VECCOPY(v1, vec2);
 
433
                        dx= -dx; dy= -dy;
 
434
                }
 
435
                
 
436
                start= floor(v1[0]);
 
437
                end= start+floor(dx);
 
438
                if(end >= zBufferWidth) end = zBufferWidth - 1;
 
439
                
 
440
                oldy= floor(v1[1]);
 
441
                dy/= dx;
 
442
                
 
443
                vergz= v1[2];
 
444
                vergz-= Azvoordeel;
 
445
                dz= (v2[2]-v1[2])/dx;
 
446
                if(vergz>0x70000000 && dz>0) maxtest= 1;                // prevent overflow
 
447
                
 
448
                apteller = zBufferWidth*(oldy-Aminy) +start;
 
449
                mask  = 1<<Zsample;     
 
450
                
 
451
                if(dy<0) ofs= -zBufferWidth;
 
452
                else ofs= zBufferWidth;
 
453
                
 
454
                for(x= start; x<=end; x++, /*  ap++, */ apteller++) {
 
455
                        
 
456
                        y= floor(v1[1]);
 
457
                        if(y!=oldy) {
 
458
                                oldy= y;
 
459
                                apteller += ofs;
 
460
                        }
 
461
                        
 
462
                        if(x>=0 && y>=Aminy && y<=Amaxy) {
 
463
                                insertObject(apteller, zvlnr, RE_POLY, vergz, mask);
 
464
                        }
 
465
                        
 
466
                        v1[1]+= dy;
 
467
                        vergz+= dz;
 
468
                        if(maxtest && vergz<0) vergz= 0x7FFFFFF0;
 
469
                }
 
470
        }
 
471
        else {
 
472
                
 
473
                /* all lines from top to bottom */
 
474
                if(vec1[1]<vec2[1]) {
 
475
                        VECCOPY(v1, vec1);
 
476
                        VECCOPY(v2, vec2);
 
477
                }
 
478
                else {
 
479
                        VECCOPY(v2, vec1);
 
480
                        VECCOPY(v1, vec2);
 
481
                        dx= -dx; dy= -dy;
 
482
                }
 
483
                
 
484
                start= floor(v1[1]);
 
485
                end= start+floor(dy);
 
486
                
 
487
                if(start>Amaxy || end<Aminy) return;
 
488
                
 
489
                if(end>Amaxy) end= Amaxy;
 
490
                
 
491
                oldx= floor(v1[0]);
 
492
                dx/= dy;
 
493
                
 
494
                vergz= v1[2];
 
495
                vergz-= Azvoordeel;
 
496
                dz= (v2[2]-v1[2])/dy;
 
497
                if(vergz>0x70000000 && dz>0) maxtest= 1;                // prevent overflow
 
498
                
 
499
                apteller = zBufferWidth*(start-Aminy) +oldx;
 
500
                
 
501
                mask= 1<<Zsample;
 
502
                
 
503
                if(dx<0) ofs= -1;
 
504
                else ofs= 1;
 
505
                
 
506
                for(y= start; y<=end; y++, apteller += zBufferWidth) {
 
507
                        
 
508
                        x= floor(v1[0]);
 
509
                        if(x!=oldx) {
 
510
                                oldx= x;
 
511
                                apteller += ofs;
 
512
                        }
 
513
                        
 
514
                        if(x>=0 && y>=Aminy && (x < zBufferWidth)) {
 
515
                                insertObject(apteller, zvlnr, RE_POLY, vergz, mask);
 
516
                        }
 
517
                        
 
518
                        v1[0]+= dx;
 
519
                        vergz+= dz;
 
520
                        if(maxtest && vergz<0) vergz= 0x7FFFFFF0;
 
521
                }
 
522
        }
 
523
}
 
524
/* ------------------------------------------------------------------------- */
 
525
 
 
526
/**
 
527
 * Count and sort the list behind ap into buf. Sorts on min. distance.
 
528
 * Low index <=> high z
 
529
 */
 
530
static int countAndSortPixelFaces(int zrow[][RE_PIXELFIELDSIZE], 
346
531
                           RE_APixstrExt *ap)
347
532
{
348
533
    int totvlak;          /* face counter                          */
378
563
    } else if (totvlak != 1) qsort(zrow, totvlak, 
379
564
                                   sizeof(int)*RE_PIXELFIELDSIZE, vergzvlak);   
380
565
    return totvlak;
381
 
} /* end of int countAndSortPixelFaces(int* zrow,RE_APixstrExt *ap ) */
 
566
382
567
 
383
568
/* ------------------------------------------------------------------------- */
384
569
/* Oversampler v3 - check CVS for older versions                             */
402
587
/** 
403
588
 * Analyze the z-buffer, and pre-sample the colours.
404
589
 */
405
 
int composeStack(int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE],
 
590
static int composeStack(int zrow[][RE_PIXELFIELDSIZE], RE_COLBUFTYPE *collector, 
406
591
                                 struct RE_faceField* stack, int ptr,
407
 
                                 int totvlak, float x, float y, int osaNr) {
408
 
 
 
592
                                 int totvlak, float x, float y, int osaNr) 
 
593
{
 
594
        VlakRen *vlr= NULL;
409
595
    float  xs = 0.0;
410
596
    float  ys = 0.0;  /* coordinates for the render-spot              */
411
597
 
419
605
    int    Cthresh             = 0;
420
606
        int    save_totvlak        = totvlak;
421
607
        int    fullsubpixelflags   = 0;
 
608
        int    full_osa;
422
609
 
423
610
        VR_covered = 0;
424
611
    for(i = 0; i < osaNr; i++) alphathreshold[i] = 0.0;
426
613
 
427
614
    while ( (!saturated || (saturated && inconflict) ) && (totvlak > 0) ) {
428
615
        totvlak--;
429
 
                        
430
 
        i= centmask[ zrow[totvlak][RE_MASK] ]; /* recenter sample position - */
431
 
        xs= (float)x+centLut[i &  15];
432
 
        ys= (float)y+centLut[i >> 4];
433
 
        
434
 
        /* stack face ----------- */
435
 
                stack[ptr].mask     = zrow[totvlak][RE_MASK];
436
 
                stack[ptr].data     = renderPixel(xs, ys, zrow[totvlak], stack[ptr].mask);
 
616
                
 
617
                full_osa= 0;
 
618
                if(R.osa && (zrow[totvlak][RE_TYPE] & RE_POLY)) {
 
619
                        vlr= RE_findOrAddVlak((zrow[totvlak][RE_INDEX]-1) & 0x7FFFFF);
 
620
                        if(vlr->flag & R_FULL_OSA) full_osa= 1;
 
621
                }
 
622
                
 
623
                if(full_osa) {
 
624
                        float div=0.0, accol[4]={0.0, 0.0, 0.0, 0.0};
 
625
                        int a, mask= zrow[totvlak][RE_MASK];
 
626
                        
 
627
                        for(a=0; a<R.osa; a++) {
 
628
                                if(mask & (1<<a)) {
 
629
                                        xs= (float)x + jit[a][0];
 
630
                                        ys= (float)y + jit[a][1];
 
631
                                        renderPixel(collector, xs, ys, zrow[totvlak], 1<<a);
 
632
                                        accol[0] += collector[0]; accol[1] += collector[1]; accol[2] += collector[2]; accol[3] += collector[3];
 
633
                                        div+= 1.0;
 
634
                                }
 
635
                        }
 
636
                        if(div!=0.0) {
 
637
                                div= 1.0/div;
 
638
                                collector[0]= accol[0]*div; collector[1]= accol[1]*div; collector[2]= accol[2]*div; collector[3]= accol[3]*div;
 
639
                        }
 
640
                        stack[ptr].mask= mask;
 
641
                        stack[ptr].data= vlr;
 
642
                }
 
643
                else {
 
644
                        if(R.osa) {
 
645
                                i= centmask[ zrow[totvlak][RE_MASK] ]; /* recenter sample position - */
 
646
                                xs= (float)x+centLut[i &  15];
 
647
                                ys= (float)y+centLut[i >> 4];
 
648
                        }
 
649
                        else {
 
650
                                xs= (float)x;
 
651
                                ys= (float)y;
 
652
                        }
 
653
                        
 
654
                        /* stack face ----------- */
 
655
                        stack[ptr].mask     = zrow[totvlak][RE_MASK];
 
656
                        stack[ptr].data     = renderPixel(collector, xs, ys, zrow[totvlak], stack[ptr].mask);
 
657
                }
437
658
                stack[ptr].faceType = zrow[totvlak][RE_TYPE];
438
659
        cpFloatColV(collector, stack[ptr].colour);
439
660
 
493
714
        ys= (float)y;
494
715
 
495
716
        /* code identical for rendering empty sky pixel */
496
 
        renderSkyPixelFloat(xs, ys);
 
717
        renderSkyPixelFloat(collector, xs, ys);
497
718
        cpFloatColV(collector, colbuf);
498
719
 
499
720
        if(R.flag & R_LAMPHALO) {
513
734
        return ptr;
514
735
}
515
736
 
516
 
/*
517
 
  Start resolving the conflict: the stack is primed to the top-most valid
518
 
  layer on the stack. Call this layer n. Layer n has a conflict count of c.
519
 
  This means layers [ n - c, ..., n ]
520
 
 */
521
 
int resolveConflict(struct RE_faceField* stack, int ptr, float x, float y) {
522
 
        int face;
523
 
    int layer;
524
 
    float dx, dy;
525
 
        float xs = 0.0;
526
 
        float ys = 0.0;  /* coordinates for the render-spot              */
527
 
        int i;
528
 
 
529
 
    for(i = 0; i< osaNr; i++) { /* per bin, buffer all faces         */
530
 
                dx = jit[i][0];
531
 
        dy = jit[i][1];
532
 
        xs = (float)x + dx;
533
 
                ys = (float)y + dy;   
534
 
 
535
 
                face = 0;  /* only counts covering faces ------------------- */
536
 
        layer = 0; /* counts all faces ----------------------------- */
537
 
 
538
 
        while (layer < stack[ptr].conflictCount) {
539
 
                        if ( (1<<i) & stack[ptr - layer].mask)  {
540
 
                                VR_cbuf[face][0] = 
541
 
                                        calcDepth(xs, ys, 
542
 
                                                          stack[ptr - layer].data,
543
 
                                                          stack[ptr - layer].faceType);
544
 
                VR_cbuf[face][1] = ptr - layer;
545
 
                face++;
546
 
                        }
547
 
                        layer++;
 
737
/* ------------------------------------------------------------------------- */
 
738
 
 
739
/**
 
740
 * Calculate the view depth to this object on this location, with 
 
741
 * the current view parameters in R.
 
742
 */
 
743
static int calcDepth(float x, float y, void *data, int type)
 
744
{
 
745
    float view[3];
 
746
        
 
747
    if (type & RE_POLY) {
 
748
        VlakRen* vlr = (VlakRen*) data;
 
749
        VertRen* v1;
 
750
        float dface, div, zco, hoco_z, hoco_w;
 
751
        int zbuf_co;
 
752
        
 
753
        v1 = vlr->v1;
 
754
        
 
755
        /* vertex dot face normal: WCS */
 
756
        dface= v1->co[0]*vlr->n[0]+v1->co[1]*vlr->n[1]+v1->co[2]*vlr->n[2]; 
 
757
        
 
758
        /* jitter has been added to x, y ! */
 
759
        /* view vector view: screen coords */
 
760
                view[0]= (x+(R.xstart)+0.5);
 
761
        
 
762
        if(R.flag & R_SEC_FIELD) {
 
763
            if(R.r.mode & R_ODDFIELD) view[1]= (y + R.ystart)*R.ycor;
 
764
            else view[1]= (y + R.ystart + 1.0)*R.ycor;
 
765
        } 
 
766
                else view[1]= (y + R.ystart + 0.5)*R.ycor;
 
767
        
 
768
                
 
769
                /* for pano, another rotation in the xz plane is needed.... */
 
770
                
 
771
        /* this is ok, in WCS */
 
772
        view[2]= -R.viewfac;  /* distance to viewplane */
 
773
        
 
774
                /* calculate zcoord */
 
775
                if(R.r.mode & R_ORTHO) {
 
776
                        /* x and y 3d coordinate can be derived from pixel coord and winmat */
 
777
                        float fx= 2.0/(R.rectx*R.winmat[0][0]);
 
778
                        float fy= 2.0/(R.recty*R.winmat[1][1]);
 
779
                        
 
780
                        fx= (0.5 + x - 0.5*R.rectx)*fx - R.winmat[3][0]/R.winmat[0][0];
 
781
                        fy= (0.5 + y - 0.5*R.recty)*fy - R.winmat[3][1]/R.winmat[1][1];
 
782
                        
 
783
                        /* using a*x + b*y + c*z = d equation, (a b c) is normal */
 
784
                        zco= (dface - vlr->n[0]*fx - vlr->n[1]*fy)/vlr->n[2];
 
785
                        
 
786
                }
 
787
                else {
 
788
                        /* face normal dot view vector: but how can this work? (nzc) */
 
789
                        div = MTC_dot3Float(vlr->n, view);
 
790
                        if (div!=0.0) zco = (view[2]*dface)/div;
 
791
                        else zco = 0.0;
 
792
                }
 
793
        
 
794
        /* same as in zbuf.c */
 
795
        hoco_z =  zco*R.winmat[2][2] + R.winmat[3][2]; 
 
796
        hoco_w =  zco*R.winmat[2][3] + R.winmat[3][3]; 
 
797
        
 
798
                if(hoco_w!=0.0) zbuf_co = 0x7FFFFFFF*(hoco_z/hoco_w);
 
799
                else zbuf_co= 0x7FFFFFFF;
 
800
        
 
801
        return  zbuf_co; /* z component of R.co */
 
802
    } else if (type & RE_HALO) {
 
803
        HaloRen* har = (HaloRen*) data;
 
804
        return har->zBufDist;
 
805
    }
 
806
    return 0;
 
807
 
808
 
 
809
/**
 
810
 * Blend source over dest, and leave result in dest. 1 pixel.
 
811
 */
 
812
static void blendOverFloat(int type, float* dest, float* source, void* data)
 
813
{
 
814
        
 
815
    if (type & RE_POLY) {
 
816
        VlakRen *ver = (VlakRen*) data;
 
817
        if ((ver->mat != NULL) && (ver->mat->add > RE_FACE_ADD_THRESHOLD)) {
 
818
            char addf = (char) (ver->mat->add * 255.0);
 
819
            addalphaAddfacFloat(dest, source, addf);
548
820
        }
549
 
        qsort(VR_cbuf, face, sizeof(int)*2, vergzvlak); 
550
 
        for(layer = 0; layer < face; layer++) {
551
 
                        blendOverFloat(stack[VR_cbuf[layer][1]].faceType, /* type */
552
 
                                                   sampcol + (4 * i),                 /* dest */
553
 
                                                   stack[VR_cbuf[layer][1]].colour,   /* src */
554
 
                                                   stack[VR_cbuf[layer][1]].data);    /* data */
555
 
                }
556
 
        }
557
 
 
558
 
        /* The number of layers that were handled. This is how many layers the   */
559
 
        /* top-level algorithm needs to skip.                                    */
560
 
        return stack[ptr].conflictCount;
561
 
}
562
 
 
563
 
/* The colour stack is blended down in a pretty straight-forward manner, or  */
564
 
/* a part of the stack is re-evaluated to resolve the conflict.              */
565
 
/* About 25-30% of rendering time is eaten here!                             */
566
 
void integrateStack(struct RE_faceField* stack, int ptr,
567
 
                                        float x, 
568
 
                                        float y, 
569
 
                                        int osaNr) {
570
 
        /* sample the colour stack: back to front ----------------------------   */
571
 
        /*    is there a possible way to ignore alpha? this would save 25% work  */
572
 
        ptr--;
573
 
        /* Little different now: let ptr point to the topmost valid face.*/
574
 
        while (ptr >= 0) {
575
 
                if (stack[ptr].conflictCount == 0) {
576
 
                        /*
577
 
                          No conflict: sample one colour into multiple bins
578
 
                        */
579
 
                        blendOverFloatRow(stack[ptr].faceType, 
580
 
                                                          sampcol, 
581
 
                                                          stack[ptr].colour,
582
 
                                                          stack[ptr].data, 
583
 
                                                          stack[ptr].mask, 
584
 
                                                          osaNr);
585
 
                        ptr--;
586
 
                } else {
587
 
                        /*
588
 
                          Recalc all z-values, and integrate per sub-pixel. 
589
 
                        */
590
 
                        ptr -= resolveConflict(stack, ptr, x, y);
591
 
                }
592
 
        }
593
 
 
594
 
        /* Done sampling. Now we still need to fill in pixels that were not      */
595
 
        /* covered at all It seems strange that we have to check for empty alpha */
596
 
        /* but somehow this is necessary. Check out the cover condition :)....   */
597
 
 
598
 
        /* It is important that we find a more efficient algorithm here, because */
599
 
        /* this little loop eats _lots_ of cycles.                               */
600
 
 
601
 
        /* Should be integrated in the rest of the rendering... */
602
 
 
603
 
        if(R.flag & R_LAMPHALO) {
604
 
                float halocol[4];
605
 
                int i;
606
 
                
607
 
                renderSpotHaloPixel(x, y, halocol);
608
 
                /* test seems to be wrong? */
609
 
                if (halocol[3] > RE_EMPTY_COLOUR_FLOAT) {
610
 
                        for (i = 0; i < osaNr; i++) { 
611
 
                                /* here's a pinch: if the pixel was only covered by a halo,  */
612
 
                                /* we still need to fill spothalo. How do we detect this?    */
613
 
                                if (!(VR_covered & (1 << i)))
614
 
                                        /* maybe a copy is enough here... */
615
 
                                        addAlphaOverFloat(sampcol + (4 * i), halocol);
616
 
                        }
617
 
                }
618
 
        } 
619
 
}
 
821
        else
 
822
            addAlphaOverFloat(dest, source);
 
823
    } else if (type & RE_HALO) {
 
824
        HaloRen *har= (HaloRen*) data;
 
825
        addalphaAddfacFloat(dest, source, har->add);
 
826
    } else if (type & RE_SKY) {
 
827
                addAlphaOverFloat(dest, source);
 
828
        }
 
829
        
 
830
}
 
831
 
620
832
 
621
833
/**
622
834
 * New approach: sample substacks. Each substack is first copied into
623
835
 * a stack buffer, and then blended down.
624
836
 * */
625
 
void integratePerSubStack(struct RE_faceField* stack,
626
 
                                                  int ptr,
627
 
                                                  float x, 
628
 
                                                  float y, 
629
 
                                                  int osaNr) {
 
837
static void integratePerSubStack(float *sampcol, struct RE_faceField* stack,
 
838
                                                  int ptr,  float x,  float y, int osaNr) 
 
839
{
630
840
        int i = 0;
631
841
        int j = 0;
632
842
        int k = 0;
789
999
/* distance, and then used for rendering pixels. zrow might be replaced by   */
790
1000
/* an RE_APixstrExt* array                                                   */
791
1001
/* - redo the numbering to something more logical                            */
792
 
void renderZBufLine(int y) {
793
 
    int  zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE];
794
 
    RE_APixstrExt *ap;       /* iterator for the face-lists                  */
 
1002
 
 
1003
 
 
1004
/* threadsafe global arrays, too large for stack */
 
1005
typedef struct zbufline {
 
1006
        int  zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE];
 
1007
        struct RE_faceField osastack[RE_MAX_FACES_PER_PIXEL + 1]; 
 
1008
} zbufline;
 
1009
 
 
1010
static zbufline zb1, zb2;
 
1011
 
 
1012
static void renderZBufLine(int y, RE_COLBUFTYPE *colbuf1, RE_COLBUFTYPE *colbuf2, RE_COLBUFTYPE *colbuf3) 
 
1013
{
 
1014
     RE_APixstrExt *ap;       /* iterator for the face-lists                  */
 
1015
        RE_COLBUFTYPE  collector[4];
 
1016
        RE_COLBUFTYPE  sampcol[RE_MAX_OSA_COUNT * 4];
 
1017
    RE_COLBUFTYPE *j = NULL; /* generic pixel pointer                        */
795
1018
        int apteller;
796
1019
    int x;                   /* pixel counter                                */
797
 
    RE_COLBUFTYPE *colbuf;   /* pointer into the line buffer                 */
798
 
    RE_COLBUFTYPE *j = NULL; /* generic pixel pointer                        */
799
1020
    int i;                   /* yet another counter                          */
800
1021
    int stackDepth;          /* faces-behind-this-pixel counter              */
801
 
        struct RE_faceField RE_OSAstack[RE_MAX_FACES_PER_PIXEL + 1]; 
802
 
        int RE_OSAstack_ptr;    /* Points to the lowest empty field. The indexed */
803
 
                            /* field is NOT readable.                        */
 
1022
        int osastack_ptr;       /* Points to the lowest empty field. The indexed */
 
1023
        zbufline *zbl;
 
1024
 
 
1025
        /* thread safe row buffers */
 
1026
        if(y & 1) zbl= &zb1;
 
1027
        else zbl= &zb2;
804
1028
        
805
 
    /* Prepare buffers and iterators */
806
 
    colbuf    = AColourBuffer;
807
 
    eraseColBuf(AColourBuffer);
 
1029
    /* Prepare iterators */
808
1030
    ap        = APixbufExt + (zBufferWidth * (y - Aminy));
809
1031
        apteller  = (zBufferWidth * (y - Aminy));
810
1032
        
811
1033
    /* Rendering: give the right colour to this pixel (shade it) */
812
 
        for( x = 0; x < bufferWidth; x++, ap++, colbuf+=4) {
 
1034
        for( x = 0; x < R.rectx; x++, ap++, colbuf1+=4, colbuf2+=4, colbuf3+=4) {
813
1035
                if(ap->t[0]) {
814
1036
            /* reset sample collector */
815
1037
            j = sampcol;
816
1038
            for(i = 0; i < osaNr; i++, j+=4) { 
817
 
                j[0] = RE_ZERO_COLOUR_FLOAT; j[1] = RE_ZERO_COLOUR_FLOAT; 
818
 
                j[2] = RE_ZERO_COLOUR_FLOAT; j[3] = RE_ZERO_COLOUR_FLOAT;
 
1039
                j[0] = 0.0f; j[1] = 0.0f; 
 
1040
                j[2] = 0.0f; j[3] = 0.0f;
819
1041
            };
820
1042
 
821
1043
            /* a. count and sort number of faces */
822
 
            stackDepth = countAndSortPixelFaces(zrow, ap);
 
1044
            stackDepth = countAndSortPixelFaces( zbl->zrow, ap);
823
1045
                        
824
1046
            /* b,c. oversample all subpixels, then integrate                 */
825
 
                        RE_OSAstack_ptr = 0;
826
 
                        RE_OSAstack_ptr = composeStack(zrow,
827
 
                                                                                   RE_OSAstack, RE_OSAstack_ptr,
828
 
                                                                                   stackDepth, x, y, osaNr);
829
 
                        integratePerSubStack(RE_OSAstack, RE_OSAstack_ptr, 
830
 
                                                                 x, y, osaNr); 
831
 
                        
832
 
                        /* d. Gamma corrected blending                                   */
833
 
                        sampleFloatColV2FloatColV(sampcol, colbuf, osaNr);
 
1047
                        osastack_ptr = 0;
 
1048
                        osastack_ptr = composeStack(zbl->zrow, collector, zbl->osastack, osastack_ptr, 
 
1049
                                                                                stackDepth, x, y, osaNr);
 
1050
                        integratePerSubStack(sampcol, zbl->osastack, osastack_ptr,  x, y, osaNr); 
 
1051
                        
 
1052
                        /* d. Gamma corrected blending and Gaussian                      */
 
1053
                        sampleFloatColV2FloatColVFilter(sampcol, colbuf1, colbuf2, colbuf3, osaNr);
 
1054
                        
834
1055
                } else {
835
1056
                        /* Remember to do things back-to-front!                          */
836
1057
                        
837
1058
                        /* This is a bit dirty. Depending on sky-mode, the pixel is      */
838
1059
                        /* blended in differently.                                       */
839
 
                        renderSkyPixelFloat(x, y);
840
 
                        cpFloatColV(collector, colbuf);
841
 
 
 
1060
                        renderSkyPixelFloat(collector, x, y);
 
1061
                        
 
1062
                        j = sampcol;
 
1063
                        for(i = 0; i < osaNr; i++, j+=4) { 
 
1064
                                j[0]= collector[0]; j[1]= collector[1];
 
1065
                                j[2]= collector[2]; j[3]= collector[3];
 
1066
                        }
 
1067
                        
 
1068
                        sampleFloatColV2FloatColVFilter(sampcol, colbuf1, colbuf2, colbuf3, osaNr);
 
1069
                        
 
1070
                        
842
1071
                        /* Spothalos are part of the normal pixelshader, so for covered  */
843
1072
                        /* pixels they are handled ok. They are 'normally' alpha blended */
844
1073
                        /* onto the existing colour in the collector.                    */
845
1074
                        if(R.flag & R_LAMPHALO) {
846
1075
                                renderSpotHaloPixel(x, y, collector);
847
 
                                addAlphaOverFloat(colbuf, collector);
 
1076
                                if(do_gamma) {
 
1077
                                        collector[0]= gammaCorrect(collector[0]);
 
1078
                                        collector[1]= gammaCorrect(collector[1]);
 
1079
                                        collector[2]= gammaCorrect(collector[2]);
 
1080
                                }
 
1081
                                addAlphaOverFloat(colbuf2+4, collector);
848
1082
                        }
849
 
                        
850
1083
                }
851
 
    } /* End of pixel loop */
852
 
    
853
 
} /* End of void renderZBufLine(int y) */
854
 
 
855
 
 
856
 
/* ------------------------------------------------------------------------- */
857
 
 
858
 
int fillZBufDistances() 
859
 
{
860
 
    int keepLooping = 1;
861
 
 
862
 
    keepLooping = zBufferAllFaces(); /* Solid and transparent faces*/
863
 
    keepLooping = zBufferAllHalos() && keepLooping; /* ...and halos*/
864
 
    return keepLooping;
865
 
 
866
 
} /* End of void fillZBufDistances() */
 
1084
    } 
 
1085
 
1086
 
 
1087
 
 
1088
/**
 
1089
 * Fills in distances of faces in the z buffer.
 
1090
 *
 
1091
 * Halo z buffering ---------------------------------------------- 
 
1092
 *
 
1093
 * A halo is treated here as a billboard: no z-extension, always   
 
1094
 * oriented perpendicular to the viewer. The rest of the z-buffer  
 
1095
 * stores face-numbers first, then calculates colours as the       
 
1096
 * final image is rendered. We'll use the same approach here,      
 
1097
 * which differs from the original method (which was add halos per 
 
1098
                                                                                   * scan line). This means that the z-buffer now also needs to      
 
1099
 * store info about what sort of 'thing' the index refers to.      
 
1100
 *                                                                 
 
1101
 * Halo extension:                                                 
 
1102
 * h.maxy  ---------                                               
 
1103
 *         |          h.xs + h.rad                                 
 
1104
 *             |      h.xs                                         
 
1105
 *                 |  h.xs - h.rad                                 
 
1106
 * h.miny  ---------                                               
 
1107
 *                                                                 
 
1108
 * These coordinates must be clipped to picture size.              
 
1109
 * I'm not quite certain about halo numbering.                     
 
1110
 *                                                                 
 
1111
 * Halos and jittering -------------------------------------------  
 
1112
 *                                                                 
 
1113
 * Halos were not jittered previously. Now they are. I wonder      
 
1114
 * whether this may have some adverse effects here.                
 
1115
 
 
1116
 * @return 1 for succes, 0 if the operation was interrupted.
 
1117
 */
867
1118
 
868
1119
/* ------------------------------------------------------------------------- */
869
1120
/* Transparent faces and the 'Azvoordeel'                                    */
878
1129
 
879
1130
/*  static int RE_treat_face_as_opaque; */
880
1131
 
881
 
int zBufferAllFaces(void) 
 
1132
static int zBufferAllFaces(void) 
882
1133
{
 
1134
        VlakRen *vlr=NULL;
 
1135
        unsigned int zvlnr;
 
1136
        int faceCounter;
883
1137
    int keepLooping = 1; 
884
 
    int faceCounter; /* counter for face number */
885
1138
    float vec[3], hoco[4], mul, zval, fval; 
886
1139
    Material *ma=0;
887
1140
    
893
1146
/*      RE_treat_face_as_opaque = 1; */
894
1147
        
895
1148
        while ( (faceCounter < R.totvlak) && keepLooping) {
896
 
                if((faceCounter & 255)==0) { Zvlr= R.blovl[faceCounter>>8]; }
897
 
                else Zvlr++;
 
1149
                if((faceCounter & 255)==0) { vlr= R.blovl[faceCounter>>8]; }
 
1150
                else vlr++;
898
1151
                
899
 
                ma= Zvlr->mat;
 
1152
                ma= vlr->mat;
900
1153
                
901
1154
                /* VERY dangerous construction... zoffs is set by a slide in the ui */
902
1155
                /* so it should be safe...                                          */
903
1156
                if((ma->mode & (MA_ZTRA)) && (ma->zoffs != 0.0)) {
904
1157
                        mul= 0x7FFFFFFF;
905
 
                        zval= mul*(1.0+Zvlr->v1->ho[2]/Zvlr->v1->ho[3]);
 
1158
                        zval= mul*(1.0+vlr->v1->ho[2]/vlr->v1->ho[3]);
906
1159
                        
907
 
                        VECCOPY(vec, Zvlr->v1->co);
 
1160
                        VECCOPY(vec, vlr->v1->co);
908
1161
                        /* z is negatief, wordt anders geclipt */ 
909
1162
                        vec[2]-= ma->zoffs;
910
1163
                        RE_projectverto(vec, hoco); /* vec onto hoco */
915
1168
                        Azvoordeel= 0;
916
1169
                } 
917
1170
                /* face number is used in the fill functions */
918
 
                Zvlnr = faceCounter + 1;
 
1171
                zvlnr = faceCounter + 1;
919
1172
                
920
 
                if(Zvlr->flag & R_VISIBLE) { /* might test for this sooner...  */
 
1173
                if(vlr->flag & R_VISIBLE) { /* might test for this sooner...  */
921
1174
                        
922
 
                        if(ma->mode & (MA_WIRE)) zbufclipwire(Zvlr);
 
1175
                        if(ma->mode & (MA_WIRE)) zbufclipwire(zvlnr, vlr);
923
1176
                        else {
924
 
                                zbufclip(Zvlr->v1->ho,   Zvlr->v2->ho,   Zvlr->v3->ho, 
925
 
                                                 Zvlr->v1->clip, Zvlr->v2->clip, Zvlr->v3->clip);
926
 
                                if(Zvlr->v4) {
927
 
                                        Zvlnr+= 0x800000; /* in a sense, the 'adjoint' face */
928
 
                                        zbufclip(Zvlr->v1->ho,   Zvlr->v3->ho,   Zvlr->v4->ho, 
929
 
                                                         Zvlr->v1->clip, Zvlr->v3->clip, Zvlr->v4->clip);
 
1177
                                zbufclip(zvlnr, vlr->v1->ho,   vlr->v2->ho,   vlr->v3->ho, 
 
1178
                                                 vlr->v1->clip, vlr->v2->clip, vlr->v3->clip);
 
1179
                                if(vlr->v4) {
 
1180
                                        zvlnr+= 0x800000; /* in a sense, the 'adjoint' face */
 
1181
                                        zbufclip(zvlnr, vlr->v1->ho,   vlr->v3->ho,   vlr->v4->ho, 
 
1182
                                                         vlr->v1->clip, vlr->v3->clip, vlr->v4->clip);
930
1183
                                }
931
1184
                        }
932
1185
                }
935
1188
        }
936
1189
        
937
1190
    return keepLooping;
938
 
} /* End of int zBufferAllFaces(void) */
 
1191
}
 
1192
 
 
1193
/**
 
1194
 * Fills in distances of halos in the z buffer.
 
1195
 * @return 1 for succes, 0 if the operation was interrupted.
 
1196
 */
939
1197
 
940
1198
/* ------------------------------------------------------------------------- */
941
1199
/* We cheat a little here: we only fill the halo on the first pass, and we   */
943
1201
/* halos to be flat (billboards), so we do not have to correct the z range   */
944
1202
/* every time we insert a halo. Also, halos fall off to zero at the edges,   */
945
1203
/* so we can safely render them in pixels where they do not exist.           */
946
 
int zBufferAllHalos(void)
 
1204
static int zBufferAllHalos(void)
947
1205
{
948
1206
    HaloRen *har = NULL;
949
 
    unsigned int haloCounter = 0;
 
1207
    int haloCounter = 0;
950
1208
    int dist = 0;
951
1209
    int keepLooping = 1;
952
1210
    short miny = 0, maxy = 0, minx = 0, maxx = 0;
1003
1261
        } 
1004
1262
 
1005
1263
    return keepLooping;
1006
 
} /* end of int zbufferAllHalos(void) */
1007
 
 
1008
 
/* ------------------------------------------------------------------------- */
 
1264
}
 
1265
/* ------------------------------------------------------------------------- */
 
1266
 
 
1267
/**
 
1268
* Fills in distances of all faces in a z buffer, for given jitter settings.
 
1269
 */
 
1270
static int fillZBufDistances() 
 
1271
{
 
1272
    int keepLooping = 1;
 
1273
        
 
1274
    keepLooping = zBufferAllFaces(); /* Solid and transparent faces*/
 
1275
    keepLooping = zBufferAllHalos() && keepLooping; /* ...and halos*/
 
1276
    return keepLooping;
 
1277
        
 
1278
}
 
1279
 
 
1280
 
 
1281
 
 
1282
#if 0
 
1283
/* ------------------------------------------------------------------------- */
 
1284
/**
 
1285
 * One more filler: fill in halo data in z buffer.
 
1286
 * Empty so far, but may receive content of halo loop.
 
1287
 */
1009
1288
void zBufferFillHalo(void)
1010
1289
{
1011
1290
    /* so far, intentionally empty */
1012
 
} /* end of void zBufferFillHalo(void) */
1013
 
 
1014
 
/* ------------------------------------------------------------------------- */
1015
 
void zBufferFillFace(float *v1, float *v2, float *v3)  
1016
 
{
1017
 
        /* Coordinates of the vertices are specified in ZCS */
1018
 
        int apteller, apoffsetteller;
1019
 
        double z0; /* used as temp var*/
1020
 
        double xx1;
1021
 
        double zxd,zyd,zy0, tmp;
1022
 
        float *minv,*maxv,*midv;
1023
 
        register int zverg,zvlak,x;
1024
 
        int my0,my2,sn1,sn2,rectx,zd;
1025
 
        int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2, mask;
1026
 
 
1027
 
        /* These used to be doubles.  We may want to change them back if the     */
1028
 
        /* loss of accuracy proves to be a problem? There does not seem to be    */
1029
 
        /* any performance issues here, so I'll just keep the doubles.           */
1030
 
        /*      float vec0[3], vec1[3], vec2[3]; */
1031
 
        double vec0[3], vec1[3], vec2[3];
1032
 
 
1033
 
        /* MIN MAX */
1034
 
        /* sort vertices for min mid max y value */
1035
 
        if(v1[1]<v2[1]) {
1036
 
                if(v2[1]<v3[1])      { minv=v1; midv=v2; maxv=v3;}
1037
 
                else if(v1[1]<v3[1]) { minv=v1; midv=v3; maxv=v2;}
1038
 
                else                 { minv=v3; midv=v1; maxv=v2;}
1039
 
        }
1040
 
        else {
1041
 
                if(v1[1]<v3[1])          { minv=v2; midv=v1; maxv=v3;}
1042
 
                else if(v2[1]<v3[1]) { minv=v2; midv=v3; maxv=v1;}
1043
 
                else                 { minv=v3; midv=v2; maxv=v1;}
1044
 
        }
1045
 
 
1046
 
        if(minv[1] == maxv[1]) return;  /* security to remove 'zero' size faces */
1047
 
 
1048
 
        my0  = ceil(minv[1]);
1049
 
        my2  = floor(maxv[1]);
1050
 
        omsl = floor(midv[1]);
1051
 
 
1052
 
        /* outside the current z buffer slice: clip whole face */
1053
 
        if( (my2 < Aminy) || (my0 > Amaxy)) return;
1054
 
 
1055
 
        if(my0<Aminy) my0= Aminy;
1056
 
 
1057
 
        /* EDGES : THE LONGEST */
1058
 
        xx1= maxv[1]-minv[1];
1059
 
        if(xx1>2.0/65536.0) {
1060
 
                z0= (maxv[0]-minv[0])/xx1;
1061
 
                
1062
 
                tmp= (-65536.0*z0);
1063
 
                dx0= CLAMPIS(tmp, INT_MIN, INT_MAX);
1064
 
                
1065
 
                tmp= 65536.0*(z0*(my2-minv[1])+minv[0]);
1066
 
                xs0= CLAMPIS(tmp, INT_MIN, INT_MAX);
1067
 
        }
1068
 
        else {
1069
 
                dx0= 0;
1070
 
                xs0= 65536.0*(MIN2(minv[0],maxv[0]));
1071
 
        }
1072
 
        /* EDGES : THE TOP ONE */
1073
 
        xx1= maxv[1]-midv[1];
1074
 
        if(xx1>2.0/65536.0) {
1075
 
                z0= (maxv[0]-midv[0])/xx1;
1076
 
                
1077
 
                tmp= (-65536.0*z0);
1078
 
                dx1= CLAMPIS(tmp, INT_MIN, INT_MAX);
1079
 
                
1080
 
                tmp= 65536.0*(z0*(my2-midv[1])+midv[0]);
1081
 
                xs1= CLAMPIS(tmp, INT_MIN, INT_MAX);
1082
 
        }
1083
 
        else {
1084
 
                dx1= 0;
1085
 
                xs1= 65536.0*(MIN2(midv[0],maxv[0]));
1086
 
        }
1087
 
        /* EDGES : THE BOTTOM ONE */
1088
 
        xx1= midv[1]-minv[1];
1089
 
        if(xx1>2.0/65536.0) {
1090
 
                z0= (midv[0]-minv[0])/xx1;
1091
 
                
1092
 
                tmp= (-65536.0*z0);
1093
 
                dx2= CLAMPIS(tmp, INT_MIN, INT_MAX);
1094
 
                
1095
 
                tmp= 65536.0*(z0*(omsl-minv[1])+minv[0]);
1096
 
                xs2= CLAMPIS(tmp, INT_MIN, INT_MAX);
1097
 
        }
1098
 
        else {
1099
 
                dx2= 0;
1100
 
                xs2= 65536.0*(MIN2(minv[0],midv[0]));
1101
 
        }
1102
 
 
1103
 
        /* ZBUF DX DY */
1104
 
        /* xyz_1 = v_1 - v_2 */
1105
 
        MTC_diff3DFF(vec1, v1, v2);
1106
 
        /* xyz_2 = v_2 - v_3 */
1107
 
        MTC_diff3DFF(vec2, v2, v3);
1108
 
        /* xyz_0 = xyz_1 cross xyz_2 */
1109
 
        MTC_cross3Double(vec0, vec1, vec2);
1110
 
 
1111
 
        /* cross product of two of the sides is 0 => this face is too small */
1112
 
        if(vec0[2]==0.0) return;
1113
 
 
1114
 
        if(midv[1] == maxv[1]) omsl= my2;
1115
 
        if(omsl < Aminy) omsl= Aminy-1;  /* make sure it takes the first loop entirely */
1116
 
 
1117
 
        while (my2 > Amaxy) {  /* my2 can be larger */
1118
 
                xs0+=dx0;
1119
 
                if (my2<=omsl) {
1120
 
                        xs2+= dx2;
1121
 
                }
1122
 
                else{
1123
 
                        xs1+= dx1;
1124
 
                }
1125
 
                my2--;
1126
 
        }
1127
 
 
1128
 
        xx1= (vec0[0]*v1[0]+vec0[1]*v1[1])/vec0[2]+v1[2];
1129
 
 
1130
 
        zxd= -vec0[0]/vec0[2];
1131
 
        zyd= -vec0[1]/vec0[2];
1132
 
        zy0= my2*zyd+xx1;
1133
 
        zd= (int)CLAMPIS(zxd, INT_MIN, INT_MAX);
1134
 
 
1135
 
        /* start-ofset in rect */
1136
 
        /*      rectx= R.rectx;  */
1137
 
        /* I suspect this var needs very careful setting... When edge rendering  */
1138
 
        /* is on, this is strange */
1139
 
        rectx = zBufferWidth;
1140
 
        apoffsetteller = rectx*(my2-Aminy);
1141
 
 
1142
 
        mask= 1<<Zsample;
1143
 
        zvlak= Zvlnr;
1144
 
 
1145
 
        xs3= 0;         /* flag */
1146
 
        if(dx0>dx1) {
1147
 
                MTC_swapInt(&xs0, &xs1);
1148
 
                MTC_swapInt(&dx0, &dx1);
1149
 
                xs3= 1; /* flag */
1150
 
 
1151
 
        }
1152
 
 
1153
 
        for(y=my2;y>omsl;y--) {
1154
 
 
1155
 
                sn1= xs0>>16;
1156
 
                xs0+= dx0;
1157
 
 
1158
 
                sn2= xs1>>16;
1159
 
                xs1+= dx1;
1160
 
 
1161
 
                sn1++;
1162
 
 
1163
 
                if(sn2>=rectx) sn2= rectx-1;
1164
 
                if(sn1<0) sn1= 0;
1165
 
                zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX);
1166
 
                apteller = apoffsetteller + sn1;
1167
 
                x= sn2-sn1;
1168
 
                
1169
 
                zverg-= Azvoordeel;
1170
 
                
1171
 
                while(x>=0) {
1172
 
                        insertObject(apteller, /*  RE_treat_face_as_opaque, */ Zvlnr, RE_POLY, zverg, mask);
1173
 
                        zverg+= zd;
1174
 
                        apteller++;
1175
 
                        x--;
1176
 
                }
1177
 
                zy0-= zyd;
1178
 
                apoffsetteller -= rectx;
1179
 
        }
1180
 
 
1181
 
        if(xs3) {
1182
 
                xs0= xs1;
1183
 
                dx0= dx1;
1184
 
        }
1185
 
        if(xs0>xs2) {
1186
 
                xs3= xs0;
1187
 
                xs0= xs2;
1188
 
                xs2= xs3;
1189
 
                xs3= dx0;
1190
 
                dx0= dx2;
1191
 
                dx2= xs3;
1192
 
        }
1193
 
 
1194
 
        for(; y>=my0; y--) {
1195
 
 
1196
 
                sn1= xs0>>16;
1197
 
                xs0+= dx0;
1198
 
 
1199
 
                sn2= xs2>>16;
1200
 
                xs2+= dx2;
1201
 
 
1202
 
                sn1++;
1203
 
 
1204
 
                if(sn2>=rectx) sn2= rectx-1;
1205
 
                if(sn1<0) sn1= 0;
1206
 
                zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX);
1207
 
                apteller = apoffsetteller + sn1;
1208
 
                x= sn2-sn1;
1209
 
      
1210
 
                zverg-= Azvoordeel;
1211
 
      
1212
 
                while(x>=0) {
1213
 
                        insertObject(apteller, /*  RE_treat_face_as_opaque, */ Zvlnr, RE_POLY, zverg, mask);
1214
 
                        zverg+= zd;
1215
 
                        apteller++;
1216
 
                        x--;
1217
 
                }
1218
 
                
1219
 
                zy0-=zyd;
1220
 
                apoffsetteller -= rectx;
1221
 
        }
1222
 
} /* end of void zBufferFillFace(float *v1, float *v2, float *v3) */
1223
 
 
1224
 
/* ------------------------------------------------------------------------- */
1225
 
 
1226
 
void zBufferFillEdge(float *vec1, float *vec2)
1227
 
{
1228
 
        int apteller;
1229
 
        int start, end, x, y, oldx, oldy, ofs;
1230
 
        int dz, vergz, mask;
1231
 
        float dx, dy;
1232
 
        float v1[3], v2[3];
1233
 
        
1234
 
        dx= vec2[0]-vec1[0];
1235
 
        dy= vec2[1]-vec1[1];
1236
 
        
1237
 
        if(fabs(dx) > fabs(dy)) {
1238
 
 
1239
 
                /* all lines from left to right */
1240
 
                if(vec1[0]<vec2[0]) {
1241
 
                        VECCOPY(v1, vec1);
1242
 
                        VECCOPY(v2, vec2);
1243
 
                }
1244
 
                else {
1245
 
                        VECCOPY(v2, vec1);
1246
 
                        VECCOPY(v1, vec2);
1247
 
                        dx= -dx; dy= -dy;
1248
 
                }
1249
 
 
1250
 
                start= floor(v1[0]);
1251
 
                end= start+floor(dx);
1252
 
                if(end >= zBufferWidth) end = zBufferWidth - 1;
1253
 
                
1254
 
                oldy= floor(v1[1]);
1255
 
                dy/= dx;
1256
 
                
1257
 
                vergz= v1[2];
1258
 
                vergz-= Azvoordeel;
1259
 
                dz= (v2[2]-v1[2])/dx;
1260
 
                
1261
 
                apteller = zBufferWidth*(oldy-Aminy) +start;
1262
 
                mask  = 1<<Zsample;     
1263
 
                
1264
 
                if(dy<0) ofs= -zBufferWidth;
1265
 
                else ofs= zBufferWidth;
1266
 
                
1267
 
                for(x= start; x<=end; x++, /*  ap++, */ apteller++) {
1268
 
                        
1269
 
                        y= floor(v1[1]);
1270
 
                        if(y!=oldy) {
1271
 
                                oldy= y;
1272
 
                                apteller += ofs;
1273
 
                        }
1274
 
                        
1275
 
                        if(x>=0 && y>=Aminy && y<=Amaxy) {
1276
 
                                insertObject(apteller, /*  RE_treat_face_as_opaque, */ Zvlnr, RE_POLY, vergz, mask);
1277
 
                        }
1278
 
                        
1279
 
                        v1[1]+= dy;
1280
 
                        vergz+= dz;
1281
 
                }
1282
 
        }
1283
 
        else {
1284
 
        
1285
 
                /* all lines from top to bottom */
1286
 
                if(vec1[1]<vec2[1]) {
1287
 
                        VECCOPY(v1, vec1);
1288
 
                        VECCOPY(v2, vec2);
1289
 
                }
1290
 
                else {
1291
 
                        VECCOPY(v2, vec1);
1292
 
                        VECCOPY(v1, vec2);
1293
 
                        dx= -dx; dy= -dy;
1294
 
                }
1295
 
 
1296
 
                start= floor(v1[1]);
1297
 
                end= start+floor(dy);
1298
 
                
1299
 
                if(start>Amaxy || end<Aminy) return;
1300
 
                
1301
 
                if(end>Amaxy) end= Amaxy;
1302
 
                
1303
 
                oldx= floor(v1[0]);
1304
 
                dx/= dy;
1305
 
                
1306
 
                vergz= v1[2];
1307
 
                vergz-= Azvoordeel;
1308
 
                dz= (v2[2]-v1[2])/dy;
1309
 
 
1310
 
                apteller = zBufferWidth*(start-Aminy) +oldx;
1311
 
                
1312
 
                mask= 1<<Zsample;
1313
 
                                
1314
 
                if(dx<0) ofs= -1;
1315
 
                else ofs= 1;
1316
 
 
1317
 
                for(y= start; y<=end; y++, apteller += zBufferWidth) {
1318
 
                        
1319
 
                        x= floor(v1[0]);
1320
 
                        if(x!=oldx) {
1321
 
                                oldx= x;
1322
 
                                apteller += ofs;
1323
 
                        }
1324
 
                        
1325
 
                        if(x>=0 && y>=Aminy && (x < zBufferWidth)) {
1326
 
                                insertObject(apteller, /*  RE_treat_face_as_opaque, */ Zvlnr, RE_POLY, vergz, mask);
1327
 
                        }
1328
 
                        
1329
 
                        v1[0]+= dx;
1330
 
                        vergz+= dz;
1331
 
                }
1332
 
        }
1333
 
} /* End of void zBufferFillEdge(float *vec1, float *vec2) */
1334
 
 
 
1291
}
 
1292
#endif
1335
1293
 
1336
1294
/* ------------------------------------------------------------------------- */
1337
1295
/* Colour buffer related:                                                    */
1339
1297
/* It expects the values R.r.postigamma, R.r.postmul and R.r.postadd.         */
1340
1298
/* This is the standard transformation, more elaborate tools are for later.  */
1341
1299
/* ------------------------------------------------------------------------- */
1342
 
void std_transFloatColV2CharColV( RE_COLBUFTYPE *buf, char *target)
 
1300
void std_floatcol_to_charcol( float *buf, char *target)
1343
1301
{
1344
 
        float fval;
 
1302
        float col[3];
 
1303
 
 
1304
        float dither_value;
 
1305
        
 
1306
        dither_value = ((BLI_frand()-0.5)*R.r.dither_intensity)/256.0; 
1345
1307
        
1346
1308
        /* alpha */
1347
 
        if(buf[3]<=0.0) target[3]= 0;
1348
 
        else if(buf[3]>1.0) target[3]= 255;
1349
 
        else target[3]= 255.0*buf[3];
 
1309
        if((buf[3]+dither_value)<=0.0) target[3]= 0;
 
1310
        else if((buf[3]+dither_value)>1.0) target[3]= 255;
 
1311
        else target[3]= 255.0*(buf[3]+dither_value);
1350
1312
        
1351
1313
        if(R.r.postgamma==1.0) {
1352
1314
                /* r */
1353
 
                fval= R.r.postmul*buf[0] + R.r.postadd;
1354
 
                if(fval<=0.0) target[0]= 0;
1355
 
                else if(fval>1.0) target[0]= 255;
1356
 
                else target[0]= 255.0*fval;
1357
 
 
 
1315
                col[0]= R.r.postmul*buf[0] + R.r.postadd + dither_value;
1358
1316
                /* g */
1359
 
                fval= R.r.postmul*buf[1] + R.r.postadd;
1360
 
                if(fval<=0.0) target[1]= 0;
1361
 
                else if(fval>1.0) target[1]= 255;
1362
 
                else target[1]= 255.0*fval;
1363
 
 
 
1317
                col[1]= R.r.postmul*buf[1] + R.r.postadd + dither_value;
1364
1318
                /* b */
1365
 
                fval= R.r.postmul*buf[2] + R.r.postadd;
1366
 
                if(fval<=0.0) target[2]= 0;
1367
 
                else if(fval>1.0) target[2]= 255;
1368
 
                else target[2]= 255.0*fval;
1369
 
 
 
1319
                col[2]= R.r.postmul*buf[2] + R.r.postadd + dither_value;
1370
1320
        }
1371
1321
        else {
1372
1322
                /* putting the postmul within the pow() gives an
1374
1324
                 * are relevant then
1375
1325
                 */
1376
1326
        
1377
 
        
1378
1327
                /* r */
1379
 
                fval= pow(R.r.postmul*buf[0], R.r.postigamma) + R.r.postadd;
1380
 
                if(fval<=0.0) target[0]= 0;
1381
 
                else if(fval>1.0) target[0]= 255;
1382
 
                else target[0]= 255.0*fval;
1383
 
 
 
1328
                col[0]= pow(R.r.postmul*buf[0], R.r.postigamma) + R.r.postadd + dither_value;
1384
1329
                /* g */
1385
 
                fval=pow( R.r.postmul*buf[1], R.r.postigamma) + R.r.postadd;
1386
 
                if(fval<=0.0) target[1]= 0;
1387
 
                else if(fval>1.0) target[1]= 255;
1388
 
                else target[1]= 255.0*fval;
1389
 
 
 
1330
                col[1]= pow( R.r.postmul*buf[1], R.r.postigamma) + R.r.postadd + dither_value;
1390
1331
                /* b */
1391
 
                fval= pow(R.r.postmul*buf[2], R.r.postigamma) + R.r.postadd;
1392
 
                if(fval<=0.0) target[2]= 0;
1393
 
                else if(fval>1.0) target[2]= 255;
1394
 
                else target[2]= 255.0*fval;
1395
 
        }
1396
 
 
1397
 
} /* end of void std_transFloatColV2CharColV( RE_COLBUFTYPE *buf, uchar *target) */
1398
 
 
 
1332
                col[2]= pow(R.r.postmul*buf[2], R.r.postigamma) + R.r.postadd + dither_value;
 
1333
        }
 
1334
 
 
1335
        if(R.r.posthue!=0.0 || R.r.postsat!=1.0) {
 
1336
                float hsv[3];
 
1337
                
 
1338
                rgb_to_hsv(col[0], col[1], col[2], hsv, hsv+1, hsv+2);
 
1339
                hsv[0]+= R.r.posthue;
 
1340
                if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
 
1341
                hsv[1]*= R.r.postsat;
 
1342
                if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0;
 
1343
                hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2);
 
1344
        }
 
1345
        
 
1346
        if(col[0]<=0.0) target[0]= 0;
 
1347
        else if(col[0]>1.0) target[0]= 255;
 
1348
        else target[0]= 255.0*col[0];
 
1349
        
 
1350
        if(col[1]<=0.0) target[1]= 0;
 
1351
        else if(col[1]>1.0) target[1]= 255;
 
1352
        else target[1]= 255.0*col[1];
 
1353
 
 
1354
        if(col[2]<=0.0) target[2]= 0;
 
1355
        else if(col[2]>1.0) target[2]= 255;
 
1356
        else target[2]= 255.0*col[2];
 
1357
}
1399
1358
 
1400
1359
/* ----------------------------------------------------------------------------
1401
1360
 
1415
1374
  - key-alpha correction
1416
1375
    Key alpha means 'un-applying' the alpha. For fully covered pixels, this
1417
1376
        operation has no effect.
 
1377
  
 
1378
  - XXX WARNING! Added the inverse render gamma here, so this cannot be used external
 
1379
        without setting Osa or Gamme flags off (ton)
1418
1380
 
1419
1381
---------------------------------------------------------------------------- */
1420
 
void transferColourBufferToOutput(int y)
 
1382
/* used external! */
 
1383
void transferColourBufferToOutput( float *buf, int y)
1421
1384
{
1422
 
    /* Copy the contents of AColourBuffer to R.rectot + y * R.rectx */
 
1385
    /* Copy the contents of AColourBuffer3 to R.rectot + y * R.rectx */
1423
1386
    int x = 0;
1424
 
    RE_COLBUFTYPE *buf = AColourBuffer;
1425
 
    char *target = (char*) (R.rectot + (y * imageWidth));
 
1387
    char *target = (char*) (R.rectot + (y * R.rectx));
1426
1388
 
1427
 
        /* Copy the first <imageWidth> pixels. We can do some more clipping on    */
 
1389
        /* Copy the first <R.rectx> pixels. We can do some more clipping on    */
1428
1390
        /* the z buffer, I think.                                                 */
1429
 
        while (x < imageWidth) {
1430
 
 
1431
 
                std_transFloatColV2CharColV(buf, target);
1432
 
                
1433
 
                /* old function was: leave it for test */
1434
 
/*              cpFloatColV2CharColV(buf, target); */
1435
 
 
 
1391
        while (x < R.rectx) {
 
1392
 
 
1393
                
 
1394
                /* invert gamma corrected additions */
 
1395
                if(do_gamma) {
 
1396
                        buf[0] = invGammaCorrect(buf[0]);
 
1397
                        buf[1] = invGammaCorrect(buf[1]);
 
1398
                        buf[2] = invGammaCorrect(buf[2]);
 
1399
                }                       
 
1400
                        
 
1401
                std_floatcol_to_charcol(buf, target);
 
1402
                
1436
1403
                /*
1437
1404
                  Key-alpha mode:
1438
1405
                  Need to un-apply alpha if alpha is non-full. For full alpha,
1449
1416
        buf+=4;
1450
1417
        x++;
1451
1418
    }
1452
 
} /* end of void transferColourBufferToOutput(int y) */
 
1419
}
 
1420
 
 
1421
/* used for redisplay after render. assumes size globals to be set OK! */
 
1422
void RE_floatbuffer_to_output(void)
 
1423
{
 
1424
        float *buf= R.rectftot;
 
1425
        int pix= R.rectx*R.recty;
 
1426
        char *target = (char *)R.rectot;
 
1427
        
 
1428
        if(R.rectftot==NULL) return;
 
1429
 
 
1430
        while(pix--) {
 
1431
                std_floatcol_to_charcol(buf, target);
 
1432
                buf+= 4;
 
1433
                target+= 4;
 
1434
        }
 
1435
}
1453
1436
 
1454
1437
/* ------------------------------------------------------------------------- */
1455
1438
 
1456
 
void eraseColBuf(RE_COLBUFTYPE *buf) {
 
1439
static void eraseColBuf(RE_COLBUFTYPE *buf) 
 
1440
{
1457
1441
    /* By definition, the buffer's length is 4 * R.rectx items */
1458
1442
    int i = 0;
1459
 
/*      while (i < 4 * R.rectx) { */
1460
 
    while (i < 4 * bufferWidth) {
1461
 
        *buf = RE_ZERO_COLOUR_FLOAT;
 
1443
 
 
1444
    while (i < 4 * (R.rectx+3)) {
 
1445
        *buf = 0.0f;
1462
1446
        buf++; i++;
1463
1447
    }
1464
 
} /* End of void eraseColBuf(RE_COLBUFTYPE *buf) */
 
1448
1465
1449
 
1466
1450
/* ------------------------------------------------------------------------- */
1467
1451
 
1468
 
int calcDepth(float x, float y, void *data, int type)
1469
 
{
1470
 
    float view[3];
1471
 
        
1472
 
    if (type & RE_POLY) {
1473
 
        VlakRen* vlr = (VlakRen*) data;
1474
 
        VertRen* v1;
1475
 
        float dvlak, deler, fac, hoco_z, hoco_w;
1476
 
        int zbuf_co;
1477
 
        
1478
 
        v1 = vlr->v1;
1479
 
        
1480
 
        /* vertex dot face normal: WCS */
1481
 
        dvlak= v1->co[0]*vlr->n[0]+v1->co[1]*vlr->n[1]+v1->co[2]*vlr->n[2]; 
1482
 
        
1483
 
        /* jitter has been added to x, y ! */
1484
 
        /* view vector view: screen coords */
1485
 
                view[0]= (x+(R.xstart) + 0.5  );
1486
 
        
1487
 
        if(R.flag & R_SEC_FIELD) {
1488
 
            if(R.r.mode & R_ODDFIELD) view[1]= (y + R.ystart)*R.ycor;
1489
 
            else view[1]= (y+R.ystart + 1.0)*R.ycor;
1490
 
        } else view[1]= (y+R.ystart  + 0.5 )*R.ycor;
1491
 
        
1492
 
 
1493
 
                /* for pano, another rotation in the xz plane is needed.... */
1494
 
 
1495
 
        /* this is ok, in WCS */
1496
 
        view[2]= -R.viewfac;  /* distance to viewplane */
1497
 
        
1498
 
        /* face normal dot view vector: but how can this work? */
1499
 
                deler = MTC_dot3Float(vlr->n, view);
1500
 
        if (deler!=0.0) fac = dvlak/deler;
1501
 
        else fac = 0.0;
1502
 
        
1503
 
        /* indices are wrong.... but gives almost the right value? */
1504
 
        hoco_z =  (fac*view[2]) * R.winmat[2][2] + R.winmat[3][2]; 
1505
 
        hoco_w =  (fac*view[2]) * R.winmat[2][3] + R.winmat[3][3]; 
1506
 
        
1507
 
        zbuf_co = 0x7FFFFFFF*(hoco_z/hoco_w);            
1508
 
        
1509
 
        return  zbuf_co; /* z component of R.co */
1510
 
    } else if (type & RE_HALO) {
1511
 
        HaloRen* har = (HaloRen*) data;
1512
 
        return har->zBufDist;
1513
 
    }
1514
 
    return 0;
1515
 
} /* end of int calcDepth(float x, float y, void* data, int type) */
1516
 
 
1517
 
/* Maybe these two should be in pixelblendeing.c---------------------------- */
1518
 
 
1519
 
void blendOverFloat(int type, float* dest, float* source, void* data)
1520
 
{
1521
 
 
1522
 
    if (type & RE_POLY) {
1523
 
        VlakRen *ver = (VlakRen*) data;
1524
 
        if ((ver->mat != NULL) && (ver->mat->add > RE_FACE_ADD_THRESHOLD)) {
1525
 
            char addf = (char) (ver->mat->add * 255.0);
1526
 
            addalphaAddfacFloat(dest, source, addf);
 
1452
 
 
1453
/** 
 
1454
 * Fill the accumulation buffer APixbufExt with face and halo indices. 
 
1455
 * Note: Uses globals.
 
1456
 * @param y the line number to set
 
1457
 */
 
1458
static void calcZBufLine(int y)
 
1459
{
 
1460
        /* These function pointers are used for z buffer filling.    */
 
1461
        extern void (*zbuffunc)(unsigned int, float *, float *, float *);
 
1462
        extern void (*zbuflinefunc)(unsigned int, float *, float *);
 
1463
        int part;
 
1464
    int keepLooping = 1;
 
1465
        
 
1466
    if(y<0) return;
 
1467
        
 
1468
        /* zbuffer fix: here? */
 
1469
        Zmulx= ((float) R.rectx)/2.0;
 
1470
        Zmuly= ((float) R.recty)/2.0;
 
1471
        
 
1472
        
 
1473
        /* use these buffer fill functions */    
 
1474
        zbuffunc     = zBufferFillFace;
 
1475
        zbuflinefunc = zBufferFillEdge;
 
1476
        
 
1477
    /* (FORALL y: Aminy =< y =< Amaxy: y is buffered)                        */
 
1478
    if( (y < Aminy) || (y > Amaxy)) {
 
1479
 
 
1480
        /* prepare buffer */
 
1481
        part  = (y/RE_ZBUFLEN);     /* These two lines are mystifying me...  */
 
1482
        Aminy = part * RE_ZBUFLEN;  /* Possibly for rounding things?         */
 
1483
        Amaxy = Aminy + RE_ZBUFLEN - 1;
 
1484
                /*          if(Amaxy >= R.recty) Amaxy = R.recty-1; */
 
1485
        if(Amaxy >= R.recty) Amaxy = R.recty - 1;
 
1486
                resetZbuffer();
 
1487
        
 
1488
        Zsample = 0; /* Zsample is used internally !                         */
 
1489
        while ( (Zsample < osaNr) && keepLooping ) {
 
1490
            /* Apply jitter to this pixel. The jitter offsets are globals.   */
 
1491
            /* They are added in zbufclip()                                  */
 
1492
            /* Negative: these offsets are added to the vertex coordinates   */
 
1493
            /* so it equals translating viewpoint over the positive vector.  */
 
1494
            Zjitx= -jit[Zsample][0]-0.5;
 
1495
            Zjity= -jit[Zsample][1]-0.5;
 
1496
                        
 
1497
            keepLooping = fillZBufDistances();
 
1498
            
 
1499
            if(RE_local_test_break()) keepLooping = 0;
 
1500
            Zsample++;
1527
1501
        }
1528
 
        else
1529
 
            addAlphaOverFloat(dest, source);
1530
 
    } else if (type & RE_HALO) {
1531
 
        HaloRen *har= (HaloRen*) data;
1532
 
        addalphaAddfacFloat(dest, source, har->add);
1533
 
    } else if (type & RE_SKY) {
1534
 
                addAlphaOverFloat(dest, source);
1535
 
        }
1536
 
 
1537
 
} /* end of void blendOverFloat(int , float*, float*, void*) */
1538
 
 
1539
 
/* ------------------------------------------------------------------------- */
1540
 
void blendOverFloatRow(int type, float* dest, float* source, 
1541
 
                       void* data, int mask, int osaNr) 
1542
 
{
 
1502
    }
1543
1503
    
1544
 
    if (type & RE_POLY) {
1545
 
        VlakRen *ver = (VlakRen*) data;
1546
 
        if ((ver->mat != NULL) 
1547
 
            && (ver->mat->add > RE_FACE_ADD_THRESHOLD)) {
1548
 
            char addf = (ver->mat->add * 255.0);
1549
 
            addAddSampColF(dest, source, mask, osaNr, addf);
1550
 
        } else {
1551
 
            addOverSampColF(dest, source, mask, osaNr);
1552
 
        }
1553
 
    } else if (type & RE_HALO) {
1554
 
        HaloRen *har = (HaloRen*) data;
1555
 
        addAddSampColF(dest, source, mask, osaNr, har->add);
1556
 
    } else if (type & RE_SKY) {
1557
 
            addOverSampColF(dest, source, mask, osaNr);         
1558
 
        }
1559
 
} /* end of void blendOverFloatRow(int, float*, float*, void*) */
1560
 
 
1561
 
/* ------------------------------------------------------------------------- */
 
1504
 
1505
 
 
1506
 
 
1507
/* ------------------------------------------------------------------------- */
 
1508
 
 
1509
struct renderline {
 
1510
        RE_COLBUFTYPE *buf1, *buf2, *buf3;
 
1511
        int y;
 
1512
};
 
1513
 
 
1514
static int do_renderline(void *poin)
 
1515
{
 
1516
        struct renderline *rl= poin;
 
1517
        
 
1518
        renderZBufLine(rl->y, rl->buf1, rl->buf2, rl->buf3);
 
1519
        return 1;
 
1520
}
 
1521
 
 
1522
void zBufShadeAdvanced()
 
1523
{
 
1524
        RE_COLBUFTYPE *cycle;
 
1525
        struct renderline rl1, rl2;
 
1526
    int      y, keepLooping = 1;
 
1527
    float xjit = 0.0, yjit = 0.0;
 
1528
        
 
1529
    Zjitx=Zjity= -0.5; /* jitter preset: -0.5 pixel */
 
1530
        
 
1531
    /* Set osaNr. Treat 'no osa' as 'osa = 1' */
 
1532
    if(R.r.mode & R_OSA) {
 
1533
                osaNr = R.osa;
 
1534
                if(osaNr > 16) { /* check was moved from calcZBufLine */
 
1535
                        printf("zBufShadeAdvanced> osa too large (internal error)\n");
 
1536
                        G.afbreek= 1;
 
1537
                        return;
 
1538
                }
 
1539
    } else {
 
1540
        /* little hack */
 
1541
        osaNr = 1;
 
1542
        xjit = jit[0][0];
 
1543
        yjit = jit[0][1];
 
1544
        jit[0][0] = 0.0;
 
1545
        jit[0][1] = 0.0;        
 
1546
    }
 
1547
 
 
1548
        RE_setwindowclip(0, -1); /* just to be sure, reset the view matrix       */
 
1549
 
 
1550
        initRenderBuffers(R.rectx);
 
1551
 
 
1552
        y = 0;
 
1553
        while ( (y < R.recty) && keepLooping) {
 
1554
                
 
1555
                calcZBufLine(y);
 
1556
                
 
1557
                rl1.buf1= AColourBuffer1;
 
1558
                rl1.buf2= AColourBuffer2;
 
1559
                rl1.buf3= AColourBuffer3;
 
1560
                rl1.y= y;
 
1561
                
 
1562
                if(R.r.mode & R_THREADS) {
 
1563
                        if((y & 1)==0) {
 
1564
                                SDL_Thread *thread;
 
1565
                                
 
1566
                                thread = SDL_CreateThread(do_renderline, &rl1);
 
1567
                                if ( thread == NULL ) {
 
1568
                                        fprintf(stderr, "Unable to create thread");
 
1569
                                        G.afbreek= 1;
 
1570
                                        break;
 
1571
                                }
 
1572
                                
 
1573
                                rl2.buf1= AColourBuffer0;
 
1574
                                rl2.buf2= AColourBuffer1a;
 
1575
                                rl2.buf3= AColourBuffer2a;
 
1576
                                rl2.y= y+1;
 
1577
                                
 
1578
                                do_renderline(&rl2);
 
1579
                                
 
1580
                                SDL_WaitThread(thread, NULL);
 
1581
                                
 
1582
                                if(R.r.mode & R_GAUSS) {
 
1583
                                        float *rb1= AColourBuffer1, *rb2= AColourBuffer2, *rb1a= AColourBuffer1a, *rb2a= AColourBuffer2a;
 
1584
                                        int a= 4*(R.rectx + 4);
 
1585
                                        while(a--) {
 
1586
                                                *rb1 += *rb1a;
 
1587
                                                *rb2 += *rb2a;
 
1588
                                                *(rb1a++)= 0.0; rb1++;
 
1589
                                                *(rb2a++)= 0.0; rb2++;
 
1590
                                        }
 
1591
                                }
 
1592
                                else {
 
1593
                                        cycle= AColourBuffer1a; AColourBuffer1a= AColourBuffer1; AColourBuffer1= cycle;
 
1594
                                }
 
1595
                        }
 
1596
                }
 
1597
                else do_renderline(&rl1);
 
1598
                
 
1599
                if(y) {
 
1600
                        transferColourBufferToOutput(AColourBuffer3+4, y-1);
 
1601
                        
 
1602
                        if((y & 1)==0) RE_local_render_display(y-2, y-1, R.rectx, R.recty, R.rectot);           
 
1603
                }
 
1604
                
 
1605
                /* buffer cycling */
 
1606
                eraseColBuf(AColourBuffer3);
 
1607
                cycle= AColourBuffer3;
 
1608
                AColourBuffer3= AColourBuffer2;
 
1609
                AColourBuffer2= AColourBuffer1;
 
1610
                AColourBuffer1= AColourBuffer0;
 
1611
                AColourBuffer0= cycle;
 
1612
                
 
1613
                if(RE_local_test_break()) keepLooping = 0;
 
1614
                y++; 
 
1615
        }
 
1616
        if(keepLooping) transferColourBufferToOutput(AColourBuffer3+4, y-1);
 
1617
 
 
1618
        freeRenderBuffers();
 
1619
 
 
1620
        /* Edge rendering is done purely as a post-effect                        */
 
1621
        if(R.r.mode & R_EDGE) {
 
1622
                addEdges((char*)R.rectot, R.rectx, R.recty,
 
1623
                                 osaNr,
 
1624
                                 R.r.edgeint, R.r.same_mat_redux,
 
1625
                                 G.compat, G.notonlysolid,
 
1626
                                 R.r.edgeR, R.r.edgeG, R.r.edgeB);
 
1627
        }
 
1628
 
 
1629
        if (!(R.r.mode & R_OSA)) {
 
1630
                jit[0][0] = xjit;
 
1631
                jit[0][1] = yjit; 
 
1632
        }
 
1633
 
 
1634
 
1635
 
 
1636
/* ------------------------------------------------------------------------- */
 
1637
 
 
1638
 
 
1639
 
1562
1640
 
1563
1641
/* eof vanillaRenderPipe.c */