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

« back to all changes in this revision

Viewing changes to shadowmap/shadowmap.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 a display driver for saving shadow maps.
 
23
                \author Paul C. Gregory (pgregory@aqsis.com)
 
24
*/
 
25
 
 
26
#include        <iostream>
 
27
#include        <fstream>
 
28
 
 
29
#include        "aqsis.h"
 
30
 
 
31
#ifdef AQSIS_SYSTEM_WIN32
 
32
 
 
33
#include        <process.h>
 
34
 
 
35
#else
 
36
 
 
37
typedef int SOCKET;
 
38
 
 
39
#endif
 
40
 
 
41
#include        "ri.h"
 
42
#include        "displaydriver.h"
 
43
#include        "dd.h"
 
44
#include        "tiffio.h"
 
45
#include        "sstring.h"
 
46
#include        "texturemap.h"
 
47
 
 
48
#if defined(AQSIS_SYSTEM_WIN32) || defined(AQSIS_SYSTEM_MACOSX)
 
49
#include        "version.h"
 
50
#endif
 
51
 
 
52
using namespace Aqsis;
 
53
 
 
54
SqDDMessageFormatResponse frmt( 2 );
 
55
SqDDMessageCloseAcknowledge closeack;
 
56
 
 
57
void SaveAsShadowMap();
 
58
 
 
59
int main( int argc, char* argv[] )
 
60
{
 
61
    int port = -1;
 
62
    char *portStr = getenv( "AQSIS_DD_PORT" );
 
63
 
 
64
    if ( portStr != NULL )
 
65
    {
 
66
        port = atoi( portStr );
 
67
    }
 
68
 
 
69
    if ( DDInitialise( NULL, port ) == 0 )
 
70
    {
 
71
        DDProcessMessages();
 
72
    }
 
73
    return 0;
 
74
}
 
75
 
 
76
#if defined(AQSIS_SYSTEM_WIN32) || defined(AQSIS_SYSTEM_MACOSX)
 
77
#define ZFILE_HEADER            "Aqsis ZFile" VERSION_STR
 
78
#else // AQSIS_SYSTEM_WIN32
 
79
#define ZFILE_HEADER            "Aqsis ZFile" VERSION
 
80
#endif // !AQSIS_SYSTEM_WIN32
 
81
 
 
82
 
 
83
TqInt   XRes, YRes;
 
84
TqInt   g_Channels;
 
85
TqInt   g_append = 0;
 
86
uint16  g_Compression = COMPRESSION_NONE;
 
87
TqFloat* pData;
 
88
TIFF*   pOut;
 
89
TqInt   CWXMin, CWYMin;
 
90
std::string     strFilename( "output.tif" );
 
91
std::string     strType( "zfile" );
 
92
TqFloat matWorldToCamera[ 4 ][ 4 ];
 
93
TqFloat matWorldToScreen[ 4 ][ 4 ];
 
94
 
 
95
TqInt Query( SOCKET s, SqDDMessageBase* pMsgB )
 
96
{
 
97
    switch ( pMsgB->m_MessageID )
 
98
    {
 
99
    case MessageID_FormatQuery:
 
100
        {
 
101
            if ( DDSendMsg( s, &frmt ) <= 0 )
 
102
                return ( -1 );
 
103
        }
 
104
        break;
 
105
    }
 
106
    return ( 0 );
 
107
}
 
108
 
 
109
TqInt Open( SOCKET s, SqDDMessageBase* pMsgB )
 
110
{
 
111
    SqDDMessageOpen * pMsg = static_cast<SqDDMessageOpen*>( pMsgB );
 
112
 
 
113
    XRes = ( pMsg->m_CropWindowXMax - pMsg->m_CropWindowXMin );
 
114
    YRes = ( pMsg->m_CropWindowYMax - pMsg->m_CropWindowYMin );
 
115
    CWXMin = pMsg->m_CropWindowXMin;
 
116
    CWYMin = pMsg->m_CropWindowYMin;
 
117
    g_Channels = pMsg->m_Channels;
 
118
 
 
119
    if ( g_Channels > 1 ) return ( -1 );
 
120
 
 
121
    // Create a buffer big enough to hold a row of buckets.
 
122
    pData = new TqFloat[ XRes * YRes ];
 
123
    return ( 0 );
 
124
}
 
125
 
 
126
 
 
127
TqInt Data( SOCKET s, SqDDMessageBase* pMsgB )
 
128
{
 
129
    SqDDMessageData * pMsg = static_cast<SqDDMessageData*>( pMsgB );
 
130
 
 
131
    TqInt       linelen = XRes * g_Channels;
 
132
    char* pBucket = reinterpret_cast<char*>( &pMsg->m_Data );
 
133
 
 
134
    TqInt y;
 
135
    for ( y = pMsg->m_YMin; y < pMsg->m_YMaxPlus1; y++ )
 
136
    {
 
137
        TqInt x;
 
138
        for ( x = pMsg->m_XMin; x < pMsg->m_XMaxPlus1; x++ )
 
139
        {
 
140
            if ( x >= 0 && y >= 0 && x < XRes && y < YRes )
 
141
            {
 
142
                TqInt so = ( y * linelen ) + ( x * g_Channels );
 
143
 
 
144
                TqInt i = 0;
 
145
                while ( i < g_Channels )
 
146
                {
 
147
                    pData[ so++ ] = reinterpret_cast<TqFloat*>( pBucket ) [ i ];
 
148
                    i++;
 
149
                }
 
150
            }
 
151
            pBucket += pMsg->m_ElementSize;
 
152
        }
 
153
    }
 
154
    return ( 0 );
 
155
}
 
156
 
 
157
 
 
158
TqInt Close( SOCKET s, SqDDMessageBase* pMsgB )
 
159
{
 
160
    // Save the shadowmap to a binary file.
 
161
    if ( strFilename != "" )
 
162
    {
 
163
        if( strType.compare( "shadow" ) == 0 )
 
164
        {
 
165
            SaveAsShadowMap();
 
166
        }
 
167
        else
 
168
        {
 
169
            std::ofstream ofile( strFilename.c_str(), std::ios::out | std::ios::binary );
 
170
            if ( ofile.is_open() )
 
171
            {
 
172
                // Save a file type and version marker
 
173
                ofile << ZFILE_HEADER;
 
174
 
 
175
                // Save the xres and yres.
 
176
                ofile.write( reinterpret_cast<char* >( &XRes ), sizeof( XRes ) );
 
177
                ofile.write( reinterpret_cast<char* >( &YRes ), sizeof( XRes ) );
 
178
 
 
179
                // Save the transformation matrices.
 
180
                ofile.write( reinterpret_cast<char*>( matWorldToCamera[ 0 ] ), sizeof( matWorldToCamera[ 0 ][ 0 ] ) * 4 );
 
181
                ofile.write( reinterpret_cast<char*>( matWorldToCamera[ 1 ] ), sizeof( matWorldToCamera[ 0 ][ 0 ] ) * 4 );
 
182
                ofile.write( reinterpret_cast<char*>( matWorldToCamera[ 2 ] ), sizeof( matWorldToCamera[ 0 ][ 0 ] ) * 4 );
 
183
                ofile.write( reinterpret_cast<char*>( matWorldToCamera[ 3 ] ), sizeof( matWorldToCamera[ 0 ][ 0 ] ) * 4 );
 
184
 
 
185
                ofile.write( reinterpret_cast<char*>( matWorldToScreen[ 0 ] ), sizeof( matWorldToScreen[ 0 ][ 0 ] ) * 4 );
 
186
                ofile.write( reinterpret_cast<char*>( matWorldToScreen[ 1 ] ), sizeof( matWorldToScreen[ 0 ][ 0 ] ) * 4 );
 
187
                ofile.write( reinterpret_cast<char*>( matWorldToScreen[ 2 ] ), sizeof( matWorldToScreen[ 0 ][ 0 ] ) * 4 );
 
188
                ofile.write( reinterpret_cast<char*>( matWorldToScreen[ 3 ] ), sizeof( matWorldToScreen[ 0 ][ 0 ] ) * 4 );
 
189
 
 
190
                // Now output the depth values
 
191
                ofile.write( reinterpret_cast<char*>( pData ), sizeof( TqFloat ) * ( XRes * YRes ) );
 
192
                ofile.close();
 
193
            }
 
194
        }
 
195
    }
 
196
    if ( DDSendMsg( s, &closeack ) <= 0 )
 
197
        return ( -1 );
 
198
    else
 
199
        return ( 1 );
 
200
}
 
201
 
 
202
 
 
203
TqInt Abandon( SOCKET s, SqDDMessageBase* pMsgB )
 
204
{
 
205
    return ( 1 );
 
206
}
 
207
 
 
208
 
 
209
void SaveAsShadowMap()
 
210
{
 
211
    TqChar version[ 80 ];
 
212
    TqInt twidth = 32;
 
213
    TqInt tlength = 32;
 
214
 
 
215
    const char* mode = (g_append)? "a" : "w";
 
216
 
 
217
    // Save the shadowmap to a binary file.
 
218
    if ( strFilename.compare( "" ) != 0 )
 
219
    {
 
220
        TIFF * pshadow = TIFFOpen( strFilename.c_str(), mode );
 
221
                if( pshadow != NULL )
 
222
                {
 
223
                        TIFFCreateDirectory( pshadow );
 
224
 
 
225
        #if defined(AQSIS_SYSTEM_WIN32) || defined(AQSIS_SYSTEM_MACOSX)
 
226
                        sprintf( version, "%s %s", STRNAME, VERSION_STR );
 
227
        #else
 
228
                        sprintf( version, "%s %s", STRNAME, VERSION );
 
229
        #endif
 
230
                        TIFFSetField( pshadow, TIFFTAG_SOFTWARE, ( uint32 ) version );
 
231
                        TIFFSetField( pshadow, TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, matWorldToCamera );
 
232
                        TIFFSetField( pshadow, TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, matWorldToScreen );
 
233
                        TIFFSetField( pshadow, TIFFTAG_PIXAR_TEXTUREFORMAT, SHADOWMAP_HEADER );
 
234
                        TIFFSetField( pshadow, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK );
 
235
 
 
236
                        // Write the floating point image to the directory.
 
237
                        TqFloat *depths = ( TqFloat * ) pData;
 
238
 
 
239
                #if defined(AQSIS_SYSTEM_WIN32) || defined(AQSIS_SYSTEM_MACOSX)
 
240
                        sprintf( version, "%s %s", STRNAME, VERSION_STR );
 
241
                #else
 
242
                        sprintf( version, "%s %s", STRNAME, VERSION );
 
243
                #endif
 
244
                        TIFFSetField( pshadow, TIFFTAG_SOFTWARE, ( uint32 ) version );
 
245
                        TIFFSetField( pshadow, TIFFTAG_IMAGEWIDTH, XRes );
 
246
                        TIFFSetField( pshadow, TIFFTAG_IMAGELENGTH, YRes );
 
247
                        TIFFSetField( pshadow, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
 
248
                        TIFFSetField( pshadow, TIFFTAG_BITSPERSAMPLE, 32 );
 
249
                        TIFFSetField( pshadow, TIFFTAG_SAMPLESPERPIXEL, g_Channels );
 
250
                        TIFFSetField( pshadow, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT );
 
251
                        TIFFSetField( pshadow, TIFFTAG_TILEWIDTH, twidth );
 
252
                        TIFFSetField( pshadow, TIFFTAG_TILELENGTH, tlength );
 
253
                        TIFFSetField( pshadow, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP );
 
254
                        TIFFSetField( pshadow, TIFFTAG_COMPRESSION, g_Compression );
 
255
 
 
256
 
 
257
                        TqInt tsize = twidth * tlength;
 
258
                        TqInt tperrow = ( XRes + twidth - 1 ) / twidth;
 
259
                        TqFloat* ptile = static_cast<TqFloat*>( _TIFFmalloc( tsize * g_Channels * sizeof( TqFloat ) ) );
 
260
 
 
261
                        if ( ptile != NULL )
 
262
                        {
 
263
                                TqInt ctiles = tperrow * ( ( YRes + tlength - 1 ) / tlength );
 
264
                                TqInt itile;
 
265
                                for ( itile = 0; itile < ctiles; itile++ )
 
266
                                {
 
267
                                        TqInt x = ( itile % tperrow ) * twidth;
 
268
                                        TqInt y = ( itile / tperrow ) * tlength;
 
269
                                        TqFloat* ptdata = pData + ( ( y * XRes ) + x ) * g_Channels;
 
270
                                        // Clear the tile to black.
 
271
                                        memset( ptile, 0, tsize * g_Channels * sizeof( TqFloat ) );
 
272
                                        for ( TqUlong i = 0; i < tlength; i++ )
 
273
                                        {
 
274
                                                for ( TqUlong j = 0; j < twidth; j++ )
 
275
                                                {
 
276
                                                        if ( ( x + j ) < XRes && ( y + i ) < YRes )
 
277
                                                        {
 
278
                                                                TqInt ii;
 
279
                                                                for ( ii = 0; ii < g_Channels; ii++ )
 
280
                                                                        ptile[ ( i * twidth * g_Channels ) + ( ( ( j * g_Channels ) + ii ) ) ] = ptdata[ ( ( j * g_Channels ) + ii ) ];
 
281
                                                        }
 
282
                                                }
 
283
                                                ptdata += ( XRes * g_Channels );
 
284
                                        }
 
285
                                        TIFFWriteTile( pshadow, ptile, x, y, 0, 0 );
 
286
                                }
 
287
                                TIFFWriteDirectory( pshadow );
 
288
 
 
289
                        }
 
290
 
 
291
                        TIFFClose( pshadow );
 
292
                }
 
293
    }
 
294
}
 
295
 
 
296
 
 
297
TqInt HandleMessage( SOCKET s, SqDDMessageBase* pMsgB )
 
298
{
 
299
    switch ( pMsgB->m_MessageID )
 
300
    {
 
301
    case MessageID_Filename:
 
302
        {
 
303
            SqDDMessageFilename * pMsg = static_cast<SqDDMessageFilename*>( pMsgB );
 
304
            strFilename = pMsg->m_String;
 
305
        }
 
306
        break;
 
307
 
 
308
    case MessageID_DisplayType:
 
309
        {
 
310
            SqDDMessageDisplayType * pMsg = static_cast<SqDDMessageDisplayType*>( pMsgB );
 
311
            strType = pMsg->m_String;
 
312
        }
 
313
        break;
 
314
 
 
315
    case MessageID_Nl:
 
316
        {
 
317
            SqDDMessageNl* pMsg = static_cast<SqDDMessageNl*>( pMsgB );
 
318
            memcpy( matWorldToCamera, pMsg->m_Matrix, sizeof( matWorldToCamera ) );
 
319
        }
 
320
        break;
 
321
 
 
322
    case MessageID_NP:
 
323
        {
 
324
            SqDDMessageNP* pMsg = static_cast<SqDDMessageNP*>( pMsgB );
 
325
            memcpy( matWorldToScreen, pMsg->m_Matrix, sizeof( matWorldToScreen ) );
 
326
        }
 
327
        break;
 
328
 
 
329
    case MessageID_UserParam:
 
330
        {
 
331
            SqDDMessageUserParam * pMsg = static_cast<SqDDMessageUserParam*>( pMsgB );
 
332
            // Check if we understand the parameter.
 
333
            if( strncmp( pMsg->m_NameAndData, "append", pMsg->m_NameLength ) == 0 )
 
334
            {
 
335
                g_append = *reinterpret_cast<TqInt*>( &pMsg->m_NameAndData[ pMsg->m_NameLength + 1 ] );
 
336
            }
 
337
            else if( strncmp( pMsg->m_NameAndData, "compression", pMsg->m_NameLength ) == 0 )
 
338
            {
 
339
                const char* pvalue = reinterpret_cast<const char*>( &pMsg->m_NameAndData[ pMsg->m_NameLength + 1 ] );
 
340
                if ( strstr( pvalue, "none" ) != 0 )
 
341
                    g_Compression = COMPRESSION_NONE;
 
342
                else if ( strstr( pvalue, "lzw" ) != 0 )
 
343
                    g_Compression = COMPRESSION_LZW;
 
344
                else if ( strstr( pvalue, "deflate" ) != 0 )
 
345
                    g_Compression = COMPRESSION_DEFLATE;
 
346
                else if ( strstr( pvalue, "jpeg" ) != 0 )
 
347
                    g_Compression = COMPRESSION_JPEG;
 
348
                else if ( strstr( pvalue, "packbits" ) != 0 )
 
349
                    g_Compression = COMPRESSION_PACKBITS;
 
350
            }
 
351
        }
 
352
        break;
 
353
    }
 
354
    return ( 0 );
 
355
}