~ubuntu-branches/ubuntu/breezy/aqsis/breezy

« back to all changes in this revision

Viewing changes to render/imagepixel.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Will Newton
  • Date: 2004-12-07 20:06:49 UTC
  • Revision ID: james.westby@ubuntu.com-20041207200649-fccswkrvp4oc8lmn
Tags: upstream-0.9.3
ImportĀ upstreamĀ versionĀ 0.9.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Aqsis
 
2
// Copyright ļæ½ 1997 - 2001, Paul C. Gregory
 
3
//
 
4
// Contact: pgregory@aqsis.com
 
5
//
 
6
// This library is free software; you can redistribute it and/or
 
7
// modify it under the terms of the GNU General Public
 
8
// License as published by the Free Software Foundation; either
 
9
// version 2 of the License, or (at your option) any later version.
 
10
//
 
11
// This library is distributed in the hope that it will be useful,
 
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
// General Public License for more details.
 
15
//
 
16
// You should have received a copy of the GNU General Public
 
17
// License along with this library; if not, write to the Free Software
 
18
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
 
 
20
 
 
21
/** \file
 
22
                \brief Implements the CqImageBuffer class responsible for rendering the primitives and storing the results.
 
23
                \author Paul C. Gregory (pgregory@aqsis.com)
 
24
*/
 
25
 
 
26
#include        "aqsis.h"
 
27
 
 
28
#ifdef WIN32
 
29
#include    <windows.h>
 
30
#endif
 
31
#include        <math.h>
 
32
 
 
33
#include        "options.h"
 
34
#include        "renderer.h"
 
35
#include    "random.h"
 
36
#include        "imagepixel.h"
 
37
#include        "logging.h"
 
38
 
 
39
 
 
40
START_NAMESPACE( Aqsis )
 
41
 
 
42
//----------------------------------------------------------------------
 
43
/** Constructor
 
44
 */
 
45
 
 
46
CqImagePixel::CqImagePixel() :
 
47
        m_XSamples( 0 ),
 
48
        m_YSamples( 0 ),
 
49
        m_MaxDepth( FLT_MAX ),
 
50
        m_MinDepth( FLT_MAX ),
 
51
        m_OcclusionBoxId( -1 ),
 
52
        m_NeedsZUpdate( TqFalse )
 
53
{}
 
54
 
 
55
 
 
56
//----------------------------------------------------------------------
 
57
/** Destructor
 
58
 */
 
59
 
 
60
CqImagePixel::~CqImagePixel()
 
61
{}
 
62
 
 
63
 
 
64
//----------------------------------------------------------------------
 
65
/** Copy constructor
 
66
 */
 
67
 
 
68
CqImagePixel::CqImagePixel( const CqImagePixel& ieFrom )
 
69
{
 
70
    *this = ieFrom;
 
71
}
 
72
 
 
73
 
 
74
//----------------------------------------------------------------------
 
75
/** Allocate the subpixel samples array.
 
76
 * \param XSamples Integer samples count in X.
 
77
 * \param YSamples Integer samples count in Y.
 
78
 */
 
79
 
 
80
void CqImagePixel::AllocateSamples( TqInt XSamples, TqInt YSamples )
 
81
{
 
82
    if( m_XSamples != XSamples || m_YSamples != YSamples )
 
83
    {
 
84
        m_XSamples = XSamples;
 
85
        m_YSamples = YSamples;
 
86
        TqInt numSamples = m_XSamples * m_YSamples;
 
87
 
 
88
        if ( XSamples > 0 && YSamples > 0 )
 
89
        {
 
90
            m_aValues.resize( numSamples );
 
91
                        // Initialise the OpaqueSampleEntries to the correct depth for the data we are
 
92
                        // rendering, including any AOV data.
 
93
                        SqImageSample def( QGetRenderContext() ->GetOutputDataTotalSize() );
 
94
                        m_OpaqueValues.resize( numSamples, def );
 
95
            m_Samples.resize( numSamples );
 
96
                        m_DofOffsetIndices.resize( numSamples );
 
97
        }
 
98
    }
 
99
}
 
100
 
 
101
//----------------------------------------------------------------------
 
102
/** Fill in the sample array usig the multijitter function from GG IV.
 
103
 * \param vecPixel Cq2DVector pixel coordinate of this image element, used to make sure sample points are absolute, not relative.
 
104
 * \param fJitter Flag indicating whether to apply jittering to the sample points or not.
 
105
 */
 
106
 
 
107
void CqImagePixel::InitialiseSamples( std::vector<CqVector2D>& vecSamples, TqBool fJitter )
 
108
{
 
109
    TqFloat opentime = QGetRenderContext() ->optCurrent().GetFloatOption( "System", "Shutter" ) [ 0 ];
 
110
    TqFloat closetime = QGetRenderContext() ->optCurrent().GetFloatOption( "System", "Shutter" ) [ 1 ];
 
111
 
 
112
        TqInt numSamples = m_XSamples * m_YSamples;
 
113
    TqFloat subcell_width = 1.0f / numSamples;
 
114
    TqInt m = m_XSamples;
 
115
    TqInt n = m_YSamples;
 
116
    TqInt i, j;
 
117
 
 
118
    vecSamples.resize(numSamples);
 
119
    if ( !fJitter )
 
120
    {
 
121
        // Initialise the samples to the centre points.
 
122
        TqFloat XInc = ( 1.0f / m_XSamples ) / 2.0f;
 
123
        TqFloat YInc = ( 1.0f / m_YSamples ) / 2.0f;
 
124
        TqInt y;
 
125
        for ( y = 0; y < m_YSamples; y++ )
 
126
        {
 
127
            TqFloat YSam = YInc + ( YInc * y );
 
128
            TqInt x;
 
129
            for ( x = 0; x < m_XSamples; x++ )
 
130
                vecSamples[ ( y * m_XSamples ) + x ] = CqVector2D( XInc + ( XInc * x ), YSam );
 
131
        }
 
132
 
 
133
 
 
134
        // Fill in the sample times for motion blur, LOD and SubCellIndex entries
 
135
 
 
136
        TqFloat time = 0;
 
137
        TqInt nSamples = m_XSamples*m_YSamples;
 
138
        TqFloat dtime = 1.0f / nSamples;
 
139
 
 
140
        for ( i = 0; i < nSamples; i++ )
 
141
        {
 
142
            m_Samples[ i ].m_SubCellIndex = 0;
 
143
            m_Samples[ i ].m_DetailLevel = m_Samples[ i ].m_Time = time;
 
144
            time += dtime;
 
145
        }
 
146
 
 
147
 
 
148
    }
 
149
    else
 
150
    {
 
151
        static CqRandom random(  53 );
 
152
 
 
153
                // Initialize points to the "canonical" multi-jittered pattern.
 
154
 
 
155
        for ( i = 0; i < n; i++ )
 
156
        {
 
157
            for ( j = 0; j < m; j++ )
 
158
            {
 
159
                TqInt which = i * m + j;
 
160
                vecSamples[which].x( i );
 
161
                vecSamples[which].y( j );
 
162
            }
 
163
        }
 
164
 
 
165
        // Shuffle y coordinates within each row of cells.
 
166
        for ( i = 0; i < n; i++ )
 
167
        {
 
168
            for ( j = 0; j < m; j++ )
 
169
            {
 
170
                TqFloat t;
 
171
                TqInt k;
 
172
 
 
173
                k = random.RandomInt( n - 1 - i ) + i;
 
174
                TqInt i1 = i * m + j;
 
175
                TqInt i2 = k * m + j;
 
176
                assert( i1 < vecSamples.size() && i2 < vecSamples.size() );
 
177
                t = vecSamples[ i1 ].y();
 
178
                vecSamples[ i1 ].y( vecSamples[ i2 ].y() );
 
179
                vecSamples[ i2 ].y( t );
 
180
            }
 
181
        }
 
182
 
 
183
        // Shuffle x coordinates within each column of cells.
 
184
        for ( i = 0; i < m; i++ )
 
185
        {
 
186
            for ( j = 0; j < n; j++ )
 
187
            {
 
188
                TqFloat t;
 
189
                TqInt k;
 
190
 
 
191
                k = random.RandomInt( n - 1 - j ) + j;
 
192
                TqInt i1 = j * m + i;
 
193
                TqInt i2 = k * m + i;
 
194
                assert( i1 < vecSamples.size() && i2 < vecSamples.size() );
 
195
                t = vecSamples[ i1 ].x();
 
196
                vecSamples[ i1 ].x( vecSamples[ i2 ].x() );
 
197
                vecSamples[ i2 ].x( t );
 
198
 
 
199
            }
 
200
        }
 
201
 
 
202
 
 
203
        TqFloat subpixelheight = 1.0f / m_YSamples;
 
204
        TqFloat subpixelwidth = 1.0f / m_XSamples;
 
205
 
 
206
        TqInt which = 0;
 
207
        for ( i = 0; i < n; i++ )
 
208
        {
 
209
            TqFloat sy = i * subpixelheight;
 
210
            for ( j = 0; j < m; j++ )
 
211
            {
 
212
                TqFloat sx = j * subpixelwidth;
 
213
                TqFloat xindex = vecSamples[ which ].x();
 
214
                TqFloat yindex = vecSamples[ which ].y();
 
215
                vecSamples[ which ].x( xindex * subcell_width + ( subcell_width * 0.5f ) + sx );
 
216
                vecSamples[ which ].y( yindex * subcell_width + ( subcell_width * 0.5f ) + sy );
 
217
                m_Samples[ which ].m_SubCellIndex = static_cast<TqInt>( ( yindex * m_YSamples ) + xindex );
 
218
                which++;
 
219
            }
 
220
        }
 
221
 
 
222
                // Fill in the sample times for motion blur, detail levels for LOD and DoF.
 
223
 
 
224
                TqFloat time = 0;
 
225
                TqFloat dtime = 1.0f / numSamples;
 
226
                // We use the same random offset for each sample within a pixel.
 
227
                // This ensures the best possible coverage whilst still avoiding
 
228
                // aliasing. (I reckon). should minimise the noise.
 
229
                TqFloat randomTime = random.RandomFloat( dtime );
 
230
 
 
231
                TqFloat lod = 0;
 
232
                TqFloat dlod = dtime;
 
233
 
 
234
                for ( i = 0; i < numSamples; i++ )
 
235
                {
 
236
                        // Scale the value of time to the shutter time.
 
237
                        TqFloat t = time + randomTime;
 
238
                        t = ( closetime - opentime ) * t + opentime;
 
239
                        m_Samples[ i ].m_Time = t;
 
240
                        time += dtime;
 
241
 
 
242
                        m_Samples[ i ].m_DetailLevel = lod + random.RandomFloat( dlod );
 
243
                        lod += dlod;
 
244
                }
 
245
 
 
246
                // we calculate dof offsets in a grid inside the unit cube and then
 
247
                // project them into the unit circle. This means that the offset
 
248
                // positions match the offset bounding boxes calculated in CqBucket.
 
249
                // The sample test in RenderMicroPoly then can be split into a number
 
250
                // of smaller bounding boxes where we know in advance which samples
 
251
                // fall into each. (This is analagous to what we do for mb now as well).
 
252
                // note that there is an implied symmetry to the way we number the bounding
 
253
                // boxes here and in the bucket code where the bb's are created (it
 
254
                // should be left to right, top to bottom).
 
255
                TqFloat dx = 2.0 / m_XSamples;
 
256
                TqFloat dy = 2.0 / m_YSamples;
 
257
                // We use the same random offset for each sample within a pixel.
 
258
                // This ensures the best possible coverage whilst still avoiding
 
259
                // aliasing. (I reckon). should minimise the noise.
 
260
                TqFloat sx = random.RandomFloat(dx);
 
261
                TqFloat sy = random.RandomFloat(dy);
 
262
                TqFloat xOffset = -1.0 + sx;
 
263
                TqFloat yOffset = -1.0 + sy;
 
264
                which = 0;
 
265
                std::vector<CqVector2D> tmpDofOffsets(numSamples);
 
266
                for ( i = 0; i < m_YSamples; ++i )
 
267
        {
 
268
            for ( j = 0; j < m_XSamples; ++j )
 
269
                        {
 
270
                                tmpDofOffsets[which].x(xOffset);
 
271
                                tmpDofOffsets[which].y(yOffset);
 
272
                                ProjectToCircle(tmpDofOffsets[which]);
 
273
 
 
274
                                m_DofOffsetIndices[which] = which;
 
275
 
 
276
                                xOffset += dx;
 
277
                                which++;
 
278
                        }
 
279
                        yOffset += dy;
 
280
                        xOffset = -1.0 + sx;
 
281
                }
 
282
 
 
283
                // we now shuffle the dof offsets but remember which one went where.
 
284
                std::random_shuffle(m_DofOffsetIndices.begin(), m_DofOffsetIndices.end());
 
285
                for( i = 0; i < numSamples; ++i)
 
286
                {
 
287
                        m_Samples[m_DofOffsetIndices[i]].m_DofOffset = tmpDofOffsets[i];
 
288
                }
 
289
        }
 
290
        m_Data.m_Data.resize( QGetRenderContext()->GetOutputDataTotalSize() );
 
291
}
 
292
 
 
293
 
 
294
//----------------------------------------------------------------------
 
295
/** Clear the relevant data from the image element preparing it for the next usage.
 
296
 */
 
297
 
 
298
void CqImagePixel::Clear()
 
299
{
 
300
    TqInt i;
 
301
    for ( i = ( m_XSamples * m_YSamples ) - 1; i >= 0; i-- )
 
302
        {
 
303
                if(!m_aValues[i].empty())
 
304
                         m_aValues[ i ].clear( );
 
305
 
 
306
                m_OpaqueValues[i].m_flags = 0;
 
307
        }
 
308
 
 
309
        m_OpaqueSampleCount = 0;
 
310
        m_AnySampleUsesSampleList = TqFalse;
 
311
    m_MaxDepth = FLT_MAX;
 
312
    m_MinDepth =  FLT_MAX;
 
313
    m_OcclusionBoxId = -1;
 
314
    m_NeedsZUpdate = TqFalse;
 
315
}
 
316
 
 
317
 
 
318
//----------------------------------------------------------------------
 
319
/** Get the color at the specified sample point by blending the colors that appear at that point.
 
320
 */
 
321
 
 
322
void CqImagePixel::Combine()
 
323
{
 
324
    TqInt depthfilter = 0;
 
325
 
 
326
    const CqString* pstrDepthFilter = QGetRenderContext() ->optCurrent().GetStringOption( "Hider", "depthfilter" );
 
327
    const CqColor* pzThreshold = QGetRenderContext() ->optCurrent().GetColorOption( "limits", "zthreshold" );
 
328
        CqColor zThreshold(1.0f, 1.0f, 1.0f);   // Default threshold of 1,1,1 means that any objects that are partially transparent won't appear in shadow maps.
 
329
        if(NULL != pzThreshold)
 
330
                zThreshold = pzThreshold[0];
 
331
 
 
332
    if ( NULL != pstrDepthFilter )
 
333
    {
 
334
        if( !pstrDepthFilter[ 0 ].compare( "min" ) )
 
335
            depthfilter = 0;
 
336
        else if ( !pstrDepthFilter[ 0 ].compare( "midpoint" ) )
 
337
            depthfilter = 1;
 
338
        else if ( !pstrDepthFilter[ 0 ].compare( "max" ) )
 
339
            depthfilter = 2;
 
340
        else if ( !pstrDepthFilter[ 0 ].compare( "average" ) )
 
341
            depthfilter = 3;
 
342
        else
 
343
            std::cerr << warning << "Invalid depthfilter \"" << pstrDepthFilter[ 0 ].c_str() << "\", depthfilter set to \"min\"" << std::endl;
 
344
    }
 
345
 
 
346
    TqUint samplecount = 0;
 
347
    TqUint numsamples = XSamples() * YSamples();
 
348
        if(m_AnySampleUsesSampleList)
 
349
        {
 
350
                TqInt sampleIndex = 0;
 
351
                std::vector<std::vector<SqImageSample> >::iterator end = m_aValues.end();
 
352
                for ( std::vector<std::vector<SqImageSample> >::iterator samples = m_aValues.begin(); samples != end; ++samples )
 
353
                {
 
354
                        SqImageSample& opaqueValue = m_OpaqueValues[sampleIndex];
 
355
                        sampleIndex++;
 
356
 
 
357
                        if(!samples->empty())
 
358
                        {
 
359
                                if(opaqueValue.m_flags & SqImageSample::Flag_Valid)
 
360
                                {
 
361
                                        //      insert opaqueValue into samples in the right place.
 
362
                                        std::vector<SqImageSample>::iterator isi = samples->begin();
 
363
                                        std::vector<SqImageSample>::iterator isend = samples->end();
 
364
                                        while( isi != isend )
 
365
                                        {
 
366
                                                if((*isi).Depth() >= opaqueValue.Depth())
 
367
                                                        break;
 
368
 
 
369
                                                ++isi;
 
370
                                        }
 
371
                                        samples->insert(isi, opaqueValue);
 
372
                                }
 
373
 
 
374
                                // Find out if any of the samples are in a CSG tree.
 
375
                                TqBool bProcessed;
 
376
                                TqBool CqCSGRequired = CqCSGTreeNode::IsRequired();
 
377
                                if (CqCSGRequired)
 
378
                                        do
 
379
                                        {
 
380
                                                bProcessed = TqFalse;
 
381
                                                //Warning ProcessTree add or remove elements in samples list
 
382
                                                //We could not optimized the for loop here at all.
 
383
                                                for ( std::vector<SqImageSample>::iterator isample = samples->begin(); isample != samples->end(); ++isample )
 
384
                                                {
 
385
                                                        if ( isample->m_pCSGNode )
 
386
                                                        {
 
387
                                                                isample->m_pCSGNode->ProcessTree( *samples );
 
388
                                                                bProcessed = TqTrue;
 
389
                                                                break;
 
390
                                                        }
 
391
                                                }
 
392
                                        } while ( bProcessed );
 
393
 
 
394
                                CqColor samplecolor = gColBlack;
 
395
                                CqColor sampleopacity = gColBlack;
 
396
                                TqBool samplehit = TqFalse;
 
397
                                TqFloat opaqueDepths[2] = { FLT_MAX, FLT_MAX };
 
398
                                TqFloat maxOpaqueDepth = FLT_MAX;
 
399
 
 
400
                                for ( std::vector<SqImageSample>::reverse_iterator sample = samples->rbegin(); sample != samples->rend(); sample++ )
 
401
                                {
 
402
                                        if ( sample->m_flags & SqImageSample::Flag_Matte )
 
403
                                        {
 
404
                                                if ( sample->m_flags & SqImageSample::Flag_Occludes )
 
405
                                                {
 
406
                                                        // Optimise common case
 
407
                                                        samplecolor = gColBlack;
 
408
                                                        sampleopacity = gColBlack;
 
409
                                                }
 
410
                                                else
 
411
                                                {
 
412
                                                        samplecolor.SetColorRGB(
 
413
                                                                LERP( sample->Os().fRed(), samplecolor.fRed(), 0 ),
 
414
                                                                LERP( sample->Os().fGreen(), samplecolor.fGreen(), 0 ),
 
415
                                                                LERP( sample->Os().fBlue(), samplecolor.fBlue(), 0 )
 
416
                                                        );
 
417
                                                        sampleopacity.SetColorRGB(
 
418
                                                                LERP( sample->Os().fRed(), sampleopacity.fRed(), 0 ),
 
419
                                                                LERP( sample->Os().fGreen(), sampleopacity.fGreen(), 0 ),
 
420
                                                                LERP( sample->Os().fBlue(), sampleopacity.fBlue(), 0 )
 
421
                                                        );
 
422
                                                }
 
423
                                        }
 
424
                                        else
 
425
                                        {
 
426
                                                samplecolor = ( samplecolor * ( gColWhite - sample->Os() ) ) + sample->Cs();
 
427
                                                sampleopacity = ( ( gColWhite - sampleopacity ) * sample->Os() ) + sampleopacity;
 
428
                                        }
 
429
 
 
430
                                        // Now determine if the sample opacity meets the limit for depth mapping.
 
431
                                        // If so, store the depth in the appropriate nearest opaque sample slot.
 
432
                                        // The test is, if any channel of the opacity color is greater or equal to the threshold.
 
433
                                        if(sample->Os().fRed() >= zThreshold.fRed() || sample->Os().fGreen() >= zThreshold.fGreen() || sample->Os().fBlue() >= zThreshold.fBlue())
 
434
                                        {
 
435
                                                // Make sure we store the nearest and second nearest depth values.
 
436
                                                opaqueDepths[1] = opaqueDepths[0];
 
437
                                                opaqueDepths[0] = sample->Depth();
 
438
                                                // Store the max opaque depth too, if not already stored.
 
439
                                                if(!(maxOpaqueDepth < FLT_MAX))
 
440
                                                        maxOpaqueDepth = sample->Depth();
 
441
                                        }
 
442
                                        samplehit = TqTrue;
 
443
                                }
 
444
 
 
445
                                if ( samplehit )
 
446
                                {
 
447
                                        samplecount++;
 
448
                                }
 
449
 
 
450
                                // Write the collapsed color values back into the opaque entry.
 
451
                                if ( !samples->empty() )
 
452
                                {
 
453
                                        // Set the color and opacity.
 
454
                                        opaqueValue.SetCs( samplecolor );
 
455
                                        opaqueValue.SetOs( sampleopacity );
 
456
                                        opaqueValue.m_flags |= SqImageSample::Flag_Valid;
 
457
 
 
458
                                        if ( depthfilter != 0)
 
459
                                        {
 
460
                                                if ( depthfilter == 1 )
 
461
                                                {
 
462
                                                        //std::cerr << debug << "OpaqueDepths: " << opaqueDepths[0] << " - " << opaqueDepths[1] << std::endl;
 
463
                                                        // Use midpoint for depth
 
464
                                                        if ( samples->size() > 1 )
 
465
                                                                opaqueValue.SetDepth( ( opaqueDepths[0] + opaqueDepths[1] ) * 0.5f );
 
466
                                                        else
 
467
                                                                opaqueValue.SetDepth( FLT_MAX );
 
468
                                                }
 
469
                                                else if ( depthfilter == 2)
 
470
                                                {
 
471
                                                        opaqueValue.SetDepth( maxOpaqueDepth );
 
472
                                                }
 
473
                                                else if ( depthfilter == 3 )
 
474
                                                {
 
475
                                                        std::vector<SqImageSample>::iterator sample;
 
476
                                                        TqFloat totDepth = 0.0f;
 
477
                                                        TqInt totCount = 0;
 
478
                                                        for ( sample = samples->begin(); sample != samples->end(); sample++ )
 
479
                                                                if(sample->Os().fRed() >= zThreshold.fRed() || sample->Os().fGreen() >= zThreshold.fGreen() || sample->Os().fBlue() >= zThreshold.fBlue())
 
480
                                                                {
 
481
                                                                        totDepth += sample->Depth();
 
482
                                                                        totCount++;
 
483
                                                                }
 
484
                                                        totDepth /= totCount;
 
485
 
 
486
                                                        opaqueValue.SetDepth( totDepth );
 
487
                                                }
 
488
                                                // Default to "min"
 
489
                                        }
 
490
                                        else
 
491
                                                opaqueValue.SetDepth( opaqueDepths[0] );
 
492
                                }
 
493
                        }
 
494
                        else
 
495
                        {
 
496
                                if(opaqueValue.m_flags & SqImageSample::Flag_Valid)
 
497
                                {
 
498
                                        samplecount++;
 
499
                                }
 
500
                        }
 
501
                }
 
502
        }
 
503
        else
 
504
        {
 
505
                samplecount = m_OpaqueSampleCount;
 
506
        }
 
507
}
 
508
 
 
509
//----------------------------------------------------------------------
 
510
/** ReCalculate the min and max z values for this pixel
 
511
 */
 
512
 
 
513
void CqImagePixel::UpdateZValues()
 
514
{
 
515
    float currentMax = 0.0f;
 
516
    float currentMin = FLT_MAX;
 
517
        TqInt sampleIndex = 0;
 
518
    TqInt sx, sy;
 
519
    for ( sy = 0; sy < m_YSamples; sy++ )
 
520
    {
 
521
        for ( sx = 0; sx < m_XSamples; sx++ )
 
522
        {
 
523
                        SqImageSample& opaqueSample = m_OpaqueValues[ sampleIndex ];
 
524
                        if(opaqueSample.m_flags & SqImageSample::Flag_Valid)
 
525
            {
 
526
                                if ( opaqueSample.Depth() > currentMax )
 
527
                                {
 
528
                                        currentMax = opaqueSample.Depth();
 
529
                                }
 
530
                                if ( opaqueSample.Depth() < currentMin )
 
531
                                {
 
532
                                        currentMin = opaqueSample.Depth();
 
533
                                }
 
534
            }
 
535
            else
 
536
            {
 
537
                currentMax = FLT_MAX;
 
538
            }
 
539
 
 
540
                        sampleIndex++;
 
541
        }
 
542
    }
 
543
 
 
544
    m_MaxDepth = currentMax;
 
545
    m_MinDepth = currentMin;
 
546
}
 
547
 
 
548
//---------------------------------------------------------------------
 
549
 
 
550
END_NAMESPACE( Aqsis )