~ubuntu-branches/ubuntu/warty/aqsis/warty

« back to all changes in this revision

Viewing changes to libshaderexecenv/shadeops.cpp

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-08-24 07:25:04 UTC
  • Revision ID: james.westby@ubuntu.com-20040824072504-zf993vnevvisdsvb
Tags: upstream-0.9.1
ImportĀ upstreamĀ versionĀ 0.9.1

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 basic shader operations.
 
23
                \author Paul C. Gregory (pgregory@aqsis.com)
 
24
*/
 
25
 
 
26
#include        "aqsis.h"
 
27
 
 
28
#include        <math.h>
 
29
#include        <map>
 
30
#include        <vector>
 
31
#include        <string>
 
32
#include        <stdio.h>
 
33
 
 
34
#include        "shaderexecenv.h"
 
35
#include        "spline.h"
 
36
#include        "shadervm.h"
 
37
#include        "irenderer.h"
 
38
#include        "itexturemap.h"
 
39
#include        "ilightsource.h"
 
40
#include        "version.h"
 
41
 
 
42
START_NAMESPACE( Aqsis )
 
43
 
 
44
IqRenderer* QGetRenderContextI();
 
45
 
 
46
 
 
47
//----------------------------------------------------------------------
 
48
// SO_sprintf
 
49
// Helper function to process a string inserting variable, used in printf and format.
 
50
 
 
51
static  CqString        SO_sprintf( const char* str, int cParams, IqShaderData** apParams, int varyingindex )
 
52
{
 
53
    CqString strRes( "" );
 
54
    CqString strTrans = str;
 
55
    strTrans = strTrans.TranslateEscapes();
 
56
 
 
57
    TqUint i = 0;
 
58
    TqUint ivar = 0;
 
59
    while ( i < strTrans.size() )
 
60
    {
 
61
        switch ( strTrans[ i ] )
 
62
        {
 
63
        case '%':       // Insert variable.
 
64
            {
 
65
                i++;
 
66
                switch ( strTrans[ i ] )
 
67
                {
 
68
                case 'f':
 
69
                    {
 
70
                        TqFloat f;
 
71
                        apParams[ ivar++ ] ->GetFloat( f, varyingindex );
 
72
                        CqString strVal;
 
73
                        strVal.Format( "%f", f );
 
74
                        strRes += strVal;
 
75
                    }
 
76
                    break;
 
77
 
 
78
                case 'p':
 
79
                    {
 
80
                        CqVector3D vec;
 
81
                        apParams[ ivar++ ] ->GetPoint( vec, varyingindex );
 
82
                        CqString strVal;
 
83
                        strVal.Format( "%f,%f,%f", vec.x(), vec.y(), vec.z() );
 
84
                        strRes += strVal;
 
85
                    }
 
86
                    break;
 
87
 
 
88
                case 'c':
 
89
                    {
 
90
                        CqColor col;
 
91
                        apParams[ ivar++ ] ->GetColor( col, varyingindex );
 
92
                        CqString strVal;
 
93
                        strVal.Format( "%f,%f,%f", col.fRed(), col.fGreen(), col.fBlue() );
 
94
                        strRes += strVal;
 
95
                    }
 
96
                    break;
 
97
 
 
98
                case 'm':
 
99
                    {
 
100
                        CqMatrix mat;
 
101
                        apParams[ ivar++ ] ->GetMatrix( mat, varyingindex );
 
102
                        CqString strVal;
 
103
                        strVal.Format( "%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f",
 
104
                                       mat.Element( 0, 0 ), mat.Element( 0, 1 ), mat.Element( 0, 2 ), mat.Element( 0, 3 ),
 
105
                                       mat.Element( 1, 0 ), mat.Element( 1, 1 ), mat.Element( 1, 2 ), mat.Element( 1, 3 ),
 
106
                                       mat.Element( 2, 0 ), mat.Element( 2, 1 ), mat.Element( 2, 2 ), mat.Element( 2, 3 ),
 
107
                                       mat.Element( 3, 0 ), mat.Element( 3, 1 ), mat.Element( 3, 2 ), mat.Element( 3, 3 ) );
 
108
                        strRes += strVal;
 
109
                    }
 
110
                    break;
 
111
 
 
112
                case 's':
 
113
                    {
 
114
                        CqString stra;
 
115
                        apParams[ ivar++ ] ->GetString( stra, varyingindex );
 
116
                        strRes += stra;
 
117
                    }
 
118
                    break;
 
119
 
 
120
                default:
 
121
                    {
 
122
                        strRes += strTrans[ i ];
 
123
                    }
 
124
                    break;
 
125
                }
 
126
                i++;
 
127
            }
 
128
            break;
 
129
 
 
130
        default:
 
131
            {
 
132
                strRes += strTrans[ i ];
 
133
                i++;
 
134
            }
 
135
            break;
 
136
        }
 
137
    }
 
138
    return ( strRes );
 
139
}
 
140
 
 
141
//----------------------------------------------------------------------
 
142
// init_illuminance()
 
143
TqBool CqShaderExecEnv::SO_init_illuminance()
 
144
{
 
145
    m_li = -1;
 
146
    return ( SO_advance_illuminance() );
 
147
}
 
148
 
 
149
 
 
150
//----------------------------------------------------------------------
 
151
// advance_illuminance()
 
152
TqBool CqShaderExecEnv::SO_advance_illuminance()
 
153
{
 
154
    m_li++;
 
155
    while ( m_li < m_pAttributes ->cLights() &&
 
156
            m_pAttributes ->pLight( m_li ) ->pShader() ->fAmbient() )
 
157
    {
 
158
        m_li++;
 
159
    }
 
160
    if ( m_li < m_pAttributes ->cLights() )
 
161
        return ( TqTrue );
 
162
    else
 
163
        return ( TqFalse );
 
164
}
 
165
 
 
166
 
 
167
void CqShaderExecEnv::ValidateIlluminanceCache( IqShaderData* pP, IqShaderData* pN, IqShader* pShader )
 
168
{
 
169
    // If this is the first call to illuminance this time round, call all lights and setup the Cl and L caches.
 
170
    if ( !m_IlluminanceCacheValid )
 
171
    {
 
172
        IqShaderData* Ns = (pN != NULL )? pN : N();
 
173
        IqShaderData* Ps = (pP != NULL )? pP : P();
 
174
        TqUint li = 0;
 
175
        while ( li < m_pAttributes ->cLights() )
 
176
        {
 
177
            IqLightsource * lp = m_pAttributes ->pLight( li );
 
178
            // Initialise the lightsource
 
179
            lp->Initialise( uGridRes(), vGridRes() );
 
180
            m_Illuminate = 0;
 
181
            // Evaluate the lightsource
 
182
            lp->Evaluate( Ps, Ns );
 
183
            li++;
 
184
        }
 
185
        m_IlluminanceCacheValid = TqTrue;;
 
186
    }
 
187
}
 
188
 
 
189
 
 
190
STD_SOIMPL      CqShaderExecEnv::SO_radians( FLOATVAL degrees, DEFPARAMIMPL )
 
191
{
 
192
    STATS_INC( SHD_so_radians );
 
193
 
 
194
    INIT_SO
 
195
 
 
196
    CHECKVARY( degrees )
 
197
    CHECKVARY( Result )
 
198
 
 
199
    BEGIN_VARYING_SECTION
 
200
    GETFLOAT( degrees );
 
201
    SETFLOAT( Result, RAD( FLOAT( degrees ) ) );
 
202
    END_VARYING_SECTION
 
203
}
 
204
 
 
205
STD_SOIMPL      CqShaderExecEnv::SO_degrees( FLOATVAL radians, DEFPARAMIMPL )
 
206
{
 
207
    STATS_INC( SHD_so_degrees );
 
208
 
 
209
    INIT_SO
 
210
 
 
211
    CHECKVARY( radians )
 
212
    CHECKVARY( Result )
 
213
 
 
214
    BEGIN_VARYING_SECTION
 
215
    GETFLOAT( radians );
 
216
    SETFLOAT( Result, DEG( FLOAT( radians ) ) );
 
217
    END_VARYING_SECTION
 
218
}
 
219
 
 
220
STD_SOIMPL      CqShaderExecEnv::SO_sin( FLOATVAL a, DEFPARAMIMPL )
 
221
{
 
222
    STATS_INC( SHD_so_sin );
 
223
 
 
224
    INIT_SO
 
225
 
 
226
    CHECKVARY( a )
 
227
    CHECKVARY( Result )
 
228
 
 
229
    BEGIN_VARYING_SECTION
 
230
    GETFLOAT( a );
 
231
    SETFLOAT( Result, static_cast<TqFloat>( sin( FLOAT( a ) ) ) );
 
232
    END_VARYING_SECTION
 
233
}
 
234
 
 
235
STD_SOIMPL      CqShaderExecEnv::SO_asin( FLOATVAL a, DEFPARAMIMPL )
 
236
{
 
237
    STATS_INC( SHD_so_asin );
 
238
 
 
239
    INIT_SO
 
240
 
 
241
    CHECKVARY( a )
 
242
    CHECKVARY( Result )
 
243
 
 
244
    BEGIN_VARYING_SECTION
 
245
    GETFLOAT( a );
 
246
    SETFLOAT( Result, static_cast<TqFloat>( asin( FLOAT( a ) ) ) );
 
247
    END_VARYING_SECTION
 
248
}
 
249
 
 
250
STD_SOIMPL      CqShaderExecEnv::SO_cos( FLOATVAL a, DEFPARAMIMPL )
 
251
{
 
252
    STATS_INC( SHD_so_cos );
 
253
 
 
254
    INIT_SO
 
255
 
 
256
    CHECKVARY( a )
 
257
    CHECKVARY( Result )
 
258
 
 
259
    BEGIN_VARYING_SECTION
 
260
    GETFLOAT( a );
 
261
    SETFLOAT( Result, static_cast<TqFloat>( cos( FLOAT( a ) ) ) );
 
262
    END_VARYING_SECTION
 
263
}
 
264
 
 
265
STD_SOIMPL      CqShaderExecEnv::SO_acos( FLOATVAL a, DEFPARAMIMPL )
 
266
{
 
267
    STATS_INC( SHD_so_acos );
 
268
 
 
269
    INIT_SO
 
270
 
 
271
    CHECKVARY( a )
 
272
    CHECKVARY( Result )
 
273
 
 
274
    BEGIN_VARYING_SECTION
 
275
    GETFLOAT( a );
 
276
    SETFLOAT( Result, static_cast<TqFloat>( acos( FLOAT( a ) ) ) );
 
277
    END_VARYING_SECTION
 
278
}
 
279
 
 
280
STD_SOIMPL      CqShaderExecEnv::SO_tan( FLOATVAL a, DEFPARAMIMPL )
 
281
{
 
282
    STATS_INC( SHD_so_tan );
 
283
 
 
284
    INIT_SO
 
285
 
 
286
    CHECKVARY( a )
 
287
    CHECKVARY( Result )
 
288
 
 
289
    BEGIN_VARYING_SECTION
 
290
    GETFLOAT( a );
 
291
    SETFLOAT( Result, static_cast<TqFloat>( tan( FLOAT( a ) ) ) );
 
292
    END_VARYING_SECTION
 
293
}
 
294
 
 
295
STD_SOIMPL      CqShaderExecEnv::SO_atan( FLOATVAL yoverx, DEFPARAMIMPL )
 
296
{
 
297
    STATS_INC( SHD_so_atan );
 
298
 
 
299
    INIT_SO
 
300
 
 
301
    CHECKVARY( yoverx )
 
302
    CHECKVARY( Result )
 
303
 
 
304
    BEGIN_VARYING_SECTION
 
305
    GETFLOAT( yoverx );
 
306
    SETFLOAT( Result, static_cast<TqFloat>( atan( FLOAT( yoverx ) ) ) );
 
307
    END_VARYING_SECTION
 
308
}
 
309
 
 
310
STD_SOIMPL      CqShaderExecEnv::SO_atan( FLOATVAL y, FLOATVAL x, DEFPARAMIMPL )
 
311
{
 
312
    STATS_INC( SHD_so_atan );
 
313
 
 
314
    INIT_SO
 
315
 
 
316
    CHECKVARY( x )
 
317
    CHECKVARY( y )
 
318
    CHECKVARY( Result )
 
319
 
 
320
    BEGIN_VARYING_SECTION
 
321
    GETFLOAT( x );
 
322
    GETFLOAT( y );
 
323
    SETFLOAT( Result, static_cast<TqFloat>( atan2( FLOAT( y ), FLOAT( x ) ) ) );
 
324
    END_VARYING_SECTION
 
325
}
 
326
 
 
327
STD_SOIMPL      CqShaderExecEnv::SO_pow( FLOATVAL x, FLOATVAL y, DEFPARAMIMPL )
 
328
{
 
329
    STATS_INC( SHD_so_pow );
 
330
 
 
331
    INIT_SO
 
332
 
 
333
    CHECKVARY( x )
 
334
    CHECKVARY( y )
 
335
    CHECKVARY( Result )
 
336
 
 
337
    BEGIN_VARYING_SECTION
 
338
    GETFLOAT( x );
 
339
    GETFLOAT( y );
 
340
    TqFloat yy = FLOAT( y );
 
341
    TqFloat xx = FLOAT( x );
 
342
    if ( xx < 0.0f ) yy = FLOOR( yy );
 
343
    SETFLOAT( Result, static_cast<TqFloat>( pow( xx, yy ) ) );
 
344
    END_VARYING_SECTION
 
345
}
 
346
 
 
347
STD_SOIMPL      CqShaderExecEnv::SO_exp( FLOATVAL x, DEFPARAMIMPL )
 
348
{
 
349
    STATS_INC( SHD_so_exp );
 
350
 
 
351
    INIT_SO
 
352
 
 
353
    CHECKVARY( x )
 
354
    CHECKVARY( Result )
 
355
 
 
356
    BEGIN_VARYING_SECTION
 
357
    GETFLOAT( x );
 
358
    SETFLOAT( Result, static_cast<TqFloat>( exp( FLOAT( x ) ) ) );
 
359
    END_VARYING_SECTION
 
360
}
 
361
 
 
362
STD_SOIMPL      CqShaderExecEnv::SO_sqrt( FLOATVAL x, DEFPARAMIMPL )
 
363
{
 
364
    STATS_INC( SHD_so_sqrt );
 
365
 
 
366
    INIT_SO
 
367
 
 
368
    CHECKVARY( x )
 
369
    CHECKVARY( Result )
 
370
 
 
371
    BEGIN_VARYING_SECTION
 
372
    GETFLOAT( x );
 
373
    SETFLOAT( Result, static_cast<TqFloat>( sqrt( FLOAT( x ) ) ) );
 
374
    END_VARYING_SECTION
 
375
}
 
376
 
 
377
STD_SOIMPL      CqShaderExecEnv::SO_log( FLOATVAL x, DEFPARAMIMPL )
 
378
{
 
379
    STATS_INC( SHD_so_log );
 
380
 
 
381
    INIT_SO
 
382
 
 
383
    CHECKVARY( x )
 
384
    CHECKVARY( Result )
 
385
 
 
386
    BEGIN_VARYING_SECTION
 
387
    GETFLOAT( x );
 
388
    SETFLOAT( Result, static_cast<TqFloat>( log( FLOAT( x ) ) ) );
 
389
    END_VARYING_SECTION
 
390
}
 
391
 
 
392
STD_SOIMPL      CqShaderExecEnv::SO_mod( FLOATVAL a, FLOATVAL b, DEFPARAMIMPL )
 
393
{
 
394
    STATS_INC( SHD_so_mod );
 
395
 
 
396
    INIT_SO
 
397
 
 
398
    CHECKVARY( a )
 
399
    CHECKVARY( b )
 
400
    CHECKVARY( Result )
 
401
 
 
402
    BEGIN_VARYING_SECTION
 
403
    GETFLOAT( a );
 
404
    GETFLOAT( b );
 
405
    TqInt n = static_cast<TqInt>( FLOAT( a ) / FLOAT( b ) );
 
406
    TqFloat a2 = FLOAT( a ) - n * FLOAT( b );
 
407
    if ( a2 < 0.0f )
 
408
        a2 += FLOAT( b );
 
409
    SETFLOAT( Result, a2 );
 
410
    END_VARYING_SECTION
 
411
}
 
412
 
 
413
//----------------------------------------------------------------------
 
414
// log(x,base)
 
415
STD_SOIMPL      CqShaderExecEnv::SO_log( FLOATVAL x, FLOATVAL base, DEFPARAMIMPL )
 
416
{
 
417
    STATS_INC( SHD_so_log );
 
418
 
 
419
    INIT_SO
 
420
 
 
421
    CHECKVARY( x )
 
422
    CHECKVARY( base )
 
423
    CHECKVARY( Result )
 
424
 
 
425
    BEGIN_VARYING_SECTION
 
426
    GETFLOAT( x );
 
427
    GETFLOAT( base );
 
428
    SETFLOAT( Result, static_cast<TqFloat>( log( FLOAT( x ) ) / log( FLOAT( base ) ) ) );
 
429
    END_VARYING_SECTION
 
430
}
 
431
 
 
432
 
 
433
STD_SOIMPL      CqShaderExecEnv::SO_abs( FLOATVAL x, DEFPARAMIMPL )
 
434
{
 
435
    STATS_INC( SHD_so_abs );
 
436
 
 
437
    INIT_SO
 
438
 
 
439
    CHECKVARY( x )
 
440
    CHECKVARY( Result )
 
441
 
 
442
    BEGIN_VARYING_SECTION
 
443
    GETFLOAT( x );
 
444
    SETFLOAT( Result, static_cast<TqFloat>( fabs( FLOAT( x ) ) ) );
 
445
    END_VARYING_SECTION
 
446
}
 
447
 
 
448
STD_SOIMPL      CqShaderExecEnv::SO_sign( FLOATVAL x, DEFPARAMIMPL )
 
449
{
 
450
    STATS_INC( SHD_so_sign );
 
451
 
 
452
    INIT_SO
 
453
 
 
454
    CHECKVARY( x )
 
455
    CHECKVARY( Result )
 
456
 
 
457
    BEGIN_VARYING_SECTION
 
458
    GETFLOAT( x );
 
459
    SETFLOAT( Result, ( FLOAT( x ) < 0.0f ) ? -1.0f : 1.0f );
 
460
    END_VARYING_SECTION
 
461
}
 
462
 
 
463
STD_SOIMPL      CqShaderExecEnv::SO_min( FLOATVAL a, FLOATVAL b, DEFPARAMVARIMPL )
 
464
{
 
465
    STATS_INC( SHD_so_min );
 
466
 
 
467
    INIT_SO
 
468
 
 
469
    CHECKVARY( a )
 
470
    CHECKVARY( b )
 
471
    CHECKVARY( Result )
 
472
 
 
473
    BEGIN_VARYING_SECTION
 
474
    GETFLOAT( a );
 
475
    GETFLOAT( b );
 
476
    TqFloat fRes = MIN( FLOAT( a ), FLOAT( b ) );
 
477
    while ( cParams-- > 0 )
 
478
    {
 
479
        TqFloat fn;
 
480
        apParams[ cParams ] ->GetFloat( fn, __iGrid );
 
481
        fRes = MIN( fRes, fn );
 
482
    }
 
483
    SETFLOAT( Result, fRes );
 
484
    END_VARYING_SECTION
 
485
}
 
486
 
 
487
STD_SOIMPL      CqShaderExecEnv::SO_max( FLOATVAL a, FLOATVAL b, DEFPARAMVARIMPL )
 
488
{
 
489
    STATS_INC( SHD_so_max );
 
490
 
 
491
    INIT_SO
 
492
 
 
493
    CHECKVARY( a )
 
494
    CHECKVARY( b )
 
495
    CHECKVARY( Result )
 
496
 
 
497
    BEGIN_VARYING_SECTION
 
498
    GETFLOAT( a );
 
499
    GETFLOAT( b );
 
500
    TqFloat fRes = MAX( FLOAT( a ), FLOAT( b ) );
 
501
    while ( cParams-- > 0 )
 
502
    {
 
503
        TqFloat fn;
 
504
        apParams[ cParams ] ->GetFloat( fn, __iGrid );
 
505
        fRes = MAX( fRes, fn );
 
506
    }
 
507
    SETFLOAT( Result, fRes );
 
508
    END_VARYING_SECTION
 
509
}
 
510
 
 
511
STD_SOIMPL      CqShaderExecEnv::SO_pmin( POINTVAL a, POINTVAL b, DEFPARAMVARIMPL )
 
512
{
 
513
    STATS_INC( SHD_so_pmin );
 
514
 
 
515
    INIT_SO
 
516
 
 
517
    CHECKVARY( a )
 
518
    CHECKVARY( b )
 
519
    CHECKVARY( Result )
 
520
 
 
521
    BEGIN_VARYING_SECTION
 
522
    GETPOINT( a );
 
523
    GETPOINT( b );
 
524
    CqVector3D res = VMIN( POINT( a ), POINT( b ) );
 
525
    while ( cParams-- > 0 )
 
526
    {
 
527
        CqVector3D pn;
 
528
        apParams[ cParams ] ->GetPoint( pn, __iGrid );
 
529
        res = VMIN( res, pn );
 
530
    }
 
531
    SETPOINT( Result, res );
 
532
    END_VARYING_SECTION
 
533
}
 
534
 
 
535
STD_SOIMPL      CqShaderExecEnv::SO_pmax( POINTVAL a, POINTVAL b, DEFPARAMVARIMPL )
 
536
{
 
537
    STATS_INC( SHD_so_pmax );
 
538
 
 
539
    INIT_SO
 
540
 
 
541
    CHECKVARY( a )
 
542
    CHECKVARY( b )
 
543
    CHECKVARY( Result )
 
544
 
 
545
    BEGIN_VARYING_SECTION
 
546
    GETPOINT( a );
 
547
    GETPOINT( b );
 
548
    CqVector3D res = VMAX( POINT( a ), POINT( b ) );
 
549
    while ( cParams-- > 0 )
 
550
    {
 
551
        CqVector3D pn;
 
552
        apParams[ cParams ] ->GetPoint( pn, __iGrid );
 
553
        res = VMAX( res, pn );
 
554
    }
 
555
    SETPOINT( Result, res );
 
556
    END_VARYING_SECTION
 
557
}
 
558
 
 
559
STD_SOIMPL      CqShaderExecEnv::SO_cmin( COLORVAL a, COLORVAL b, DEFPARAMVARIMPL )
 
560
{
 
561
    STATS_INC( SHD_so_cmin );
 
562
 
 
563
    INIT_SO
 
564
 
 
565
    CHECKVARY( a )
 
566
    CHECKVARY( b )
 
567
    CHECKVARY( Result )
 
568
 
 
569
    BEGIN_VARYING_SECTION
 
570
    GETCOLOR( a );
 
571
    GETCOLOR( b );
 
572
    CqColor res = CMIN( COLOR( a ), COLOR( b ) );
 
573
    while ( cParams-- > 0 )
 
574
    {
 
575
        CqColor cn;
 
576
        apParams[ cParams ] ->GetColor( cn, __iGrid );
 
577
        res = CMIN( res, cn );
 
578
    }
 
579
    SETCOLOR( Result, res );
 
580
    END_VARYING_SECTION
 
581
}
 
582
 
 
583
STD_SOIMPL      CqShaderExecEnv::SO_cmax( COLORVAL a, COLORVAL b, DEFPARAMVARIMPL )
 
584
{
 
585
    STATS_INC( SHD_so_cmax );
 
586
 
 
587
    INIT_SO
 
588
 
 
589
    CHECKVARY( a )
 
590
    CHECKVARY( b )
 
591
    CHECKVARY( Result )
 
592
 
 
593
    BEGIN_VARYING_SECTION
 
594
    GETCOLOR( a );
 
595
    GETCOLOR( b );
 
596
    CqColor res = CMAX( COLOR( a ), COLOR( b ) );
 
597
    while ( cParams-- > 0 )
 
598
    {
 
599
        CqColor cn;
 
600
        apParams[ cParams ] ->GetColor( cn, __iGrid );
 
601
        res = CMAX( res, cn );
 
602
    }
 
603
    SETCOLOR( Result, res );
 
604
    END_VARYING_SECTION
 
605
}
 
606
 
 
607
STD_SOIMPL      CqShaderExecEnv::SO_clamp( FLOATVAL a, FLOATVAL _min, FLOATVAL _max, DEFPARAMIMPL )
 
608
{
 
609
    STATS_INC( SHD_so_clamp );
 
610
 
 
611
    INIT_SO
 
612
 
 
613
    CHECKVARY( a )
 
614
    CHECKVARY( _min )
 
615
    CHECKVARY( _max )
 
616
    CHECKVARY( Result )
 
617
 
 
618
    BEGIN_VARYING_SECTION
 
619
    GETFLOAT( a );
 
620
    GETFLOAT( _min );
 
621
    GETFLOAT( _max );
 
622
    SETFLOAT( Result, CLAMP( FLOAT( a ), FLOAT( _min ), FLOAT( _max ) ) );
 
623
    END_VARYING_SECTION
 
624
}
 
625
 
 
626
STD_SOIMPL      CqShaderExecEnv::SO_pclamp( POINTVAL a, POINTVAL _min, POINTVAL _max, DEFPARAMIMPL )
 
627
{
 
628
    STATS_INC( SHD_so_pclamp );
 
629
 
 
630
    INIT_SO
 
631
 
 
632
    CHECKVARY( a )
 
633
    CHECKVARY( _min )
 
634
    CHECKVARY( _max )
 
635
    CHECKVARY( Result )
 
636
 
 
637
    BEGIN_VARYING_SECTION
 
638
    GETPOINT( a );
 
639
    GETPOINT( _min );
 
640
    GETPOINT( _max );
 
641
    SETPOINT( Result, VCLAMP( POINT( a ), POINT( _min ), POINT( _max ) ) );
 
642
    END_VARYING_SECTION
 
643
}
 
644
 
 
645
STD_SOIMPL      CqShaderExecEnv::SO_cclamp( COLORVAL a, COLORVAL _min, COLORVAL _max, DEFPARAMIMPL )
 
646
{
 
647
    STATS_INC( SHD_so_cclamp );
 
648
 
 
649
    INIT_SO
 
650
 
 
651
    CHECKVARY( a )
 
652
    CHECKVARY( _min )
 
653
    CHECKVARY( _max )
 
654
    CHECKVARY( Result )
 
655
 
 
656
    BEGIN_VARYING_SECTION
 
657
    GETCOLOR( a );
 
658
    GETCOLOR( _min );
 
659
    GETCOLOR( _max );
 
660
    SETCOLOR( Result, CCLAMP( COLOR( a ), COLOR( _min ), COLOR( _max ) ) );
 
661
    END_VARYING_SECTION
 
662
}
 
663
 
 
664
STD_SOIMPL      CqShaderExecEnv::SO_floor( FLOATVAL x, DEFPARAMIMPL )
 
665
{
 
666
    STATS_INC( SHD_so_floor );
 
667
 
 
668
    INIT_SO
 
669
 
 
670
    CHECKVARY( x )
 
671
    CHECKVARY( Result )
 
672
 
 
673
    BEGIN_VARYING_SECTION
 
674
    GETFLOAT( x );
 
675
    SETFLOAT( Result, static_cast<TqFloat>( FLOOR( FLOAT( x ) ) ) );
 
676
    END_VARYING_SECTION
 
677
}
 
678
 
 
679
STD_SOIMPL      CqShaderExecEnv::SO_ceil( FLOATVAL x, DEFPARAMIMPL )
 
680
{
 
681
    STATS_INC( SHD_so_ceil );
 
682
 
 
683
    INIT_SO
 
684
 
 
685
    CHECKVARY( x )
 
686
    CHECKVARY( Result )
 
687
 
 
688
    BEGIN_VARYING_SECTION
 
689
    GETFLOAT( x );
 
690
    SETFLOAT( Result, static_cast<TqFloat>( CEIL( FLOAT( x ) ) ) );
 
691
    END_VARYING_SECTION
 
692
}
 
693
 
 
694
STD_SOIMPL      CqShaderExecEnv::SO_round( FLOATVAL x, DEFPARAMIMPL )
 
695
{
 
696
    INIT_SO
 
697
    double v;
 
698
 
 
699
    CHECKVARY( x )
 
700
    CHECKVARY( Result )
 
701
 
 
702
    BEGIN_VARYING_SECTION
 
703
    GETFLOAT( x );
 
704
    SETFLOAT( Result, ( modf( FLOAT( x ), &v ) > 0.5f ) ? static_cast<TqFloat>( v ) + 1.0f : static_cast<TqFloat>( v ) );
 
705
    END_VARYING_SECTION
 
706
}
 
707
 
 
708
STD_SOIMPL      CqShaderExecEnv::SO_step( FLOATVAL _min, FLOATVAL value, DEFPARAMIMPL )
 
709
{
 
710
    STATS_INC( SHD_so_step );
 
711
 
 
712
    INIT_SO
 
713
 
 
714
    CHECKVARY( _min )
 
715
    CHECKVARY( value )
 
716
    CHECKVARY( Result )
 
717
 
 
718
    BEGIN_VARYING_SECTION
 
719
    GETFLOAT( _min );
 
720
    GETFLOAT( value );
 
721
    SETFLOAT( Result, ( FLOAT( value ) < FLOAT( _min ) ) ? 0.0f : 1.0f );
 
722
    END_VARYING_SECTION
 
723
}
 
724
 
 
725
 
 
726
//----------------------------------------------------------------------
 
727
// smoothstep(_min,_max,value)
 
728
STD_SOIMPL      CqShaderExecEnv::SO_smoothstep( FLOATVAL _min, FLOATVAL _max, FLOATVAL value, DEFPARAMIMPL )
 
729
{
 
730
    STATS_INC( SHD_so_smoothstep );
 
731
 
 
732
    INIT_SO
 
733
 
 
734
    CHECKVARY( value )
 
735
    CHECKVARY( _min )
 
736
    CHECKVARY( _max )
 
737
    CHECKVARY( Result )
 
738
 
 
739
    BEGIN_VARYING_SECTION
 
740
    GETFLOAT( _min );
 
741
    GETFLOAT( _max );
 
742
    GETFLOAT( value );
 
743
    if ( FLOAT( value ) < FLOAT( _min ) )
 
744
        SETFLOAT( Result, 0.0f );
 
745
    else if ( FLOAT( value ) >= FLOAT( _max ) )
 
746
        SETFLOAT( Result, 1.0f );
 
747
    else
 
748
    {
 
749
        TqFloat v = ( FLOAT( value ) - FLOAT( _min ) ) / ( FLOAT( _max ) - FLOAT( _min ) );
 
750
        SETFLOAT( Result, v * v * ( 3.0f - 2.0f * v ) );
 
751
    }
 
752
    END_VARYING_SECTION
 
753
}
 
754
 
 
755
 
 
756
//----------------------------------------------------------------------
 
757
// spline(value, f1,f2,...,fn)
 
758
STD_SOIMPL      CqShaderExecEnv::SO_fspline( FLOATVAL value, DEFPARAMVARIMPL )
 
759
{
 
760
    STATS_INC( SHD_so_fspline );
 
761
 
 
762
    INIT_SO
 
763
 
 
764
    CqSplineCubic spline( cParams );
 
765
 
 
766
    CHECKVARY( value )
 
767
    TqInt v;
 
768
    for ( v = 0; v < cParams; v++ )
 
769
    {
 
770
        CHECKVARY( ( apParams[ v ] ) )
 
771
    }
 
772
    CHECKVARY( Result )
 
773
 
 
774
    BEGIN_VARYING_SECTION
 
775
    GETFLOAT( value );
 
776
    if ( FLOAT( value ) >= 1.0f )
 
777
    {
 
778
        TqFloat fl;
 
779
        apParams[ cParams - 2 ] ->GetFloat( fl, __iGrid );
 
780
        SETFLOAT( Result, fl );
 
781
    }
 
782
    else if ( FLOAT( value ) <= 0.0f )
 
783
    {
 
784
        TqFloat ff;
 
785
        apParams[ 1 ] ->GetFloat( ff, __iGrid );
 
786
        SETFLOAT( Result, ff );
 
787
    }
 
788
    else
 
789
    {
 
790
        TqInt j;
 
791
        for ( j = 0; j < cParams; j++ )
 
792
        {
 
793
            TqFloat fn;
 
794
            apParams[ j ] ->GetFloat( fn, __iGrid );
 
795
            spline[ j ] = CqVector4D( fn, 0.0f, 0.0f, 1.0f );
 
796
        }
 
797
 
 
798
        CqVector4D      res = spline.Evaluate( FLOAT( value ) );
 
799
        SETFLOAT( Result, res.x() );
 
800
    }
 
801
    END_VARYING_SECTION
 
802
}
 
803
 
 
804
 
 
805
//----------------------------------------------------------------------
 
806
// spline(value, f1,f2,...,fn)
 
807
STD_SOIMPL      CqShaderExecEnv::SO_cspline( FLOATVAL value, DEFPARAMVARIMPL )
 
808
{
 
809
    STATS_INC( SHD_so_cspline );
 
810
 
 
811
    INIT_SO
 
812
 
 
813
    CqSplineCubic spline( cParams );
 
814
 
 
815
    CHECKVARY( value )
 
816
    TqInt v;
 
817
    for ( v = 0; v < cParams; v++ )
 
818
    {
 
819
        CHECKVARY( ( apParams[ v ] ) )
 
820
    }
 
821
    CHECKVARY( Result )
 
822
 
 
823
    BEGIN_VARYING_SECTION
 
824
    GETFLOAT( value );
 
825
    if ( FLOAT( value ) >= 1.0f )
 
826
    {
 
827
        CqColor cl;
 
828
        apParams[ cParams - 2 ] ->GetColor( cl, __iGrid );
 
829
        SETCOLOR( Result, cl );
 
830
    }
 
831
    else if ( FLOAT( value ) <= 0.0f )
 
832
    {
 
833
        CqColor cf;
 
834
        apParams[ 1 ] ->GetColor( cf, __iGrid );
 
835
        SETCOLOR( Result, cf );
 
836
    }
 
837
    else
 
838
    {
 
839
        TqInt j;
 
840
        for ( j = 0; j < cParams; j++ )
 
841
        {
 
842
            CqColor cn;
 
843
            apParams[ j ] ->GetColor( cn, __iGrid );
 
844
            spline[ j ] = CqVector4D( cn.fRed(), cn.fGreen(), cn.fBlue(), 1.0f );
 
845
        }
 
846
 
 
847
        CqVector4D      res = spline.Evaluate( FLOAT( value ) );
 
848
        SETCOLOR( Result, CqColor( res.x(), res.y(), res.z() ) );
 
849
    }
 
850
    END_VARYING_SECTION
 
851
}
 
852
 
 
853
 
 
854
//----------------------------------------------------------------------
 
855
// spline(value, f1,f2,...,fn)
 
856
STD_SOIMPL      CqShaderExecEnv::SO_pspline( FLOATVAL value, DEFPARAMVARIMPL )
 
857
{
 
858
    STATS_INC( SHD_so_pspline );
 
859
 
 
860
    INIT_SO
 
861
 
 
862
    CqSplineCubic spline( cParams );
 
863
 
 
864
    CHECKVARY( value )
 
865
    TqInt v;
 
866
    for ( v = 0; v < cParams; v++ )
 
867
    {
 
868
        CHECKVARY( ( apParams[ v ] ) )
 
869
    }
 
870
    CHECKVARY( Result )
 
871
 
 
872
    BEGIN_VARYING_SECTION
 
873
    GETFLOAT( value );
 
874
    if ( FLOAT( value ) >= 1.0f )
 
875
    {
 
876
        CqVector3D pl;
 
877
        apParams[ cParams - 2 ] ->GetPoint( pl, __iGrid );
 
878
        SETPOINT( Result, pl );
 
879
    }
 
880
    else if ( FLOAT( value ) <= 0.0f )
 
881
    {
 
882
        CqVector3D pf;
 
883
        apParams[ 1 ] ->GetPoint( pf, __iGrid );
 
884
        SETPOINT( Result, pf );
 
885
    }
 
886
    else
 
887
    {
 
888
        TqInt j;
 
889
        for ( j = 0; j < cParams; j++ )
 
890
        {
 
891
            CqVector3D pn;
 
892
            apParams[ j ] ->GetPoint( pn, __iGrid );
 
893
            spline[ j ] = pn;
 
894
        }
 
895
 
 
896
        CqVector3D      res = spline.Evaluate( FLOAT( value ) );
 
897
        SETPOINT( Result, res );
 
898
    }
 
899
    END_VARYING_SECTION
 
900
}
 
901
 
 
902
 
 
903
//----------------------------------------------------------------------
 
904
// spline(value, f1,f2,...,fn)
 
905
STD_SOIMPL      CqShaderExecEnv::SO_sfspline( STRINGVAL basis, FLOATVAL value, DEFPARAMVARIMPL )
 
906
{
 
907
    STATS_INC( SHD_so_sfspline );
 
908
 
 
909
    INIT_SO
 
910
 
 
911
    CqSplineCubic spline( cParams );
 
912
 
 
913
    CHECKVARY( value )
 
914
    TqInt v;
 
915
    for ( v = 0; v < cParams; v++ )
 
916
    {
 
917
        CHECKVARY( ( apParams[ v ] ) )
 
918
    }
 
919
    CHECKVARY( Result )
 
920
 
 
921
    BEGIN_UNIFORM_SECTION
 
922
    GETSTRING( basis );
 
923
    spline.SetmatBasis( STRING( basis ) );
 
924
    END_UNIFORM_SECTION
 
925
 
 
926
    BEGIN_VARYING_SECTION
 
927
    GETFLOAT( value );
 
928
    if ( FLOAT( value ) >= 1.0f )
 
929
    {
 
930
        TqFloat fl;
 
931
        apParams[ cParams - 2 ] ->GetFloat( fl, __iGrid );
 
932
        SETFLOAT( Result, fl );
 
933
    }
 
934
    else if ( FLOAT( value ) <= 0.0f )
 
935
    {
 
936
        TqFloat ff;
 
937
        apParams[ 1 ] ->GetFloat( ff, __iGrid );
 
938
        SETFLOAT( Result, ff );
 
939
    }
 
940
    else
 
941
    {
 
942
        TqInt j;
 
943
        for ( j = 0; j < cParams; j++ )
 
944
        {
 
945
            TqFloat fn;
 
946
            apParams[ j ] ->GetFloat( fn, __iGrid );
 
947
            spline[ j ] = CqVector4D( fn, 0.0f, 0.0f, 1.0f );
 
948
        }
 
949
 
 
950
        CqVector4D      res = spline.Evaluate( FLOAT( value ) );
 
951
        SETFLOAT( Result, res.x() );
 
952
    }
 
953
    END_VARYING_SECTION
 
954
}
 
955
 
 
956
 
 
957
//----------------------------------------------------------------------
 
958
// spline(value, f1,f2,...,fn)
 
959
STD_SOIMPL      CqShaderExecEnv::SO_scspline( STRINGVAL basis, FLOATVAL value, DEFPARAMVARIMPL )
 
960
{
 
961
    STATS_INC( SHD_so_scspline );
 
962
 
 
963
    INIT_SO
 
964
 
 
965
    CqSplineCubic spline( cParams );
 
966
 
 
967
    CHECKVARY( value )
 
968
    TqInt v;
 
969
    for ( v = 0; v < cParams; v++ )
 
970
    {
 
971
        CHECKVARY( ( apParams[ v ] ) )
 
972
    }
 
973
    CHECKVARY( Result )
 
974
 
 
975
    BEGIN_UNIFORM_SECTION
 
976
    GETFLOAT( basis );
 
977
    spline.SetmatBasis( STRING( basis ) );
 
978
    END_UNIFORM_SECTION
 
979
 
 
980
    BEGIN_VARYING_SECTION
 
981
    GETFLOAT( value );
 
982
    if ( FLOAT( value ) >= 1.0f )
 
983
    {
 
984
        CqColor cl;
 
985
        apParams[ cParams - 2 ] ->GetColor( cl, __iGrid );
 
986
        SETCOLOR( Result, cl );
 
987
    }
 
988
    else if ( FLOAT( value ) <= 0.0f )
 
989
    {
 
990
        CqColor cf;
 
991
        apParams[ 1 ] ->GetColor( cf, __iGrid );
 
992
        SETCOLOR( Result, cf );
 
993
    }
 
994
    else
 
995
    {
 
996
        TqInt j;
 
997
        for ( j = 0; j < cParams; j++ )
 
998
        {
 
999
            CqColor cn;
 
1000
            apParams[ j ] ->GetColor( cn, __iGrid );
 
1001
            spline[ j ] = CqVector4D( cn.fRed(), cn.fGreen(), cn.fBlue(), 1.0f );
 
1002
        }
 
1003
 
 
1004
        CqVector4D      res = spline.Evaluate( FLOAT( value ) );
 
1005
        SETCOLOR( Result, CqColor( res.x(), res.y(), res.z() ) );
 
1006
    }
 
1007
    END_VARYING_SECTION
 
1008
}
 
1009
 
 
1010
 
 
1011
//----------------------------------------------------------------------
 
1012
// spline(value, f1,f2,...,fn)
 
1013
STD_SOIMPL      CqShaderExecEnv::SO_spspline( STRINGVAL basis, FLOATVAL value, DEFPARAMVARIMPL )
 
1014
{
 
1015
    STATS_INC( SHD_so_spspline );
 
1016
 
 
1017
    INIT_SO
 
1018
 
 
1019
    CqSplineCubic spline( cParams );
 
1020
 
 
1021
    CHECKVARY( value )
 
1022
    TqInt v;
 
1023
    for ( v = 0; v < cParams; v++ )
 
1024
    {
 
1025
        CHECKVARY( ( apParams[ v ] ) )
 
1026
    }
 
1027
    CHECKVARY( Result )
 
1028
 
 
1029
    BEGIN_UNIFORM_SECTION
 
1030
    GETSTRING( basis );
 
1031
    spline.SetmatBasis( STRING( basis ) );
 
1032
    END_UNIFORM_SECTION
 
1033
 
 
1034
    BEGIN_VARYING_SECTION
 
1035
    GETFLOAT( value );
 
1036
    if ( FLOAT( value ) >= 1.0f )
 
1037
    {
 
1038
        CqVector3D pl;
 
1039
        apParams[ cParams - 2 ] ->GetPoint( pl, __iGrid );
 
1040
        SETPOINT( Result, pl );
 
1041
    }
 
1042
    else if ( FLOAT( value ) <= 0.0f )
 
1043
    {
 
1044
        CqVector3D pf;
 
1045
        apParams[ 1 ] ->GetPoint( pf, __iGrid );
 
1046
        SETPOINT( Result, pf );
 
1047
    }
 
1048
    else
 
1049
    {
 
1050
        TqInt j;
 
1051
        for ( j = 0; j < cParams; j++ )
 
1052
        {
 
1053
            CqVector3D pn;
 
1054
            apParams[ j ] ->GetPoint( pn, __iGrid );
 
1055
            spline[ j ] = pn;
 
1056
        }
 
1057
 
 
1058
        CqVector3D      res = spline.Evaluate( FLOAT( value ) );
 
1059
        SETPOINT( Result, res );
 
1060
    }
 
1061
    END_VARYING_SECTION
 
1062
}
 
1063
 
 
1064
 
 
1065
STD_SOIMPL      CqShaderExecEnv::SO_fDu( FLOATVAL p, DEFPARAMIMPL )
 
1066
{
 
1067
    STATS_INC( SHD_so_fDu );
 
1068
 
 
1069
    TqFloat Deffloat = 0.0f;
 
1070
    INIT_SO
 
1071
 
 
1072
    CHECKVARY( p )
 
1073
    CHECKVARY( Result )
 
1074
 
 
1075
    BEGIN_VARYING_SECTION
 
1076
    SETFLOAT( Result, SO_DuType<TqFloat>( p, __iGrid, this, Deffloat ) );
 
1077
    END_VARYING_SECTION
 
1078
}
 
1079
 
 
1080
 
 
1081
STD_SOIMPL      CqShaderExecEnv::SO_fDv( FLOATVAL p, DEFPARAMIMPL )
 
1082
{
 
1083
    STATS_INC( SHD_so_fDv );
 
1084
 
 
1085
    TqFloat Deffloat = 0.0f;
 
1086
    INIT_SO
 
1087
 
 
1088
    CHECKVARY( p )
 
1089
    CHECKVARY( Result )
 
1090
 
 
1091
    BEGIN_VARYING_SECTION
 
1092
    SETFLOAT( Result, SO_DvType<TqFloat>( p, __iGrid, this, Deffloat ) );
 
1093
    END_VARYING_SECTION
 
1094
}
 
1095
 
 
1096
 
 
1097
STD_SOIMPL      CqShaderExecEnv::SO_fDeriv( FLOATVAL p, FLOATVAL den, DEFPARAMIMPL )
 
1098
{
 
1099
    STATS_INC( SHD_so_fDeriv );
 
1100
 
 
1101
    INIT_SO
 
1102
 
 
1103
    CHECKVARY( p )
 
1104
    CHECKVARY( den )
 
1105
    CHECKVARY( Result )
 
1106
 
 
1107
    BEGIN_VARYING_SECTION
 
1108
    SETFLOAT( Result, SO_DerivType<TqFloat>( p, den, __iGrid, this ) );
 
1109
    END_VARYING_SECTION
 
1110
}
 
1111
 
 
1112
 
 
1113
STD_SOIMPL      CqShaderExecEnv::SO_cDu( COLORVAL p, DEFPARAMIMPL )
 
1114
{
 
1115
    STATS_INC( SHD_so_cDu );
 
1116
 
 
1117
    CqColor Defcol( 0.0f, 0.0f, 0.0f );
 
1118
    INIT_SO
 
1119
 
 
1120
    CHECKVARY( p )
 
1121
    CHECKVARY( Result )
 
1122
 
 
1123
    BEGIN_VARYING_SECTION
 
1124
    SETCOLOR( Result, SO_DuType<CqColor>( p, __iGrid, this, Defcol ) );
 
1125
    END_VARYING_SECTION
 
1126
}
 
1127
 
 
1128
 
 
1129
STD_SOIMPL      CqShaderExecEnv::SO_cDv( COLORVAL p, DEFPARAMIMPL )
 
1130
{
 
1131
    STATS_INC( SHD_so_cDv );
 
1132
 
 
1133
    CqColor Defcol( 0.0f, 0.0f, 0.0f );
 
1134
    INIT_SO
 
1135
 
 
1136
    CHECKVARY( p )
 
1137
    CHECKVARY( Result )
 
1138
 
 
1139
    BEGIN_VARYING_SECTION
 
1140
    SETCOLOR( Result, SO_DvType<CqColor>( p, __iGrid, this, Defcol ) );
 
1141
    END_VARYING_SECTION
 
1142
}
 
1143
 
 
1144
 
 
1145
STD_SOIMPL      CqShaderExecEnv::SO_cDeriv( COLORVAL p, FLOATVAL den, DEFPARAMIMPL )
 
1146
{
 
1147
    STATS_INC( SHD_so_cDeriv );
 
1148
 
 
1149
    INIT_SO
 
1150
 
 
1151
    CHECKVARY( p )
 
1152
    CHECKVARY( den )
 
1153
    CHECKVARY( Result )
 
1154
 
 
1155
    BEGIN_VARYING_SECTION
 
1156
    SETCOLOR( Result, SO_DerivType<CqColor>( p, den, __iGrid, this ) );
 
1157
    END_VARYING_SECTION
 
1158
}
 
1159
 
 
1160
 
 
1161
STD_SOIMPL      CqShaderExecEnv::SO_pDu( POINTVAL p, DEFPARAMIMPL )
 
1162
{
 
1163
    STATS_INC( SHD_so_pDu );
 
1164
 
 
1165
    CqVector3D Defvec( 0.0f, 0.0f, 0.0f );
 
1166
    INIT_SO
 
1167
 
 
1168
    CHECKVARY( p )
 
1169
    CHECKVARY( Result )
 
1170
 
 
1171
    BEGIN_VARYING_SECTION
 
1172
    SETPOINT( Result, SO_DuType<CqVector3D>( p, __iGrid, this, Defvec ) );
 
1173
    END_VARYING_SECTION
 
1174
}
 
1175
 
 
1176
 
 
1177
STD_SOIMPL      CqShaderExecEnv::SO_pDv( POINTVAL p, DEFPARAMIMPL )
 
1178
{
 
1179
    STATS_INC( SHD_so_pDv );
 
1180
 
 
1181
    CqVector3D Defvec( 0.0f, 0.0f, 0.0f );
 
1182
    INIT_SO
 
1183
 
 
1184
    CHECKVARY( p )
 
1185
    CHECKVARY( Result )
 
1186
 
 
1187
    BEGIN_VARYING_SECTION
 
1188
    SETPOINT( Result, SO_DvType<CqVector3D>( p, __iGrid, this, Defvec ) );
 
1189
    END_VARYING_SECTION
 
1190
}
 
1191
 
 
1192
 
 
1193
STD_SOIMPL      CqShaderExecEnv::SO_pDeriv( POINTVAL p, FLOATVAL den, DEFPARAMIMPL )
 
1194
{
 
1195
    STATS_INC( SHD_so_pDeriv );
 
1196
 
 
1197
    INIT_SO
 
1198
 
 
1199
    CHECKVARY( p )
 
1200
    CHECKVARY( den )
 
1201
    CHECKVARY( Result )
 
1202
 
 
1203
    BEGIN_VARYING_SECTION
 
1204
    SETPOINT( Result, SO_DerivType<CqVector3D>( p, den, __iGrid, this ) );
 
1205
    END_VARYING_SECTION
 
1206
}
 
1207
 
 
1208
 
 
1209
STD_SOIMPL      CqShaderExecEnv::SO_frandom( DEFPARAMIMPL )
 
1210
{
 
1211
    STATS_INC( SHD_so_frandom );
 
1212
 
 
1213
    INIT_SO
 
1214
 
 
1215
    CHECKVARY( Result )
 
1216
 
 
1217
    BEGIN_VARYING_SECTION
 
1218
    SETFLOAT( Result, m_random.RandomFloat() );
 
1219
    END_VARYING_SECTION
 
1220
}
 
1221
 
 
1222
STD_SOIMPL      CqShaderExecEnv::SO_crandom( DEFPARAMIMPL )
 
1223
{
 
1224
    STATS_INC( SHD_so_crandom );
 
1225
 
 
1226
    INIT_SO
 
1227
 
 
1228
    CHECKVARY( Result )
 
1229
 
 
1230
    BEGIN_VARYING_SECTION
 
1231
    SETCOLOR( Result, CqColor( m_random.RandomFloat(), m_random.RandomFloat(), m_random.RandomFloat() ) );
 
1232
    END_VARYING_SECTION
 
1233
}
 
1234
 
 
1235
STD_SOIMPL      CqShaderExecEnv::SO_prandom( DEFPARAMIMPL )
 
1236
{
 
1237
    STATS_INC( SHD_so_prandom );
 
1238
 
 
1239
    INIT_SO
 
1240
 
 
1241
    CHECKVARY( Result )
 
1242
 
 
1243
    BEGIN_VARYING_SECTION
 
1244
    SETCOLOR( Result, CqVector3D( m_random.RandomFloat(), m_random.RandomFloat(), m_random.RandomFloat() ) );
 
1245
    END_VARYING_SECTION
 
1246
}
 
1247
 
 
1248
 
 
1249
//----------------------------------------------------------------------
 
1250
// noise(v)
 
1251
STD_SOIMPL      CqShaderExecEnv::SO_fnoise1( FLOATVAL v, DEFPARAMIMPL )
 
1252
{
 
1253
    STATS_INC( SHD_so_fnoise1 );
 
1254
 
 
1255
    INIT_SO
 
1256
 
 
1257
    CHECKVARY( v )
 
1258
    CHECKVARY( Result )
 
1259
 
 
1260
    BEGIN_VARYING_SECTION
 
1261
    GETFLOAT( v );
 
1262
    SETFLOAT( Result, ( m_noise.FGNoise1( FLOAT( v ) ) + 1 ) / 2.0f );
 
1263
    END_VARYING_SECTION
 
1264
}
 
1265
 
 
1266
//----------------------------------------------------------------------
 
1267
// noise(u,v)
 
1268
STD_SOIMPL CqShaderExecEnv::SO_fnoise2( FLOATVAL u, FLOATVAL v, DEFPARAMIMPL )
 
1269
{
 
1270
    STATS_INC( SHD_so_fnoise2 );
 
1271
 
 
1272
    INIT_SO
 
1273
 
 
1274
    CHECKVARY( u )
 
1275
    CHECKVARY( v )
 
1276
    CHECKVARY( Result )
 
1277
 
 
1278
    BEGIN_VARYING_SECTION
 
1279
    GETFLOAT( u );
 
1280
    GETFLOAT( v );
 
1281
    SETFLOAT( Result, ( m_noise.FGNoise2( FLOAT( u ), FLOAT( v ) ) + 1 ) / 2.0f );
 
1282
    END_VARYING_SECTION
 
1283
}
 
1284
 
 
1285
//----------------------------------------------------------------------
 
1286
// noise(p)
 
1287
STD_SOIMPL CqShaderExecEnv::SO_fnoise3( POINTVAL p, DEFPARAMIMPL )
 
1288
{
 
1289
    STATS_INC( SHD_so_fnoise3 );
 
1290
 
 
1291
    INIT_SO
 
1292
 
 
1293
    CHECKVARY( p )
 
1294
    CHECKVARY( Result )
 
1295
 
 
1296
    BEGIN_VARYING_SECTION
 
1297
    GETPOINT( p );
 
1298
    SETFLOAT( Result, ( m_noise.FGNoise3( POINT( p ) ) + 1 ) / 2.0f );
 
1299
    END_VARYING_SECTION
 
1300
}
 
1301
 
 
1302
//----------------------------------------------------------------------
 
1303
// noise(p,t)
 
1304
STD_SOIMPL CqShaderExecEnv::SO_fnoise4( POINTVAL p, FLOATVAL t, DEFPARAMIMPL )
 
1305
{
 
1306
    // TODO: Do proper 4D noise.
 
1307
    STATS_INC( SHD_so_fnoise4 );
 
1308
 
 
1309
    INIT_SO
 
1310
 
 
1311
    CHECKVARY( p )
 
1312
    CHECKVARY( t )
 
1313
    CHECKVARY( Result )
 
1314
 
 
1315
    BEGIN_VARYING_SECTION
 
1316
    GETPOINT( p );
 
1317
    GETFLOAT( t );
 
1318
    SETFLOAT( Result, ( m_noise.FGNoise3( POINT( p ) ) + 1 ) / 2.0f );
 
1319
    END_VARYING_SECTION
 
1320
}
 
1321
 
 
1322
//----------------------------------------------------------------------
 
1323
// noise(v)
 
1324
STD_SOIMPL      CqShaderExecEnv::SO_cnoise1( FLOATVAL v, DEFPARAMIMPL )
 
1325
{
 
1326
    STATS_INC( SHD_so_cnoise1 );
 
1327
 
 
1328
    INIT_SO
 
1329
 
 
1330
    CHECKVARY( v )
 
1331
    CHECKVARY( Result )
 
1332
 
 
1333
    BEGIN_VARYING_SECTION
 
1334
    GETFLOAT( v );
 
1335
    SETCOLOR( Result, ( m_noise.CGNoise1( FLOAT( v ) ) + 1 ) / 2.0f );
 
1336
    END_VARYING_SECTION
 
1337
}
 
1338
 
 
1339
//----------------------------------------------------------------------
 
1340
// noise(u,v)
 
1341
STD_SOIMPL CqShaderExecEnv::SO_cnoise2( FLOATVAL u, FLOATVAL v, DEFPARAMIMPL )
 
1342
{
 
1343
    STATS_INC( SHD_so_cnoise2 );
 
1344
 
 
1345
    INIT_SO
 
1346
 
 
1347
    CHECKVARY( u )
 
1348
    CHECKVARY( v )
 
1349
    CHECKVARY( Result )
 
1350
 
 
1351
    BEGIN_VARYING_SECTION
 
1352
    GETFLOAT( u );
 
1353
    GETFLOAT( v );
 
1354
    SETCOLOR( Result, ( m_noise.CGNoise2( FLOAT( u ), FLOAT( v ) ) + 1 ) / 2.0f );
 
1355
    END_VARYING_SECTION
 
1356
}
 
1357
 
 
1358
//----------------------------------------------------------------------
 
1359
// noise(p)
 
1360
STD_SOIMPL CqShaderExecEnv::SO_cnoise3( POINTVAL p, DEFPARAMIMPL )
 
1361
{
 
1362
    STATS_INC( SHD_so_cnoise3 );
 
1363
 
 
1364
    INIT_SO
 
1365
 
 
1366
    CHECKVARY( p )
 
1367
    CHECKVARY( Result )
 
1368
 
 
1369
    BEGIN_VARYING_SECTION
 
1370
    GETPOINT( p );
 
1371
    SETCOLOR( Result, ( m_noise.CGNoise3( POINT( p ) ) + 1 ) / 2.0f );
 
1372
    END_VARYING_SECTION
 
1373
}
 
1374
 
 
1375
//----------------------------------------------------------------------
 
1376
// noise(p,t)
 
1377
STD_SOIMPL CqShaderExecEnv::SO_cnoise4( POINTVAL p, FLOATVAL t, DEFPARAMIMPL )
 
1378
{
 
1379
    // TODO: Do proper 4D noise.
 
1380
    STATS_INC( SHD_so_cnoise4 );
 
1381
 
 
1382
    INIT_SO
 
1383
 
 
1384
    CHECKVARY( p )
 
1385
    CHECKVARY( t )
 
1386
    CHECKVARY( Result )
 
1387
 
 
1388
    BEGIN_VARYING_SECTION
 
1389
    GETPOINT( p );
 
1390
    GETFLOAT( t );
 
1391
    SETCOLOR( Result, ( m_noise.CGNoise3( POINT( p ) ) + 1 ) / 2.0f );
 
1392
    END_VARYING_SECTION
 
1393
}
 
1394
 
 
1395
//----------------------------------------------------------------------
 
1396
// noise(v)
 
1397
STD_SOIMPL CqShaderExecEnv::SO_pnoise1( FLOATVAL v, DEFPARAMIMPL )
 
1398
{
 
1399
    STATS_INC( SHD_so_pnoise1 );
 
1400
 
 
1401
    INIT_SO
 
1402
 
 
1403
    CHECKVARY( v )
 
1404
    CHECKVARY( Result )
 
1405
 
 
1406
    BEGIN_VARYING_SECTION
 
1407
    GETFLOAT( v );
 
1408
    SETPOINT( Result, ( m_noise.PGNoise1( FLOAT( v ) ) + 1 ) / 2.0f );
 
1409
    END_VARYING_SECTION
 
1410
}
 
1411
 
 
1412
//----------------------------------------------------------------------
 
1413
// noise(u,v)
 
1414
STD_SOIMPL CqShaderExecEnv::SO_pnoise2( FLOATVAL u, FLOATVAL v, DEFPARAMIMPL )
 
1415
{
 
1416
    STATS_INC( SHD_so_pnoise2 );
 
1417
 
 
1418
    INIT_SO
 
1419
 
 
1420
    CHECKVARY( u )
 
1421
    CHECKVARY( v )
 
1422
    CHECKVARY( Result )
 
1423
 
 
1424
    BEGIN_VARYING_SECTION
 
1425
    GETFLOAT( u );
 
1426
    GETFLOAT( v );
 
1427
    SETPOINT( Result, ( m_noise.PGNoise2( FLOAT( u ), FLOAT( v ) ) + 1 ) / 2.0f );
 
1428
    END_VARYING_SECTION
 
1429
}
 
1430
 
 
1431
//----------------------------------------------------------------------
 
1432
// noise(p)
 
1433
STD_SOIMPL CqShaderExecEnv::SO_pnoise3( POINTVAL p, DEFPARAMIMPL )
 
1434
{
 
1435
    STATS_INC( SHD_so_pnoise3 );
 
1436
 
 
1437
    INIT_SO
 
1438
 
 
1439
    CHECKVARY( p )
 
1440
    CHECKVARY( Result )
 
1441
 
 
1442
    BEGIN_VARYING_SECTION
 
1443
    GETPOINT( p );
 
1444
    SETPOINT( Result, ( m_noise.PGNoise3( POINT( p ) ) + 1 ) / 2.0f );
 
1445
    END_VARYING_SECTION
 
1446
}
 
1447
 
 
1448
//----------------------------------------------------------------------
 
1449
// noise(p,t)
 
1450
STD_SOIMPL CqShaderExecEnv::SO_pnoise4( POINTVAL p, FLOATVAL t, DEFPARAMIMPL )
 
1451
{
 
1452
    // TODO: Do proper 4D noise.
 
1453
    STATS_INC( SHD_so_pnoise4 );
 
1454
 
 
1455
    INIT_SO
 
1456
 
 
1457
    CHECKVARY( p )
 
1458
    CHECKVARY( t )
 
1459
    CHECKVARY( Result )
 
1460
 
 
1461
    BEGIN_VARYING_SECTION
 
1462
    GETPOINT( p );
 
1463
    GETFLOAT( t );
 
1464
    SETPOINT( Result, ( m_noise.PGNoise3( POINT( p ) ) + 1 ) / 2.0f );
 
1465
    END_VARYING_SECTION
 
1466
}
 
1467
 
 
1468
//----------------------------------------------------------------------
 
1469
// setcomp(c,__iGrid,v)
 
1470
STD_SOIMPL      CqShaderExecEnv::SO_setcomp( COLORVAL p, FLOATVAL index, FLOATVAL v, DEFVOIDPARAMIMPL )
 
1471
{
 
1472
    STATS_INC( SHD_so_setcomp );
 
1473
 
 
1474
    INIT_SO
 
1475
 
 
1476
    CHECKVARY( p )
 
1477
    CHECKVARY( v )
 
1478
    CHECKVARY( index )
 
1479
 
 
1480
    BEGIN_VARYING_SECTION
 
1481
    GETCOLOR( p );
 
1482
    GETFLOAT( index );
 
1483
    GETFLOAT( v );
 
1484
    COLOR( p ) [ FLOAT( index ) ] = FLOAT( v );
 
1485
    SETCOLOR( p, COLOR( p ) );
 
1486
    END_VARYING_SECTION
 
1487
}
 
1488
 
 
1489
//----------------------------------------------------------------------
 
1490
// setxcomp(p,v)
 
1491
STD_SOIMPL      CqShaderExecEnv::SO_setxcomp( POINTVAL p, FLOATVAL v, DEFVOIDPARAMIMPL )
 
1492
{
 
1493
    STATS_INC( SHD_so_setxcomp );
 
1494
 
 
1495
    INIT_SO
 
1496
 
 
1497
    CHECKVARY( p )
 
1498
    CHECKVARY( v )
 
1499
 
 
1500
    BEGIN_VARYING_SECTION
 
1501
    GETPOINT( p );
 
1502
    GETFLOAT( v );
 
1503
    POINT( p ).x( FLOAT( v ) );
 
1504
    SETPOINT( p, POINT( p ) );
 
1505
    END_VARYING_SECTION
 
1506
}
 
1507
 
 
1508
//----------------------------------------------------------------------
 
1509
// setycomp(p,v)
 
1510
STD_SOIMPL      CqShaderExecEnv::SO_setycomp( POINTVAL p, FLOATVAL v, DEFVOIDPARAMIMPL )
 
1511
{
 
1512
    STATS_INC( SHD_so_setycomp );
 
1513
 
 
1514
    INIT_SO
 
1515
 
 
1516
    CHECKVARY( p )
 
1517
    CHECKVARY( v )
 
1518
 
 
1519
    BEGIN_VARYING_SECTION
 
1520
    GETPOINT( p );
 
1521
    GETFLOAT( v );
 
1522
    POINT( p ).y( FLOAT( v ) );
 
1523
    SETPOINT( p, POINT( p ) );
 
1524
    END_VARYING_SECTION
 
1525
}
 
1526
 
 
1527
//----------------------------------------------------------------------
 
1528
// setzcomp(p,v)
 
1529
STD_SOIMPL      CqShaderExecEnv::SO_setzcomp( POINTVAL p, FLOATVAL v, DEFVOIDPARAMIMPL )
 
1530
{
 
1531
    STATS_INC( SHD_so_setzcomp );
 
1532
 
 
1533
    INIT_SO
 
1534
 
 
1535
    CHECKVARY( p )
 
1536
    CHECKVARY( v )
 
1537
 
 
1538
    BEGIN_VARYING_SECTION
 
1539
    GETPOINT( p );
 
1540
    GETFLOAT( v );
 
1541
    POINT( p ).z( FLOAT( v ) );
 
1542
    SETPOINT( p, POINT( p ) );
 
1543
    END_VARYING_SECTION
 
1544
}
 
1545
 
 
1546
 
 
1547
 
 
1548
STD_SOIMPL      CqShaderExecEnv::SO_length( VECTORVAL V, DEFPARAMIMPL )
 
1549
{
 
1550
    STATS_INC( SHD_so_length );
 
1551
 
 
1552
    INIT_SO
 
1553
 
 
1554
    CHECKVARY( V )
 
1555
    CHECKVARY( Result )
 
1556
 
 
1557
    BEGIN_VARYING_SECTION
 
1558
    GETVECTOR( V );
 
1559
    SETFLOAT( Result, VECTOR( V ).Magnitude() );
 
1560
    END_VARYING_SECTION
 
1561
}
 
1562
 
 
1563
STD_SOIMPL      CqShaderExecEnv::SO_distance( POINTVAL P1, POINTVAL P2, DEFPARAMIMPL )
 
1564
{
 
1565
    STATS_INC( SHD_so_distance );
 
1566
 
 
1567
    INIT_SO
 
1568
 
 
1569
    CHECKVARY( P1 )
 
1570
    CHECKVARY( P2 )
 
1571
    CHECKVARY( Result )
 
1572
 
 
1573
    BEGIN_VARYING_SECTION
 
1574
    GETPOINT( P1 );
 
1575
    GETPOINT( P2 );
 
1576
    SETFLOAT( Result, ( POINT( P1 ) - POINT( P2 ) ).Magnitude() );
 
1577
    END_VARYING_SECTION
 
1578
}
 
1579
 
 
1580
 
 
1581
//----------------------------------------------------------------------
 
1582
// area(P)
 
1583
STD_SOIMPL CqShaderExecEnv::SO_area( POINTVAL p, DEFPARAMIMPL )
 
1584
{
 
1585
    STATS_INC( SHD_so_area );
 
1586
 
 
1587
    CqVector3D Defvec( 0.0f, 0.0f, 0.0f );
 
1588
    INIT_SO
 
1589
 
 
1590
    CqVector3D  vecR;
 
1591
 
 
1592
    CHECKVARY( p )
 
1593
    CHECKVARY( Result )
 
1594
 
 
1595
    BEGIN_VARYING_SECTION
 
1596
    if ( m_pAttributes )
 
1597
    {
 
1598
        TqFloat fdu, fdv;
 
1599
        du() ->GetFloat( fdu, __iGrid );
 
1600
        dv() ->GetFloat( fdv, __iGrid );
 
1601
        vecR = ( SO_DuType<CqVector3D>( p, __iGrid, this, Defvec ) * fdu ) %
 
1602
               ( SO_DvType<CqVector3D>( p, __iGrid, this, Defvec ) * fdv );
 
1603
        SETFLOAT( Result, vecR.Magnitude() );
 
1604
    }
 
1605
 
 
1606
    END_VARYING_SECTION
 
1607
}
 
1608
 
 
1609
 
 
1610
STD_SOIMPL      CqShaderExecEnv::SO_normalize( VECTORVAL V, DEFPARAMIMPL )
 
1611
{
 
1612
    STATS_INC( SHD_so_normalize );
 
1613
 
 
1614
    INIT_SO
 
1615
 
 
1616
    CHECKVARY( V )
 
1617
    CHECKVARY( Result )
 
1618
 
 
1619
    BEGIN_VARYING_SECTION
 
1620
    GETVECTOR( V );
 
1621
    VECTOR( V ).Unit();
 
1622
    SETVECTOR( Result, VECTOR( V ) );
 
1623
    END_VARYING_SECTION
 
1624
}
 
1625
 
 
1626
 
 
1627
//----------------------------------------------------------------------
 
1628
// faceforward(N,I)
 
1629
STD_SOIMPL CqShaderExecEnv::SO_faceforward( NORMALVAL N, VECTORVAL I, DEFPARAMIMPL )
 
1630
{
 
1631
    STATS_INC( SHD_so_faceforward );
 
1632
 
 
1633
    INIT_SO
 
1634
 
 
1635
    CHECKVARY( N )
 
1636
    CHECKVARY( I )
 
1637
    CHECKVARY( Result )
 
1638
 
 
1639
    BEGIN_VARYING_SECTION
 
1640
    GETNORMAL( N );
 
1641
    GETVECTOR( I );
 
1642
    CqVector3D Nref;
 
1643
    Ng() ->GetNormal( Nref, __iGrid );
 
1644
    TqFloat s = ( ( ( -VECTOR( I ) ) * Nref ) < 0.0f ) ? -1.0f : 1.0f;
 
1645
    SETNORMAL( Result, NORMAL( N ) * s );
 
1646
    END_VARYING_SECTION
 
1647
}
 
1648
 
 
1649
 
 
1650
//----------------------------------------------------------------------
 
1651
// faceforward(N,I,Nref)
 
1652
STD_SOIMPL CqShaderExecEnv::SO_faceforward2( NORMALVAL N, VECTORVAL I, NORMALVAL Nref, DEFPARAMIMPL )
 
1653
{
 
1654
    STATS_INC( SHD_so_faceforward2 );
 
1655
 
 
1656
    INIT_SO
 
1657
 
 
1658
    CHECKVARY( N )
 
1659
    CHECKVARY( I )
 
1660
    CHECKVARY( Nref )
 
1661
    CHECKVARY( Result )
 
1662
 
 
1663
    BEGIN_VARYING_SECTION
 
1664
    GETNORMAL( N );
 
1665
    GETVECTOR( I );
 
1666
    GETNORMAL( Nref );
 
1667
    TqFloat s = ( ( ( -VECTOR( I ) ) * NORMAL( Nref ) ) < 0.0f ) ? -1.0f : 1.0f;
 
1668
    SETNORMAL( Result, NORMAL( N ) * s );
 
1669
    END_VARYING_SECTION
 
1670
}
 
1671
 
 
1672
 
 
1673
//----------------------------------------------------------------------
 
1674
// reflect(I,N)
 
1675
STD_SOIMPL CqShaderExecEnv::SO_reflect( VECTORVAL I, NORMALVAL N, DEFPARAMIMPL )
 
1676
{
 
1677
    STATS_INC( SHD_so_reflect );
 
1678
 
 
1679
    INIT_SO
 
1680
 
 
1681
    CHECKVARY( I )
 
1682
    CHECKVARY( N )
 
1683
    CHECKVARY( Result )
 
1684
 
 
1685
    BEGIN_VARYING_SECTION
 
1686
    GETVECTOR( I );
 
1687
    GETNORMAL( N );
 
1688
    TqFloat idn = 2.0f * ( VECTOR( I ) * NORMAL( N ) );
 
1689
    CqVector3D res = VECTOR( I ) - ( idn * NORMAL( N ) );
 
1690
    SETVECTOR( Result, res );
 
1691
    END_VARYING_SECTION
 
1692
}
 
1693
 
 
1694
 
 
1695
//----------------------------------------------------------------------
 
1696
// reftact(I,N,eta)
 
1697
STD_SOIMPL CqShaderExecEnv::SO_refract( VECTORVAL I, NORMALVAL N, FLOATVAL eta, DEFPARAMIMPL )
 
1698
{
 
1699
    STATS_INC( SHD_so_refract );
 
1700
 
 
1701
    INIT_SO
 
1702
 
 
1703
    CHECKVARY( I )
 
1704
    CHECKVARY( N )
 
1705
    CHECKVARY( eta )
 
1706
    CHECKVARY( Result )
 
1707
 
 
1708
    BEGIN_VARYING_SECTION
 
1709
    GETVECTOR( I );
 
1710
    GETNORMAL( N );
 
1711
    GETFLOAT( eta );
 
1712
    TqFloat IdotN = VECTOR( I ) * NORMAL( N );
 
1713
    TqFloat feta = FLOAT( eta );
 
1714
    TqFloat k = 1 - feta * feta * ( 1 - IdotN * IdotN );
 
1715
    SETVECTOR( Result, ( k < 0.0f ) ? CqVector3D( 0, 0, 0 ) : CqVector3D( feta * VECTOR( I ) - ( feta * IdotN + sqrt( k ) ) * NORMAL( N ) ) );
 
1716
    END_VARYING_SECTION
 
1717
}
 
1718
 
 
1719
 
 
1720
//----------------------------------------------------------------------
 
1721
// fresnel(I,N,eta,Kr,Kt)
 
1722
#define SQR(A)  ((A)*(A))
 
1723
STD_SOIMPL CqShaderExecEnv::SO_fresnel( VECTORVAL I, NORMALVAL N, FLOATVAL eta, FLOATVAL Kr, FLOATVAL Kt, DEFVOIDPARAMIMPL )
 
1724
{
 
1725
    STATS_INC( SHD_so_fresnel );
 
1726
 
 
1727
    INIT_SO
 
1728
 
 
1729
    CHECKVARY( I )
 
1730
    CHECKVARY( N )
 
1731
    CHECKVARY( eta )
 
1732
    CHECKVARY( Kr )
 
1733
    CHECKVARY( Kt )
 
1734
 
 
1735
    BEGIN_VARYING_SECTION
 
1736
    GETVECTOR( I );
 
1737
    GETNORMAL( N );
 
1738
    GETFLOAT( eta );
 
1739
    GETFLOAT( Kr );
 
1740
    GETFLOAT( Kt );
 
1741
    TqFloat cos_theta = -VECTOR( I ) * NORMAL( N );
 
1742
    TqFloat fuvA = SQR( 1.0f / FLOAT( eta ) ) - ( 1.0f - SQR( cos_theta ) );
 
1743
    TqFloat fuvB = fabs( fuvA );
 
1744
    TqFloat fu2 = ( fuvA + fuvB ) / 2;
 
1745
    TqFloat fv2 = ( -fuvA + fuvB ) / 2;
 
1746
    TqFloat fv2sqrt = ( fv2 == 0.0f ) ? 0.0f : sqrt( fabs( fv2 ) );
 
1747
    TqFloat fu2sqrt = ( fu2 == 0.0f ) ? 0.0f : sqrt( fabs( fu2 ) );
 
1748
    TqFloat fperp2 = ( SQR( cos_theta - fu2sqrt ) + fv2 ) / ( SQR( cos_theta + fu2sqrt ) + fv2 );
 
1749
    TqFloat feta = FLOAT( eta );
 
1750
    TqFloat fpara2 = ( SQR( SQR( 1.0f / feta ) * cos_theta - fu2sqrt ) + SQR( -fv2sqrt ) ) /
 
1751
                     ( SQR( SQR( 1.0f / feta ) * cos_theta + fu2sqrt ) + SQR( fv2sqrt ) );
 
1752
 
 
1753
    TqFloat __Kr = 0.5f * ( fperp2 + fpara2 );
 
1754
    SETFLOAT( Kr, __Kr );
 
1755
    SETFLOAT( Kt, 1.0f - __Kr );
 
1756
    END_VARYING_SECTION
 
1757
}
 
1758
 
 
1759
//----------------------------------------------------------------------
 
1760
// fresnel(I,N,eta,Kr,Kt,R,T)
 
1761
STD_SOIMPL CqShaderExecEnv::SO_fresnel( VECTORVAL I, NORMALVAL N, FLOATVAL eta, FLOATVAL Kr, FLOATVAL Kt, VECTORVAL R, VECTORVAL T, DEFVOIDPARAMIMPL )
 
1762
{
 
1763
    STATS_INC( SHD_so_fresnel );
 
1764
 
 
1765
    INIT_SO
 
1766
 
 
1767
    CHECKVARY( I )
 
1768
    CHECKVARY( N )
 
1769
    CHECKVARY( eta )
 
1770
    CHECKVARY( Kr )
 
1771
    CHECKVARY( Kt )
 
1772
    CHECKVARY( R )
 
1773
    CHECKVARY( T )
 
1774
 
 
1775
    BEGIN_VARYING_SECTION
 
1776
    GETVECTOR( I );
 
1777
    GETNORMAL( N );
 
1778
    GETFLOAT( eta );
 
1779
    GETFLOAT( Kr );
 
1780
    GETFLOAT( Kt );
 
1781
    GETVECTOR( R );
 
1782
    GETVECTOR( T );
 
1783
    TqFloat cos_theta = -VECTOR( I ) * NORMAL( N );
 
1784
    TqFloat fuvA = SQR( 1.0f / FLOAT( eta ) ) - ( 1.0f - SQR( cos_theta ) );
 
1785
    TqFloat fuvB = fabs( fuvA );
 
1786
    TqFloat fu2 = ( fuvA + fuvB ) / 2;
 
1787
    TqFloat fv2 = ( -fuvA + fuvB ) / 2;
 
1788
    TqFloat feta = FLOAT( eta );
 
1789
    TqFloat fv2sqrt = ( fv2 == 0.0f ) ? 0.0f : sqrt( fabs( fv2 ) );
 
1790
    TqFloat fu2sqrt = ( fu2 == 0.0f ) ? 0.0f : sqrt( fabs( fu2 ) );
 
1791
    TqFloat fperp2 = ( SQR( cos_theta - fu2sqrt ) + fv2 ) / ( SQR( cos_theta + fu2sqrt ) + fv2 );
 
1792
    TqFloat fpara2 = ( SQR( SQR( 1.0f / feta ) * cos_theta - fu2sqrt ) + SQR( -fv2sqrt ) ) /
 
1793
                     ( SQR( SQR( 1.0f / feta ) * cos_theta + fu2sqrt ) + SQR( fv2sqrt ) );
 
1794
    TqFloat __Kr = 0.5f * ( fperp2 + fpara2 );
 
1795
    SETFLOAT( Kr, __Kr );
 
1796
    SETFLOAT( Kt, 1.0f - __Kr );
 
1797
    END_VARYING_SECTION
 
1798
 
 
1799
    SO_reflect( I, N, R );
 
1800
    SO_refract( I, N, eta, T );
 
1801
}
 
1802
 
 
1803
 
 
1804
//----------------------------------------------------------------------
 
1805
// transform(s,s,P)
 
1806
STD_SOIMPL CqShaderExecEnv::SO_transform( STRINGVAL fromspace, STRINGVAL tospace, POINTVAL p, DEFPARAMIMPL )
 
1807
{
 
1808
    STATS_INC( SHD_so_transform );
 
1809
 
 
1810
    INIT_SO
 
1811
 
 
1812
    assert( pShader != 0 );
 
1813
 
 
1814
    CHECKVARY( p )
 
1815
    CHECKVARY( Result )
 
1816
 
 
1817
    if ( NULL != QGetRenderContextI() )
 
1818
    {
 
1819
        BEGIN_UNIFORM_SECTION
 
1820
        GETSTRING( fromspace );
 
1821
        GETSTRING( tospace );
 
1822
        const CqMatrix& mat = QGetRenderContextI() ->matSpaceToSpace( STRING( fromspace ).c_str(), STRING( tospace ).c_str(), pShader->matCurrent(), matObjectToWorld(), QGetRenderContextI()->Time() );
 
1823
        END_UNIFORM_SECTION
 
1824
 
 
1825
        BEGIN_VARYING_SECTION
 
1826
        GETPOINT( p );
 
1827
        SETPOINT( Result, mat * POINT( p ) );
 
1828
        END_VARYING_SECTION
 
1829
    }
 
1830
    else
 
1831
    {
 
1832
        BEGIN_VARYING_SECTION
 
1833
        GETPOINT( p );
 
1834
        SETPOINT( Result, POINT( p ) );
 
1835
        END_VARYING_SECTION
 
1836
    }
 
1837
}
 
1838
 
 
1839
 
 
1840
//----------------------------------------------------------------------
 
1841
// transform(s,P)
 
1842
STD_SOIMPL CqShaderExecEnv::SO_transform( STRINGVAL tospace, POINTVAL p, DEFPARAMIMPL )
 
1843
{
 
1844
    STATS_INC( SHD_so_transform );
 
1845
 
 
1846
    INIT_SO
 
1847
 
 
1848
    assert( pShader != 0 );
 
1849
 
 
1850
    CHECKVARY( p )
 
1851
    CHECKVARY( Result )
 
1852
 
 
1853
    if ( NULL != QGetRenderContextI() )
 
1854
    {
 
1855
        BEGIN_UNIFORM_SECTION
 
1856
        GETSTRING( tospace );
 
1857
        const CqMatrix& mat = QGetRenderContextI() ->matSpaceToSpace( "current", STRING( tospace ).c_str(), pShader->matCurrent(), matObjectToWorld(), QGetRenderContextI()->Time() );
 
1858
        END_UNIFORM_SECTION
 
1859
 
 
1860
        BEGIN_VARYING_SECTION
 
1861
        GETPOINT( p );
 
1862
        SETPOINT( Result, mat * POINT( p ) );
 
1863
        END_VARYING_SECTION
 
1864
    }
 
1865
    else
 
1866
    {
 
1867
        BEGIN_VARYING_SECTION
 
1868
        GETPOINT( p );
 
1869
        SETPOINT( Result, POINT( p ) );
 
1870
        END_VARYING_SECTION
 
1871
    }
 
1872
}
 
1873
 
 
1874
 
 
1875
//----------------------------------------------------------------------
 
1876
// transform(m,P)
 
1877
STD_SOIMPL CqShaderExecEnv::SO_transformm( MATRIXVAL tospace, POINTVAL p, DEFPARAMIMPL )
 
1878
{
 
1879
    STATS_INC( SHD_so_transform );
 
1880
 
 
1881
    INIT_SO
 
1882
 
 
1883
    assert( pShader != 0 );
 
1884
 
 
1885
    CHECKVARY( p )
 
1886
    CHECKVARY( Result )
 
1887
 
 
1888
    BEGIN_VARYING_SECTION
 
1889
    GETMATRIX( tospace );
 
1890
    GETPOINT( p );
 
1891
    SETPOINT( Result, MATRIX( tospace ) * POINT( p ) );
 
1892
    END_VARYING_SECTION
 
1893
}
 
1894
 
 
1895
 
 
1896
//----------------------------------------------------------------------
 
1897
// vtransform(s,s,P)
 
1898
STD_SOIMPL CqShaderExecEnv::SO_vtransform( STRINGVAL fromspace, STRINGVAL tospace, VECTORVAL p, DEFPARAMIMPL )
 
1899
{
 
1900
    STATS_INC( SHD_so_vtransform );
 
1901
 
 
1902
    INIT_SO
 
1903
 
 
1904
    assert( pShader != 0 );
 
1905
 
 
1906
    CHECKVARY( p )
 
1907
    CHECKVARY( Result )
 
1908
 
 
1909
    if ( NULL != QGetRenderContextI() )
 
1910
    {
 
1911
        BEGIN_UNIFORM_SECTION
 
1912
        GETSTRING( fromspace );
 
1913
        GETSTRING( tospace );
 
1914
        const CqMatrix& mat = QGetRenderContextI() ->matVSpaceToSpace( STRING( fromspace ).c_str(), STRING( tospace ).c_str(), pShader->matCurrent(), matObjectToWorld(), QGetRenderContextI()->Time() );
 
1915
        END_UNIFORM_SECTION
 
1916
 
 
1917
        BEGIN_VARYING_SECTION
 
1918
        GETVECTOR( p );
 
1919
        SETVECTOR( Result, mat * VECTOR( p ) );
 
1920
        END_VARYING_SECTION
 
1921
    }
 
1922
    else
 
1923
    {
 
1924
        BEGIN_VARYING_SECTION
 
1925
        GETVECTOR( p );
 
1926
        SETVECTOR( Result, VECTOR( p ) );
 
1927
        END_VARYING_SECTION
 
1928
    }
 
1929
}
 
1930
 
 
1931
 
 
1932
//----------------------------------------------------------------------
 
1933
// vtransform(s,P)
 
1934
STD_SOIMPL CqShaderExecEnv::SO_vtransform( STRINGVAL tospace, VECTORVAL p, DEFPARAMIMPL )
 
1935
{
 
1936
    STATS_INC( SHD_so_vtransform );
 
1937
 
 
1938
    INIT_SO
 
1939
 
 
1940
    assert( pShader != 0 );
 
1941
 
 
1942
    CHECKVARY( p )
 
1943
    CHECKVARY( Result )
 
1944
 
 
1945
    if ( NULL != QGetRenderContextI() )
 
1946
    {
 
1947
        BEGIN_UNIFORM_SECTION
 
1948
        GETSTRING( tospace );
 
1949
        const CqMatrix& mat = QGetRenderContextI() ->matVSpaceToSpace( "current", STRING( tospace ).c_str(), pShader->matCurrent(), matObjectToWorld(), QGetRenderContextI()->Time() );
 
1950
        END_UNIFORM_SECTION
 
1951
 
 
1952
        BEGIN_VARYING_SECTION
 
1953
        GETVECTOR( p );
 
1954
        SETVECTOR( Result, mat * VECTOR( p ) );
 
1955
        END_VARYING_SECTION
 
1956
    }
 
1957
    else
 
1958
    {
 
1959
        BEGIN_VARYING_SECTION
 
1960
        GETVECTOR( p );
 
1961
        SETVECTOR( Result, VECTOR( p ) );
 
1962
        END_VARYING_SECTION
 
1963
    }
 
1964
}
 
1965
 
 
1966
 
 
1967
//----------------------------------------------------------------------
 
1968
// vtransform(m,P)
 
1969
STD_SOIMPL CqShaderExecEnv::SO_vtransformm( MATRIXVAL tospace, VECTORVAL p, DEFPARAMIMPL )
 
1970
{
 
1971
    STATS_INC( SHD_so_vtransform );
 
1972
 
 
1973
    INIT_SO
 
1974
 
 
1975
    assert( pShader != 0 );
 
1976
 
 
1977
    CHECKVARY( p )
 
1978
    CHECKVARY( Result )
 
1979
 
 
1980
    BEGIN_VARYING_SECTION
 
1981
    GETMATRIX( tospace );
 
1982
    GETVECTOR( p );
 
1983
    SETVECTOR( Result, MATRIX( tospace ) * VECTOR( p ) );
 
1984
    END_VARYING_SECTION
 
1985
}
 
1986
 
 
1987
 
 
1988
//----------------------------------------------------------------------
 
1989
// ntransform(s,s,P)
 
1990
STD_SOIMPL CqShaderExecEnv::SO_ntransform( STRINGVAL fromspace, STRINGVAL tospace, NORMALVAL p, DEFPARAMIMPL )
 
1991
{
 
1992
    STATS_INC( SHD_so_ntransform );
 
1993
 
 
1994
    INIT_SO
 
1995
 
 
1996
    assert( pShader != 0 );
 
1997
 
 
1998
    CHECKVARY( p )
 
1999
    CHECKVARY( Result )
 
2000
 
 
2001
    if ( NULL != QGetRenderContextI() )
 
2002
    {
 
2003
        BEGIN_UNIFORM_SECTION
 
2004
        GETSTRING( fromspace );
 
2005
        GETSTRING( tospace );
 
2006
        const CqMatrix& mat = QGetRenderContextI() ->matNSpaceToSpace( STRING( fromspace ).c_str(), STRING( tospace ).c_str(), pShader->matCurrent(), matObjectToWorld(), QGetRenderContextI()->Time() );
 
2007
        BEGIN_UNIFORM_SECTION
 
2008
 
 
2009
        BEGIN_VARYING_SECTION
 
2010
        GETNORMAL( p );
 
2011
        SETNORMAL( Result, mat * NORMAL( p ) );
 
2012
        END_VARYING_SECTION
 
2013
    }
 
2014
    else
 
2015
    {
 
2016
        BEGIN_VARYING_SECTION
 
2017
        GETNORMAL( p );
 
2018
        SETNORMAL( Result, NORMAL( p ) );
 
2019
        END_VARYING_SECTION
 
2020
    }
 
2021
}
 
2022
 
 
2023
 
 
2024
//----------------------------------------------------------------------
 
2025
// ntransform(s,P)
 
2026
STD_SOIMPL CqShaderExecEnv::SO_ntransform( STRINGVAL tospace, NORMALVAL p, DEFPARAMIMPL )
 
2027
{
 
2028
    STATS_INC( SHD_so_ntransform );
 
2029
 
 
2030
    INIT_SO
 
2031
 
 
2032
    assert( pShader != 0 );
 
2033
 
 
2034
    CHECKVARY( p )
 
2035
    CHECKVARY( Result )
 
2036
 
 
2037
    if ( NULL != QGetRenderContextI() )
 
2038
    {
 
2039
        BEGIN_UNIFORM_SECTION
 
2040
        GETSTRING( tospace );
 
2041
        const CqMatrix& mat = QGetRenderContextI() ->matNSpaceToSpace( "current", STRING( tospace ).c_str(), pShader->matCurrent(), matObjectToWorld(), QGetRenderContextI()->Time() );
 
2042
        BEGIN_UNIFORM_SECTION
 
2043
 
 
2044
        BEGIN_VARYING_SECTION
 
2045
        GETNORMAL( p );
 
2046
        SETNORMAL( Result, mat * NORMAL( p ) );
 
2047
        END_VARYING_SECTION
 
2048
    }
 
2049
    else
 
2050
    {
 
2051
        BEGIN_VARYING_SECTION
 
2052
        GETNORMAL( p );
 
2053
        SETNORMAL( Result, NORMAL( p ) );
 
2054
        END_VARYING_SECTION
 
2055
    }
 
2056
}
 
2057
 
 
2058
 
 
2059
//----------------------------------------------------------------------
 
2060
// ntransform(m,P)
 
2061
STD_SOIMPL CqShaderExecEnv::SO_ntransformm( MATRIXVAL tospace, NORMALVAL p, DEFPARAMIMPL )
 
2062
{
 
2063
    STATS_INC( SHD_so_ntransform );
 
2064
 
 
2065
    INIT_SO
 
2066
 
 
2067
    assert( pShader != 0 );
 
2068
 
 
2069
    CHECKVARY( p )
 
2070
    CHECKVARY( Result )
 
2071
 
 
2072
    BEGIN_VARYING_SECTION
 
2073
    GETMATRIX( tospace );
 
2074
    GETNORMAL( p );
 
2075
    SETNORMAL( Result, MATRIX( tospace ) * NORMAL( p ) );
 
2076
    END_VARYING_SECTION
 
2077
}
 
2078
 
 
2079
 
 
2080
//----------------------------------------------------------------------
 
2081
// depth(P)
 
2082
STD_SOIMPL CqShaderExecEnv::SO_depth( POINTVAL p, DEFPARAMIMPL )
 
2083
{
 
2084
    STATS_INC( SHD_so_depth );
 
2085
 
 
2086
    INIT_SO
 
2087
 
 
2088
    if ( NULL == QGetRenderContextI() )
 
2089
        return ;
 
2090
 
 
2091
    CHECKVARY( p )
 
2092
    CHECKVARY( Result )
 
2093
 
 
2094
    BEGIN_VARYING_SECTION
 
2095
    GETPOINT( p );
 
2096
    TqFloat d = POINT( p ).z();
 
2097
    d = ( d - QGetRenderContextI() ->GetFloatOption( "System", "Clipping" ) [ 0 ] ) /
 
2098
        ( QGetRenderContextI() ->GetFloatOption( "System", "Clipping" ) [ 1 ] - QGetRenderContextI() ->GetFloatOption( "System", "Clipping" ) [ 0 ] );
 
2099
    SETFLOAT( Result, d );
 
2100
    END_VARYING_SECTION
 
2101
}
 
2102
 
 
2103
 
 
2104
//----------------------------------------------------------------------
 
2105
// calculatenormal(P)
 
2106
STD_SOIMPL CqShaderExecEnv::SO_calculatenormal( POINTVAL p, DEFPARAMIMPL )
 
2107
{
 
2108
    STATS_INC( SHD_so_calculatenormal );
 
2109
 
 
2110
    CqVector3D Defvec( 0.0f, 0.0f, 0.0f );
 
2111
    INIT_SO
 
2112
 
 
2113
    // Find out if the orientation is inverted.
 
2114
    TqBool CSO = pTransform()->GetHandedness(QGetRenderContextI()->Time());
 
2115
    TqBool O = TqFalse;
 
2116
        if( pAttributes() )
 
2117
            TqBool O = pAttributes() ->GetIntegerAttribute( "System", "Orientation" ) [ 0 ] != 0;
 
2118
    TqFloat neg = 1;
 
2119
        if ( O != CSO ) neg = -1;
 
2120
 
 
2121
    CHECKVARY( p )
 
2122
    CHECKVARY( Result )
 
2123
 
 
2124
    BEGIN_VARYING_SECTION
 
2125
    //CqVector3D        dPdu = SO_DuType<CqVector3D>( p, __iGrid, this, Defvec );
 
2126
    //CqVector3D        dPdv = SO_DvType<CqVector3D>( p, __iGrid, this, Defvec );
 
2127
    //CqVector3D        N = dPdu % dPdv;
 
2128
 
 
2129
    CqVector3D Ret, Ret2;
 
2130
    TqInt uRes = uGridRes();
 
2131
    TqInt GridX = __iGrid % ( uRes + 1 );
 
2132
 
 
2133
    CqVector3D v1, v2;
 
2134
    if ( GridX < uRes )
 
2135
    {
 
2136
        p->GetValue( v1, __iGrid + 1 );
 
2137
        p->GetValue( v2, __iGrid );
 
2138
        Ret = ( v1 - v2 );
 
2139
    }
 
2140
    else
 
2141
    {
 
2142
        p->GetValue( v1, __iGrid );
 
2143
        p->GetValue( v2, __iGrid - 1 );
 
2144
        Ret = ( v1 - v2 );
 
2145
    }
 
2146
    TqInt vRes = vGridRes();
 
2147
    TqInt GridY = ( __iGrid / ( uRes + 1 ) );
 
2148
 
 
2149
    if ( GridY < vRes )
 
2150
    {
 
2151
        p->GetValue( v1, __iGrid + uRes + 1 );
 
2152
        p->GetValue( v2, __iGrid );
 
2153
        Ret2 = ( v1 - v2 );
 
2154
    }
 
2155
    else
 
2156
    {
 
2157
        p->GetValue( v1, __iGrid );
 
2158
        p->GetValue( v2, __iGrid - ( uRes + 1 ) );
 
2159
        Ret2 = ( v1 - v2 );
 
2160
    }
 
2161
 
 
2162
    CqVector3D N = Ret % Ret2;
 
2163
    N.Unit();
 
2164
    N *= neg;
 
2165
    SETNORMAL( Result, N );
 
2166
    END_VARYING_SECTION
 
2167
}
 
2168
 
 
2169
STD_SOIMPL CqShaderExecEnv::SO_cmix( COLORVAL color0, COLORVAL color1, FLOATVAL value, DEFPARAMIMPL )
 
2170
{
 
2171
    STATS_INC( SHD_so_cmix );
 
2172
 
 
2173
    INIT_SO
 
2174
 
 
2175
    CHECKVARY( color0 )
 
2176
    CHECKVARY( color1 )
 
2177
    CHECKVARY( value )
 
2178
    CHECKVARY( Result )
 
2179
 
 
2180
    BEGIN_VARYING_SECTION
 
2181
    GETCOLOR( color0 );
 
2182
    GETCOLOR( color1 );
 
2183
    GETFLOAT( value );
 
2184
    CqColor c( ( 1.0f - FLOAT( value ) ) * COLOR( color0 ) + FLOAT( value ) * COLOR( color1 ) );
 
2185
    SETCOLOR( Result, c );
 
2186
    END_VARYING_SECTION
 
2187
}
 
2188
 
 
2189
STD_SOIMPL      CqShaderExecEnv::SO_fmix( FLOATVAL f0, FLOATVAL f1, FLOATVAL value, DEFPARAMIMPL )
 
2190
{
 
2191
    STATS_INC( SHD_so_fmix );
 
2192
 
 
2193
    INIT_SO
 
2194
 
 
2195
    CHECKVARY( f0 )
 
2196
    CHECKVARY( f1 )
 
2197
    CHECKVARY( value )
 
2198
 
 
2199
    BEGIN_VARYING_SECTION
 
2200
    GETFLOAT( f0 );
 
2201
    GETFLOAT( f1 );
 
2202
    GETFLOAT( value );
 
2203
    TqFloat f( ( 1.0f - FLOAT( value ) ) * FLOAT( f0 ) + FLOAT( value ) * FLOAT( f1 ) );
 
2204
    SETFLOAT( Result, f );
 
2205
    END_VARYING_SECTION
 
2206
}
 
2207
 
 
2208
STD_SOIMPL      CqShaderExecEnv::SO_pmix( POINTVAL p0, POINTVAL p1, FLOATVAL value, DEFPARAMIMPL )
 
2209
{
 
2210
    STATS_INC( SHD_so_pmix );
 
2211
 
 
2212
    INIT_SO
 
2213
 
 
2214
    CHECKVARY( p0 )
 
2215
    CHECKVARY( p1 )
 
2216
    CHECKVARY( value )
 
2217
 
 
2218
    BEGIN_VARYING_SECTION
 
2219
    GETPOINT( p0 );
 
2220
    GETPOINT( p1 );
 
2221
    GETFLOAT( value );
 
2222
    CqVector3D p( ( 1.0f - FLOAT( value ) ) * POINT( p0 ) + FLOAT( value ) * POINT( p1 ) );
 
2223
    SETPOINT( Result, p );
 
2224
    END_VARYING_SECTION
 
2225
}
 
2226
 
 
2227
STD_SOIMPL      CqShaderExecEnv::SO_vmix( VECTORVAL v0, VECTORVAL v1, FLOATVAL value, DEFPARAMIMPL )
 
2228
{
 
2229
    STATS_INC( SHD_so_vmix );
 
2230
 
 
2231
    INIT_SO
 
2232
 
 
2233
    CHECKVARY( v0 )
 
2234
    CHECKVARY( v1 )
 
2235
    CHECKVARY( value )
 
2236
 
 
2237
    BEGIN_VARYING_SECTION
 
2238
    GETVECTOR( v0 );
 
2239
    GETVECTOR( v1 );
 
2240
    GETFLOAT( value );
 
2241
    CqVector3D v( ( 1.0f - FLOAT( value ) ) * VECTOR( v0 ) + FLOAT( value ) * VECTOR( v1 ) );
 
2242
    SETVECTOR( Result, v );
 
2243
    END_VARYING_SECTION
 
2244
}
 
2245
 
 
2246
STD_SOIMPL      CqShaderExecEnv::SO_nmix( NORMALVAL n0, NORMALVAL n1, FLOATVAL value, DEFPARAMIMPL )
 
2247
{
 
2248
    INIT_SO
 
2249
 
 
2250
    CHECKVARY( n0 )
 
2251
    CHECKVARY( n1 )
 
2252
    CHECKVARY( value )
 
2253
 
 
2254
    BEGIN_VARYING_SECTION
 
2255
    GETNORMAL( n0 );
 
2256
    GETNORMAL( n1 );
 
2257
    GETFLOAT( value );
 
2258
    CqVector3D n( ( 1.0f - FLOAT( value ) ) * NORMAL( n0 ) + FLOAT( value ) * NORMAL( n1 ) );
 
2259
    SETNORMAL( Result, n );
 
2260
    END_VARYING_SECTION
 
2261
}
 
2262
 
 
2263
 
 
2264
//----------------------------------------------------------------------
 
2265
// texture(S)
 
2266
STD_SOIMPL CqShaderExecEnv::SO_ftexture1( STRINGVAL name, FLOATVAL channel, DEFPARAMVARIMPL )
 
2267
{
 
2268
    STATS_INC( SHD_so_ftexture1 );
 
2269
 
 
2270
    TqFloat Deffloat = 0.0f;
 
2271
    INIT_SO
 
2272
 
 
2273
    if ( NULL == QGetRenderContextI() )
 
2274
        return ;
 
2275
 
 
2276
    GET_TEXTURE_PARAMS;
 
2277
 
 
2278
    TqFloat fill = 0.0f;
 
2279
    if ( paramMap.find( "fill" ) != paramMap.end() )
 
2280
        paramMap[ "fill" ] ->GetFloat( fill );
 
2281
 
 
2282
    BEGIN_UNIFORM_SECTION
 
2283
    GETSTRING( name );
 
2284
    GETFLOAT( channel );
 
2285
    IqTextureMap* pTMap = QGetRenderContextI() ->GetTextureMap( STRING( name ) );
 
2286
    TqFloat fdu = 0.0f, fdv = 0.0f;
 
2287
    if ( m_pAttributes )
 
2288
    {
 
2289
        du() ->GetFloat( fdu );
 
2290
        dv() ->GetFloat( fdv );
 
2291
    }
 
2292
    END_UNIFORM_SECTION
 
2293
 
 
2294
 
 
2295
    __fVarying = TqTrue;
 
2296
    if ( pTMap != 0 && pTMap->IsValid() )
 
2297
    {
 
2298
        std::valarray<TqFloat> val;
 
2299
        pTMap->PrepareSampleOptions( paramMap );
 
2300
 
 
2301
        BEGIN_VARYING_SECTION
 
2302
        TqFloat swidth = 0.0f, twidth = 0.0f;
 
2303
        if ( fdu != 0.0f && fdv != 0.0f )
 
2304
        {
 
2305
            TqFloat dsdu = SO_DuType<TqFloat>( s(), __iGrid, this, Deffloat );
 
2306
            swidth = fabs( dsdu * fdu );
 
2307
            TqFloat dtdu = SO_DuType<TqFloat>( t(), __iGrid, this, Deffloat );
 
2308
            twidth = fabs( dtdu * fdu );
 
2309
 
 
2310
            TqFloat dsdv = SO_DvType<TqFloat>( s(), __iGrid, this, Deffloat );
 
2311
            swidth += fabs( dsdv * fdv );
 
2312
            TqFloat dtdv = SO_DvType<TqFloat>( t(), __iGrid, this, Deffloat );
 
2313
            twidth += fabs( dtdv * fdv );
 
2314
        }
 
2315
        else
 
2316
        {
 
2317
            swidth = 1.0 / pTMap->XRes();
 
2318
            twidth = 1.0 / pTMap->YRes();
 
2319
        }
 
2320
 
 
2321
        // Sample the texture.
 
2322
        TqFloat fs, ft;
 
2323
        s() ->GetFloat( fs, __iGrid );
 
2324
        t() ->GetFloat( ft, __iGrid );
 
2325
        pTMap->SampleMap( fs, ft, swidth, twidth, val );
 
2326
 
 
2327
        // Grab the appropriate channel.
 
2328
        TqFloat fchan = FLOAT( channel );
 
2329
        if ( fchan >= val.size() )
 
2330
            SETFLOAT( Result, fill );
 
2331
        else
 
2332
            SETFLOAT( Result, val[ static_cast<unsigned int>( fchan ) ] );
 
2333
        END_VARYING_SECTION
 
2334
    }
 
2335
    else
 
2336
    {
 
2337
        BEGIN_VARYING_SECTION
 
2338
        SETFLOAT( Result, 0.0f );
 
2339
        END_VARYING_SECTION
 
2340
    }
 
2341
}
 
2342
 
 
2343
//----------------------------------------------------------------------
 
2344
// texture(S,F,F)
 
2345
STD_SOIMPL CqShaderExecEnv::SO_ftexture2( STRINGVAL name, FLOATVAL channel, FLOATVAL s, FLOATVAL t, DEFPARAMVARIMPL )
 
2346
{
 
2347
    STATS_INC( SHD_so_ftexture2 );
 
2348
 
 
2349
    TqFloat Deffloat = 0.0f;
 
2350
    INIT_SO
 
2351
 
 
2352
    if ( NULL == QGetRenderContextI() )
 
2353
        return ;
 
2354
 
 
2355
    GET_TEXTURE_PARAMS;
 
2356
 
 
2357
    TqFloat fill = 0.0f;
 
2358
    if ( paramMap.find( "fill" ) != paramMap.end() )
 
2359
        paramMap[ "fill" ] ->GetFloat( fill );
 
2360
 
 
2361
    BEGIN_UNIFORM_SECTION
 
2362
    GETSTRING( name );
 
2363
    GETFLOAT( channel );
 
2364
    IqTextureMap* pTMap = QGetRenderContextI() ->GetTextureMap( STRING( name ) );
 
2365
    TqFloat fdu = 0.0f, fdv = 0.0f;
 
2366
    if ( m_pAttributes )
 
2367
    {
 
2368
        du() ->GetFloat( fdu );
 
2369
        dv() ->GetFloat( fdv );
 
2370
    }
 
2371
    END_UNIFORM_SECTION
 
2372
 
 
2373
 
 
2374
    __fVarying = TqTrue;
 
2375
    if ( pTMap != 0 && pTMap->IsValid() )
 
2376
    {
 
2377
        std::valarray<TqFloat> val;
 
2378
        pTMap->PrepareSampleOptions( paramMap );
 
2379
 
 
2380
        BEGIN_VARYING_SECTION
 
2381
        TqFloat swidth = 0.0f, twidth = 0.0f;
 
2382
        if ( fdu != 0.0f && fdv != 0.0f )
 
2383
        {
 
2384
            TqFloat dsdu = SO_DuType<TqFloat>( s, __iGrid, this, Deffloat );
 
2385
            swidth = fabs( dsdu * fdu );
 
2386
            TqFloat dtdu = SO_DuType<TqFloat>( t, __iGrid, this, Deffloat );
 
2387
            twidth = fabs( dtdu * fdu );
 
2388
 
 
2389
            TqFloat dsdv = SO_DvType<TqFloat>( s, __iGrid, this, Deffloat );
 
2390
            swidth += fabs( dsdv * fdv );
 
2391
            TqFloat dtdv = SO_DvType<TqFloat>( t, __iGrid, this, Deffloat );
 
2392
            twidth += fabs( dtdv * fdv );
 
2393
        }
 
2394
        else
 
2395
        {
 
2396
            swidth = 1.0 / pTMap->XRes();
 
2397
            twidth = 1.0 / pTMap->YRes();
 
2398
        }
 
2399
 
 
2400
        // Sample the texture.
 
2401
        GETFLOAT( s );
 
2402
        GETFLOAT( t );
 
2403
        pTMap->SampleMap( FLOAT( s ), FLOAT( t ), swidth, twidth, val );
 
2404
 
 
2405
        // Grab the appropriate channel.
 
2406
        TqFloat fchan = FLOAT( channel );
 
2407
        if ( fchan >= val.size() )
 
2408
            SETFLOAT( Result, fill );
 
2409
        else
 
2410
            SETFLOAT( Result, val[ static_cast<unsigned int>( fchan ) ] );
 
2411
        END_VARYING_SECTION
 
2412
    }
 
2413
    else
 
2414
    {
 
2415
        BEGIN_VARYING_SECTION
 
2416
        SETFLOAT( Result, 0.0f );       // Default, completely lit
 
2417
        END_VARYING_SECTION
 
2418
    }
 
2419
}
 
2420
 
 
2421
//----------------------------------------------------------------------
 
2422
// texture(S,F,F,F,F,F,F,F,F)
 
2423
STD_SOIMPL CqShaderExecEnv::SO_ftexture3( STRINGVAL name, FLOATVAL channel, FLOATVAL s1, FLOATVAL t1, FLOATVAL s2, FLOATVAL t2, FLOATVAL s3, FLOATVAL t3, FLOATVAL s4, FLOATVAL t4, DEFPARAMVARIMPL )
 
2424
{
 
2425
    STATS_INC( SHD_so_ftexture3 );
 
2426
 
 
2427
    INIT_SO
 
2428
 
 
2429
    if ( NULL == QGetRenderContextI() )
 
2430
        return ;
 
2431
 
 
2432
    GET_TEXTURE_PARAMS;
 
2433
 
 
2434
    TqFloat fill = 0.0f;
 
2435
    if ( paramMap.find( "fill" ) != paramMap.end() )
 
2436
        paramMap[ "fill" ] ->GetFloat( fill );
 
2437
 
 
2438
    BEGIN_UNIFORM_SECTION
 
2439
    GETSTRING( name );
 
2440
    GETFLOAT( channel );
 
2441
    IqTextureMap* pTMap = QGetRenderContextI() ->GetTextureMap( STRING( name ) );
 
2442
    END_UNIFORM_SECTION
 
2443
 
 
2444
 
 
2445
    __fVarying = TqTrue;
 
2446
    if ( pTMap != 0 && pTMap->IsValid() )
 
2447
    {
 
2448
        std::valarray<TqFloat> val;
 
2449
        pTMap->PrepareSampleOptions( paramMap );
 
2450
 
 
2451
        BEGIN_VARYING_SECTION
 
2452
 
 
2453
        // Sample the texture.
 
2454
        GETFLOAT( s1 );
 
2455
        GETFLOAT( t1 );
 
2456
        GETFLOAT( s2 );
 
2457
        GETFLOAT( t2 );
 
2458
        GETFLOAT( s3 );
 
2459
        GETFLOAT( t3 );
 
2460
        GETFLOAT( s4 );
 
2461
        GETFLOAT( t4 );
 
2462
        pTMap->SampleMap( FLOAT( s1 ), FLOAT( t1 ), FLOAT( s2 ), FLOAT( t2 ), FLOAT( s3 ), FLOAT( t3 ), FLOAT( s4 ), FLOAT( t4 ), val );
 
2463
 
 
2464
        // Grab the appropriate channel.
 
2465
        TqFloat fchan = FLOAT( channel );
 
2466
        if ( fchan >= val.size() )
 
2467
            SETFLOAT( Result, fill );
 
2468
        else
 
2469
            SETFLOAT( Result, val[ static_cast<unsigned int>( fchan ) ] );
 
2470
        END_VARYING_SECTION
 
2471
    }
 
2472
    else
 
2473
    {
 
2474
        BEGIN_VARYING_SECTION
 
2475
        SETFLOAT( Result, 0.0f );       // Default, completely lit
 
2476
        END_VARYING_SECTION
 
2477
    }
 
2478
}
 
2479
 
 
2480
//----------------------------------------------------------------------
 
2481
// texture(S)
 
2482
STD_SOIMPL CqShaderExecEnv::SO_ctexture1( STRINGVAL name, FLOATVAL channel, DEFPARAMVARIMPL )
 
2483
{
 
2484
    STATS_INC( SHD_so_ctexture1 );
 
2485
 
 
2486
    TqFloat Deffloat = 0.0f;
 
2487
    INIT_SO
 
2488
 
 
2489
    if ( NULL == QGetRenderContextI() )
 
2490
        return ;
 
2491
 
 
2492
    GET_TEXTURE_PARAMS;
 
2493
 
 
2494
    TqFloat fill = 0.0f;
 
2495
    if ( paramMap.find( "fill" ) != paramMap.end() )
 
2496
        paramMap[ "fill" ] ->GetFloat( fill );
 
2497
 
 
2498
    BEGIN_UNIFORM_SECTION
 
2499
    GETSTRING( name );
 
2500
    GETFLOAT( channel );
 
2501
    IqTextureMap* pTMap = QGetRenderContextI() ->GetTextureMap( STRING( name ) );
 
2502
    TqFloat fdu = 0.0f, fdv = 0.0f;
 
2503
    if ( m_pAttributes )
 
2504
    {
 
2505
        du() ->GetFloat( fdu );
 
2506
        dv() ->GetFloat( fdv );
 
2507
    }
 
2508
    END_UNIFORM_SECTION
 
2509
 
 
2510
 
 
2511
    __fVarying = TqTrue;
 
2512
    if ( pTMap != 0 && pTMap->IsValid() )
 
2513
    {
 
2514
        std::valarray<TqFloat> val;
 
2515
        pTMap->PrepareSampleOptions( paramMap );
 
2516
 
 
2517
        BEGIN_VARYING_SECTION
 
2518
        TqFloat swidth = 0.0f, twidth = 0.0f;
 
2519
        if ( fdu != 0.0f && fdv != 0.0f )
 
2520
        {
 
2521
            TqFloat dsdu = SO_DuType<TqFloat>( s(), __iGrid, this, Deffloat );
 
2522
            swidth = fabs( dsdu * fdu );
 
2523
            TqFloat dsdv = SO_DvType<TqFloat>( s(), __iGrid, this, Deffloat );
 
2524
            swidth += fabs( dsdv * fdv );
 
2525
 
 
2526
            TqFloat dtdu = SO_DuType<TqFloat>( t(), __iGrid, this, Deffloat );
 
2527
            twidth = fabs( dtdu * fdu );
 
2528
            TqFloat dtdv = SO_DvType<TqFloat>( t(), __iGrid, this, Deffloat );
 
2529
            twidth += fabs( dtdv * fdv );
 
2530
        }
 
2531
        else
 
2532
        {
 
2533
            swidth = 1.0 / pTMap->XRes();
 
2534
            twidth = 1.0 / pTMap->YRes();
 
2535
        }
 
2536
 
 
2537
        // Sample the texture.
 
2538
        TqFloat fs, ft;
 
2539
        s() ->GetFloat( fs, __iGrid );
 
2540
        t() ->GetFloat( ft, __iGrid );
 
2541
        pTMap->SampleMap( fs, ft, swidth, twidth, val );
 
2542
 
 
2543
        // Grab the appropriate channel.
 
2544
        TqFloat fchan = FLOAT( channel );
 
2545
        if ( fchan + 2 >= val.size() )
 
2546
            SETCOLOR( Result, CqColor( fill, fill, fill ) );
 
2547
        else
 
2548
            SETCOLOR( Result, CqColor( val[ static_cast<unsigned int>( fchan ) ], val[ static_cast<unsigned int>( fchan ) + 1 ], val[ static_cast<unsigned int>( fchan ) + 2 ] ) );
 
2549
        END_VARYING_SECTION
 
2550
    }
 
2551
    else
 
2552
    {
 
2553
        BEGIN_VARYING_SECTION
 
2554
        SETCOLOR( Result, CqColor( 0, 0, 0 ) ); // Default, no color
 
2555
        END_VARYING_SECTION
 
2556
    }
 
2557
}
 
2558
 
 
2559
//----------------------------------------------------------------------
 
2560
// texture(S,F,F)
 
2561
STD_SOIMPL CqShaderExecEnv::SO_ctexture2( STRINGVAL name, FLOATVAL channel, FLOATVAL s, FLOATVAL t, DEFPARAMVARIMPL )
 
2562
{
 
2563
    STATS_INC( SHD_so_ctexture2 );
 
2564
 
 
2565
    TqFloat Deffloat = 0.0f;
 
2566
    INIT_SO
 
2567
 
 
2568
    if ( NULL == QGetRenderContextI() )
 
2569
        return ;
 
2570
 
 
2571
    GET_TEXTURE_PARAMS;
 
2572
 
 
2573
    TqFloat fill = 0.0f;
 
2574
    if ( paramMap.find( "fill" ) != paramMap.end() )
 
2575
        paramMap[ "fill" ] ->GetFloat( fill );
 
2576
 
 
2577
    BEGIN_UNIFORM_SECTION
 
2578
    GETSTRING( name );
 
2579
    GETFLOAT( channel );
 
2580
    IqTextureMap* pTMap = QGetRenderContextI() ->GetTextureMap( STRING( name ) );
 
2581
    TqFloat fdu = 0.0f, fdv = 0.0f;
 
2582
    if ( m_pAttributes )
 
2583
    {
 
2584
        du() ->GetFloat( fdu );
 
2585
        dv() ->GetFloat( fdv );
 
2586
    }
 
2587
    END_UNIFORM_SECTION
 
2588
 
 
2589
 
 
2590
    __fVarying = TqTrue;
 
2591
    if ( pTMap != 0 && pTMap->IsValid() )
 
2592
    {
 
2593
        std::valarray<TqFloat> val;
 
2594
        pTMap->PrepareSampleOptions( paramMap );
 
2595
 
 
2596
        BEGIN_VARYING_SECTION
 
2597
        TqFloat swidth = 0.0f, twidth = 0.0f;
 
2598
        if ( fdu != 0.0f && fdv != 0.0f )
 
2599
        {
 
2600
            TqFloat dsdu = SO_DuType<TqFloat>( s, __iGrid, this, Deffloat );
 
2601
            swidth = fabs( dsdu * fdu );
 
2602
            TqFloat dsdv = SO_DvType<TqFloat>( s, __iGrid, this, Deffloat );
 
2603
            swidth += fabs( dsdv * fdv );
 
2604
 
 
2605
            TqFloat dtdu = SO_DuType<TqFloat>( t, __iGrid, this, Deffloat );
 
2606
            twidth = fabs( dtdu * fdu );
 
2607
            TqFloat dtdv = SO_DvType<TqFloat>( t, __iGrid, this, Deffloat );
 
2608
            twidth += fabs( dtdv * fdv );
 
2609
        }
 
2610
        else
 
2611
        {
 
2612
            swidth = 1.0 / pTMap->XRes();
 
2613
            twidth = 1.0 / pTMap->YRes();
 
2614
        }
 
2615
 
 
2616
        // Sample the texture.
 
2617
        GETFLOAT( s );
 
2618
        GETFLOAT( t );
 
2619
        pTMap->SampleMap( FLOAT( s ), FLOAT( t ), swidth, twidth, val );
 
2620
 
 
2621
        // Grab the appropriate channel.
 
2622
        TqFloat fchan = FLOAT( channel );
 
2623
        if ( fchan + 2 >= val.size() )
 
2624
            SETCOLOR( Result, CqColor( fill, fill, fill ) );
 
2625
        else
 
2626
            SETCOLOR( Result, CqColor( val[ static_cast<unsigned int>( fchan ) ], val[ static_cast<unsigned int>( fchan ) + 1 ], val[ static_cast<unsigned int>( fchan ) + 2 ] ) );
 
2627
        END_VARYING_SECTION
 
2628
    }
 
2629
    else
 
2630
    {
 
2631
        BEGIN_VARYING_SECTION
 
2632
        SETCOLOR( Result, CqColor( 0, 0, 0 ) ); // Default, completely lit
 
2633
        END_VARYING_SECTION
 
2634
    }
 
2635
}
 
2636
 
 
2637
//----------------------------------------------------------------------
 
2638
// texture(S,F,F,F,F,F,F,F,F)
 
2639
STD_SOIMPL CqShaderExecEnv::SO_ctexture3( STRINGVAL name, FLOATVAL channel, FLOATVAL s1, FLOATVAL t1, FLOATVAL s2, FLOATVAL t2, FLOATVAL s3, FLOATVAL t3, FLOATVAL s4, FLOATVAL t4, DEFPARAMVARIMPL )
 
2640
{
 
2641
    STATS_INC( SHD_so_ctexture3 );
 
2642
 
 
2643
    INIT_SO
 
2644
 
 
2645
    if ( NULL == QGetRenderContextI() )
 
2646
        return ;
 
2647
 
 
2648
    GET_TEXTURE_PARAMS;
 
2649
 
 
2650
    TqFloat fill = 0.0f;
 
2651
    if ( paramMap.find( "fill" ) != paramMap.end() )
 
2652
        paramMap[ "fill" ] ->GetFloat( fill );
 
2653
 
 
2654
    BEGIN_UNIFORM_SECTION
 
2655
    GETSTRING( name );
 
2656
    GETFLOAT( channel );
 
2657
    IqTextureMap* pTMap = QGetRenderContextI() ->GetTextureMap( STRING( name ) );
 
2658
    END_UNIFORM_SECTION
 
2659
 
 
2660
 
 
2661
    __fVarying = TqTrue;
 
2662
    if ( pTMap != 0 && pTMap->IsValid() )
 
2663
    {
 
2664
        std::valarray<TqFloat> val;
 
2665
        pTMap->PrepareSampleOptions( paramMap );
 
2666
 
 
2667
        BEGIN_VARYING_SECTION
 
2668
        // Sample the texture.
 
2669
        GETFLOAT( s1 );
 
2670
        GETFLOAT( t1 );
 
2671
        GETFLOAT( s2 );
 
2672
        GETFLOAT( t2 );
 
2673
        GETFLOAT( s3 );
 
2674
        GETFLOAT( t3 );
 
2675
        GETFLOAT( s4 );
 
2676
        GETFLOAT( t4 );
 
2677
        pTMap->SampleMap( FLOAT( s1 ), FLOAT( t1 ), FLOAT( s2 ), FLOAT( t2 ), FLOAT( s3 ), FLOAT( t3 ), FLOAT( s4 ), FLOAT( t4 ), val );
 
2678
 
 
2679
        // Grab the appropriate channel.
 
2680
        TqFloat fchan = FLOAT( channel );
 
2681
        if ( fchan + 2 >= val.size() )
 
2682
            SETCOLOR( Result, CqColor( fill, fill, fill ) );
 
2683
        else
 
2684
            SETCOLOR( Result, CqColor( val[ static_cast<unsigned int>( fchan ) ], val[ static_cast<unsigned int>( fchan ) + 1 ], val[ static_cast<unsigned int>( fchan ) + 2 ] ) );
 
2685
        END_VARYING_SECTION
 
2686
    }
 
2687
    else
 
2688
    {
 
2689
        BEGIN_VARYING_SECTION
 
2690
        SETCOLOR( Result, CqColor( 0, 0, 0 ) ); // Default, completely lit
 
2691
        END_VARYING_SECTION
 
2692
    }
 
2693
}
 
2694
 
 
2695
 
 
2696
//----------------------------------------------------------------------
 
2697
// environment(S,P)
 
2698
STD_SOIMPL CqShaderExecEnv::SO_fenvironment2( STRINGVAL name, FLOATVAL channel, VECTORVAL R, DEFPARAMVARIMPL )
 
2699
{
 
2700
    STATS_INC( SHD_so_fenvironment2 );
 
2701
 
 
2702
    CqVector3D Defvec( 0.0f, 0.0f, 0.0f );
 
2703
    INIT_SO
 
2704
 
 
2705
    if ( NULL == QGetRenderContextI() )
 
2706
        return ;
 
2707
 
 
2708
    GET_TEXTURE_PARAMS;
 
2709
 
 
2710
    TqFloat fill = 0.0f;
 
2711
    if ( paramMap.find( "fill" ) != paramMap.end() )
 
2712
        paramMap[ "fill" ] ->GetFloat( fill );
 
2713
 
 
2714
    BEGIN_UNIFORM_SECTION
 
2715
    GETSTRING( name );
 
2716
    GETFLOAT( channel );
 
2717
    IqTextureMap* pTMap = QGetRenderContextI() ->GetEnvironmentMap( STRING( name ) );
 
2718
 
 
2719
    // Try with LatLong map file
 
2720
    if ( pTMap == 0 )
 
2721
    {
 
2722
        pTMap = QGetRenderContextI() ->GetLatLongMap( STRING( name ) );
 
2723
    }
 
2724
    TqFloat fdu = 0.0f, fdv = 0.0f;
 
2725
    if ( m_pAttributes )
 
2726
    {
 
2727
        du() ->GetFloat( fdu );
 
2728
        dv() ->GetFloat( fdv );
 
2729
    }
 
2730
    END_UNIFORM_SECTION
 
2731
 
 
2732
    __fVarying = TqTrue;
 
2733
    if ( pTMap != 0 && pTMap->IsValid() )
 
2734
    {
 
2735
        pTMap->PrepareSampleOptions( paramMap );
 
2736
        std::valarray<TqFloat> val;
 
2737
 
 
2738
        BEGIN_VARYING_SECTION
 
2739
        CqVector3D swidth = 0.0f, twidth = 0.0f;
 
2740
        if ( fdu != 0.0f )
 
2741
        {
 
2742
            CqVector3D dRdu = SO_DuType<CqVector3D>( R, __iGrid, this, Defvec );
 
2743
            swidth = dRdu * fdu;
 
2744
        }
 
2745
        if ( fdv != 0.0f )
 
2746
        {
 
2747
            CqVector3D dRdv = SO_DvType<CqVector3D>( R, __iGrid, this, Defvec );
 
2748
            twidth = dRdv * fdv;
 
2749
        }
 
2750
        else
 
2751
        {
 
2752
            swidth = CqVector3D( 1.0 / pTMap->XRes() );
 
2753
            twidth = CqVector3D( 1.0 / pTMap->YRes() );
 
2754
        }
 
2755
 
 
2756
        // Sample the texture.
 
2757
        GETVECTOR( R );
 
2758
        pTMap->SampleMap( VECTOR( R ), swidth, twidth, val );
 
2759
 
 
2760
        // Grab the appropriate channel.
 
2761
        TqFloat fchan = FLOAT( channel );
 
2762
        if ( fchan >= val.size() )
 
2763
            SETFLOAT( Result, fill );
 
2764
        else
 
2765
            SETFLOAT( Result, val[ static_cast<unsigned int>( fchan ) ] );
 
2766
        END_VARYING_SECTION
 
2767
    }
 
2768
    else
 
2769
    {
 
2770
        BEGIN_VARYING_SECTION
 
2771
        SETFLOAT( Result, 0.0f );       // Default, completely lit
 
2772
        END_VARYING_SECTION
 
2773
    }
 
2774
}
 
2775
 
 
2776
//----------------------------------------------------------------------
 
2777
// environment(S,P,P,P,P)
 
2778
STD_SOIMPL CqShaderExecEnv::SO_fenvironment3( STRINGVAL name, FLOATVAL channel, VECTORVAL R1, VECTORVAL R2, VECTORVAL R3, VECTORVAL R4, DEFPARAMVARIMPL )
 
2779
{
 
2780
    STATS_INC( SHD_so_fenvironment3 );
 
2781
 
 
2782
    INIT_SO
 
2783
 
 
2784
    if ( NULL == QGetRenderContextI() )
 
2785
        return ;
 
2786
 
 
2787
    GET_TEXTURE_PARAMS;
 
2788
 
 
2789
    TqFloat fill = 0.0f;
 
2790
    if ( paramMap.find( "fill" ) != paramMap.end() )
 
2791
        paramMap[ "fill" ] ->GetFloat( fill );
 
2792
 
 
2793
    BEGIN_UNIFORM_SECTION
 
2794
    GETSTRING( name );
 
2795
    GETFLOAT( channel );
 
2796
    IqTextureMap* pTMap = QGetRenderContextI() ->GetEnvironmentMap( STRING( name ) );
 
2797
    // Try with LatLong map file
 
2798
    if ( pTMap == 0 )
 
2799
    {
 
2800
        pTMap = QGetRenderContextI() ->GetLatLongMap( STRING( name ) );
 
2801
    }
 
2802
    END_UNIFORM_SECTION
 
2803
 
 
2804
    __fVarying = TqTrue;
 
2805
    if ( pTMap != 0 && pTMap->IsValid() )
 
2806
    {
 
2807
        std::valarray<TqFloat> val;
 
2808
        pTMap->PrepareSampleOptions( paramMap );
 
2809
 
 
2810
        BEGIN_VARYING_SECTION
 
2811
        // Sample the texture.
 
2812
        GETVECTOR( R1 );
 
2813
        GETVECTOR( R2 );
 
2814
        GETVECTOR( R3 );
 
2815
        GETVECTOR( R4 );
 
2816
        pTMap->SampleMap( VECTOR( R1 ), VECTOR( R2 ), VECTOR( R3 ), VECTOR( R4 ), val );
 
2817
 
 
2818
        // Grab the appropriate channel.
 
2819
        TqFloat fchan = FLOAT( channel );
 
2820
        if ( fchan >= val.size() )
 
2821
            SETFLOAT( Result, fill );
 
2822
        else
 
2823
            SETFLOAT( Result, val[ static_cast<unsigned int>( fchan ) ] );
 
2824
        END_VARYING_SECTION
 
2825
    }
 
2826
    else
 
2827
    {
 
2828
        BEGIN_VARYING_SECTION
 
2829
        SETFLOAT( Result, 0.0f );       // Default, completely lit
 
2830
        END_VARYING_SECTION
 
2831
    }
 
2832
}
 
2833
 
 
2834
 
 
2835
//----------------------------------------------------------------------
 
2836
// environment(S,P)
 
2837
STD_SOIMPL CqShaderExecEnv::SO_cenvironment2( STRINGVAL name, FLOATVAL channel, VECTORVAL R, DEFPARAMVARIMPL )
 
2838
{
 
2839
    STATS_INC( SHD_so_cenvironment2 );
 
2840
 
 
2841
    CqVector3D Defvec( 0.0f, 0.0f, 0.0f );
 
2842
    INIT_SO
 
2843
 
 
2844
    if ( NULL == QGetRenderContextI() )
 
2845
        return ;
 
2846
 
 
2847
    GET_TEXTURE_PARAMS;
 
2848
 
 
2849
    TqFloat fill = 0.0f;
 
2850
    if ( paramMap.find( "fill" ) != paramMap.end() )
 
2851
        paramMap[ "fill" ] ->GetFloat( fill );
 
2852
 
 
2853
    BEGIN_UNIFORM_SECTION
 
2854
    GETSTRING( name );
 
2855
    GETFLOAT( channel );
 
2856
    IqTextureMap* pTMap = QGetRenderContextI() ->GetEnvironmentMap( STRING( name ) );
 
2857
    // Try with LatLong map file
 
2858
    if ( pTMap == 0 )
 
2859
    {
 
2860
        pTMap = QGetRenderContextI() ->GetLatLongMap( STRING( name ) );
 
2861
    }
 
2862
    TqFloat fdu = 0.0f, fdv = 0.0f;
 
2863
    if ( m_pAttributes )
 
2864
    {
 
2865
        du() ->GetFloat( fdu );
 
2866
        dv() ->GetFloat( fdv );
 
2867
    }
 
2868
    END_UNIFORM_SECTION
 
2869
 
 
2870
    __fVarying = TqTrue;
 
2871
    if ( pTMap != 0 && pTMap->IsValid() )
 
2872
    {
 
2873
        std::valarray<TqFloat> val;
 
2874
        pTMap->PrepareSampleOptions( paramMap );
 
2875
 
 
2876
        BEGIN_VARYING_SECTION
 
2877
        CqVector3D swidth = 0.0f, twidth = 0.0f;
 
2878
        if ( fdu != 0.0f )
 
2879
        {
 
2880
            CqVector3D dRdu = SO_DuType<CqVector3D>( R, __iGrid, this, Defvec );
 
2881
            swidth = dRdu * fdu;
 
2882
        }
 
2883
        if ( fdv != 0.0f )
 
2884
        {
 
2885
            CqVector3D dRdv = SO_DvType<CqVector3D>( R, __iGrid, this, Defvec );
 
2886
            twidth = dRdv * fdv;
 
2887
        }
 
2888
        else
 
2889
        {
 
2890
            swidth = CqVector3D( 1.0 / pTMap->XRes() );
 
2891
            twidth = CqVector3D( 1.0 / pTMap->YRes() );
 
2892
        }
 
2893
 
 
2894
        // Sample the texture.
 
2895
        GETVECTOR( R );
 
2896
        pTMap->SampleMap( VECTOR( R ), swidth, twidth, val );
 
2897
 
 
2898
 
 
2899
        // Grab the appropriate channel.
 
2900
        TqFloat fchan = FLOAT( channel );
 
2901
        if ( fchan + 2 >= val.size() )
 
2902
            SETCOLOR( Result, CqColor( fill, fill, fill ) );
 
2903
        else
 
2904
            SETCOLOR( Result, CqColor( val[ static_cast<unsigned int>( fchan ) ], val[ static_cast<unsigned int>( fchan ) + 1 ], val[ static_cast<unsigned int>( fchan ) + 2 ] ) );
 
2905
        END_VARYING_SECTION
 
2906
    }
 
2907
    else
 
2908
    {
 
2909
        BEGIN_VARYING_SECTION
 
2910
        SETCOLOR( Result, CqColor( 0.0f, 0.0f, 0.0f ) );        // Default, completely lit
 
2911
        END_VARYING_SECTION
 
2912
    }
 
2913
}
 
2914
 
 
2915
//----------------------------------------------------------------------
 
2916
// environment(S,P,P,P,P)
 
2917
STD_SOIMPL CqShaderExecEnv::SO_cenvironment3( STRINGVAL name, FLOATVAL channel, VECTORVAL R1, VECTORVAL R2, VECTORVAL R3, VECTORVAL R4, DEFPARAMVARIMPL )
 
2918
{
 
2919
    STATS_INC( SHD_so_cenvironment3 );
 
2920
 
 
2921
    INIT_SO
 
2922
 
 
2923
    if ( NULL == QGetRenderContextI() )
 
2924
        return ;
 
2925
 
 
2926
    GET_TEXTURE_PARAMS;
 
2927
 
 
2928
    TqFloat fill = 0.0f;
 
2929
    if ( paramMap.find( "fill" ) != paramMap.end() )
 
2930
        paramMap[ "fill" ] ->GetFloat( fill );
 
2931
 
 
2932
    BEGIN_UNIFORM_SECTION
 
2933
    GETSTRING( name );
 
2934
    GETFLOAT( channel );
 
2935
    IqTextureMap* pTMap = QGetRenderContextI() ->GetEnvironmentMap( STRING( name ) );
 
2936
    // Try with LatLong map file
 
2937
    if ( pTMap == 0 )
 
2938
    {
 
2939
        pTMap = QGetRenderContextI() ->GetLatLongMap( STRING( name ) );
 
2940
    }
 
2941
    BEGIN_UNIFORM_SECTION
 
2942
 
 
2943
    __fVarying = TqTrue;
 
2944
    if ( pTMap != 0 && pTMap->IsValid() )
 
2945
    {
 
2946
        std::valarray<TqFloat> val;
 
2947
        pTMap->PrepareSampleOptions( paramMap );
 
2948
 
 
2949
        BEGIN_VARYING_SECTION
 
2950
        // Sample the texture.
 
2951
        GETVECTOR( R1 );
 
2952
        GETVECTOR( R2 );
 
2953
        GETVECTOR( R3 );
 
2954
        GETVECTOR( R4 );
 
2955
        pTMap->SampleMap( VECTOR( R1 ), VECTOR( R2 ), VECTOR( R3 ), VECTOR( R4 ), val );
 
2956
 
 
2957
        // Grab the appropriate channel.
 
2958
        TqFloat fchan = FLOAT( channel );
 
2959
        if ( fchan + 2 >= val.size() )
 
2960
            SETCOLOR( Result, CqColor( fill, fill, fill ) );
 
2961
        else
 
2962
            SETCOLOR( Result, CqColor( val[ static_cast<unsigned int>( fchan ) ], val[ static_cast<unsigned int>( fchan ) + 1 ], val[ static_cast<unsigned int>( fchan ) + 2 ] ) );
 
2963
        END_VARYING_SECTION
 
2964
    }
 
2965
    else
 
2966
    {
 
2967
        BEGIN_VARYING_SECTION
 
2968
        SETCOLOR( Result, CqColor( 0.0f, 0.0f, 0.0f ) );        // Default, completely lit
 
2969
        END_VARYING_SECTION
 
2970
    }
 
2971
}
 
2972
 
 
2973
//----------------------------------------------------------------------
 
2974
// bump(S)
 
2975
STD_SOIMPL CqShaderExecEnv::SO_bump1( STRINGVAL name, FLOATVAL channel, DEFPARAMVARIMPL )
 
2976
{
 
2977
    INIT_SO
 
2978
 
 
2979
    __fVarying = TqTrue;
 
2980
 
 
2981
    BEGIN_VARYING_SECTION
 
2982
    SETPOINT( Result, CqVector3D( 0, 0, 0 ) );
 
2983
    END_VARYING_SECTION
 
2984
}
 
2985
 
 
2986
//----------------------------------------------------------------------
 
2987
// bump(S,F,F)
 
2988
STD_SOIMPL CqShaderExecEnv::SO_bump2( STRINGVAL name, FLOATVAL channel, FLOATVAL s, FLOATVAL t, DEFPARAMVARIMPL )
 
2989
{
 
2990
    INIT_SO
 
2991
 
 
2992
    __fVarying = TqTrue;
 
2993
 
 
2994
    BEGIN_VARYING_SECTION
 
2995
    SETPOINT( Result, CqVector3D( 0, 0, 0 ) );
 
2996
    END_VARYING_SECTION
 
2997
}
 
2998
 
 
2999
//----------------------------------------------------------------------
 
3000
// bump(S,F,F,F,F,F,F,F,F)
 
3001
STD_SOIMPL CqShaderExecEnv::SO_bump3( STRINGVAL name, FLOATVAL channel, FLOATVAL s1, FLOATVAL t1, FLOATVAL s2, FLOATVAL t2, FLOATVAL s3, FLOATVAL t3, FLOATVAL s4, FLOATVAL t4, DEFPARAMVARIMPL )
 
3002
{
 
3003
    INIT_SO
 
3004
 
 
3005
    __fVarying = TqTrue;
 
3006
 
 
3007
    BEGIN_VARYING_SECTION
 
3008
    SETPOINT( Result, CqVector3D( 0, 0, 0 ) );
 
3009
    END_VARYING_SECTION
 
3010
}
 
3011
 
 
3012
//----------------------------------------------------------------------
 
3013
// shadow(S,P)
 
3014
STD_SOIMPL CqShaderExecEnv::SO_shadow( STRINGVAL name, FLOATVAL channel, POINTVAL P, DEFPARAMVARIMPL )
 
3015
{
 
3016
    STATS_INC( SHD_so_shadow );
 
3017
 
 
3018
    INIT_SO
 
3019
 
 
3020
    if ( NULL == QGetRenderContextI() )
 
3021
        return ;
 
3022
 
 
3023
    GET_TEXTURE_PARAMS;
 
3024
 
 
3025
    BEGIN_UNIFORM_SECTION
 
3026
    GETSTRING( name );
 
3027
    GETFLOAT( channel );
 
3028
    IqTextureMap* pMap = QGetRenderContextI() ->GetShadowMap( STRING( name ) );
 
3029
    END_UNIFORM_SECTION
 
3030
 
 
3031
    __fVarying = TqTrue;
 
3032
    if ( pMap != 0 && pMap->IsValid() )
 
3033
    {
 
3034
        std::valarray<TqFloat> fv;
 
3035
        pMap->PrepareSampleOptions( paramMap );
 
3036
 
 
3037
        BEGIN_VARYING_SECTION
 
3038
        CqVector3D swidth = 0.0f, twidth = 0.0f, nullv = 0.0f;
 
3039
 
 
3040
        swidth = SO_DerivType<CqVector3D>( P, NULL, __iGrid, this );
 
3041
        twidth = SO_DerivType<CqVector3D>( P, NULL, __iGrid, this );
 
3042
 
 
3043
        GETPOINT( P );
 
3044
 
 
3045
        pMap->SampleMap( POINT( P ), swidth, twidth, fv, 0 );
 
3046
        pMap->PrepareSampleOptions( paramMap );
 
3047
        SETFLOAT( Result, fv[ 0 ] );
 
3048
        END_VARYING_SECTION
 
3049
    }
 
3050
    else
 
3051
    {
 
3052
        BEGIN_VARYING_SECTION
 
3053
        SETFLOAT( Result, 0.0f );       // Default, completely lit
 
3054
        END_VARYING_SECTION
 
3055
    }
 
3056
}
 
3057
 
 
3058
//----------------------------------------------------------------------
 
3059
// shadow(S,P,P,P,P)
 
3060
 
 
3061
STD_SOIMPL CqShaderExecEnv::SO_shadow1( STRINGVAL name, FLOATVAL channel, POINTVAL P1, POINTVAL P2, POINTVAL P3, POINTVAL P4, DEFPARAMVARIMPL )
 
3062
{
 
3063
    STATS_INC( SHD_so_shadow1 );
 
3064
 
 
3065
    INIT_SO
 
3066
 
 
3067
    if ( NULL == QGetRenderContextI() )
 
3068
        return ;
 
3069
 
 
3070
    GET_TEXTURE_PARAMS;
 
3071
 
 
3072
    BEGIN_UNIFORM_SECTION
 
3073
    GETSTRING( name );
 
3074
    GETFLOAT( channel );
 
3075
    IqTextureMap* pMap = QGetRenderContextI() ->GetShadowMap( STRING( name ) );
 
3076
    END_UNIFORM_SECTION
 
3077
 
 
3078
    __fVarying = TqTrue;
 
3079
    if ( pMap != 0 && pMap->IsValid() )
 
3080
    {
 
3081
        std::valarray<TqFloat> fv;
 
3082
        pMap->PrepareSampleOptions( paramMap );
 
3083
 
 
3084
        BEGIN_VARYING_SECTION
 
3085
        GETPOINT( P1 );
 
3086
        GETPOINT( P2 );
 
3087
        GETPOINT( P3 );
 
3088
        GETPOINT( P4 );
 
3089
        pMap->SampleMap( POINT( P1 ), POINT( P2 ), POINT( P3 ), POINT( P4 ), fv, 0 );
 
3090
        SETFLOAT( Result, fv[ 0 ] );
 
3091
        END_VARYING_SECTION
 
3092
    }
 
3093
    else
 
3094
    {
 
3095
        BEGIN_VARYING_SECTION
 
3096
        SETFLOAT( Result, 0.0f );       // Default, completely lit
 
3097
        END_VARYING_SECTION
 
3098
    }
 
3099
}
 
3100
 
 
3101
 
 
3102
//----------------------------------------------------------------------
 
3103
// ambient()
 
3104
 
 
3105
STD_SOIMPL CqShaderExecEnv::SO_ambient( DEFPARAMIMPL )
 
3106
{
 
3107
    STATS_INC( SHD_so_ambient );
 
3108
 
 
3109
    INIT_SO
 
3110
 
 
3111
    // Use the lightsource stack on the current surface
 
3112
    if ( m_pAttributes != 0 )
 
3113
    {
 
3114
        // If this is the first call to illuminance this time round, call all lights and setup the Cl and L caches.
 
3115
        if ( !m_IlluminanceCacheValid )
 
3116
        {
 
3117
            ValidateIlluminanceCache( NULL, NULL, pShader );
 
3118
        }
 
3119
 
 
3120
        Result->SetColor( gColBlack );
 
3121
 
 
3122
        for ( TqUint light_index = 0; light_index < m_pAttributes ->cLights(); light_index++ )
 
3123
        {
 
3124
            __fVarying = TqTrue;
 
3125
 
 
3126
            IqLightsource* lp = m_pAttributes ->pLight( light_index );
 
3127
            if ( lp->pShader() ->fAmbient() )
 
3128
            {
 
3129
                BEGIN_VARYING_SECTION
 
3130
                // Now Combine the color of all ambient lightsources.
 
3131
                GETCOLOR( Result );
 
3132
                CqColor colCl;
 
3133
                if ( NULL != lp->Cl() )
 
3134
                    lp->Cl() ->GetColor( colCl, __iGrid );
 
3135
                SETCOLOR( Result, COLOR( Result ) + colCl );
 
3136
 
 
3137
                END_VARYING_SECTION
 
3138
            }
 
3139
        }
 
3140
    }
 
3141
}
 
3142
 
 
3143
 
 
3144
//----------------------------------------------------------------------
 
3145
// diffuse(N)
 
3146
STD_SOIMPL CqShaderExecEnv::SO_diffuse( NORMALVAL N, DEFPARAMIMPL )
 
3147
{
 
3148
    STATS_INC( SHD_so_diffuse );
 
3149
 
 
3150
    INIT_SO
 
3151
 
 
3152
    // If the illuminance cache is already OK, then we don't need to bother filling in the illuminance parameters.
 
3153
    if ( !m_IlluminanceCacheValid )
 
3154
    {
 
3155
        ValidateIlluminanceCache( NULL, N, pShader );
 
3156
    }
 
3157
 
 
3158
    IqShaderData* pDefAngle = pShader->CreateTemporaryStorage( type_float, class_uniform );
 
3159
    if ( NULL == pDefAngle ) return ;
 
3160
 
 
3161
    pDefAngle->SetFloat( PIO2 );
 
3162
 
 
3163
    Result->SetColor( gColBlack );
 
3164
 
 
3165
    __fVarying = TqTrue;
 
3166
        IqShaderData* __nondiffuse = NULL;
 
3167
        __nondiffuse = pShader->CreateTemporaryStorage( type_float, class_varying );
 
3168
 
 
3169
    // SO_init_illuminance returns TRUE if there are any non ambient ligthsources available.
 
3170
    if ( SO_init_illuminance() )
 
3171
    {
 
3172
        IqShader * pLightsource = 0;
 
3173
        do
 
3174
        {
 
3175
            // Get the "__nondiffuse" setting from the current lightsource, if specified.
 
3176
            TqFloat     __nondiffuse_val;
 
3177
            if ( m_li < m_pAttributes ->cLights() )
 
3178
                pLightsource = m_pAttributes ->pLight( m_li ) ->pShader();
 
3179
            if ( pLightsource )
 
3180
            {
 
3181
                pLightsource->GetValue( "__nondiffuse", __nondiffuse );
 
3182
                /// \note: This is OK here, outside the BEGIN_VARYING_SECTION as, varying in terms of lightsources
 
3183
                /// is not valid.
 
3184
                if( NULL != __nondiffuse )
 
3185
                {
 
3186
                    __nondiffuse->GetFloat( __nondiffuse_val, 0 );
 
3187
                    if( __nondiffuse_val != 0.0f )
 
3188
                        continue;
 
3189
                }
 
3190
            }
 
3191
 
 
3192
            // SO_illuminance sets the current state to whether the lightsource illuminates the points or not.
 
3193
            SO_illuminance( NULL, NULL, N, pDefAngle, NULL );
 
3194
 
 
3195
            PushState();
 
3196
            GetCurrentState();
 
3197
 
 
3198
            BEGIN_VARYING_SECTION
 
3199
 
 
3200
            // Get the light vector and color from the lightsource.
 
3201
            CqVector3D Ln;
 
3202
            L() ->GetVector( Ln, __iGrid );
 
3203
            Ln.Unit();
 
3204
 
 
3205
            // Combine the light color into the result
 
3206
            GETCOLOR( Result );
 
3207
            GETNORMAL( N );
 
3208
            CqColor colCl;
 
3209
            Cl() ->GetColor( colCl, __iGrid );
 
3210
            SETCOLOR( Result, COLOR( Result ) + colCl * ( Ln * NORMAL( N ) ) );
 
3211
 
 
3212
            END_VARYING_SECTION
 
3213
            PopState();
 
3214
            // SO_advance_illuminance returns TRUE if there are any more non ambient lightsources.
 
3215
        }
 
3216
        while ( SO_advance_illuminance() );
 
3217
    }
 
3218
        pShader->DeleteTemporaryStorage( __nondiffuse );
 
3219
    pShader->DeleteTemporaryStorage( pDefAngle );
 
3220
}
 
3221
 
 
3222
 
 
3223
//----------------------------------------------------------------------
 
3224
// specular(N,V,roughness)
 
3225
STD_SOIMPL CqShaderExecEnv::SO_specular( NORMALVAL N, VECTORVAL V, FLOATVAL roughness, DEFPARAMIMPL )
 
3226
{
 
3227
    STATS_INC( SHD_so_specular );
 
3228
 
 
3229
    INIT_SO
 
3230
 
 
3231
    // If the illuminance cache is already OK, then we don't need to bother filling in the illuminance parameters.
 
3232
    if ( !m_IlluminanceCacheValid )
 
3233
    {
 
3234
        ValidateIlluminanceCache( NULL, N, pShader );
 
3235
    }
 
3236
 
 
3237
    IqShaderData* pDefAngle = pShader->CreateTemporaryStorage( type_float, class_uniform );
 
3238
    if ( NULL == pDefAngle ) return ;
 
3239
 
 
3240
    pDefAngle->SetFloat( PIO2 );
 
3241
 
 
3242
    Result->SetColor( gColBlack );
 
3243
    __fVarying = TqTrue;
 
3244
 
 
3245
        IqShaderData* __nonspecular = NULL;
 
3246
        __nonspecular = pShader->CreateTemporaryStorage( type_float, class_varying );
 
3247
 
 
3248
    // SO_init_illuminance returns TRUE if there are any non ambient ligthsources available.
 
3249
    if ( SO_init_illuminance() )
 
3250
    {
 
3251
        IqShader * pLightsource = 0;
 
3252
        do
 
3253
        {
 
3254
            // Get the "__nonspecular" setting from the current lightsource, if specified.
 
3255
            TqFloat     __nonspecular_val;
 
3256
            if ( m_li < m_pAttributes ->cLights() )
 
3257
                pLightsource = m_pAttributes ->pLight( m_li ) ->pShader();
 
3258
            if ( pLightsource )
 
3259
            {
 
3260
                pLightsource->GetValue( "__nonspecular", __nonspecular );
 
3261
                /// \note: This is OK here, outside the BEGIN_VARYING_SECTION as, varying in terms of lightsources
 
3262
                /// is not valid.
 
3263
                if( NULL != __nonspecular )
 
3264
                {
 
3265
                    __nonspecular->GetFloat( __nonspecular_val, 0 );
 
3266
                    if( __nonspecular_val != 0.0f )
 
3267
                        continue;
 
3268
                }
 
3269
            }
 
3270
 
 
3271
            // SO_illuminance sets the current state to whether the lightsource illuminates the points or not.
 
3272
            SO_illuminance( NULL, NULL, N, pDefAngle, NULL );
 
3273
 
 
3274
            PushState();
 
3275
            GetCurrentState();
 
3276
            BEGIN_VARYING_SECTION
 
3277
 
 
3278
            GETVECTOR( V );
 
3279
            // Get the ligth vector and color from the lightsource
 
3280
            CqVector3D Ln;
 
3281
            L() ->GetVector( Ln, __iGrid );
 
3282
            Ln.Unit();
 
3283
            CqVector3D  H = Ln + VECTOR( V );
 
3284
            H.Unit();
 
3285
 
 
3286
            // Combine the color into the result.
 
3287
            /// \note The (roughness/8) term emulates the BMRT behaviour for prmanspecular.
 
3288
            GETCOLOR( Result );
 
3289
            GETNORMAL( N );
 
3290
            GETFLOAT( roughness );
 
3291
            CqColor colCl;
 
3292
            Cl() ->GetColor( colCl, __iGrid );
 
3293
            SETCOLOR( Result, COLOR( Result ) + colCl * pow( MAX( 0.0f, NORMAL( N ) * H ), 1.0f / ( FLOAT( roughness ) / 8.0f ) ) );
 
3294
 
 
3295
            END_VARYING_SECTION
 
3296
            PopState();
 
3297
            // SO_advance_illuminance returns TRUE if there are any more non ambient lightsources.
 
3298
        }
 
3299
        while ( SO_advance_illuminance() );
 
3300
    }
 
3301
        pShader->DeleteTemporaryStorage( __nonspecular );
 
3302
    pShader->DeleteTemporaryStorage( pDefAngle );
 
3303
}
 
3304
 
 
3305
 
 
3306
//----------------------------------------------------------------------
 
3307
// phong(N,V,size)
 
3308
STD_SOIMPL CqShaderExecEnv::SO_phong( NORMALVAL N, VECTORVAL V, FLOATVAL size, DEFPARAMIMPL )
 
3309
{
 
3310
    STATS_INC( SHD_so_phong );
 
3311
 
 
3312
    INIT_SO
 
3313
 
 
3314
    IqShaderData * pnV = pShader ->CreateTemporaryStorage( type_vector, class_varying );
 
3315
    IqShaderData* pnN = pShader ->CreateTemporaryStorage( type_normal, class_varying );
 
3316
    IqShaderData* pR = pShader ->CreateTemporaryStorage( type_vector, class_varying );
 
3317
 
 
3318
    /// note: Not happy about this, the shader should take care of this at construction time,
 
3319
    /// but at the moment, it can't guarantee the validity of the m_u/vGridRes data members.
 
3320
    pnV->Initialise( uGridRes(), vGridRes() );
 
3321
    pnN->Initialise( uGridRes(), vGridRes() );
 
3322
    pR->Initialise( uGridRes(), vGridRes() );
 
3323
 
 
3324
    SO_normalize( V, pnV );
 
3325
    SO_normalize( N, pnN );
 
3326
 
 
3327
    __fVarying = TqTrue;
 
3328
    BEGIN_VARYING_SECTION
 
3329
    CqVector3D vecnV;
 
3330
    pnV->GetVector( vecnV, __iGrid );
 
3331
    pnV->SetVector( -vecnV, __iGrid );
 
3332
    END_VARYING_SECTION
 
3333
 
 
3334
    SO_reflect( pnV, pnN, pR );
 
3335
 
 
3336
    pShader->DeleteTemporaryStorage( pnV );
 
3337
    pShader->DeleteTemporaryStorage( pnN );
 
3338
 
 
3339
    // If the illuminance cache is already OK, then we don't need to bother filling in the illuminance parameters.
 
3340
    if ( !m_IlluminanceCacheValid )
 
3341
    {
 
3342
        ValidateIlluminanceCache( NULL, N, pShader );
 
3343
    }
 
3344
 
 
3345
    IqShaderData* pDefAngle = pShader->CreateTemporaryStorage( type_float, class_uniform );
 
3346
    if ( NULL == pDefAngle ) return ;
 
3347
 
 
3348
    pDefAngle->SetFloat( PIO2 );
 
3349
 
 
3350
    // Initialise the return value
 
3351
    Result->SetColor( gColBlack );
 
3352
 
 
3353
    // SO_init_illuminance returns TRUE if there are any non ambient ligthsources available.
 
3354
    if ( SO_init_illuminance() )
 
3355
    {
 
3356
        do
 
3357
        {
 
3358
            // SO_illuminance sets the current state to whether the lightsource illuminates the points or not.
 
3359
            SO_illuminance( NULL, NULL, N, pDefAngle, NULL );
 
3360
 
 
3361
            PushState();
 
3362
            GetCurrentState();
 
3363
 
 
3364
            BEGIN_VARYING_SECTION
 
3365
 
 
3366
            // Get the light vector and color from the loght source.
 
3367
            CqVector3D Ln;
 
3368
            L() ->GetVector( Ln, __iGrid );
 
3369
            Ln.Unit();
 
3370
 
 
3371
            // Now combine the color into the result.
 
3372
            GETCOLOR( Result );
 
3373
            CqVector3D vecR;
 
3374
            pR->GetVector( vecR, __iGrid );
 
3375
            GETFLOAT( size );
 
3376
            CqColor colCl;
 
3377
            Cl() ->GetColor( colCl, __iGrid );
 
3378
            SETCOLOR( Result, COLOR( Result ) + colCl * pow( MAX( 0.0f, vecR * Ln ), FLOAT( size ) ) );
 
3379
 
 
3380
            END_VARYING_SECTION
 
3381
 
 
3382
            PopState();
 
3383
            // SO_advance_illuminance returns TRUE if there are any more non ambient lightsources.
 
3384
        }
 
3385
        while ( SO_advance_illuminance() );
 
3386
    }
 
3387
    pShader->DeleteTemporaryStorage( pDefAngle );
 
3388
    pShader->DeleteTemporaryStorage( pR );
 
3389
}
 
3390
 
 
3391
 
 
3392
//----------------------------------------------------------------------
 
3393
// trace(P,R)
 
3394
STD_SOIMPL CqShaderExecEnv::SO_trace( POINTVAL P, VECTORVAL R, DEFPARAMIMPL )
 
3395
{
 
3396
    STATS_INC( SHD_so_trace );
 
3397
 
 
3398
    INIT_SO
 
3399
 
 
3400
    CHECKVARY( P )
 
3401
    CHECKVARY( R )
 
3402
    CHECKVARY( Result )
 
3403
 
 
3404
    BEGIN_VARYING_SECTION
 
3405
    SETCOLOR( Result, CqColor( 0, 0, 0 ) );
 
3406
    END_VARYING_SECTION
 
3407
}
 
3408
 
 
3409
 
 
3410
//----------------------------------------------------------------------
 
3411
// illuminance(P,nsamples)
 
3412
STD_SOIMPL CqShaderExecEnv::SO_illuminance( STRINGVAL Category, POINTVAL P, VECTORVAL Axis, FLOATVAL Angle, DEFVOIDPARAMIMPL )
 
3413
{
 
3414
    STATS_INC( SHD_so_illuminance );
 
3415
 
 
3416
    INIT_SO
 
3417
 
 
3418
    BEGIN_UNIFORM_SECTION
 
3419
    CqString cat( "" );
 
3420
    if ( NULL != Category ) Category->GetString( cat );
 
3421
    END_UNIFORM_SECTION
 
3422
 
 
3423
    __fVarying = TqTrue;
 
3424
 
 
3425
    // Fill in the lightsource information, and transfer the results to the shader variables,
 
3426
    if ( m_pAttributes != 0 )
 
3427
    {
 
3428
        IqLightsource * lp = m_pAttributes ->pLight( m_li );
 
3429
 
 
3430
        if ( NULL != Axis ) CHECKVARY( Axis )
 
3431
            if ( NULL != Angle ) CHECKVARY( Angle )
 
3432
 
 
3433
                TqBool exec = TqTrue;
 
3434
 
 
3435
        if( cat.size() )
 
3436
        {
 
3437
 
 
3438
            TqBool exclude = TqFalse;
 
3439
            CqString lightcategories;
 
3440
            CqString catname;
 
3441
 
 
3442
 
 
3443
            if( cat.find( "-" ) == 0 )
 
3444
            {
 
3445
                exclude = true;
 
3446
                catname = cat.substr( 1, cat.size() );
 
3447
            }
 
3448
            else
 
3449
            {
 
3450
                catname = cat;
 
3451
            }
 
3452
 
 
3453
            IqShaderData* pcats = lp->pShader()->FindArgument("__category");
 
3454
            if( pcats )
 
3455
            {
 
3456
                pcats->GetString( lightcategories );
 
3457
 
 
3458
                exec = TqFalse;
 
3459
                // While no matching category has been found...
 
3460
                TqInt tokenpos = 0, tokenend;
 
3461
                while( 1 )
 
3462
                {
 
3463
                    tokenend = lightcategories.find(',', tokenpos);
 
3464
                    CqString token = lightcategories.substr( tokenpos, tokenend );
 
3465
                    if( catname.compare( token ) == 0 )
 
3466
                    {
 
3467
                        if( !exclude )
 
3468
                        {
 
3469
                            exec = TqTrue;
 
3470
                            break;
 
3471
                        }
 
3472
                    }
 
3473
                    if( tokenend == std::string::npos )
 
3474
                        break;
 
3475
                    else
 
3476
                        tokenpos = tokenend+1;
 
3477
                }
 
3478
            }
 
3479
        }
 
3480
 
 
3481
        if( exec )
 
3482
        {
 
3483
            BEGIN_VARYING_SECTION
 
3484
 
 
3485
            CqVector3D Ln;
 
3486
            lp->L() ->GetVector( Ln, __iGrid );
 
3487
            Ln = -Ln;
 
3488
 
 
3489
            // Store them locally on the surface.
 
3490
            L() ->SetVector( Ln, __iGrid );
 
3491
            CqColor colCl;
 
3492
            lp->Cl() ->GetColor( colCl, __iGrid );
 
3493
            Cl() ->SetColor( colCl, __iGrid );
 
3494
 
 
3495
            // Check if its within the cone.
 
3496
            Ln.Unit();
 
3497
            CqVector3D vecAxis( 0, 1, 0 );
 
3498
            if ( NULL != Axis ) Axis->GetVector( vecAxis, __iGrid );
 
3499
            TqFloat fAngle = PI;
 
3500
            if ( NULL != Angle ) Angle->GetFloat( fAngle, __iGrid );
 
3501
 
 
3502
            TqFloat cosangle = Ln * vecAxis;
 
3503
            cosangle = CLAMP( cosangle, -1, 1 );
 
3504
            if ( acos( cosangle ) > fAngle )
 
3505
                m_CurrentState.SetValue( __iGrid, TqFalse );
 
3506
            else
 
3507
                m_CurrentState.SetValue( __iGrid, TqTrue );
 
3508
            END_VARYING_SECTION
 
3509
        }
 
3510
    }
 
3511
}
 
3512
 
 
3513
 
 
3514
STD_SOIMPL      CqShaderExecEnv::SO_illuminance( STRINGVAL Category, POINTVAL P, DEFVOIDPARAMIMPL )
 
3515
{
 
3516
    STATS_INC( SHD_so_illuminance );
 
3517
 
 
3518
    SO_illuminance( Category, P, NULL, NULL );
 
3519
}
 
3520
 
 
3521
 
 
3522
//----------------------------------------------------------------------
 
3523
// illuminate(P)
 
3524
STD_SOIMPL CqShaderExecEnv::SO_illuminate( POINTVAL P, VECTORVAL Axis, FLOATVAL Angle, DEFVOIDPARAMIMPL )
 
3525
{
 
3526
    STATS_INC( SHD_so_illuminate );
 
3527
 
 
3528
    INIT_SO
 
3529
 
 
3530
    TqBool res = TqTrue;
 
3531
    if ( m_Illuminate > 0 ) res = TqFalse;
 
3532
 
 
3533
    __fVarying = TqTrue;
 
3534
    if ( res )
 
3535
    {
 
3536
        BEGIN_VARYING_SECTION
 
3537
        // Get the point being lit and set the ligth vector.
 
3538
        GETPOINT( P );
 
3539
        CqVector3D vecPs;
 
3540
        Ps() ->GetPoint( vecPs, __iGrid );
 
3541
        L() ->SetVector( vecPs - POINT( P ), __iGrid );
 
3542
 
 
3543
        // Check if its within the cone.
 
3544
        CqVector3D Ln;
 
3545
        L() ->GetVector( Ln, __iGrid );
 
3546
        Ln.Unit();
 
3547
 
 
3548
        CqVector3D vecAxis( 0.0f, 1.0f, 0.0f );
 
3549
        if ( NULL != Axis ) Axis->GetVector( vecAxis, __iGrid );
 
3550
        TqFloat fAngle = PI;
 
3551
        if ( NULL != Angle ) Angle->GetFloat( fAngle, __iGrid );
 
3552
        TqFloat cosangle = Ln * vecAxis;
 
3553
        cosangle = CLAMP( cosangle, -1, 1 );
 
3554
                if ( acos( cosangle ) > fAngle )
 
3555
        {
 
3556
            // Make sure we set the light color to zero in the areas that won't be lit.
 
3557
            Cl() ->SetColor( CqColor( 0, 0, 0 ), __iGrid );
 
3558
            m_CurrentState.SetValue( __iGrid, TqFalse );
 
3559
        }
 
3560
        else
 
3561
            m_CurrentState.SetValue( __iGrid, TqTrue );
 
3562
        END_VARYING_SECTION
 
3563
    }
 
3564
 
 
3565
    m_Illuminate++;
 
3566
}
 
3567
 
 
3568
 
 
3569
STD_SOIMPL      CqShaderExecEnv::SO_illuminate( POINTVAL P, DEFVOIDPARAMIMPL )
 
3570
{
 
3571
    STATS_INC( SHD_so_illuminate );
 
3572
 
 
3573
    SO_illuminate( P, NULL, NULL, pShader );
 
3574
}
 
3575
 
 
3576
 
 
3577
//----------------------------------------------------------------------
 
3578
// solar()
 
3579
STD_SOIMPL CqShaderExecEnv::SO_solar( VECTORVAL Axis, FLOATVAL Angle, DEFVOIDPARAMIMPL )
 
3580
{
 
3581
    // TODO: Check light cone, and exclude points outside.
 
3582
    STATS_INC( SHD_so_solar );
 
3583
 
 
3584
    INIT_SO
 
3585
 
 
3586
    TqBool res = TqTrue;
 
3587
    if ( m_Illuminate > 0 ) res = TqFalse;
 
3588
 
 
3589
    __fVarying = TqTrue;
 
3590
    BEGIN_VARYING_SECTION
 
3591
    if ( res )
 
3592
    {
 
3593
        CqVector3D vecAxis( 0.0f, 1.0f, 0.0f );
 
3594
        if ( NULL != Axis ) Axis->GetVector( vecAxis, __iGrid );
 
3595
        L() ->SetVector( vecAxis, __iGrid );
 
3596
        m_CurrentState.SetValue( __iGrid, TqTrue );
 
3597
    }
 
3598
    END_VARYING_SECTION
 
3599
 
 
3600
    m_Illuminate++;
 
3601
}
 
3602
 
 
3603
 
 
3604
STD_SOIMPL      CqShaderExecEnv::SO_solar( DEFVOIDPARAMIMPL )
 
3605
{
 
3606
    STATS_INC( SHD_so_solar );
 
3607
 
 
3608
    SO_solar( NULL, NULL, pShader );
 
3609
}
 
3610
 
 
3611
 
 
3612
//----------------------------------------------------------------------
 
3613
// printf(s,...)
 
3614
 
 
3615
STD_SOIMPL      CqShaderExecEnv::SO_printf( STRINGVAL str, DEFVOIDPARAMVARIMPL )
 
3616
{
 
3617
    STATS_INC( SHD_so_printf );
 
3618
 
 
3619
    INIT_SO
 
3620
 
 
3621
    if ( NULL == QGetRenderContextI() )
 
3622
        return ;
 
3623
 
 
3624
    CHECKVARY( str )
 
3625
    TqInt ii;
 
3626
    for ( ii = 0; ii < cParams; ii++ )
 
3627
    {
 
3628
        CHECKVARY( apParams[ ii ] );
 
3629
    }
 
3630
 
 
3631
    BEGIN_VARYING_SECTION
 
3632
    GETSTRING( str );
 
3633
    CqString strA = SO_sprintf( STRING( str ).c_str(), cParams, apParams, __iGrid );
 
3634
    QGetRenderContextI() ->PrintString( strA.c_str() );
 
3635
    END_VARYING_SECTION
 
3636
}
 
3637
 
 
3638
 
 
3639
//----------------------------------------------------------------------
 
3640
// format(s,...)
 
3641
 
 
3642
STD_SOIMPL      CqShaderExecEnv::SO_format( STRINGVAL str, DEFPARAMVARIMPL )
 
3643
{
 
3644
    STATS_INC( SHD_so_format );
 
3645
 
 
3646
    INIT_SO
 
3647
 
 
3648
    CHECKVARY( str )
 
3649
    int ii;
 
3650
    for ( ii = 0; ii < cParams; ii++ )
 
3651
    {
 
3652
        CHECKVARY( apParams[ ii ] );
 
3653
    }
 
3654
    CHECKVARY( Result );
 
3655
 
 
3656
    BEGIN_VARYING_SECTION
 
3657
    GETSTRING( str );
 
3658
    CqString strA = SO_sprintf( STRING( str ).c_str(), cParams, apParams, __iGrid );
 
3659
    SETSTRING( Result, strA );
 
3660
    END_VARYING_SECTION
 
3661
}
 
3662
 
 
3663
 
 
3664
//----------------------------------------------------------------------
 
3665
// concat(s,s,...)
 
3666
 
 
3667
STD_SOIMPL      CqShaderExecEnv::SO_concat( STRINGVAL stra, STRINGVAL strb, DEFPARAMVARIMPL )
 
3668
{
 
3669
    STATS_INC( SHD_so_concat );
 
3670
 
 
3671
    INIT_SO
 
3672
 
 
3673
    CHECKVARY( stra )
 
3674
    CHECKVARY( strb )
 
3675
    int ii;
 
3676
    for ( ii = 0; ii < cParams; ii++ )
 
3677
    {
 
3678
        CHECKVARY( apParams[ ii ] );
 
3679
    }
 
3680
    CHECKVARY( Result );
 
3681
 
 
3682
    BEGIN_VARYING_SECTION
 
3683
    GETSTRING( stra );
 
3684
    CqString strRes = STRING( stra );
 
3685
    GETSTRING( strb );
 
3686
    strRes += STRING( strb );
 
3687
    for ( ii = 0; ii < cParams; ii++ )
 
3688
    {
 
3689
        CqString sn;
 
3690
        apParams[ ii ] ->GetString( sn, __iGrid );
 
3691
        strRes += sn;
 
3692
    }
 
3693
    SETSTRING( Result, strRes );
 
3694
    END_VARYING_SECTION
 
3695
}
 
3696
 
 
3697
 
 
3698
//----------------------------------------------------------------------
 
3699
// noise(v)
 
3700
STD_SOIMPL CqShaderExecEnv::SO_fcellnoise1( FLOATVAL v, DEFPARAMIMPL )
 
3701
{
 
3702
    STATS_INC( SHD_so_fcellnoise1 );
 
3703
 
 
3704
    INIT_SO
 
3705
 
 
3706
    CHECKVARY( v )
 
3707
    CHECKVARY( Result )
 
3708
 
 
3709
    BEGIN_VARYING_SECTION
 
3710
    GETFLOAT( v );
 
3711
    SETFLOAT( Result, m_cellnoise.FCellNoise1( FLOAT( v ) ) );
 
3712
    END_VARYING_SECTION
 
3713
}
 
3714
 
 
3715
STD_SOIMPL CqShaderExecEnv::SO_ccellnoise1( FLOATVAL v, DEFPARAMIMPL )
 
3716
{
 
3717
    STATS_INC( SHD_so_ccellnoise1 );
 
3718
 
 
3719
    INIT_SO
 
3720
 
 
3721
    CHECKVARY( v )
 
3722
    CHECKVARY( Result )
 
3723
 
 
3724
    BEGIN_VARYING_SECTION
 
3725
    GETFLOAT( v );
 
3726
    SETCOLOR( Result, CqColor( m_cellnoise.PCellNoise1( FLOAT( v ) ) ) );
 
3727
    END_VARYING_SECTION
 
3728
}
 
3729
 
 
3730
STD_SOIMPL CqShaderExecEnv::SO_pcellnoise1( FLOATVAL v, DEFPARAMIMPL )
 
3731
{
 
3732
    STATS_INC( SHD_so_pcellnoise1 );
 
3733
 
 
3734
    INIT_SO
 
3735
 
 
3736
    CHECKVARY( v )
 
3737
    CHECKVARY( Result )
 
3738
 
 
3739
    BEGIN_VARYING_SECTION
 
3740
    GETFLOAT( v );
 
3741
    SETPOINT( Result, m_cellnoise.PCellNoise1( FLOAT( v ) ) );
 
3742
    END_VARYING_SECTION
 
3743
}
 
3744
 
 
3745
//----------------------------------------------------------------------
 
3746
// noise(u,v)
 
3747
STD_SOIMPL CqShaderExecEnv::SO_fcellnoise2( FLOATVAL u, FLOATVAL v, DEFPARAMIMPL )
 
3748
{
 
3749
    STATS_INC( SHD_so_fcellnoise2 );
 
3750
 
 
3751
    INIT_SO
 
3752
 
 
3753
    CHECKVARY( u )
 
3754
    CHECKVARY( v )
 
3755
    CHECKVARY( Result )
 
3756
 
 
3757
    BEGIN_VARYING_SECTION
 
3758
    GETFLOAT( u );
 
3759
    GETFLOAT( v );
 
3760
    SETFLOAT( Result, m_cellnoise.FCellNoise2( FLOAT( u ), FLOAT( v ) ) );
 
3761
    END_VARYING_SECTION
 
3762
}
 
3763
STD_SOIMPL CqShaderExecEnv::SO_ccellnoise2( FLOATVAL u, FLOATVAL v, DEFPARAMIMPL )
 
3764
{
 
3765
    STATS_INC( SHD_so_ccellnoise2 );
 
3766
 
 
3767
    INIT_SO
 
3768
 
 
3769
    CHECKVARY( u )
 
3770
    CHECKVARY( v )
 
3771
    CHECKVARY( Result )
 
3772
 
 
3773
    BEGIN_VARYING_SECTION
 
3774
    GETFLOAT( u );
 
3775
    GETFLOAT( v );
 
3776
    SETCOLOR( Result, CqColor( m_cellnoise.PCellNoise2( FLOAT( u ), FLOAT( v ) ) ) );
 
3777
    END_VARYING_SECTION
 
3778
}
 
3779
STD_SOIMPL CqShaderExecEnv::SO_pcellnoise2( FLOATVAL u, FLOATVAL v, DEFPARAMIMPL )
 
3780
{
 
3781
    STATS_INC( SHD_so_pcellnoise3 );
 
3782
 
 
3783
    INIT_SO
 
3784
 
 
3785
    CHECKVARY( u )
 
3786
    CHECKVARY( v )
 
3787
    CHECKVARY( Result )
 
3788
 
 
3789
    BEGIN_VARYING_SECTION
 
3790
    GETFLOAT( u );
 
3791
    GETFLOAT( v );
 
3792
    SETPOINT( Result, m_cellnoise.PCellNoise2( FLOAT( u ), FLOAT( v ) ) );
 
3793
    END_VARYING_SECTION
 
3794
}
 
3795
 
 
3796
//----------------------------------------------------------------------
 
3797
// noise(p)
 
3798
STD_SOIMPL CqShaderExecEnv::SO_fcellnoise3( POINTVAL p, DEFPARAMIMPL )
 
3799
{
 
3800
    STATS_INC( SHD_so_fcellnoise3 );
 
3801
 
 
3802
    INIT_SO
 
3803
 
 
3804
    CHECKVARY( p )
 
3805
    CHECKVARY( Result )
 
3806
 
 
3807
    BEGIN_VARYING_SECTION
 
3808
    GETPOINT( p );
 
3809
    SETFLOAT( Result, m_cellnoise.FCellNoise3( POINT( p ) ) );
 
3810
    END_VARYING_SECTION
 
3811
}
 
3812
STD_SOIMPL CqShaderExecEnv::SO_ccellnoise3( POINTVAL p, DEFPARAMIMPL )
 
3813
{
 
3814
    STATS_INC( SHD_so_ccellnoise3 );
 
3815
 
 
3816
    INIT_SO
 
3817
 
 
3818
    CHECKVARY( p )
 
3819
    CHECKVARY( Result )
 
3820
 
 
3821
    BEGIN_VARYING_SECTION
 
3822
    GETPOINT( p );
 
3823
    SETCOLOR( Result, CqColor( m_cellnoise.PCellNoise3( POINT( p ) ) ) );
 
3824
    END_VARYING_SECTION
 
3825
}
 
3826
STD_SOIMPL CqShaderExecEnv::SO_pcellnoise3( POINTVAL p, DEFPARAMIMPL )
 
3827
{
 
3828
    STATS_INC( SHD_so_pcellnoise2 );
 
3829
 
 
3830
    INIT_SO
 
3831
 
 
3832
    CHECKVARY( p )
 
3833
    CHECKVARY( Result )
 
3834
 
 
3835
    BEGIN_VARYING_SECTION
 
3836
    GETPOINT( p );
 
3837
    SETPOINT( Result, m_cellnoise.PCellNoise3( POINT( p ) ) );
 
3838
    END_VARYING_SECTION
 
3839
}
 
3840
 
 
3841
//----------------------------------------------------------------------
 
3842
// noise(p,f)
 
3843
STD_SOIMPL CqShaderExecEnv::SO_fcellnoise4( POINTVAL p, FLOATVAL v, DEFPARAMIMPL )
 
3844
{
 
3845
    STATS_INC( SHD_so_fcellnoise4 );
 
3846
 
 
3847
    INIT_SO
 
3848
 
 
3849
    CHECKVARY( p )
 
3850
    CHECKVARY( v )
 
3851
    CHECKVARY( Result )
 
3852
 
 
3853
    BEGIN_VARYING_SECTION
 
3854
    GETPOINT( p );
 
3855
    GETFLOAT( v );
 
3856
    SETFLOAT( Result, m_cellnoise.FCellNoise4( POINT( p ), FLOAT( v ) ) );
 
3857
    END_VARYING_SECTION
 
3858
}
 
3859
STD_SOIMPL CqShaderExecEnv::SO_ccellnoise4( POINTVAL p, FLOATVAL v, DEFPARAMIMPL )
 
3860
{
 
3861
    STATS_INC( SHD_so_ccellnoise4 );
 
3862
 
 
3863
    INIT_SO
 
3864
 
 
3865
    CHECKVARY( p )
 
3866
    CHECKVARY( v )
 
3867
    CHECKVARY( Result )
 
3868
 
 
3869
    BEGIN_VARYING_SECTION
 
3870
    GETPOINT( p );
 
3871
    GETFLOAT( v );
 
3872
    SETCOLOR( Result, CqColor( m_cellnoise.PCellNoise4( POINT( p ), FLOAT( v ) ) ) );
 
3873
    END_VARYING_SECTION
 
3874
}
 
3875
STD_SOIMPL CqShaderExecEnv::SO_pcellnoise4( POINTVAL p, FLOATVAL v, DEFPARAMIMPL )
 
3876
{
 
3877
    STATS_INC( SHD_so_pcellnoise2 );
 
3878
 
 
3879
    INIT_SO
 
3880
 
 
3881
    CHECKVARY( p )
 
3882
    CHECKVARY( v )
 
3883
    CHECKVARY( Result )
 
3884
 
 
3885
    BEGIN_VARYING_SECTION
 
3886
    GETPOINT( p );
 
3887
    GETFLOAT( v );
 
3888
    SETPOINT( Result, m_cellnoise.PCellNoise4( POINT( p ), FLOAT( v ) ) );
 
3889
    END_VARYING_SECTION
 
3890
}
 
3891
 
 
3892
 
 
3893
 
 
3894
//----------------------------------------------------------------------
 
3895
// atmosphere
 
3896
//
 
3897
 
 
3898
STD_SOIMPL CqShaderExecEnv::SO_atmosphere( STRINGVAL name, IqShaderData* pV, DEFPARAMIMPL )
 
3899
{
 
3900
    STATS_INC( SHD_so_atmosphere );
 
3901
 
 
3902
    INIT_SO
 
3903
 
 
3904
    IqShader * pAtmosphere = NULL;
 
3905
 
 
3906
    if ( NULL != m_pAttributes && NULL != m_pAttributes ->pshadAtmosphere(QGetRenderContextI()->Time()) )
 
3907
        pAtmosphere = m_pAttributes ->pshadAtmosphere(QGetRenderContextI()->Time());
 
3908
 
 
3909
    BEGIN_UNIFORM_SECTION
 
3910
    GETSTRING( name );
 
3911
    if ( pAtmosphere )
 
3912
        Result->SetValue( pAtmosphere->GetValue( STRING( name ).c_str(), pV ) ? 1.0f : 0.0f, 0 );
 
3913
    else
 
3914
        Result->SetValue( 0.0f, 0 );
 
3915
    END_UNIFORM_SECTION
 
3916
}
 
3917
 
 
3918
 
 
3919
//----------------------------------------------------------------------
 
3920
// displacement
 
3921
//
 
3922
 
 
3923
STD_SOIMPL CqShaderExecEnv::SO_displacement( STRINGVAL name, IqShaderData* pV, DEFPARAMIMPL )
 
3924
{
 
3925
    STATS_INC( SHD_so_displacement );
 
3926
 
 
3927
    INIT_SO
 
3928
 
 
3929
    IqShader * pDisplacement = NULL;
 
3930
 
 
3931
    if ( NULL != m_pAttributes && NULL != m_pAttributes ->pshadDisplacement(QGetRenderContextI()->Time()) )
 
3932
        pDisplacement = m_pAttributes ->pshadDisplacement(QGetRenderContextI()->Time());
 
3933
 
 
3934
    BEGIN_UNIFORM_SECTION
 
3935
    GETSTRING( name );
 
3936
    if ( pDisplacement )
 
3937
        Result->SetValue( pDisplacement->GetValue( STRING( name ).c_str(), pV ) ? 1.0f : 0.0f, 0 );
 
3938
    else
 
3939
        Result->SetValue( 0.0f, 0 );
 
3940
    END_UNIFORM_SECTION
 
3941
}
 
3942
 
 
3943
 
 
3944
//----------------------------------------------------------------------
 
3945
// lightsource
 
3946
//
 
3947
 
 
3948
STD_SOIMPL CqShaderExecEnv::SO_lightsource( STRINGVAL name, IqShaderData* pV, DEFPARAMIMPL )
 
3949
{
 
3950
    STATS_INC( SHD_so_lightsource );
 
3951
 
 
3952
    INIT_SO
 
3953
 
 
3954
    // This should only be called within an Illuminance construct, so m_li should be valid.
 
3955
    IqShader * pLightsource = 0;
 
3956
 
 
3957
    BEGIN_UNIFORM_SECTION
 
3958
    GETSTRING( name );
 
3959
    if ( m_li < m_pAttributes ->cLights() )
 
3960
        pLightsource = m_pAttributes ->pLight( m_li ) ->pShader();
 
3961
    if ( pLightsource )
 
3962
        Result->SetValue( pLightsource->GetValue( STRING( name ).c_str(), pV ) ? 1.0f : 0.0f, 0 );
 
3963
    else
 
3964
        Result->SetValue( 0.0f, 0 );
 
3965
    END_UNIFORM_SECTION
 
3966
}
 
3967
 
 
3968
 
 
3969
//----------------------------------------------------------------------
 
3970
// surface
 
3971
//
 
3972
 
 
3973
STD_SOIMPL CqShaderExecEnv::SO_surface( STRINGVAL name, IqShaderData* pV, DEFPARAMIMPL )
 
3974
{
 
3975
    STATS_INC( SHD_so_surface );
 
3976
 
 
3977
    INIT_SO
 
3978
 
 
3979
    IqShader * pSurface = NULL;
 
3980
 
 
3981
    if ( NULL != m_pAttributes && NULL != m_pAttributes ->pshadSurface(QGetRenderContextI()->Time()) )
 
3982
        pSurface = m_pAttributes ->pshadSurface(QGetRenderContextI()->Time());
 
3983
 
 
3984
    BEGIN_UNIFORM_SECTION
 
3985
    GETSTRING( name );
 
3986
    if ( pSurface )
 
3987
        Result->SetValue( pSurface->GetValue( STRING( name ).c_str(), pV ) ? 1.0f : 0.0f, 0 );
 
3988
    else
 
3989
        Result->SetValue( 0.0f, 0 );
 
3990
    END_UNIFORM_SECTION
 
3991
}
 
3992
 
 
3993
 
 
3994
//----------------------------------------------------------------------
 
3995
// attribute
 
3996
//
 
3997
 
 
3998
STD_SOIMPL CqShaderExecEnv::SO_attribute( STRINGVAL name, IqShaderData* pV, DEFPARAMIMPL )
 
3999
{
 
4000
    STATS_INC( SHD_so_attribute );
 
4001
 
 
4002
    INIT_SO
 
4003
 
 
4004
    //Find out if it is a specific attribute request
 
4005
    BEGIN_UNIFORM_SECTION
 
4006
    GETSTRING( name );
 
4007
    TqFloat Ret = 0.0f;
 
4008
 
 
4009
    if ( STRING( name ).compare( "ShadingRate" ) == 0 )
 
4010
    {
 
4011
        if ( pV->Type() == type_float )
 
4012
        {
 
4013
            pV->SetFloat( m_pAttributes ->GetFloatAttribute( "System", "ShadingRate" ) [ 0 ] );
 
4014
            Ret = 1.0f;
 
4015
        }
 
4016
    }
 
4017
    else if ( STRING( name ).compare( "Sides" ) == 0 )
 
4018
    {
 
4019
        if ( pV->Type() == type_float )
 
4020
        {
 
4021
            pV->SetFloat( m_pAttributes ->GetIntegerAttribute( "System", "Sides" ) [ 0 ] );
 
4022
            Ret = 1.0f;
 
4023
        }
 
4024
    }
 
4025
    else if ( STRING( name ).compare( "Matte" ) == 0 )
 
4026
    {
 
4027
        if ( pV->Type() == type_float )
 
4028
        {
 
4029
            pV->SetFloat( m_pAttributes ->GetIntegerAttribute( "System", "Matte" ) [ 0 ] );
 
4030
            Ret = 1.0f;
 
4031
        }
 
4032
    }
 
4033
    else
 
4034
    {
 
4035
        int iColon = STRING( name ).find_first_of( ':' );
 
4036
        if ( iColon >= 0 )
 
4037
        {
 
4038
            CqString strParam = STRING( name ).substr( iColon + 1, STRING( name ).size() - iColon - 1 );
 
4039
            STRING( name ) = STRING( name ).substr( 0, iColon );
 
4040
            //const CqParameter* pParam = m_pAttributes ->pParameter( STRING( name ).c_str(), strParam.c_str() );
 
4041
 
 
4042
            Ret = 1.0f;
 
4043
            if ( NULL != pAttributes() ->GetFloatAttribute( STRING( name ).c_str(), strParam.c_str() ) )
 
4044
                pV->SetFloat( pAttributes() ->GetFloatAttribute( STRING( name ).c_str(), strParam.c_str() ) [ 0 ] );
 
4045
            else if ( NULL != pAttributes() ->GetIntegerAttribute( STRING( name ).c_str(), strParam.c_str() ) )
 
4046
                pV->SetFloat( pAttributes() ->GetIntegerAttribute( STRING( name ).c_str(), strParam.c_str() ) [ 0 ] );
 
4047
            else if ( NULL != pAttributes() ->GetStringAttribute( STRING( name ).c_str(), strParam.c_str() ) )
 
4048
                pV->SetString( pAttributes() ->GetStringAttribute( STRING( name ).c_str(), strParam.c_str() ) [ 0 ] );
 
4049
            else if ( NULL != pAttributes() ->GetPointAttribute( STRING( name ).c_str(), strParam.c_str() ) )
 
4050
                pV->SetPoint( pAttributes() ->GetPointAttribute( STRING( name ).c_str(), strParam.c_str() ) [ 0 ] );
 
4051
            else if ( NULL != pAttributes() ->GetVectorAttribute( STRING( name ).c_str(), strParam.c_str() ) )
 
4052
                pV->SetVector( pAttributes() ->GetVectorAttribute( STRING( name ).c_str(), strParam.c_str() ) [ 0 ] );
 
4053
            else if ( NULL != pAttributes() ->GetNormalAttribute( STRING( name ).c_str(), strParam.c_str() ) )
 
4054
                pV->SetNormal( pAttributes() ->GetNormalAttribute( STRING( name ).c_str(), strParam.c_str() ) [ 0 ] );
 
4055
            else if ( NULL != pAttributes() ->GetColorAttribute( STRING( name ).c_str(), strParam.c_str() ) )
 
4056
                pV->SetColor( pAttributes() ->GetColorAttribute( STRING( name ).c_str(), strParam.c_str() ) [ 0 ] );
 
4057
            else if ( NULL != pAttributes() ->GetMatrixAttribute( STRING( name ).c_str(), strParam.c_str() ) )
 
4058
                pV->SetMatrix( pAttributes() ->GetMatrixAttribute( STRING( name ).c_str(), strParam.c_str() ) [ 0 ] );
 
4059
            else
 
4060
                Ret = 0.0f;
 
4061
        }
 
4062
    }
 
4063
    Result->SetValue( Ret, 0 );
 
4064
    END_UNIFORM_SECTION
 
4065
}
 
4066
 
 
4067
 
 
4068
//----------------------------------------------------------------------
 
4069
// option
 
4070
//
 
4071
 
 
4072
STD_SOIMPL CqShaderExecEnv::SO_option( STRINGVAL name, IqShaderData* pV, DEFPARAMIMPL )
 
4073
{
 
4074
    STATS_INC( SHD_so_option );
 
4075
 
 
4076
    INIT_SO
 
4077
 
 
4078
    if ( NULL == QGetRenderContextI() )
 
4079
        return ;
 
4080
 
 
4081
    BEGIN_UNIFORM_SECTION
 
4082
    //Find out if it is a specific option request
 
4083
    GETSTRING( name );
 
4084
    TqFloat Ret = 0.0f;
 
4085
 
 
4086
    if ( STRING( name ).compare( "Format" ) == 0 )
 
4087
    {
 
4088
        if ( pV->Type() == type_float &&
 
4089
                pV->ArrayLength() > 0 )
 
4090
        {
 
4091
            if ( pV->ArrayLength() >= 3 )
 
4092
            {
 
4093
                pV->ArrayEntry( 0 ) ->SetFloat( static_cast<TqFloat>( QGetRenderContextI() ->GetIntegerOption( "System", "Resolution" ) [ 0 ] ) );
 
4094
                pV->ArrayEntry( 1 ) ->SetFloat( static_cast<TqFloat>( QGetRenderContextI() ->GetIntegerOption( "System", "Resolution" ) [ 1 ] ) );
 
4095
                pV->ArrayEntry( 2 ) ->SetFloat( static_cast<TqFloat>( QGetRenderContextI() ->GetFloatOption( "System", "PixelAspectRatio" ) [ 2 ] ) );
 
4096
                Ret = 1.0f;
 
4097
            }
 
4098
        }
 
4099
    }
 
4100
    else if ( STRING( name ).compare( "CropWindow" ) == 0 )
 
4101
    {
 
4102
        if ( pV->Type() == type_float &&
 
4103
                pV->ArrayLength() > 0 )
 
4104
        {
 
4105
            if ( pV->ArrayLength() >= 4 )
 
4106
            {
 
4107
                pV->ArrayEntry( 0 ) ->SetFloat( static_cast<TqFloat>( QGetRenderContextI() ->GetFloatOption( "System", "CropWindow" ) [ 0 ] ) );
 
4108
                pV->ArrayEntry( 1 ) ->SetFloat( static_cast<TqFloat>( QGetRenderContextI() ->GetFloatOption( "System", "CropWindow" ) [ 1 ] ) );
 
4109
                pV->ArrayEntry( 2 ) ->SetFloat( static_cast<TqFloat>( QGetRenderContextI() ->GetFloatOption( "System", "CropWindow" ) [ 2 ] ) );
 
4110
                pV->ArrayEntry( 3 ) ->SetFloat( static_cast<TqFloat>( QGetRenderContextI() ->GetFloatOption( "System", "CropWindow" ) [ 3 ] ) );
 
4111
                Ret = 1.0f;
 
4112
            }
 
4113
        }
 
4114
    }
 
4115
    else if ( STRING( name ).compare( "FrameAspectRatio" ) == 0 )
 
4116
    {
 
4117
        if ( pV->Type() == type_float )
 
4118
        {
 
4119
            pV->SetFloat( static_cast<TqFloat>( QGetRenderContextI() ->GetFloatOption( "System", "FrameAspectRatio" ) [ 0 ] ) );
 
4120
            Ret = 1.0f;
 
4121
        }
 
4122
    }
 
4123
    else if ( STRING( name ).compare( "DepthOfField" ) == 0 )
 
4124
    {
 
4125
        if ( pV->Type() == type_float &&
 
4126
                pV->ArrayLength() > 0 )
 
4127
        {
 
4128
            if ( pV->ArrayLength() >= 3 )
 
4129
            {
 
4130
                pV->ArrayEntry( 0 ) ->SetFloat( static_cast<TqFloat>( QGetRenderContextI() ->GetFloatOption( "System", "DepthOfField" ) [ 0 ] ) );
 
4131
                pV->ArrayEntry( 1 ) ->SetFloat( static_cast<TqFloat>( QGetRenderContextI() ->GetFloatOption( "System", "DepthOfField" ) [ 1 ] ) );
 
4132
                pV->ArrayEntry( 2 ) ->SetFloat( static_cast<TqFloat>( QGetRenderContextI() ->GetFloatOption( "System", "DepthOfField" ) [ 2 ] ) );
 
4133
                Ret = 1.0f;
 
4134
            }
 
4135
        }
 
4136
    }
 
4137
    else if ( STRING( name ).compare( "Shutter" ) == 0 )
 
4138
    {
 
4139
        if ( pV->Type() == type_float &&
 
4140
                pV->ArrayLength() > 0 )
 
4141
        {
 
4142
            if ( pV->ArrayLength() >= 2 )
 
4143
            {
 
4144
                pV->ArrayEntry( 0 ) ->SetFloat( static_cast<TqFloat>( QGetRenderContextI() ->GetFloatOption( "System", "Shutter" ) [ 0 ] ) );
 
4145
                pV->ArrayEntry( 1 ) ->SetFloat( static_cast<TqFloat>( QGetRenderContextI() ->GetFloatOption( "System", "Shutter" ) [ 1 ] ) );
 
4146
                Ret = 1.0f;
 
4147
            }
 
4148
        }
 
4149
    }
 
4150
    else if ( STRING( name ).compare( "Clipping" ) == 0 )
 
4151
    {
 
4152
        if ( pV->Type() == type_float &&
 
4153
                pV->ArrayLength() > 0 )
 
4154
        {
 
4155
            if ( pV->ArrayLength() >= 2 )
 
4156
            {
 
4157
                pV->ArrayEntry( 0 ) ->SetFloat( static_cast<TqFloat>( QGetRenderContextI() ->GetFloatOption( "System", "Clipping" ) [ 0 ] ) );
 
4158
                pV->ArrayEntry( 1 ) ->SetFloat( static_cast<TqFloat>( QGetRenderContextI() ->GetFloatOption( "System", "Clipping" ) [ 1 ] ) );
 
4159
                Ret = 1.0f;
 
4160
            }
 
4161
        }
 
4162
    }
 
4163
    else
 
4164
    {
 
4165
        CqString strName = STRING( name ).c_str();
 
4166
        int iColon = strName.find_first_of( ':' );
 
4167
        if ( iColon >= 0 )
 
4168
        {
 
4169
            CqString strParam = strName.substr( iColon + 1, strName.size() - iColon - 1 );
 
4170
            strName = strName.substr( 0, iColon );
 
4171
            //const CqParameter* pParam = m_pAttributes ->pParameter( strName.c_str(), strParam.c_str() );
 
4172
 
 
4173
            Ret = 1.0f;
 
4174
 
 
4175
            if ( NULL != QGetRenderContextI() ->GetStringOption( strName.c_str(), strParam.c_str() ) )
 
4176
                pV->SetString( QGetRenderContextI() ->GetStringOption( strName.c_str(), strParam.c_str() ) [ 0 ] );
 
4177
            else if ( NULL != QGetRenderContextI() ->GetIntegerOption( strName.c_str(), strParam.c_str() ) )
 
4178
                pV->SetFloat( QGetRenderContextI() ->GetIntegerOption( strName.c_str(), strParam.c_str() ) [ 0 ] );
 
4179
 
 
4180
            else if ( NULL != QGetRenderContextI() ->GetPointOption( strName.c_str(), strParam.c_str() ) )
 
4181
                pV->SetPoint( QGetRenderContextI() ->GetPointOption( strName.c_str(), strParam.c_str() ) [ 0 ] );
 
4182
 
 
4183
            else if ( NULL != QGetRenderContextI() ->GetColorOption( strName.c_str(), strParam.c_str() ) )
 
4184
                pV->SetColor( QGetRenderContextI() ->GetColorOption( strName.c_str(), strParam.c_str() ) [ 0 ] );
 
4185
            else if ( NULL != QGetRenderContextI() ->GetFloatOption( strName.c_str(), strParam.c_str() ) )
 
4186
                pV->SetFloat( QGetRenderContextI() ->GetFloatOption( strName.c_str(), strParam.c_str() ) [ 0 ] );
 
4187
            /* did not deal with Vector, Normal and Matrix yet */
 
4188
            else
 
4189
                Ret = 0.0f;
 
4190
        }
 
4191
    }
 
4192
 
 
4193
    Result->SetValue( Ret, 0 );
 
4194
    END_UNIFORM_SECTION
 
4195
}
 
4196
 
 
4197
 
 
4198
//----------------------------------------------------------------------
 
4199
// rendererinfo
 
4200
//
 
4201
 
 
4202
STD_SOIMPL CqShaderExecEnv::SO_rendererinfo( STRINGVAL name, IqShaderData* pV, DEFPARAMIMPL )
 
4203
{
 
4204
    STATS_INC( SHD_so_rendererinfo );
 
4205
 
 
4206
    INIT_SO
 
4207
 
 
4208
    BEGIN_UNIFORM_SECTION
 
4209
    GETSTRING( name );
 
4210
    TqFloat Ret = 0.0f;
 
4211
 
 
4212
    if ( STRING( name ).compare( "renderer" ) == 0 )
 
4213
    {
 
4214
        if ( pV->Type() == type_string )
 
4215
        {
 
4216
            pV->SetString( STRNAME );
 
4217
            Ret = 1.0f;
 
4218
        }
 
4219
    }
 
4220
    else if ( STRING( name ).compare( "version" ) == 0 )
 
4221
    {
 
4222
        if ( pV->Type() == type_float &&
 
4223
                pV->ArrayLength() > 0 )
 
4224
        {
 
4225
            if ( pV->ArrayLength() >= 4 )
 
4226
            {
 
4227
                pV->ArrayEntry( 0 ) ->SetFloat( static_cast<TqFloat>( VERMAJOR ) );
 
4228
                pV->ArrayEntry( 1 ) ->SetFloat( static_cast<TqFloat>( VERMINOR ) );
 
4229
                pV->ArrayEntry( 2 ) ->SetFloat( static_cast<TqFloat>( BUILD ) );
 
4230
                pV->ArrayEntry( 3 ) ->SetFloat( 0.0f );
 
4231
                Ret = 1.0f;
 
4232
            }
 
4233
        }
 
4234
    }
 
4235
    else if ( STRING( name ).compare( "versionstring" ) == 0 )
 
4236
    {
 
4237
        if ( pV->Type() == type_string )
 
4238
        {
 
4239
#if defined(AQSIS_SYSTEM_WIN32) || defined(AQSIS_SYSTEM_MACOSX)
 
4240
            pV->SetString( VERSION_STR );
 
4241
#else // AQSIS_SYSTEM_WIN32
 
4242
            pV->SetString( VERSION );
 
4243
#endif // !AQSIS_SYSTEM_WIN32
 
4244
            Ret = 1.0f;
 
4245
        }
 
4246
    }
 
4247
    Result->SetValue( Ret, 0 );
 
4248
    END_UNIFORM_SECTION
 
4249
}
 
4250
 
 
4251
 
 
4252
//----------------------------------------------------------------------
 
4253
// incident
 
4254
 
 
4255
STD_SOIMPL CqShaderExecEnv::SO_incident( STRINGVAL name, IqShaderData* pV, DEFPARAMIMPL )
 
4256
{
 
4257
    STATS_INC( SHD_so_incident );
 
4258
 
 
4259
    INIT_SO
 
4260
 
 
4261
    BEGIN_UNIFORM_SECTION
 
4262
    Result->SetValue( 0.0f, 0 );
 
4263
    END_UNIFORM_SECTION
 
4264
}
 
4265
 
 
4266
 
 
4267
//----------------------------------------------------------------------
 
4268
// opposite
 
4269
 
 
4270
STD_SOIMPL CqShaderExecEnv::SO_opposite( STRINGVAL name, IqShaderData* pV, DEFPARAMIMPL )
 
4271
{
 
4272
    STATS_INC( SHD_so_opposite );
 
4273
 
 
4274
    INIT_SO
 
4275
 
 
4276
    BEGIN_UNIFORM_SECTION
 
4277
    Result->SetValue( 0.0f, 0 );
 
4278
    END_UNIFORM_SECTION
 
4279
}
 
4280
 
 
4281
 
 
4282
//----------------------------------------------------------------------
 
4283
// ctransform(s,s,c)
 
4284
STD_SOIMPL CqShaderExecEnv::SO_ctransform( STRINGVAL fromspace, STRINGVAL tospace, COLORVAL c, DEFPARAMIMPL )
 
4285
{
 
4286
    STATS_INC( SHD_so_ctransform );
 
4287
 
 
4288
    INIT_SO
 
4289
 
 
4290
    CHECKVARY( c )
 
4291
    CHECKVARY( Result )
 
4292
 
 
4293
    BEGIN_UNIFORM_SECTION
 
4294
    CqString strfromspace( "rgb" );
 
4295
    if ( NULL != fromspace ) fromspace->GetString( strfromspace );
 
4296
    GETSTRING( tospace );
 
4297
    END_UNIFORM_SECTION
 
4298
 
 
4299
    BEGIN_VARYING_SECTION
 
4300
    GETCOLOR( c );
 
4301
    CqColor res( COLOR( c ) );
 
4302
    if ( strfromspace.compare( "hsv" ) == 0 ) res = COLOR( c ).hsvtorgb();
 
4303
    else if ( strfromspace.compare( "hsl" ) == 0 ) res = COLOR( c ).hsltorgb();
 
4304
    else if ( strfromspace.compare( "XYZ" ) == 0 ) res = COLOR( c ).XYZtorgb();
 
4305
    else if ( strfromspace.compare( "xyY" ) == 0 ) res = COLOR( c ).xyYtorgb();
 
4306
    else if ( strfromspace.compare( "YIQ" ) == 0 ) res = COLOR( c ).YIQtorgb();
 
4307
 
 
4308
    if ( STRING( tospace ).compare( "hsv" ) == 0 ) res = COLOR( c ).rgbtohsv();
 
4309
    else if ( STRING( tospace ).compare( "hsl" ) == 0 ) res = COLOR( c ).rgbtohsl();
 
4310
    else if ( STRING( tospace ).compare( "XYZ" ) == 0 ) res = COLOR( c ).rgbtoXYZ();
 
4311
    else if ( STRING( tospace ).compare( "xyY" ) == 0 ) res = COLOR( c ).rgbtoxyY();
 
4312
    else if ( STRING( tospace ).compare( "YIQ" ) == 0 ) res = COLOR( c ).rgbtoYIQ();
 
4313
 
 
4314
    SETCOLOR( Result, res );
 
4315
    END_VARYING_SECTION
 
4316
}
 
4317
 
 
4318
 
 
4319
//----------------------------------------------------------------------
 
4320
// ctransform(s,c)
 
4321
STD_SOIMPL CqShaderExecEnv::SO_ctransform( STRINGVAL tospace, COLORVAL c, DEFPARAMIMPL )
 
4322
{
 
4323
    STATS_INC( SHD_so_ctransform );
 
4324
 
 
4325
    assert( pShader != 0 );
 
4326
    SO_ctransform( NULL, tospace, c, Result, pShader );
 
4327
}
 
4328
 
 
4329
 
 
4330
//----------------------------------------------------------------------
 
4331
// ctransform(s,c)
 
4332
STD_SOIMPL CqShaderExecEnv::SO_ptlined( POINTVAL P0, POINTVAL P1, POINTVAL Q, DEFPARAMIMPL )
 
4333
{
 
4334
    STATS_INC( SHD_so_ptlined );
 
4335
 
 
4336
    INIT_SO
 
4337
 
 
4338
    CHECKVARY( P0 )
 
4339
    CHECKVARY( P1 )
 
4340
    CHECKVARY( Q )
 
4341
    CHECKVARY( Result )
 
4342
 
 
4343
    BEGIN_VARYING_SECTION
 
4344
    GETPOINT( P0 );
 
4345
    GETPOINT( P1 );
 
4346
    GETPOINT( Q );
 
4347
    CqVector3D kDiff = POINT( Q ) - POINT( P0 );
 
4348
    CqVector3D vecDir = POINT( P1 ) - POINT( P0 );
 
4349
    TqFloat fT = kDiff * vecDir;
 
4350
 
 
4351
    if ( fT <= 0.0f )
 
4352
        fT = 0.0f;
 
4353
    else
 
4354
    {
 
4355
        TqFloat fSqrLen = vecDir.Magnitude2();
 
4356
        if ( fT >= fSqrLen )
 
4357
        {
 
4358
            fT = 1.0f;
 
4359
            kDiff -= vecDir;
 
4360
        }
 
4361
        else
 
4362
        {
 
4363
            fT /= fSqrLen;
 
4364
            kDiff -= fT * vecDir;
 
4365
        }
 
4366
    }
 
4367
    SETFLOAT( Result, kDiff.Magnitude() );
 
4368
    END_VARYING_SECTION
 
4369
}
 
4370
 
 
4371
 
 
4372
STD_SOIMPL      CqShaderExecEnv::SO_inversesqrt( FLOATVAL x, DEFPARAMIMPL )
 
4373
{
 
4374
    STATS_INC( SHD_so_inversesqrt );
 
4375
 
 
4376
    INIT_SO
 
4377
 
 
4378
    CHECKVARY( x )
 
4379
    CHECKVARY( Result )
 
4380
 
 
4381
    BEGIN_VARYING_SECTION
 
4382
    GETFLOAT( x );
 
4383
    SETFLOAT( Result, 1.0f / static_cast<TqFloat>( sqrt( FLOAT( x ) ) ) );
 
4384
    END_VARYING_SECTION
 
4385
}
 
4386
 
 
4387
STD_SOIMPL      CqShaderExecEnv::SO_match( STRINGVAL a, STRINGVAL b, DEFPARAMIMPL )
 
4388
{
 
4389
    // TODO: Do this properly.
 
4390
    STATS_INC( SHD_so_match );
 
4391
 
 
4392
    INIT_SO
 
4393
 
 
4394
    BEGIN_UNIFORM_SECTION
 
4395
    float r = 0.0f;
 
4396
    GETSTRING( a );
 
4397
    GETSTRING( b );
 
4398
    if ( STRING( a ).size() == 0 ) r = 0.0f;
 
4399
    else if ( STRING( b ).size() == 0 ) r = 0.0f;
 
4400
    else
 
4401
    {
 
4402
        // MJO> Only check the occurrence of string b in string a
 
4403
        // It doesn't support the regular expression yet
 
4404
        r = ( float ) ( strstr( STRING( b ).c_str(), STRING( a ).c_str() ) != 0 );
 
4405
    }
 
4406
 
 
4407
    SETFLOAT( Result, r );
 
4408
    END_UNIFORM_SECTION
 
4409
}
 
4410
 
 
4411
 
 
4412
//----------------------------------------------------------------------
 
4413
// pnoise(u,period)
 
4414
STD_SOIMPL CqShaderExecEnv::SO_fpnoise1( FLOATVAL v, FLOATVAL period, DEFPARAMIMPL )
 
4415
{
 
4416
    STATS_INC( SHD_so_fpnoise1 );
 
4417
 
 
4418
    INIT_SO
 
4419
 
 
4420
    CHECKVARY( v )
 
4421
    CHECKVARY( period )
 
4422
    CHECKVARY( Result )
 
4423
 
 
4424
    BEGIN_VARYING_SECTION
 
4425
    GETFLOAT( v );
 
4426
    GETFLOAT( period );
 
4427
    SETFLOAT( Result, ( m_noise.FGNoise1( fmod( FLOAT( v ), FLOAT( period ) ) ) + 1 ) / 2.0f );
 
4428
    END_VARYING_SECTION
 
4429
}
 
4430
 
 
4431
//----------------------------------------------------------------------
 
4432
// pnoise(u,v,uperiod,vperiod)
 
4433
STD_SOIMPL CqShaderExecEnv::SO_fpnoise2( FLOATVAL u, FLOATVAL v, FLOATVAL uperiod, FLOATVAL vperiod, DEFPARAMIMPL )
 
4434
{
 
4435
    STATS_INC( SHD_so_fpnoise2 );
 
4436
 
 
4437
    INIT_SO
 
4438
 
 
4439
    CHECKVARY( u )
 
4440
    CHECKVARY( uperiod )
 
4441
    CHECKVARY( v )
 
4442
    CHECKVARY( vperiod )
 
4443
    CHECKVARY( Result )
 
4444
 
 
4445
    BEGIN_VARYING_SECTION
 
4446
    GETFLOAT( u );
 
4447
    GETFLOAT( v );
 
4448
    GETFLOAT( uperiod );
 
4449
    GETFLOAT( vperiod );
 
4450
    SETFLOAT( Result, ( m_noise.FGNoise2( fmod( FLOAT( u ), FLOAT( uperiod ) ),
 
4451
                                          fmod( FLOAT( v ), FLOAT( vperiod ) ) ) + 1 ) / 2.0f );
 
4452
    END_VARYING_SECTION
 
4453
}
 
4454
 
 
4455
//----------------------------------------------------------------------
 
4456
// pnoise(p,pperiod)
 
4457
STD_SOIMPL CqShaderExecEnv::SO_fpnoise3( POINTVAL p, POINTVAL pperiod, DEFPARAMIMPL )
 
4458
{
 
4459
    STATS_INC( SHD_so_fnoise3 );
 
4460
 
 
4461
    INIT_SO
 
4462
 
 
4463
    CHECKVARY( p )
 
4464
    CHECKVARY( pperiod )
 
4465
    CHECKVARY( Result )
 
4466
 
 
4467
    BEGIN_VARYING_SECTION
 
4468
    GETPOINT( p );
 
4469
    GETPOINT( pperiod );
 
4470
    SETFLOAT( Result, ( m_noise.FGNoise3( CqVector3D( fmod( POINT( p ).x(), POINT( pperiod ).x() ),
 
4471
                                          fmod( POINT( p ).y(), POINT( pperiod ).y() ),
 
4472
                                          fmod( POINT( p ).z(), POINT( pperiod ).z() ) ) ) + 1 ) / 2.0f );
 
4473
    END_VARYING_SECTION
 
4474
}
 
4475
 
 
4476
//----------------------------------------------------------------------
 
4477
// pnoise(p,t,pperiod,tperiod)
 
4478
STD_SOIMPL CqShaderExecEnv::SO_fpnoise4( POINTVAL p, FLOATVAL t, POINTVAL pperiod, FLOATVAL tperiod, DEFPARAMIMPL )
 
4479
{
 
4480
    STATS_INC( SHD_so_fnoise4 );
 
4481
 
 
4482
    INIT_SO
 
4483
 
 
4484
    CHECKVARY( p )
 
4485
    CHECKVARY( pperiod )
 
4486
    CHECKVARY( t )
 
4487
    CHECKVARY( tperiod )
 
4488
    CHECKVARY( Result )
 
4489
 
 
4490
    BEGIN_VARYING_SECTION
 
4491
    GETPOINT( p );
 
4492
    GETFLOAT( t );
 
4493
    GETPOINT( pperiod );
 
4494
    GETFLOAT( tperiod );
 
4495
    SETFLOAT( Result, ( m_noise.FGNoise3( CqVector3D( fmod( POINT( p ).x(), POINT( pperiod ).x() ),
 
4496
                                          fmod( POINT( p ).y(), POINT( pperiod ).y() ),
 
4497
                                          fmod( POINT( p ).z(), POINT( pperiod ).z() ) ) ) + 1 ) / 2.0f );
 
4498
    END_VARYING_SECTION
 
4499
}
 
4500
 
 
4501
//----------------------------------------------------------------------
 
4502
// pnoise(u,period)
 
4503
STD_SOIMPL CqShaderExecEnv::SO_cpnoise1( FLOATVAL v, FLOATVAL period, DEFPARAMIMPL )
 
4504
{
 
4505
    STATS_INC( SHD_so_cpnoise1 );
 
4506
 
 
4507
    INIT_SO
 
4508
 
 
4509
    CHECKVARY( v )
 
4510
    CHECKVARY( period )
 
4511
    CHECKVARY( Result )
 
4512
 
 
4513
    BEGIN_VARYING_SECTION
 
4514
    GETFLOAT( v );
 
4515
    GETFLOAT( period );
 
4516
    SETCOLOR( Result, ( m_noise.CGNoise1( fmod( FLOAT( v ), FLOAT( period ) ) ) + 1 ) / 2.0f );
 
4517
    END_VARYING_SECTION
 
4518
}
 
4519
 
 
4520
//----------------------------------------------------------------------
 
4521
// pnoise(u,v,uperiod,vperiod)
 
4522
STD_SOIMPL CqShaderExecEnv::SO_cpnoise2( FLOATVAL u, FLOATVAL v, FLOATVAL uperiod, FLOATVAL vperiod, DEFPARAMIMPL )
 
4523
{
 
4524
    STATS_INC( SHD_so_cpnoise2 );
 
4525
 
 
4526
    INIT_SO
 
4527
 
 
4528
    CHECKVARY( u )
 
4529
    CHECKVARY( uperiod )
 
4530
    CHECKVARY( v )
 
4531
    CHECKVARY( vperiod )
 
4532
    CHECKVARY( Result )
 
4533
 
 
4534
    BEGIN_VARYING_SECTION
 
4535
    GETFLOAT( u );
 
4536
    GETFLOAT( v );
 
4537
    GETFLOAT( uperiod );
 
4538
    GETFLOAT( vperiod );
 
4539
    SETCOLOR( Result, ( m_noise.CGNoise2( fmod( FLOAT( u ), FLOAT( uperiod ) ),
 
4540
                                          fmod( FLOAT( v ), FLOAT( vperiod ) ) ) + 1 ) / 2.0f );
 
4541
    END_VARYING_SECTION
 
4542
}
 
4543
 
 
4544
//----------------------------------------------------------------------
 
4545
// pnoise(p,pperiod)
 
4546
STD_SOIMPL CqShaderExecEnv::SO_cpnoise3( POINTVAL p, POINTVAL pperiod, DEFPARAMIMPL )
 
4547
{
 
4548
    STATS_INC( SHD_so_cpnoise3 );
 
4549
 
 
4550
    INIT_SO
 
4551
 
 
4552
    CHECKVARY( p )
 
4553
    CHECKVARY( pperiod )
 
4554
    CHECKVARY( Result )
 
4555
 
 
4556
    BEGIN_VARYING_SECTION
 
4557
    GETPOINT( p );
 
4558
    GETPOINT( pperiod );
 
4559
    SETCOLOR( Result, ( m_noise.CGNoise3( CqVector3D( fmod( POINT( p ).x(), POINT( pperiod ).x() ),
 
4560
                                          fmod( POINT( p ).y(), POINT( pperiod ).y() ),
 
4561
                                          fmod( POINT( p ).z(), POINT( pperiod ).z() ) ) ) + 1 ) / 2.0f );
 
4562
    END_VARYING_SECTION
 
4563
}
 
4564
 
 
4565
//----------------------------------------------------------------------
 
4566
// pnoise(p,t,pperiod,tperiod)
 
4567
STD_SOIMPL CqShaderExecEnv::SO_cpnoise4( POINTVAL p, FLOATVAL t, POINTVAL pperiod, FLOATVAL tperiod, DEFPARAMIMPL )
 
4568
{
 
4569
    STATS_INC( SHD_so_cpnoise4 );
 
4570
 
 
4571
    INIT_SO
 
4572
 
 
4573
    CHECKVARY( p )
 
4574
    CHECKVARY( pperiod )
 
4575
    CHECKVARY( t )
 
4576
    CHECKVARY( tperiod )
 
4577
    CHECKVARY( Result )
 
4578
 
 
4579
    BEGIN_VARYING_SECTION
 
4580
    GETPOINT( p );
 
4581
    GETFLOAT( t );
 
4582
    GETPOINT( pperiod );
 
4583
    GETFLOAT( tperiod );
 
4584
    SETCOLOR( Result, ( m_noise.CGNoise3( CqVector3D( fmod( POINT( p ).x(), POINT( pperiod ).x() ),
 
4585
                                          fmod( POINT( p ).y(), POINT( pperiod ).y() ),
 
4586
                                          fmod( POINT( p ).z(), POINT( pperiod ).z() ) ) ) + 1 ) / 2.0f );
 
4587
    END_VARYING_SECTION
 
4588
}
 
4589
 
 
4590
//----------------------------------------------------------------------
 
4591
// pnoise(u,period)
 
4592
STD_SOIMPL CqShaderExecEnv::SO_ppnoise1( FLOATVAL v, FLOATVAL period, DEFPARAMIMPL )
 
4593
{
 
4594
    STATS_INC( SHD_so_ppnoise1 );
 
4595
 
 
4596
    INIT_SO
 
4597
 
 
4598
    CHECKVARY( v )
 
4599
    CHECKVARY( period )
 
4600
    CHECKVARY( Result )
 
4601
 
 
4602
    BEGIN_VARYING_SECTION
 
4603
    GETFLOAT( v );
 
4604
    GETFLOAT( period );
 
4605
    SETPOINT( Result, ( m_noise.PGNoise1( fmod( FLOAT( v ), FLOAT( period ) ) ) + 1 ) / 2.0f );
 
4606
    END_VARYING_SECTION
 
4607
}
 
4608
 
 
4609
//----------------------------------------------------------------------
 
4610
// pnoise(u,v,uperiod,vperiod)
 
4611
STD_SOIMPL CqShaderExecEnv::SO_ppnoise2( FLOATVAL u, FLOATVAL v, FLOATVAL uperiod, FLOATVAL vperiod, DEFPARAMIMPL )
 
4612
{
 
4613
    STATS_INC( SHD_so_ppnoise2 );
 
4614
 
 
4615
    INIT_SO
 
4616
 
 
4617
    CHECKVARY( u )
 
4618
    CHECKVARY( uperiod )
 
4619
    CHECKVARY( v )
 
4620
    CHECKVARY( vperiod )
 
4621
    CHECKVARY( Result )
 
4622
 
 
4623
    BEGIN_VARYING_SECTION
 
4624
    GETFLOAT( u );
 
4625
    GETFLOAT( v );
 
4626
    GETFLOAT( uperiod );
 
4627
    GETFLOAT( vperiod );
 
4628
    SETPOINT( Result, ( m_noise.PGNoise2( fmod( FLOAT( u ), FLOAT( uperiod ) ),
 
4629
                                          fmod( FLOAT( v ), FLOAT( vperiod ) ) ) + 1 ) / 2.0f );
 
4630
    END_VARYING_SECTION
 
4631
}
 
4632
 
 
4633
//----------------------------------------------------------------------
 
4634
// pnoise(p,pperiod)
 
4635
STD_SOIMPL CqShaderExecEnv::SO_ppnoise3( POINTVAL p, POINTVAL pperiod, DEFPARAMIMPL )
 
4636
{
 
4637
    STATS_INC( SHD_so_ppnoise3 );
 
4638
 
 
4639
    INIT_SO
 
4640
 
 
4641
    CHECKVARY( p )
 
4642
    CHECKVARY( pperiod )
 
4643
    CHECKVARY( Result )
 
4644
 
 
4645
    BEGIN_VARYING_SECTION
 
4646
    GETPOINT( p );
 
4647
    GETPOINT( pperiod );
 
4648
    SETPOINT( Result, ( m_noise.PGNoise3( CqVector3D( fmod( POINT( p ).x(), POINT( pperiod ).x() ),
 
4649
                                          fmod( POINT( p ).y(), POINT( pperiod ).y() ),
 
4650
                                          fmod( POINT( p ).z(), POINT( pperiod ).z() ) ) ) + 1 ) / 2.0f );
 
4651
    END_VARYING_SECTION
 
4652
}
 
4653
 
 
4654
//----------------------------------------------------------------------
 
4655
// pnoise(p,t,pperiod,tperiod)
 
4656
STD_SOIMPL CqShaderExecEnv::SO_ppnoise4( POINTVAL p, FLOATVAL t, POINTVAL pperiod, FLOATVAL tperiod, DEFPARAMIMPL )
 
4657
{
 
4658
    STATS_INC( SHD_so_ppnoise4 );
 
4659
 
 
4660
    INIT_SO
 
4661
 
 
4662
    CHECKVARY( p )
 
4663
    CHECKVARY( pperiod )
 
4664
    CHECKVARY( t )
 
4665
    CHECKVARY( tperiod )
 
4666
    CHECKVARY( Result )
 
4667
 
 
4668
    BEGIN_VARYING_SECTION
 
4669
    GETPOINT( p );
 
4670
    GETFLOAT( t );
 
4671
    GETPOINT( pperiod );
 
4672
    GETFLOAT( tperiod );
 
4673
    SETPOINT( Result, ( m_noise.PGNoise3( CqVector3D( fmod( POINT( p ).x(), POINT( pperiod ).x() ),
 
4674
                                          fmod( POINT( p ).y(), POINT( pperiod ).y() ),
 
4675
                                          fmod( POINT( p ).z(), POINT( pperiod ).z() ) ) ) + 1 ) / 2.0f );
 
4676
    END_VARYING_SECTION
 
4677
}
 
4678
 
 
4679
 
 
4680
//----------------------------------------------------------------------
 
4681
// rotate(Q,angle,P0,P1)
 
4682
STD_SOIMPL CqShaderExecEnv::SO_rotate( VECTORVAL Q, FLOATVAL angle, POINTVAL P0, POINTVAL P1, DEFPARAMIMPL )
 
4683
{
 
4684
    STATS_INC( SHD_so_rotate );
 
4685
 
 
4686
    INIT_SO
 
4687
 
 
4688
    CHECKVARY( Q )
 
4689
    CHECKVARY( angle )
 
4690
    CHECKVARY( P0 )
 
4691
    CHECKVARY( P1 )
 
4692
    CHECKVARY( Result )
 
4693
 
 
4694
    BEGIN_VARYING_SECTION
 
4695
    GETFLOAT( angle );
 
4696
    GETVECTOR( Q );
 
4697
    GETPOINT( P0 );
 
4698
    GETPOINT( P1 );
 
4699
    CqMatrix matR( FLOAT( angle ), POINT( P1 ) - POINT( P0 ) );
 
4700
 
 
4701
    CqVector3D  Res( VECTOR( Q ) );
 
4702
    Res = matR * Res;
 
4703
 
 
4704
    SETPOINT( Result, Res );
 
4705
    END_VARYING_SECTION
 
4706
}
 
4707
 
 
4708
//----------------------------------------------------------------------
 
4709
// filterstep(edge,s1)
 
4710
STD_SOIMPL CqShaderExecEnv::SO_filterstep( FLOATVAL edge, FLOATVAL s1, DEFPARAMVARIMPL )
 
4711
{
 
4712
    STATS_INC( SHD_so_filterstep );
 
4713
 
 
4714
    TqFloat Deffloat = 0.0f;
 
4715
    INIT_SO
 
4716
 
 
4717
    GET_FILTER_PARAMS;
 
4718
 
 
4719
    CHECKVARY( edge )
 
4720
    CHECKVARY( s1 )
 
4721
    CHECKVARY( Result )
 
4722
 
 
4723
    BEGIN_UNIFORM_SECTION
 
4724
    TqFloat fdu, fdv;
 
4725
    du() ->GetFloat( fdu );
 
4726
    dv() ->GetFloat( fdv );
 
4727
    END_UNIFORM_SECTION
 
4728
 
 
4729
    BEGIN_VARYING_SECTION
 
4730
    GETFLOAT( s1 );
 
4731
    GETFLOAT( edge );
 
4732
    TqFloat dsdu = SO_DuType<TqFloat>( s1, __iGrid, this, Deffloat );
 
4733
    TqFloat dsdv = SO_DvType<TqFloat>( s1, __iGrid, this, Deffloat );
 
4734
 
 
4735
    TqFloat uwidth = fabs( dsdu * fdu );
 
4736
    TqFloat vwidth = fabs( dsdv * fdv );
 
4737
 
 
4738
    TqFloat w = uwidth + vwidth;
 
4739
    w *= _pswidth;
 
4740
 
 
4741
    SETFLOAT( Result, CLAMP( ( FLOAT( s1 ) + w / 2.0f - FLOAT( edge ) ) / w, 0, 1 ) );
 
4742
 
 
4743
    //  TqFloat res  = RiCatmullRomFilter( FLOAT( s1 ) - FLOAT( edge ), 0, w, 0);
 
4744
    //  SETFLOAT( Result, res );
 
4745
 
 
4746
    //  std::cout << res << std::endl;
 
4747
    //  TqFloat res = 1.0f - CLAMP( ( FLOAT( s1 ) + w / 2.0f - FLOAT( edge ) ) / w, 0, 1 );
 
4748
    //  if( res > 0.0f )
 
4749
    //          std::cout << "Aqsis angle/dangle: " << FLOAT(s1) << ", edge: " << FLOAT(edge) << ", dsdu: " << dsdu << ", dsdv: " << dsdv << ", w: " << w << ", res: " << res << std::endl;
 
4750
    END_VARYING_SECTION
 
4751
}
 
4752
 
 
4753
//----------------------------------------------------------------------
 
4754
// filterstep(edge,s1,s2)
 
4755
STD_SOIMPL CqShaderExecEnv::SO_filterstep2( FLOATVAL edge, FLOATVAL s1, FLOATVAL s2, DEFPARAMVARIMPL )
 
4756
{
 
4757
    STATS_INC( SHD_so_filterstep2 );
 
4758
 
 
4759
    GET_FILTER_PARAMS;
 
4760
 
 
4761
    INIT_SO
 
4762
 
 
4763
    CHECKVARY( edge )
 
4764
    CHECKVARY( s1 )
 
4765
    CHECKVARY( s2 )
 
4766
    CHECKVARY( Result )
 
4767
 
 
4768
    BEGIN_VARYING_SECTION
 
4769
    GETFLOAT( edge );
 
4770
    GETFLOAT( s1 );
 
4771
    GETFLOAT( s2 );
 
4772
    TqFloat w = FLOAT( s2 ) - FLOAT( s1 );
 
4773
    w *= _pswidth;
 
4774
    SETFLOAT( Result, CLAMP( ( FLOAT( s1 ) + w / 2.0f - FLOAT( edge ) ) / w, 0, 1 ) );
 
4775
    END_VARYING_SECTION
 
4776
}
 
4777
 
 
4778
//----------------------------------------------------------------------
 
4779
// specularbrdf(L,N,V,rough)
 
4780
STD_SOIMPL CqShaderExecEnv::SO_specularbrdf( VECTORVAL L, NORMALVAL N, VECTORVAL V, FLOATVAL rough, DEFPARAMIMPL )
 
4781
{
 
4782
    STATS_INC( SHD_so_specularbrdf );
 
4783
 
 
4784
    INIT_SO
 
4785
 
 
4786
    CHECKVARY( L )
 
4787
    CHECKVARY( N )
 
4788
    CHECKVARY( V )
 
4789
    CHECKVARY( rough )
 
4790
    CHECKVARY( Result )
 
4791
 
 
4792
    BEGIN_VARYING_SECTION
 
4793
    GETVECTOR( L );
 
4794
    GETVECTOR( V );
 
4795
    VECTOR( L ).Unit();
 
4796
 
 
4797
    CqVector3D  H = VECTOR( L ) + VECTOR( V );
 
4798
    H.Unit();
 
4799
    /// \note The (roughness/8) term emulates the BMRT behaviour for prmanspecular.
 
4800
    GETNORMAL( N );
 
4801
    GETFLOAT( rough );
 
4802
    CqColor colCl;
 
4803
    Cl() ->GetColor( colCl, __iGrid );
 
4804
    SETCOLOR( Result, colCl * pow( MAX( 0.0f, NORMAL( N ) * H ), 1.0f / ( FLOAT( rough ) / 8.0f ) ) );
 
4805
    END_VARYING_SECTION
 
4806
}
 
4807
 
 
4808
 
 
4809
//----------------------------------------------------------------------
 
4810
// determinant(m)
 
4811
STD_SOIMPL CqShaderExecEnv::SO_determinant( MATRIXVAL M, DEFPARAMIMPL )
 
4812
{
 
4813
    STATS_INC( SHD_so_determinant );
 
4814
 
 
4815
    INIT_SO
 
4816
 
 
4817
    CHECKVARY( M )
 
4818
    CHECKVARY( Result )
 
4819
 
 
4820
    BEGIN_VARYING_SECTION
 
4821
    GETMATRIX( M );
 
4822
    SETFLOAT( Result, MATRIX( M ).Determinant() );
 
4823
    END_VARYING_SECTION
 
4824
}
 
4825
 
 
4826
 
 
4827
//----------------------------------------------------------------------
 
4828
// translate(m,v)
 
4829
STD_SOIMPL CqShaderExecEnv::SO_mtranslate( MATRIXVAL M, VECTORVAL V, DEFPARAMIMPL )
 
4830
{
 
4831
    STATS_INC( SHD_so_mtranslate );
 
4832
 
 
4833
    INIT_SO
 
4834
 
 
4835
    CHECKVARY( M )
 
4836
    CHECKVARY( V )
 
4837
    CHECKVARY( Result )
 
4838
 
 
4839
    BEGIN_VARYING_SECTION
 
4840
    GETMATRIX( M );
 
4841
    GETVECTOR( V );
 
4842
    MATRIX( M ).Translate( VECTOR( V ) );
 
4843
    SETMATRIX( Result, MATRIX( M ) );
 
4844
    END_VARYING_SECTION
 
4845
}
 
4846
 
 
4847
//----------------------------------------------------------------------
 
4848
// rotate(m,v)
 
4849
STD_SOIMPL CqShaderExecEnv::SO_mrotate( MATRIXVAL M, FLOATVAL angle, VECTORVAL axis, DEFPARAMIMPL )
 
4850
{
 
4851
    STATS_INC( SHD_so_mrotate );
 
4852
 
 
4853
    INIT_SO
 
4854
 
 
4855
    CHECKVARY( M )
 
4856
    CHECKVARY( angle )
 
4857
    CHECKVARY( axis )
 
4858
    CHECKVARY( Result )
 
4859
 
 
4860
    BEGIN_VARYING_SECTION
 
4861
    GETMATRIX( M );
 
4862
    GETFLOAT( angle );
 
4863
    GETVECTOR( axis );
 
4864
    MATRIX( M ).Rotate( FLOAT( angle ), VECTOR( axis ) );
 
4865
    SETMATRIX( Result, MATRIX( M ) );
 
4866
    END_VARYING_SECTION
 
4867
}
 
4868
 
 
4869
//----------------------------------------------------------------------
 
4870
// scale(m,p)
 
4871
STD_SOIMPL CqShaderExecEnv::SO_mscale( MATRIXVAL M, POINTVAL S, DEFPARAMIMPL )
 
4872
{
 
4873
    STATS_INC( SHD_so_mscale );
 
4874
 
 
4875
    INIT_SO
 
4876
 
 
4877
    CHECKVARY( M )
 
4878
    CHECKVARY( S )
 
4879
    CHECKVARY( Result )
 
4880
 
 
4881
    BEGIN_VARYING_SECTION
 
4882
    GETPOINT( S );
 
4883
    GETMATRIX( M );
 
4884
    MATRIX( M ).Scale( POINT( S ).x(), POINT( S ).y(), POINT( S ).z() );
 
4885
    SETMATRIX( Result, MATRIX( M ) );
 
4886
    END_VARYING_SECTION
 
4887
}
 
4888
 
 
4889
 
 
4890
//----------------------------------------------------------------------
 
4891
// setmcomp(p,v)
 
4892
STD_SOIMPL      CqShaderExecEnv::SO_setmcomp( MATRIXVAL M, FLOATVAL r, FLOATVAL c, FLOATVAL v, DEFVOIDPARAMIMPL )
 
4893
{
 
4894
    STATS_INC( SHD_so_setmcomp );
 
4895
 
 
4896
    INIT_SO
 
4897
 
 
4898
    CHECKVARY( M )
 
4899
    CHECKVARY( r )
 
4900
    CHECKVARY( c )
 
4901
    CHECKVARY( v )
 
4902
 
 
4903
    BEGIN_VARYING_SECTION
 
4904
    GETMATRIX( M );
 
4905
    GETFLOAT( r );
 
4906
    GETFLOAT( c );
 
4907
    GETFLOAT( v );
 
4908
    MATRIX( M ) [ static_cast<TqInt>( FLOAT( r ) ) ][ static_cast<TqInt>( FLOAT( c ) ) ] = FLOAT( v );
 
4909
    MATRIX( M ).SetfIdentity( TqFalse );
 
4910
    M->SetValue( MATRIX( M ), __iGrid );
 
4911
    END_VARYING_SECTION
 
4912
}
 
4913
 
 
4914
 
 
4915
//----------------------------------------------------------------------
 
4916
// spline(value, f1,f2,...,fn)
 
4917
STD_SOIMPL      CqShaderExecEnv::SO_fsplinea( FLOATVAL value, FLOATARRAYVAL a, DEFPARAMIMPL )
 
4918
{
 
4919
    STATS_INC( SHD_so_fsplinea );
 
4920
 
 
4921
    INIT_SO
 
4922
 
 
4923
    assert( a->ArrayLength() > 0 );
 
4924
    assert( a->Type() == type_float );
 
4925
 
 
4926
    TqInt       cParams = a->ArrayLength();
 
4927
    CqSplineCubic spline( cParams );
 
4928
 
 
4929
    CHECKVARY( value )
 
4930
    CHECKVARY( a )
 
4931
    CHECKVARY( Result )
 
4932
 
 
4933
    BEGIN_VARYING_SECTION
 
4934
    GETFLOAT( value );
 
4935
 
 
4936
    TqFloat fTemp;
 
4937
    if ( FLOAT( value ) >= 1.0f )
 
4938
    {
 
4939
        a->ArrayEntry( cParams - 2 ) ->GetFloat( fTemp, __iGrid );
 
4940
        Result->SetFloat( fTemp, __iGrid );
 
4941
    }
 
4942
    else if ( FLOAT( value ) <= 0.0f )
 
4943
    {
 
4944
        a->ArrayEntry( 1 ) ->GetFloat( fTemp, __iGrid );
 
4945
        Result->SetFloat( fTemp, __iGrid );
 
4946
    }
 
4947
    else
 
4948
    {
 
4949
        TqInt j;
 
4950
        for ( j = 0; j < cParams; j++ )
 
4951
        {
 
4952
            a->ArrayEntry( j ) ->GetFloat( fTemp, __iGrid );
 
4953
            spline[ j ] = CqVector4D( fTemp, 0.0f, 0.0f, 1.0f );
 
4954
        }
 
4955
 
 
4956
        CqVector4D      res = spline.Evaluate( FLOAT( value ) );
 
4957
        SETFLOAT( Result, res.x() );
 
4958
    }
 
4959
    END_VARYING_SECTION
 
4960
}
 
4961
 
 
4962
 
 
4963
//----------------------------------------------------------------------
 
4964
// spline(value, f1,f2,...,fn)
 
4965
STD_SOIMPL      CqShaderExecEnv::SO_csplinea( FLOATVAL value, COLORARRAYVAL a, DEFPARAMIMPL )
 
4966
{
 
4967
    STATS_INC( SHD_so_csplinea );
 
4968
 
 
4969
    INIT_SO
 
4970
 
 
4971
    assert( a->ArrayLength() > 0 );
 
4972
    assert( a->Type() == type_color );
 
4973
 
 
4974
    TqInt       cParams = a->ArrayLength();
 
4975
    CqSplineCubic spline( cParams );
 
4976
    CqColor colTemp;
 
4977
 
 
4978
    CHECKVARY( value )
 
4979
    CHECKVARY( a )
 
4980
    CHECKVARY( Result )
 
4981
 
 
4982
    BEGIN_VARYING_SECTION
 
4983
    GETFLOAT( value );
 
4984
 
 
4985
    CqColor cTemp;
 
4986
    if ( FLOAT( value ) >= 1.0f )
 
4987
    {
 
4988
        a->ArrayEntry( cParams - 2 ) ->GetColor( colTemp, __iGrid );
 
4989
        Result->SetColor( colTemp, __iGrid );
 
4990
    }
 
4991
    else if ( FLOAT( value ) <= 0.0f )
 
4992
    {
 
4993
        a->ArrayEntry( 1 ) ->GetColor( colTemp, __iGrid );
 
4994
        Result->SetColor( colTemp, __iGrid );
 
4995
    }
 
4996
    else
 
4997
    {
 
4998
        TqInt j;
 
4999
        for ( j = 0; j < cParams; j++ )
 
5000
        {
 
5001
            a->ArrayEntry( j ) ->GetColor( colTemp, __iGrid );
 
5002
            spline[ j ] = CqVector4D( colTemp.fRed(), colTemp.fGreen(), colTemp.fBlue(), 1.0f );
 
5003
        }
 
5004
 
 
5005
        CqVector4D      res = spline.Evaluate( FLOAT( value ) );
 
5006
        SETCOLOR( Result, CqColor( res.x(), res.y(), res.z() ) );
 
5007
    }
 
5008
    END_VARYING_SECTION
 
5009
}
 
5010
 
 
5011
 
 
5012
//----------------------------------------------------------------------
 
5013
// spline(value, f1,f2,...,fn)
 
5014
STD_SOIMPL      CqShaderExecEnv::SO_psplinea( FLOATVAL value, POINTARRAYVAL a, DEFPARAMIMPL )
 
5015
{
 
5016
    STATS_INC( SHD_so_psplinea );
 
5017
 
 
5018
    INIT_SO
 
5019
 
 
5020
    assert( a->ArrayLength() > 0 );
 
5021
    assert( a->Type() == type_point );
 
5022
 
 
5023
    TqInt       cParams = a->ArrayLength();
 
5024
    CqSplineCubic spline( cParams );
 
5025
    CqVector3D vecTemp;
 
5026
 
 
5027
    CHECKVARY( value )
 
5028
    CHECKVARY( a )
 
5029
    CHECKVARY( Result )
 
5030
 
 
5031
    BEGIN_VARYING_SECTION
 
5032
    GETFLOAT( value );
 
5033
 
 
5034
    CqVector3D vecTemp;
 
5035
    if ( FLOAT( value ) >= 1.0f )
 
5036
    {
 
5037
        a->ArrayEntry( cParams - 2 ) ->GetPoint( vecTemp, __iGrid );
 
5038
        Result->SetPoint( vecTemp, __iGrid );
 
5039
    }
 
5040
    else if ( FLOAT( value ) <= 0.0f )
 
5041
    {
 
5042
        a->ArrayEntry( 1 ) ->GetPoint( vecTemp, __iGrid );
 
5043
        Result->SetPoint( vecTemp, __iGrid );
 
5044
    }
 
5045
    else
 
5046
    {
 
5047
        TqInt j;
 
5048
        for ( j = 0; j < cParams; j++ )
 
5049
        {
 
5050
            a->ArrayEntry( j ) ->GetPoint( vecTemp, __iGrid );
 
5051
            spline[ j ] = vecTemp;
 
5052
        }
 
5053
 
 
5054
        CqVector3D      res = spline.Evaluate( FLOAT( value ) );
 
5055
        SETPOINT( Result, res );
 
5056
    }
 
5057
    END_VARYING_SECTION
 
5058
}
 
5059
 
 
5060
 
 
5061
//----------------------------------------------------------------------
 
5062
// spline(value, f1,f2,...,fn)
 
5063
STD_SOIMPL      CqShaderExecEnv::SO_sfsplinea( STRINGVAL basis, FLOATVAL value, FLOATARRAYVAL a, DEFPARAMIMPL )
 
5064
{
 
5065
    STATS_INC( SHD_so_sfsplinea );
 
5066
 
 
5067
    INIT_SO
 
5068
 
 
5069
    assert( a->ArrayLength() > 0 );
 
5070
    assert( a->Type() == type_float );
 
5071
 
 
5072
    TqInt       cParams = a->ArrayLength();
 
5073
    CqSplineCubic spline( cParams );
 
5074
 
 
5075
    CHECKVARY( value )
 
5076
    CHECKVARY( a )
 
5077
    CHECKVARY( Result )
 
5078
 
 
5079
    BEGIN_UNIFORM_SECTION
 
5080
    GETSTRING( basis );
 
5081
    spline.SetmatBasis( STRING( basis ) );
 
5082
    END_UNIFORM_SECTION
 
5083
 
 
5084
    BEGIN_VARYING_SECTION
 
5085
    GETFLOAT( value );
 
5086
 
 
5087
    TqFloat fTemp;
 
5088
    if ( FLOAT( value ) >= 1.0f )
 
5089
    {
 
5090
        a->ArrayEntry( cParams - 2 ) ->GetFloat( fTemp, __iGrid );
 
5091
        Result->SetFloat( fTemp, __iGrid );
 
5092
    }
 
5093
    else if ( FLOAT( value ) <= 0.0f )
 
5094
    {
 
5095
        a->ArrayEntry( 1 ) ->GetFloat( fTemp, __iGrid );
 
5096
        Result->SetFloat( fTemp, __iGrid );
 
5097
    }
 
5098
    else
 
5099
    {
 
5100
        TqInt j;
 
5101
        for ( j = 0; j < cParams; j++ )
 
5102
        {
 
5103
            a->ArrayEntry( j ) ->GetFloat( fTemp, __iGrid );
 
5104
            spline[ j ] = CqVector4D( fTemp, 0.0f, 0.0f, 1.0f );
 
5105
        }
 
5106
 
 
5107
        CqVector4D      res = spline.Evaluate( FLOAT( value ) );
 
5108
        SETFLOAT( Result, res.x() );
 
5109
    }
 
5110
    END_VARYING_SECTION
 
5111
}
 
5112
 
 
5113
 
 
5114
//----------------------------------------------------------------------
 
5115
// spline(value, f1,f2,...,fn)
 
5116
STD_SOIMPL      CqShaderExecEnv::SO_scsplinea( STRINGVAL basis, FLOATVAL value, COLORARRAYVAL a, DEFPARAMIMPL )
 
5117
{
 
5118
    STATS_INC( SHD_so_scsplinea );
 
5119
 
 
5120
    INIT_SO
 
5121
 
 
5122
    assert( a->ArrayLength() > 0 );
 
5123
    assert( a->Type() == type_color );
 
5124
 
 
5125
    TqInt       cParams = a->ArrayLength();
 
5126
    CqSplineCubic spline( cParams );
 
5127
    CqColor colTemp;
 
5128
 
 
5129
    CHECKVARY( value )
 
5130
    CHECKVARY( a )
 
5131
    CHECKVARY( Result )
 
5132
 
 
5133
    BEGIN_UNIFORM_SECTION
 
5134
    GETSTRING( basis );
 
5135
    spline.SetmatBasis( STRING( basis ) );
 
5136
    END_UNIFORM_SECTION
 
5137
 
 
5138
    BEGIN_VARYING_SECTION
 
5139
    GETFLOAT( value );
 
5140
 
 
5141
    CqColor colTemp;
 
5142
    if ( FLOAT( value ) >= 1.0f )
 
5143
    {
 
5144
        a->ArrayEntry( cParams - 2 ) ->GetColor( colTemp, __iGrid );
 
5145
        Result->SetColor( colTemp, __iGrid );
 
5146
    }
 
5147
    else if ( FLOAT( value ) <= 0.0f )
 
5148
    {
 
5149
        a->ArrayEntry( 1 ) ->GetColor( colTemp, __iGrid );
 
5150
        Result->SetColor( colTemp, __iGrid );
 
5151
    }
 
5152
    else
 
5153
    {
 
5154
        TqInt j;
 
5155
        for ( j = 0; j < cParams; j++ )
 
5156
        {
 
5157
            a->ArrayEntry( j ) ->GetColor( colTemp, __iGrid );
 
5158
            spline[ j ] = CqVector4D( colTemp.fRed(), colTemp.fGreen(), colTemp.fBlue(), 1.0f );
 
5159
        }
 
5160
 
 
5161
        CqVector4D      res = spline.Evaluate( FLOAT( value ) );
 
5162
        SETCOLOR( Result, CqColor( res.x(), res.y(), res.z() ) );
 
5163
    }
 
5164
    END_VARYING_SECTION
 
5165
}
 
5166
 
 
5167
 
 
5168
//----------------------------------------------------------------------
 
5169
// spline(value, f1,f2,...,fn)
 
5170
STD_SOIMPL      CqShaderExecEnv::SO_spsplinea( STRINGVAL basis, FLOATVAL value, POINTARRAYVAL a, DEFPARAMIMPL )
 
5171
{
 
5172
    STATS_INC( SHD_so_spsplinea );
 
5173
 
 
5174
    INIT_SO
 
5175
 
 
5176
    assert( a->ArrayLength() > 0 );
 
5177
    assert( a->Type() == type_point );
 
5178
 
 
5179
    TqInt       cParams = a->ArrayLength();
 
5180
    CqSplineCubic spline( cParams );
 
5181
    CqVector3D vecTemp;
 
5182
 
 
5183
    CHECKVARY( value )
 
5184
    CHECKVARY( a )
 
5185
    CHECKVARY( Result )
 
5186
 
 
5187
    BEGIN_UNIFORM_SECTION
 
5188
    GETSTRING( basis );
 
5189
    spline.SetmatBasis( STRING( basis ) );
 
5190
    END_UNIFORM_SECTION
 
5191
 
 
5192
    BEGIN_VARYING_SECTION
 
5193
    GETFLOAT( value );
 
5194
 
 
5195
    CqVector3D vecTemp;
 
5196
    if ( FLOAT( value ) >= 1.0f )
 
5197
    {
 
5198
        a->ArrayEntry( cParams - 2 ) ->GetPoint( vecTemp, __iGrid );
 
5199
        Result->SetPoint( vecTemp, __iGrid );
 
5200
    }
 
5201
    else if ( FLOAT( value ) <= 0.0f )
 
5202
    {
 
5203
        a->ArrayEntry( 1 ) ->GetPoint( vecTemp, __iGrid );
 
5204
        Result->SetPoint( vecTemp, __iGrid );
 
5205
    }
 
5206
    else
 
5207
    {
 
5208
        TqInt j;
 
5209
        for ( j = 0; j < cParams; j++ )
 
5210
        {
 
5211
            a->ArrayEntry( j ) ->GetPoint( vecTemp, __iGrid );
 
5212
            spline[ j ] = vecTemp;
 
5213
        }
 
5214
 
 
5215
        CqVector3D      res = spline.Evaluate( FLOAT( value ) );
 
5216
        SETPOINT( Result, res );
 
5217
    }
 
5218
    END_VARYING_SECTION
 
5219
}
 
5220
 
 
5221
 
 
5222
//----------------------------------------------------------------------
 
5223
// shadername()
 
5224
STD_SOIMPL      CqShaderExecEnv::SO_shadername( DEFPARAMIMPL )
 
5225
{
 
5226
    STATS_INC( SHD_so_shadername );
 
5227
 
 
5228
    INIT_SO
 
5229
 
 
5230
    CHECKVARY( Result )
 
5231
 
 
5232
    BEGIN_VARYING_SECTION
 
5233
    SETSTRING( Result, pShader->strName() );
 
5234
    END_VARYING_SECTION
 
5235
}
 
5236
 
 
5237
 
 
5238
//----------------------------------------------------------------------
 
5239
// shadername(s)
 
5240
STD_SOIMPL      CqShaderExecEnv::SO_shadername2( STRINGVAL shader, DEFPARAMIMPL )
 
5241
{
 
5242
    STATS_INC( SHD_so_shadername2 );
 
5243
 
 
5244
    INIT_SO
 
5245
 
 
5246
    CqString strName( "" );
 
5247
    CqString strShader;
 
5248
        IqShader* pSurface = 0;
 
5249
        IqShader* pDisplacement = 0;
 
5250
        IqShader* pAtmosphere = 0;
 
5251
    if( m_pAttributes )
 
5252
        {
 
5253
                pSurface = m_pAttributes ->pshadSurface(QGetRenderContextI()->Time());
 
5254
                pDisplacement = m_pAttributes ->pshadDisplacement(QGetRenderContextI()->Time());
 
5255
                pAtmosphere = m_pAttributes ->pshadAtmosphere(QGetRenderContextI()->Time());
 
5256
        }
 
5257
 
 
5258
    CHECKVARY( Result )
 
5259
 
 
5260
    BEGIN_VARYING_SECTION
 
5261
    strName = "";
 
5262
    GETSTRING( shader );
 
5263
    if ( STRING( shader ).compare( "surface" ) == 0 && pSurface != 0 ) strName = pSurface->strName();
 
5264
    else if ( STRING( shader ).compare( "displacement" ) == 0 && pDisplacement != 0 ) strName = pDisplacement->strName();
 
5265
    else if ( STRING( shader ).compare( "atmosphere" ) == 0 && pAtmosphere != 0 ) strName = pAtmosphere->strName();
 
5266
    SETSTRING( Result, strName );
 
5267
    END_VARYING_SECTION
 
5268
}
 
5269
 
 
5270
 
 
5271
//----------------------------------------------------------------------
 
5272
// textureinfo
 
5273
// support resolution, type, channels, projectionmatrix(*) and viewingmatrix(*)
 
5274
// User has to provide an array of TqFloat (2) for resolution
 
5275
//                     an string for type
 
5276
//                     an integer for channels
 
5277
//                     an array of floats (16) for both projectionmatrix and viewingmatrix
 
5278
//                     (*) the name must be a shadow map
 
5279
//
 
5280
 
 
5281
STD_SOIMPL CqShaderExecEnv::SO_textureinfo( STRINGVAL name, STRINGVAL dataname, IqShaderData* pV, DEFPARAMIMPL )
 
5282
{
 
5283
    STATS_INC( SHD_so_textureinfo );
 
5284
 
 
5285
    INIT_SO
 
5286
 
 
5287
    if ( NULL == QGetRenderContextI() )
 
5288
        return ;
 
5289
 
 
5290
    TqFloat Ret = 0.0f;
 
5291
    IqTextureMap* pMap = NULL;
 
5292
    IqTextureMap *pSMap = NULL;
 
5293
    IqTextureMap *pLMap = NULL;
 
5294
    IqTextureMap *pEMap = NULL;
 
5295
    IqTextureMap *pTMap = NULL;
 
5296
 
 
5297
    BEGIN_UNIFORM_SECTION
 
5298
    GETSTRING( name );
 
5299
    GETSTRING( dataname );
 
5300
 
 
5301
    if ( !pMap && strstr( STRING( name ).c_str(), ".tif" ) )
 
5302
    {
 
5303
        pTMap = QGetRenderContextI() ->GetTextureMap( STRING( name ) );
 
5304
        if ( pTMap && ( pTMap->Type() == MapType_Texture ) )
 
5305
        {
 
5306
            pMap = pTMap;
 
5307
        }
 
5308
        else if ( pTMap ) delete pTMap;
 
5309
    }
 
5310
    if ( !pMap )
 
5311
    {
 
5312
        pSMap = QGetRenderContextI() ->GetShadowMap( STRING( name ) );
 
5313
        if ( pSMap && ( pSMap->Type() == MapType_Shadow ) )
 
5314
        {
 
5315
            pMap = pSMap;
 
5316
        }
 
5317
        else if ( pSMap ) delete pSMap;
 
5318
    }
 
5319
 
 
5320
    if ( !pMap )
 
5321
    {
 
5322
        pEMap = QGetRenderContextI() ->GetEnvironmentMap( STRING( name ) );
 
5323
        if ( pEMap && ( pEMap->Type() == MapType_Environment ) )
 
5324
        {
 
5325
            pMap = pEMap;
 
5326
        }
 
5327
        else if ( pEMap ) delete pEMap;
 
5328
    }
 
5329
 
 
5330
    if ( !pMap )
 
5331
    {
 
5332
        pTMap = QGetRenderContextI() ->GetTextureMap( STRING( name ) );
 
5333
        if ( pTMap && ( pTMap->Type() == MapType_Texture ) )
 
5334
        {
 
5335
            pMap = pTMap;
 
5336
        }
 
5337
        else if ( pTMap ) delete pTMap;
 
5338
    }
 
5339
 
 
5340
 
 
5341
    if ( pMap == 0 ) return ;
 
5342
 
 
5343
    if ( STRING( dataname ).compare( "resolution" ) == 0 )
 
5344
    {
 
5345
        if ( pV->Type() == type_float &&
 
5346
                pV->ArrayLength() > 0 )
 
5347
        {
 
5348
 
 
5349
            if ( pV->ArrayLength() == 2 )
 
5350
            {
 
5351
                pV->ArrayEntry( 0 ) ->SetFloat( static_cast<TqFloat>( pMap->XRes() ) );
 
5352
                pV->ArrayEntry( 1 ) ->SetFloat( static_cast<TqFloat>( pMap->YRes() ) );
 
5353
                Ret = 1.0f;
 
5354
 
 
5355
            }
 
5356
        }
 
5357
    }
 
5358
    if ( STRING( dataname ).compare( "type" ) == 0 )
 
5359
    {
 
5360
        if ( pV->Type() == type_string )
 
5361
        {
 
5362
            if ( pMap->Type() == MapType_Texture )
 
5363
            {
 
5364
                pV->SetString( "texture" );
 
5365
                Ret = 1.0f;
 
5366
 
 
5367
            }
 
5368
            if ( pMap->Type() == MapType_Bump )
 
5369
            {
 
5370
                pV->SetString( "bump" );
 
5371
                Ret = 1.0f;
 
5372
 
 
5373
            }
 
5374
 
 
5375
            if ( pMap->Type() == MapType_Shadow )
 
5376
            {
 
5377
                pV->SetString( "shadow" );
 
5378
                Ret = 1.0f;
 
5379
 
 
5380
            }
 
5381
            if ( pMap->Type() == MapType_Environment )
 
5382
            {
 
5383
                pV->SetString( "environment" );
 
5384
                Ret = 1.0f;
 
5385
 
 
5386
            }
 
5387
            if ( pMap->Type() == MapType_LatLong )
 
5388
            {
 
5389
                // both latlong/cube respond the same way according to BMRT
 
5390
                // It makes sense since both use environment() shader fct.
 
5391
                pV->SetString( "environment" );
 
5392
                Ret = 1.0f;
 
5393
 
 
5394
            }
 
5395
 
 
5396
 
 
5397
        }
 
5398
    }
 
5399
 
 
5400
    if ( STRING( dataname ).compare( "channels" ) == 0 )
 
5401
    {
 
5402
        if ( pV->Type() == type_float )
 
5403
        {
 
5404
            pV->SetFloat( static_cast<TqFloat>( pMap->SamplesPerPixel() ) );
 
5405
            Ret = 1.0f;
 
5406
        }
 
5407
 
 
5408
    }
 
5409
 
 
5410
    if ( STRING( dataname ).compare( "viewingmatrix" ) == 0 )
 
5411
    {
 
5412
        if ( ( ( pV->Type() == type_float ) && ( pV->ArrayLength() == 16 ) ) ||
 
5413
                ( pV->Type() == type_matrix ) )
 
5414
        {
 
5415
            if ( pSMap )   // && pSMap->Type() == MapType_Shadow)
 
5416
            {
 
5417
 
 
5418
                CqMatrix m = pSMap->GetMatrix( 0 );  /* WorldToCamera */
 
5419
                if ( pV->ArrayLength() == 16 )
 
5420
                {
 
5421
 
 
5422
                    pV->ArrayEntry( 0 ) ->SetFloat( static_cast<TqFloat>( m[ 0 ][ 0 ] ) );
 
5423
                    pV->ArrayEntry( 1 ) ->SetFloat( static_cast<TqFloat>( m[ 0 ][ 1 ] ) );
 
5424
                    pV->ArrayEntry( 2 ) ->SetFloat( static_cast<TqFloat>( m[ 0 ][ 2 ] ) );
 
5425
                    pV->ArrayEntry( 3 ) ->SetFloat( static_cast<TqFloat>( m[ 0 ][ 3 ] ) );
 
5426
                    pV->ArrayEntry( 4 ) ->SetFloat( static_cast<TqFloat>( m[ 1 ][ 0 ] ) );
 
5427
                    pV->ArrayEntry( 5 ) ->SetFloat( static_cast<TqFloat>( m[ 1 ][ 1 ] ) );
 
5428
                    pV->ArrayEntry( 6 ) ->SetFloat( static_cast<TqFloat>( m[ 1 ][ 2 ] ) );
 
5429
                    pV->ArrayEntry( 7 ) ->SetFloat( static_cast<TqFloat>( m[ 1 ][ 3 ] ) );
 
5430
                    pV->ArrayEntry( 8 ) ->SetFloat( static_cast<TqFloat>( m[ 2 ][ 0 ] ) );
 
5431
                    pV->ArrayEntry( 9 ) ->SetFloat( static_cast<TqFloat>( m[ 2 ][ 1 ] ) );
 
5432
                    pV->ArrayEntry( 10 ) ->SetFloat( static_cast<TqFloat>( m[ 2 ][ 2 ] ) );
 
5433
                    pV->ArrayEntry( 11 ) ->SetFloat( static_cast<TqFloat>( m[ 2 ][ 3 ] ) );
 
5434
                    pV->ArrayEntry( 12 ) ->SetFloat( static_cast<TqFloat>( m[ 3 ][ 0 ] ) );
 
5435
                    pV->ArrayEntry( 13 ) ->SetFloat( static_cast<TqFloat>( m[ 3 ][ 1 ] ) );
 
5436
                    pV->ArrayEntry( 14 ) ->SetFloat( static_cast<TqFloat>( m[ 3 ][ 2 ] ) );
 
5437
                    pV->ArrayEntry( 15 ) ->SetFloat( static_cast<TqFloat>( m[ 3 ][ 3 ] ) );
 
5438
 
 
5439
                }
 
5440
                else
 
5441
                {
 
5442
                    pV->SetMatrix( m, 0 );
 
5443
                }
 
5444
                Ret = 1.0f;
 
5445
 
 
5446
            }
 
5447
 
 
5448
        }
 
5449
    }
 
5450
 
 
5451
    if ( STRING( dataname ).compare( "projectionmatrix" ) == 0 )
 
5452
    {
 
5453
        if ( ( ( pV->Type() == type_float ) && ( pV->ArrayLength() == 16 ) ) ||
 
5454
                ( pV->Type() == type_matrix ) )
 
5455
        {
 
5456
            if ( pSMap )    // && pSMap->Type() == MapType_Shadow)
 
5457
            {
 
5458
 
 
5459
                CqMatrix m = pSMap->GetMatrix( 1 ); /* WorldToScreen */
 
5460
 
 
5461
                if ( pV->ArrayLength() == 16 )
 
5462
                {
 
5463
                    pV->ArrayEntry( 0 ) ->SetFloat( static_cast<TqFloat>( m[ 0 ][ 0 ] ) );
 
5464
                    pV->ArrayEntry( 1 ) ->SetFloat( static_cast<TqFloat>( m[ 0 ][ 1 ] ) );
 
5465
                    pV->ArrayEntry( 2 ) ->SetFloat( static_cast<TqFloat>( m[ 0 ][ 2 ] ) );
 
5466
                    pV->ArrayEntry( 3 ) ->SetFloat( static_cast<TqFloat>( m[ 0 ][ 3 ] ) );
 
5467
                    pV->ArrayEntry( 4 ) ->SetFloat( static_cast<TqFloat>( m[ 1 ][ 0 ] ) );
 
5468
                    pV->ArrayEntry( 5 ) ->SetFloat( static_cast<TqFloat>( m[ 1 ][ 1 ] ) );
 
5469
                    pV->ArrayEntry( 6 ) ->SetFloat( static_cast<TqFloat>( m[ 1 ][ 2 ] ) );
 
5470
                    pV->ArrayEntry( 7 ) ->SetFloat( static_cast<TqFloat>( m[ 1 ][ 3 ] ) );
 
5471
                    pV->ArrayEntry( 8 ) ->SetFloat( static_cast<TqFloat>( m[ 2 ][ 0 ] ) );
 
5472
                    pV->ArrayEntry( 9 ) ->SetFloat( static_cast<TqFloat>( m[ 2 ][ 1 ] ) );
 
5473
                    pV->ArrayEntry( 10 ) ->SetFloat( static_cast<TqFloat>( m[ 2 ][ 2 ] ) );
 
5474
                    pV->ArrayEntry( 11 ) ->SetFloat( static_cast<TqFloat>( m[ 2 ][ 3 ] ) );
 
5475
                    pV->ArrayEntry( 12 ) ->SetFloat( static_cast<TqFloat>( m[ 3 ][ 0 ] ) );
 
5476
                    pV->ArrayEntry( 13 ) ->SetFloat( static_cast<TqFloat>( m[ 3 ][ 1 ] ) );
 
5477
                    pV->ArrayEntry( 14 ) ->SetFloat( static_cast<TqFloat>( m[ 3 ][ 2 ] ) );
 
5478
                    pV->ArrayEntry( 15 ) ->SetFloat( static_cast<TqFloat>( m[ 3 ][ 3 ] ) );
 
5479
 
 
5480
 
 
5481
                }
 
5482
                else
 
5483
                {
 
5484
                    pV->SetMatrix( m, 0 );
 
5485
 
 
5486
                }
 
5487
                Ret = 1.0f;
 
5488
            }
 
5489
 
 
5490
        }
 
5491
    }
 
5492
 
 
5493
    delete pMap;
 
5494
 
 
5495
    SETFLOAT( Result, Ret );
 
5496
    END_UNIFORM_SECTION
 
5497
}
 
5498
 
 
5499
// SIGGRAPH 2002; Larry G. Bake functions
 
5500
 
 
5501
const int batchsize = 10240; // elements to buffer before writing
 
5502
// Make sure we're thread-safe on those file writes
 
5503
 
 
5504
class BakingChannel
 
5505
{
 
5506
    // A "BakingChannel" is the buffer for a single baking output file.
 
5507
    // We buffer up samples until "batchsize" has been accepted, then
 
5508
    // write them all at once. This keeps us from constantly accessing
 
5509
    // the disk. Note that we are careful to use a mutex to keep
 
5510
    // simultaneous multithreaded writes from clobbering each other.
 
5511
public:
 
5512
    // Constructors
 
5513
    BakingChannel ( void ) : buffered( 0 ), data( NULL ), filename( NULL )
 
5514
    { }
 
5515
    BakingChannel ( const char *_filename, int _elsize )
 
5516
    {
 
5517
        init ( _filename, _elsize );
 
5518
    }
 
5519
    // Initialize - allocate memory, etc.
 
5520
    void init ( const char *_filename, int _elsize )
 
5521
    {
 
5522
        elsize = _elsize + 2;
 
5523
        buffered = 0;
 
5524
        data = new float [ elsize * batchsize ];
 
5525
        filename = strdup ( _filename );
 
5526
    }
 
5527
    // Destructor: write buffered output, close file, deallocate
 
5528
    ~BakingChannel ()
 
5529
    {
 
5530
        writedata();
 
5531
        free ( filename );
 
5532
        delete [] data;
 
5533
    }
 
5534
    // Add one more data item
 
5535
    void moredata ( float s, float t, float *newdata )
 
5536
    {
 
5537
        if ( buffered >= batchsize )
 
5538
            writedata();
 
5539
        float *f = data + elsize * buffered;
 
5540
        f[ 0 ] = s;
 
5541
        f[ 1 ] = t;
 
5542
        for ( int j = 2; j < elsize; ++j )
 
5543
            f[ j ] = newdata[ j - 2 ];
 
5544
        ++buffered;
 
5545
    }
 
5546
private:
 
5547
    int elsize; // element size (e.g., 3 for colors)
 
5548
    int buffered; // how many elements are currently buffered
 
5549
    float *data; // pointer to the allocated buffer (new'ed)
 
5550
    char *filename; // pointer to filename (strdup'ed)
 
5551
    // Write any buffered data to the file
 
5552
    void writedata ( void )
 
5553
    {
 
5554
 
 
5555
        if ( buffered > 0 && filename != NULL )
 
5556
        {
 
5557
            FILE * file = fopen ( filename, "a" );
 
5558
            float *f = data;
 
5559
            for ( int i = 0; i < buffered; ++i, f += elsize )
 
5560
            {
 
5561
                for ( int j = 0; j < elsize; ++j )
 
5562
                    fprintf ( file, "%g ", f[ j ] );
 
5563
                fprintf ( file, "\n" );
 
5564
            }
 
5565
            fclose ( file );
 
5566
        }
 
5567
 
 
5568
        buffered = 0;
 
5569
    }
 
5570
};
 
5571
 
 
5572
typedef std::map<std::string, BakingChannel> BakingData;
 
5573
 
 
5574
 
 
5575
extern "C" BakingData *bake_init()
 
5576
{
 
5577
    BakingData * bd = new BakingData;
 
5578
 
 
5579
    return bd;
 
5580
}
 
5581
extern "C" void bake_done( BakingData *bd )
 
5582
{
 
5583
    delete bd; // Will destroy bd, and in turn all its BakingChannel's
 
5584
}
 
5585
// Workhorse routine -- look up the channel name, add a new BakingChannel
 
5586
// if it doesn't exist, add one point's data to the channel.
 
5587
extern "C" void bake ( BakingData *bd, const std::string &name,
 
5588
                           float s, float t, int elsize, float *data )
 
5589
{
 
5590
    BakingData::iterator found = bd->find ( name );
 
5591
 
 
5592
    if ( found == bd->end() )
 
5593
    {
 
5594
        // This named map doesn't yet exist
 
5595
        ( *bd ) [ name ] = BakingChannel();
 
5596
        found = bd->find ( name );
 
5597
        BakingChannel &bc = ( found->second );
 
5598
        bc.init ( name.c_str(), elsize );
 
5599
        bc.moredata ( s, t, data );
 
5600
    }
 
5601
    else
 
5602
    {
 
5603
        BakingChannel &bc = ( found->second );
 
5604
        bc.moredata ( s, t, data );
 
5605
    }
 
5606
}
 
5607
 
 
5608
extern "C" int bake_f( BakingData *bd, char *name, float s, float t, float f )
 
5609
{
 
5610
    float * bakedata = ( float * ) & f;
 
5611
 
 
5612
    bake ( bd, name, s, t, 1, bakedata );
 
5613
    return 0;
 
5614
}
 
5615
// for baking a triple -- just call bake with appropriate args
 
5616
extern "C" int bake_3( BakingData *bd, char *name, float s, float t, float *bakedata )
 
5617
{
 
5618
    bake ( bd, name, s, t, 3, bakedata );
 
5619
    return 0;
 
5620
}
 
5621
 
 
5622
 
 
5623
 
 
5624
STD_SOIMPL CqShaderExecEnv::SO_bake_f( STRINGVAL name, FLOATVAL s, FLOATVAL t, FLOATVAL f, DEFVOIDPARAMVARIMPL )
 
5625
{
 
5626
    STATS_INC( SHD_so_bake );
 
5627
 
 
5628
    INIT_SO
 
5629
 
 
5630
    CHECKVARY( f );
 
5631
    CHECKVARY( s );
 
5632
    CHECKVARY( t );
 
5633
 
 
5634
    BEGIN_UNIFORM_SECTION
 
5635
    GETSTRING( name );
 
5636
    BakingData *bd = bake_init(  /*STRING( name).c_str() */ );
 
5637
    END_UNIFORM_SECTION
 
5638
 
 
5639
    BEGIN_VARYING_SECTION
 
5640
    GETFLOAT( s );
 
5641
    GETFLOAT( t );
 
5642
    GETFLOAT( f );
 
5643
    bake_f( bd, ( char * ) STRING( name ).c_str(), FLOAT( s ), FLOAT( t ), FLOAT( f ) );
 
5644
    END_VARYING_SECTION
 
5645
 
 
5646
    BEGIN_UNIFORM_SECTION
 
5647
    bake_done( bd );
 
5648
    END_UNIFORM_SECTION
 
5649
}
 
5650
 
 
5651
STD_SOIMPL CqShaderExecEnv::SO_bake_3c( STRINGVAL name, FLOATVAL s, FLOATVAL t, COLORVAL f, DEFVOIDPARAMVARIMPL )
 
5652
{
 
5653
    STATS_INC( SHD_so_bake );
 
5654
 
 
5655
    INIT_SO
 
5656
 
 
5657
    CHECKVARY( f );
 
5658
    CHECKVARY( s );
 
5659
    CHECKVARY( t );
 
5660
 
 
5661
    BEGIN_UNIFORM_SECTION
 
5662
    TqFloat rgb[ 3 ];
 
5663
 
 
5664
    GETSTRING( name );
 
5665
    BakingData *bd = bake_init(  /*(char *) STRING( name ).c_str()*/ );
 
5666
    END_UNIFORM_SECTION
 
5667
    BEGIN_VARYING_SECTION
 
5668
    GETFLOAT( s );
 
5669
    GETFLOAT( t );
 
5670
    GETCOLOR( f );
 
5671
    COLOR( f ).GetColorRGB( &rgb[ 0 ], &rgb[ 1 ], &rgb[ 2 ] );
 
5672
    bake_3( bd, ( char * ) STRING( name ).c_str(), FLOAT( s ), FLOAT( t ), rgb );
 
5673
    END_VARYING_SECTION
 
5674
    BEGIN_UNIFORM_SECTION
 
5675
    bake_done( bd );
 
5676
    END_UNIFORM_SECTION
 
5677
}
 
5678
 
 
5679
STD_SOIMPL CqShaderExecEnv::SO_bake_3n( STRINGVAL name, FLOATVAL s, FLOATVAL t, NORMALVAL f, DEFVOIDPARAMVARIMPL )
 
5680
{
 
5681
    STATS_INC( SHD_so_bake );
 
5682
 
 
5683
    INIT_SO
 
5684
 
 
5685
    CHECKVARY( f );
 
5686
    CHECKVARY( s );
 
5687
    CHECKVARY( t );
 
5688
 
 
5689
    BEGIN_UNIFORM_SECTION
 
5690
    GETSTRING( name );
 
5691
    BakingData *bd = bake_init(  /*(char *) STRING( name ).c_str() */ );
 
5692
    END_UNIFORM_SECTION
 
5693
 
 
5694
    BEGIN_VARYING_SECTION
 
5695
    GETFLOAT( s );
 
5696
    GETFLOAT( t );
 
5697
    GETNORMAL( f );
 
5698
    TqFloat rgb[ 3 ];
 
5699
    rgb[ 0 ] = VECTOR( f ) [ 0 ];
 
5700
    rgb[ 1 ] = VECTOR( f ) [ 1 ];
 
5701
    rgb[ 2 ] = VECTOR( f ) [ 2 ];
 
5702
    bake_3( bd, ( char * ) STRING( name ).c_str(), FLOAT( s ), FLOAT( t ), rgb );
 
5703
    END_VARYING_SECTION
 
5704
 
 
5705
    BEGIN_UNIFORM_SECTION
 
5706
    bake_done( bd );
 
5707
    END_UNIFORM_SECTION
 
5708
}
 
5709
 
 
5710
STD_SOIMPL CqShaderExecEnv::SO_bake_3p( STRINGVAL name, FLOATVAL s, FLOATVAL t, POINTVAL f, DEFVOIDPARAMVARIMPL )
 
5711
{
 
5712
    STATS_INC( SHD_so_bake );
 
5713
 
 
5714
    INIT_SO
 
5715
 
 
5716
    CHECKVARY( f );
 
5717
    CHECKVARY( s );
 
5718
    CHECKVARY( t );
 
5719
 
 
5720
    BEGIN_UNIFORM_SECTION
 
5721
    GETSTRING( name );
 
5722
    BakingData *bd = bake_init(  /*(char *) STRING( name ).c_str()  */ );
 
5723
    END_UNIFORM_SECTION
 
5724
 
 
5725
    BEGIN_VARYING_SECTION
 
5726
    GETFLOAT( s );
 
5727
    GETFLOAT( t );
 
5728
    GETPOINT( f );
 
5729
    TqFloat rgb[ 3 ];
 
5730
    rgb[ 0 ] = VECTOR( f ) [ 0 ];
 
5731
    rgb[ 1 ] = VECTOR( f ) [ 1 ];
 
5732
    rgb[ 2 ] = VECTOR( f ) [ 2 ];
 
5733
    bake_3( bd, ( char * ) STRING( name ).c_str(), FLOAT( s ), FLOAT( t ), rgb );
 
5734
    END_VARYING_SECTION
 
5735
 
 
5736
    BEGIN_UNIFORM_SECTION
 
5737
    bake_done( bd );
 
5738
    END_UNIFORM_SECTION
 
5739
}
 
5740
 
 
5741
STD_SOIMPL CqShaderExecEnv::SO_bake_3v( STRINGVAL name, FLOATVAL s, FLOATVAL t, VECTORVAL f, DEFVOIDPARAMVARIMPL )
 
5742
{
 
5743
    STATS_INC( SHD_so_bake );
 
5744
 
 
5745
    INIT_SO
 
5746
    CHECKVARY( f );
 
5747
    CHECKVARY( s );
 
5748
    CHECKVARY( t );
 
5749
 
 
5750
    BEGIN_UNIFORM_SECTION
 
5751
    GETSTRING( name );
 
5752
    BakingData *bd = bake_init(  /*(char *) STRING( name ).c_str()  */ );
 
5753
    END_UNIFORM_SECTION
 
5754
 
 
5755
    BEGIN_VARYING_SECTION
 
5756
    GETFLOAT( s );
 
5757
    GETFLOAT( t );
 
5758
    GETVECTOR( f );
 
5759
    TqFloat rgb[ 3 ];
 
5760
    rgb[ 0 ] = VECTOR( f ) [ 0 ];
 
5761
    rgb[ 1 ] = VECTOR( f ) [ 1 ];
 
5762
    rgb[ 2 ] = VECTOR( f ) [ 2 ];
 
5763
    bake_3( bd, ( char * ) STRING( name ).c_str(), FLOAT( s ), FLOAT( t ), rgb );
 
5764
    END_VARYING_SECTION
 
5765
 
 
5766
    BEGIN_UNIFORM_SECTION
 
5767
    bake_done( bd );
 
5768
    END_UNIFORM_SECTION
 
5769
}
 
5770
 
 
5771
 
 
5772
// We manually decalr th
 
5773
STD_SOIMPL CqShaderExecEnv::SO_external( DSOMethod method, void *initData, DEFPARAMVARIMPL )
 
5774
{
 
5775
    STATS_INC( SHD_so_external );
 
5776
 
 
5777
    INIT_SO
 
5778
 
 
5779
    CHECKVARY( Result );
 
5780
    int p;
 
5781
    for ( p = 0;p < cParams;p++ )
 
5782
    {
 
5783
        CHECKVARY( apParams[ p ] );
 
5784
    };
 
5785
 
 
5786
    int dso_argc = cParams + 1; // dso_argv[0] is used for the return value
 
5787
    void **dso_argv = new void * [ dso_argc ] ;
 
5788
 
 
5789
    // create storage for the returned value
 
5790
    switch ( Result->Type() )
 
5791
    {
 
5792
 
 
5793
    case type_float:
 
5794
        dso_argv[ 0 ] = ( void* ) new TqFloat; break;
 
5795
    case type_point:
 
5796
    case type_color:
 
5797
    case type_triple:
 
5798
    case type_vector:
 
5799
    case type_normal:
 
5800
    case type_hpoint:
 
5801
        dso_argv[ 0 ] = ( void* ) new TqFloat[ 3 ]; break;
 
5802
    case type_string:
 
5803
        dso_argv[ 0 ] = ( void* ) new STRING_DESC;
 
5804
        ( ( STRING_DESC* ) dso_argv[ 0 ] ) ->s = NULL;
 
5805
        ( ( STRING_DESC* ) dso_argv[ 0 ] ) ->bufflen = 0;
 
5806
        break;
 
5807
    case type_matrix:
 
5808
    case type_sixteentuple:
 
5809
        dso_argv[ 0 ] = ( void* ) new TqFloat[ 16 ];
 
5810
        break;
 
5811
    default:
 
5812
        // Unhandled TYpe
 
5813
        break;
 
5814
    };
 
5815
 
 
5816
    // Allocate space for the arguments
 
5817
    for ( p = 1;p <= cParams;p++ )
 
5818
    {
 
5819
 
 
5820
        switch ( apParams[ p - 1 ] ->Type() )
 
5821
        {
 
5822
        case type_float:
 
5823
            dso_argv[ p ] = ( void* ) new TqFloat; break;
 
5824
        case type_hpoint:
 
5825
        case type_point:
 
5826
        case type_triple:  // This seems reasonable
 
5827
        case type_vector:
 
5828
        case type_normal:
 
5829
        case type_color:
 
5830
            dso_argv[ p ] = ( void* ) new TqFloat[ 3 ]; break;
 
5831
        case type_string:
 
5832
            dso_argv[ p ] = ( void* ) new STRING_DESC;
 
5833
            ( ( STRING_DESC* ) dso_argv[ p ] ) ->s = NULL;
 
5834
            ( ( STRING_DESC* ) dso_argv[ p ] ) ->bufflen = 0;
 
5835
            break;
 
5836
        case type_matrix:
 
5837
        case type_sixteentuple:
 
5838
            dso_argv[ 0 ] = ( void* ) new TqFloat[ 16 ];
 
5839
            break;
 
5840
        default:
 
5841
            // Unhandled TYpe
 
5842
            break;
 
5843
        };
 
5844
    };
 
5845
 
 
5846
 
 
5847
    BEGIN_VARYING_SECTION
 
5848
 
 
5849
    // Convert the arguments to the required format for the DSO
 
5850
    for ( p = 1;p <= cParams;p++ )
 
5851
    {
 
5852
 
 
5853
        switch ( apParams[ p - 1 ] ->Type() )
 
5854
        {
 
5855
        case type_float:
 
5856
            apParams[ p - 1 ] ->GetFloat( *( ( float* ) dso_argv[ p ] ), __iGrid );
 
5857
            break;
 
5858
        case type_hpoint:
 
5859
        case type_point:
 
5860
            {
 
5861
                CqVector3D v;
 
5862
                apParams[ p - 1 ] ->GetPoint( v, __iGrid );
 
5863
                ( ( float* ) dso_argv[ p ] ) [ 0 ] = v[ 0 ];
 
5864
                ( ( float* ) dso_argv[ p ] ) [ 1 ] = v[ 1 ];
 
5865
                ( ( float* ) dso_argv[ p ] ) [ 2 ] = v[ 2 ];
 
5866
            }
 
5867
            ; break;
 
5868
        case type_triple:  // This seems reasonable
 
5869
        case type_vector:
 
5870
            {
 
5871
                CqVector3D v;
 
5872
                apParams[ p - 1 ] ->GetVector( v, __iGrid );
 
5873
                ( ( float* ) dso_argv[ p ] ) [ 0 ] = v[ 0 ];
 
5874
                ( ( float* ) dso_argv[ p ] ) [ 1 ] = v[ 1 ];
 
5875
                ( ( float* ) dso_argv[ p ] ) [ 2 ] = v[ 2 ];
 
5876
            }
 
5877
            ; break;
 
5878
        case type_normal:
 
5879
            {
 
5880
                CqVector3D v;
 
5881
                apParams[ p - 1 ] ->GetNormal( v, __iGrid );
 
5882
                ( ( float* ) dso_argv[ p ] ) [ 0 ] = v[ 0 ];
 
5883
                ( ( float* ) dso_argv[ p ] ) [ 1 ] = v[ 1 ];
 
5884
                ( ( float* ) dso_argv[ p ] ) [ 2 ] = v[ 2 ];
 
5885
            }
 
5886
            ; break;
 
5887
        case type_color:
 
5888
            {
 
5889
                CqColor c;
 
5890
                apParams[ p - 1 ] ->GetColor( c, __iGrid );
 
5891
                ( ( float* ) dso_argv[ p ] ) [ 0 ] = c[ 0 ];
 
5892
                ( ( float* ) dso_argv[ p ] ) [ 1 ] = c[ 1 ];
 
5893
                ( ( float* ) dso_argv[ p ] ) [ 2 ] = c[ 2 ];
 
5894
            }
 
5895
            ; break;
 
5896
        case type_string:
 
5897
            {
 
5898
                CqString s;
 
5899
                apParams[ p - 1 ] ->GetString( s, __iGrid );
 
5900
                char *ps = new char[ s.size() + 1 ];
 
5901
                strncpy ( ps, s.c_str(), s.size() + 1 );
 
5902
                ( ( STRING_DESC* ) dso_argv[ p ] ) ->s = ps;
 
5903
                ( ( STRING_DESC* ) dso_argv[ p ] ) ->bufflen = s.size() + 1;
 
5904
            }
 
5905
            ; break;
 
5906
        case type_matrix:
 
5907
        case type_sixteentuple:
 
5908
            {
 
5909
                CqMatrix m;
 
5910
                int r, c;
 
5911
                apParams[ p - 1 ] ->GetMatrix( m, __iGrid );
 
5912
                for ( r = 0; r < 4; r++ )
 
5913
                    for ( c = 0; c < 4; c++ )
 
5914
                        ( ( TqFloat* ) dso_argv[ p ] ) [ ( r * 4 ) + c ] = m[ r ][ c ];
 
5915
            }
 
5916
            ; break;
 
5917
        default:
 
5918
            // Unhandled TYpe
 
5919
            break;
 
5920
        };
 
5921
    };
 
5922
 
 
5923
    // Atlast, we call the shadeop method, looks rather dull after all this effort.
 
5924
    method( initData, dso_argc, dso_argv );
 
5925
 
 
5926
    // Pass the returned value back to aqsis
 
5927
    switch ( Result->Type() )
 
5928
    {
 
5929
 
 
5930
    case type_float:
 
5931
        {
 
5932
            TqFloat val = *( ( float* ) ( dso_argv[ 0 ] ) );
 
5933
            Result->SetFloat( val, __iGrid );
 
5934
        }
 
5935
        ; break;
 
5936
    case type_hpoint:
 
5937
    case type_point:
 
5938
        {
 
5939
            CqVector3D v;
 
5940
            v[ 0 ] = ( ( float* ) dso_argv[ 0 ] ) [ 0 ];
 
5941
            v[ 1 ] = ( ( float* ) dso_argv[ 0 ] ) [ 1 ];
 
5942
            v[ 2 ] = ( ( float* ) dso_argv[ 0 ] ) [ 2 ];
 
5943
            Result->SetPoint( v, __iGrid );
 
5944
        }
 
5945
        ; break;
 
5946
    case type_triple:  // This seems reasonable
 
5947
    case type_vector:
 
5948
        {
 
5949
            CqVector3D v;
 
5950
            v[ 0 ] = ( ( float* ) dso_argv[ 0 ] ) [ 0 ];
 
5951
            v[ 1 ] = ( ( float* ) dso_argv[ 0 ] ) [ 1 ];
 
5952
            v[ 2 ] = ( ( float* ) dso_argv[ 0 ] ) [ 2 ];
 
5953
            Result->SetVector( v, __iGrid );
 
5954
        }
 
5955
        ; break;
 
5956
    case type_normal:
 
5957
        {
 
5958
            CqVector3D v;
 
5959
            v[ 0 ] = ( ( float* ) dso_argv[ 0 ] ) [ 0 ];
 
5960
            v[ 1 ] = ( ( float* ) dso_argv[ 0 ] ) [ 1 ];
 
5961
            v[ 2 ] = ( ( float* ) dso_argv[ 0 ] ) [ 2 ];
 
5962
            Result->SetNormal( v, __iGrid );
 
5963
        }
 
5964
        ; break;
 
5965
    case type_color:
 
5966
        {
 
5967
            CqColor c;
 
5968
            c[ 0 ] = ( ( float* ) dso_argv[ 0 ] ) [ 0 ];
 
5969
            c[ 1 ] = ( ( float* ) dso_argv[ 0 ] ) [ 1 ];
 
5970
            c[ 2 ] = ( ( float* ) dso_argv[ 0 ] ) [ 2 ];
 
5971
            Result->SetColor( c, __iGrid );
 
5972
        }
 
5973
        ; break;
 
5974
    case type_string:
 
5975
        {
 
5976
            CqString s( ( ( STRING_DESC* ) dso_argv[ 0 ] ) ->s );
 
5977
            Result->SetString( s, __iGrid );
 
5978
        }
 
5979
        ; break;
 
5980
    case type_matrix:
 
5981
    case type_sixteentuple:
 
5982
        {
 
5983
            CqMatrix m( ( float* ) dso_argv[ 0 ] );
 
5984
            Result->SetMatrix( m, __iGrid );
 
5985
        }
 
5986
        ; break;
 
5987
    default:
 
5988
        // Unhandled TYpe
 
5989
        std::cout << "Unsupported type" << std::endl;
 
5990
        break;
 
5991
    };
 
5992
 
 
5993
 
 
5994
    // Set the values that were altered by the Shadeop
 
5995
    for ( p = 1;p <= cParams;p++ )
 
5996
    {
 
5997
        switch ( apParams[ p - 1 ] ->Type() )
 
5998
        {
 
5999
        case type_float:
 
6000
            {
 
6001
                TqFloat val = *( ( float* ) dso_argv[ p ] ) ;
 
6002
                apParams[ p - 1 ] ->SetFloat( val, __iGrid );
 
6003
            }
 
6004
            ;break;
 
6005
        case type_hpoint:
 
6006
        case type_point:
 
6007
            {
 
6008
                CqVector3D v;
 
6009
                v[ 0 ] = ( ( float* ) dso_argv[ p ] ) [ 0 ];
 
6010
                v[ 1 ] = ( ( float* ) dso_argv[ p ] ) [ 1 ];
 
6011
                v[ 2 ] = ( ( float* ) dso_argv[ p ] ) [ 2 ];
 
6012
                apParams[ p - 1 ] ->SetPoint( v, __iGrid );
 
6013
            }
 
6014
            ;break;
 
6015
        case type_triple:  // This seems reasonable
 
6016
        case type_vector:
 
6017
            {
 
6018
                CqVector3D v;
 
6019
                v[ 0 ] = ( ( float* ) dso_argv[ p ] ) [ 0 ];
 
6020
                v[ 1 ] = ( ( float* ) dso_argv[ p ] ) [ 1 ];
 
6021
                v[ 2 ] = ( ( float* ) dso_argv[ p ] ) [ 2 ];
 
6022
                apParams[ p - 1 ] ->SetVector( v, __iGrid );
 
6023
            }
 
6024
            ;break;
 
6025
        case type_normal:
 
6026
            {
 
6027
                CqVector3D v;
 
6028
                v[ 0 ] = ( ( float* ) dso_argv[ p ] ) [ 0 ];
 
6029
                v[ 1 ] = ( ( float* ) dso_argv[ p ] ) [ 1 ];
 
6030
                v[ 2 ] = ( ( float* ) dso_argv[ p ] ) [ 2 ];
 
6031
                apParams[ p - 1 ] ->SetNormal( v, __iGrid );
 
6032
            }
 
6033
            ;break;
 
6034
        case type_color:
 
6035
            {
 
6036
                CqColor c;
 
6037
                c[ 0 ] = ( ( float* ) dso_argv[ p ] ) [ 0 ];
 
6038
                c[ 1 ] = ( ( float* ) dso_argv[ p ] ) [ 1 ];
 
6039
                c[ 2 ] = ( ( float* ) dso_argv[ p ] ) [ 2 ];
 
6040
                apParams[ p - 1 ] ->SetColor( c, __iGrid );
 
6041
            }
 
6042
            ;break;
 
6043
        case type_string:
 
6044
            {
 
6045
                CqString s( ( ( STRING_DESC* ) dso_argv[ p ] ) ->s );
 
6046
                apParams[ p - 1 ] ->SetString( s, __iGrid );
 
6047
            }
 
6048
            ; break;
 
6049
        case type_matrix:
 
6050
        case type_sixteentuple:
 
6051
            {
 
6052
                CqMatrix m( ( float* ) dso_argv[ p ] );
 
6053
                apParams[ p - 1 ] ->SetMatrix( m, __iGrid );
 
6054
            }
 
6055
            ; break;
 
6056
        default:
 
6057
            // Unhandled TYpe
 
6058
            break;
 
6059
        };
 
6060
    };
 
6061
 
 
6062
    END_VARYING_SECTION
 
6063
 
 
6064
    // Free up the storage allocated for the return type
 
6065
    switch ( Result->Type() )
 
6066
    {
 
6067
 
 
6068
    case type_float:
 
6069
        delete ( float* ) dso_argv[ 0 ]; break;
 
6070
    case type_point:
 
6071
    case type_triple:  // This seems reasonable
 
6072
    case type_vector:
 
6073
    case type_normal:
 
6074
    case type_color:
 
6075
    case type_hpoint:
 
6076
        delete[] ( float* ) dso_argv[ 0 ]; break;
 
6077
    case type_string:  // Need to look into these
 
6078
        delete ( STRING_DESC* ) dso_argv[ 0 ]; break;
 
6079
    case type_matrix:
 
6080
    case type_sixteentuple:
 
6081
        delete[] ( float* ) dso_argv[ 0 ]; break;
 
6082
    default:
 
6083
        // Unhandled TYpe
 
6084
        break;
 
6085
    };
 
6086
 
 
6087
    // Free up the storage allocated for the args
 
6088
    for ( p = 1;p <= cParams;p++ )
 
6089
    {
 
6090
        switch ( apParams[ p - 1 ] ->Type() )
 
6091
        {
 
6092
        case type_float:
 
6093
            delete ( float* ) dso_argv[ p ]; break;
 
6094
        case type_point:
 
6095
        case type_triple:
 
6096
        case type_vector:
 
6097
        case type_normal:
 
6098
        case type_color:
 
6099
        case type_hpoint:
 
6100
            delete[] ( float* ) dso_argv[ p ]; break;
 
6101
        case type_string:
 
6102
            delete ( STRING_DESC* ) dso_argv[ p ]; break;
 
6103
        case type_matrix:
 
6104
        case type_sixteentuple:
 
6105
            delete[] ( float* ) dso_argv[ p ]; break;
 
6106
        default:
 
6107
            // Unhandled TYpe
 
6108
            break;
 
6109
        };
 
6110
    };
 
6111
 
 
6112
    delete dso_argv;
 
6113
}
 
6114
 
 
6115
//----------------------------------------------------------------------
 
6116
// occlusion(occlmap,P,N,samples)
 
6117
STD_SOIMPL CqShaderExecEnv::SO_occlusion( STRINGVAL occlmap, FLOATVAL channel, POINTVAL P, NORMALVAL N, FLOATVAL samples, DEFPARAMVARIMPL )
 
6118
{
 
6119
    STATS_INC( SHD_so_occlusion );
 
6120
 
 
6121
    INIT_SO
 
6122
 
 
6123
    if ( NULL == QGetRenderContextI() )
 
6124
        return ;
 
6125
 
 
6126
    GET_TEXTURE_PARAMS;
 
6127
 
 
6128
    BEGIN_UNIFORM_SECTION
 
6129
    GETSTRING( occlmap );
 
6130
    GETNORMAL( N );
 
6131
    GETFLOAT( samples );
 
6132
    IqTextureMap* pMap = QGetRenderContextI() ->GetShadowMap( STRING( occlmap ) );
 
6133
    END_UNIFORM_SECTION
 
6134
 
 
6135
    CqVector3D L(0,0,-1);
 
6136
 
 
6137
    __fVarying = TqTrue;
 
6138
    if ( pMap != 0 && pMap->IsValid() )
 
6139
    {
 
6140
        std::valarray<TqFloat> fv;
 
6141
        pMap->PrepareSampleOptions( paramMap );
 
6142
 
 
6143
        BEGIN_VARYING_SECTION
 
6144
        // Storage for the final combined occlusion value.
 
6145
        TqFloat occlsum = 0.0f;
 
6146
        TqFloat dotsum = 0.0f;
 
6147
 
 
6148
        CqVector3D swidth = 0.0f, twidth = 0.0f;
 
6149
 
 
6150
        swidth = SO_DerivType<CqVector3D>( P, NULL, __iGrid, this );
 
6151
        twidth = SO_DerivType<CqVector3D>( P, NULL, __iGrid, this );
 
6152
 
 
6153
        GETPOINT( P );
 
6154
        GETNORMAL( N );
 
6155
        TqInt i = pMap->NumPages() - 1;
 
6156
        for( ; i >= 0; i-- )
 
6157
        {
 
6158
            // Check if the lightsource is behind the sample.
 
6159
            CqVector3D Nl = pMap->GetMatrix(2, i) * NORMAL( N );
 
6160
            TqFloat cosangle = Nl * L;
 
6161
            if( cosangle < 0.0f )
 
6162
                continue;
 
6163
 
 
6164
            fv = 0.0f;
 
6165
            pMap->SampleMap( POINT( P ), swidth, twidth, fv, i );
 
6166
            occlsum += cosangle * fv[0];
 
6167
            dotsum += cosangle;
 
6168
        }
 
6169
        occlsum /= dotsum;
 
6170
        SETFLOAT( Result, occlsum);
 
6171
        END_VARYING_SECTION
 
6172
    }
 
6173
    else
 
6174
    {
 
6175
        BEGIN_VARYING_SECTION
 
6176
        SETFLOAT( Result, 0.0f );       // Default, completely lit
 
6177
        END_VARYING_SECTION
 
6178
    }
 
6179
}
 
6180
 
 
6181
 
 
6182
END_NAMESPACE( Aqsis )
 
6183
//---------------------------------------------------------------------