~ubuntu-branches/ubuntu/saucy/fgfs-atlas/saucy

« back to all changes in this revision

Viewing changes to src/RenderTexture.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Ove Kaaven
  • Date: 2006-03-31 13:37:25 UTC
  • Revision ID: james.westby@ubuntu.com-20060331133725-h671cls8c2a2vpwv
Tags: upstream-0.3.0
ImportĀ upstreamĀ versionĀ 0.3.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//---------------------------------------------------------------------------
 
2
// File : RenderTexture.cpp
 
3
//---------------------------------------------------------------------------
 
4
// Copyright (c) 2002-2004 Mark J. Harris
 
5
//---------------------------------------------------------------------------
 
6
// This software is provided 'as-is', without any express or implied
 
7
// warranty. In no event will the authors be held liable for any
 
8
// damages arising from the use of this software.
 
9
//
 
10
// Permission is granted to anyone to use this software for any
 
11
// purpose, including commercial applications, and to alter it and
 
12
// redistribute it freely, subject to the following restrictions:
 
13
//
 
14
// 1. The origin of this software must not be misrepresented; you
 
15
//    must not claim that you wrote the original software. If you use
 
16
//    this software in a product, an acknowledgment in the product
 
17
//    documentation would be appreciated but is not required.
 
18
//
 
19
// 2. Altered source versions must be plainly marked as such, and
 
20
//    must not be misrepresented as being the original software.
 
21
//
 
22
// 3. This notice may not be removed or altered from any source
 
23
//    distribution.
 
24
//
 
25
// --------------------------------------------------------------------------
 
26
// Credits:
 
27
// Original RenderTexture class: Mark J. Harris
 
28
// Original Render to Depth Texture support: Thorsten Scheuermann
 
29
// Linux Copy-to-texture: Eric Werness
 
30
// Various Bug Fixes: Daniel (Redge) Sperl 
 
31
//                    Bill Baxter
 
32
//
 
33
// --------------------------------------------------------------------------
 
34
/**
 
35
* @file RenderTexture.cpp
 
36
 
37
* Implementation of class RenderTexture.  A multi-format render to 
 
38
* texture wrapper.
 
39
*/
 
40
#pragma warning(disable:4786)
 
41
 
 
42
/*
 
43
 * Changelog:
 
44
 *
 
45
 * Jan. 2005, Removed GLEW dependencies, Erik Hofman, Fred Bouvier
 
46
 */
 
47
 
 
48
#include <simgear/compiler.h>
 
49
#include <plib/ul.h>
 
50
#ifdef UL_GLX
 
51
#  include SG_GL_H
 
52
#  define GLX_GLXEXT_PROTOTYPES
 
53
#  ifdef __APPLE__
 
54
#    include <AGL/agl.h>
 
55
#  else
 
56
#    include <GL/glx.h>
 
57
#  endif
 
58
#elif defined UL_WIN32
 
59
#  include <windows.h> // MUST be before SG_GL_H and all other GL related include directive
 
60
#  include SG_GL_H
 
61
#endif
 
62
#include "extensions.hxx"
 
63
#include "RenderTexture.h"
 
64
 
 
65
#include <stdio.h>
 
66
#include <stdlib.h>
 
67
#include <stdarg.h>
 
68
#include <assert.h>
 
69
 
 
70
#ifdef _WIN32
 
71
#pragma comment(lib, "gdi32.lib") // required for GetPixelFormat()
 
72
#endif
 
73
 
 
74
using namespace std;
 
75
 
 
76
#ifdef _WIN32
 
77
static bool fctPtrInited = false;
 
78
/* WGL_ARB_pixel_format */
 
79
static wglChoosePixelFormatARBProc wglChoosePixelFormatARBPtr = 0;
 
80
static wglGetPixelFormatAttribivARBProc wglGetPixelFormatAttribivARBPtr = 0;
 
81
/* WGL_ARB_pbuffer */
 
82
static wglCreatePbufferARBProc wglCreatePbufferARBPtr = 0;
 
83
static wglGetPbufferDCARBProc wglGetPbufferDCARBPtr = 0;
 
84
static wglQueryPbufferARBProc wglQueryPbufferARBPtr = 0;
 
85
static wglReleasePbufferDCARBProc wglReleasePbufferDCARBPtr = 0;
 
86
static wglDestroyPbufferARBProc wglDestroyPbufferARBPtr = 0;
 
87
/* WGL_ARB_render_texture */
 
88
static wglBindTexImageARBProc wglBindTexImageARBPtr = 0;
 
89
static wglReleaseTexImageARBProc wglReleaseTexImageARBPtr = 0;
 
90
#endif
 
91
 
 
92
//---------------------------------------------------------------------------
 
93
// Function      : RenderTexture::RenderTexture
 
94
// Description   : 
 
95
//---------------------------------------------------------------------------
 
96
/**
 
97
* @fn RenderTexture::RenderTexture()
 
98
* @brief Mode-string-based Constructor.
 
99
*/ 
 
100
RenderTexture::RenderTexture(const char *strMode)
 
101
:   _iWidth(0), 
 
102
    _iHeight(0), 
 
103
    _bIsTexture(false),
 
104
    _bIsDepthTexture(false),
 
105
    _bHasARBDepthTexture(true),            // [Redge]
 
106
#ifdef _WIN32
 
107
    _eUpdateMode(RT_RENDER_TO_TEXTURE),
 
108
#else
 
109
    _eUpdateMode(RT_COPY_TO_TEXTURE),
 
110
#endif
 
111
    _bInitialized(false),
 
112
    _iNumAuxBuffers(0),
 
113
    _bIsBufferBound(false),
 
114
    _iCurrentBoundBuffer(0),
 
115
    _iNumDepthBits(0),
 
116
    _iNumStencilBits(0),
 
117
    _bFloat(false),
 
118
    _bDoubleBuffered(false),
 
119
    _bPowerOf2(true),
 
120
    _bRectangle(false),
 
121
    _bMipmap(false),
 
122
    _bShareObjects(false),
 
123
    _bCopyContext(false),
 
124
#ifdef _WIN32
 
125
    _hDC(NULL), 
 
126
    _hGLContext(NULL), 
 
127
    _hPBuffer(NULL),
 
128
    _hPreviousDC(0),
 
129
    _hPreviousContext(0),
 
130
#elif defined( __APPLE__ )
 
131
#else
 
132
    _pDisplay(NULL),
 
133
    _hGLContext(NULL),
 
134
    _hPBuffer(0),
 
135
    _hPreviousContext(0),
 
136
    _hPreviousDrawable(0),
 
137
#endif
 
138
    _iTextureTarget(GL_NONE),
 
139
    _iTextureID(0),
 
140
    _iDepthTextureID(0),
 
141
    _pPoorDepthTexture(0) // [Redge]
 
142
{
 
143
    _iNumColorBits[0] = _iNumColorBits[1] = 
 
144
        _iNumColorBits[2] = _iNumColorBits[3] = 0;
 
145
 
 
146
#ifdef _WIN32
 
147
    _pixelFormatAttribs.push_back(WGL_DRAW_TO_PBUFFER_ARB);
 
148
    _pixelFormatAttribs.push_back(true);
 
149
    _pixelFormatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB);
 
150
    _pixelFormatAttribs.push_back(true);
 
151
    
 
152
    _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
 
153
    _pbufferAttribs.push_back(true);
 
154
#elif defined( __APPLE__ )
 
155
#else
 
156
    _pbufferAttribs.push_back(GLX_RENDER_TYPE_SGIX);
 
157
    _pbufferAttribs.push_back(GLX_RGBA_BIT_SGIX);
 
158
    _pbufferAttribs.push_back(GLX_DRAWABLE_TYPE_SGIX);
 
159
    _pbufferAttribs.push_back(GLX_PBUFFER_BIT_SGIX);
 
160
#endif
 
161
 
 
162
    _ParseModeString(strMode, _pixelFormatAttribs, _pbufferAttribs);
 
163
 
 
164
#ifdef _WIN32
 
165
    _pixelFormatAttribs.push_back(0);
 
166
    _pbufferAttribs.push_back(0);
 
167
#else
 
168
    _pixelFormatAttribs.push_back(None);
 
169
#endif
 
170
}
 
171
 
 
172
 
 
173
//---------------------------------------------------------------------------
 
174
// Function             : RenderTexture::~RenderTexture
 
175
// Description      : 
 
176
//---------------------------------------------------------------------------
 
177
/**
 
178
* @fn RenderTexture::~RenderTexture()
 
179
* @brief Destructor.
 
180
*/ 
 
181
RenderTexture::~RenderTexture()
 
182
{
 
183
    _Invalidate();
 
184
}
 
185
 
 
186
 
 
187
//---------------------------------------------------------------------------
 
188
// Function             : _wglGetLastError
 
189
// Description      : 
 
190
//---------------------------------------------------------------------------
 
191
/**
 
192
* @fn wglGetLastError()
 
193
* @brief Returns the last windows error generated.
 
194
*/ 
 
195
#ifdef _WIN32
 
196
void _wglGetLastError()
 
197
{
 
198
#ifdef _DEBUG
 
199
    
 
200
    DWORD err = GetLastError();
 
201
    switch(err)
 
202
    {
 
203
    case ERROR_INVALID_PIXEL_FORMAT:
 
204
        fprintf(stderr, 
 
205
                "RenderTexture Win32 Error:  ERROR_INVALID_PIXEL_FORMAT\n");
 
206
        break;
 
207
    case ERROR_NO_SYSTEM_RESOURCES:
 
208
        fprintf(stderr, 
 
209
                "RenderTexture Win32 Error:  ERROR_NO_SYSTEM_RESOURCES\n");
 
210
        break;
 
211
    case ERROR_INVALID_DATA:
 
212
        fprintf(stderr, 
 
213
                "RenderTexture Win32 Error:  ERROR_INVALID_DATA\n");
 
214
        break;
 
215
    case ERROR_INVALID_WINDOW_HANDLE:
 
216
        fprintf(stderr, 
 
217
                "RenderTexture Win32 Error:  ERROR_INVALID_WINDOW_HANDLE\n");
 
218
        break;
 
219
    case ERROR_RESOURCE_TYPE_NOT_FOUND:
 
220
        fprintf(stderr, 
 
221
                "RenderTexture Win32 Error:  ERROR_RESOURCE_TYPE_NOT_FOUND\n");
 
222
        break;
 
223
    case ERROR_SUCCESS:
 
224
        // no error
 
225
        break;
 
226
    default:
 
227
        LPVOID lpMsgBuf;
 
228
        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
 
229
            FORMAT_MESSAGE_FROM_SYSTEM | 
 
230
            FORMAT_MESSAGE_IGNORE_INSERTS,
 
231
            NULL,
 
232
            err,
 
233
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
 
234
            (LPTSTR) &lpMsgBuf,
 
235
            0,
 
236
            NULL);
 
237
        
 
238
        fprintf(stderr, "RenderTexture Win32 Error %d: %s\n", err, lpMsgBuf);
 
239
        LocalFree( lpMsgBuf );
 
240
        break;
 
241
    }
 
242
    SetLastError(0);
 
243
    
 
244
#endif // _DEBUG
 
245
}
 
246
#endif
 
247
 
 
248
//---------------------------------------------------------------------------
 
249
// Function             : PrintExtensionError
 
250
// Description      : 
 
251
//---------------------------------------------------------------------------
 
252
/**
 
253
* @fn PrintExtensionError( char* strMsg, ... )
 
254
* @brief Prints an error about missing OpenGL extensions.
 
255
*/ 
 
256
void PrintExtensionError( char* strMsg, ... )
 
257
{
 
258
    fprintf(stderr, 
 
259
            "Error: RenderTexture requires the following unsupported "
 
260
            "OpenGL extensions: \n");
 
261
    char strBuffer[512];
 
262
    va_list args;
 
263
    va_start(args, strMsg);
 
264
#if defined _WIN32 && !defined __CYGWIN__
 
265
    _vsnprintf( strBuffer, 512, strMsg, args );
 
266
#else
 
267
    vsnprintf( strBuffer, 512, strMsg, args );
 
268
#endif
 
269
    va_end(args);
 
270
    
 
271
    fprintf(stderr, strMsg);
 
272
}
 
273
 
 
274
//---------------------------------------------------------------------------
 
275
// Function             : RenderTexture::Initialize
 
276
// Description      : 
 
277
//---------------------------------------------------------------------------
 
278
/**
 
279
* @fn RenderTexture::Initialize(int width, int height, bool shareObjects, bool copyContext);
 
280
* @brief Initializes the RenderTexture, sharing display lists and textures if specified.
 
281
 
282
* This function creates of the p-buffer.  It can only be called once a GL 
 
283
* context has already been created.  
 
284
*/ 
 
285
bool RenderTexture::Initialize(int width, int height,
 
286
                                bool shareObjects       /* = true */,
 
287
                                bool copyContext        /* = false */)
 
288
{
 
289
    assert(width > 0 && height > 0);
 
290
 
 
291
    _iWidth = width; _iHeight = height;
 
292
    _bPowerOf2 = IsPowerOfTwo(width) && IsPowerOfTwo(height);
 
293
 
 
294
    _bShareObjects = shareObjects;
 
295
    _bCopyContext  = copyContext;
 
296
 
 
297
    // Check if this is an NVXX GPU and verify necessary extensions.
 
298
    if (!_VerifyExtensions())
 
299
        return false;
 
300
    
 
301
    if (_bInitialized)
 
302
        _Invalidate();
 
303
 
 
304
#ifdef _WIN32
 
305
    // Get the current context.
 
306
    HDC hdc = wglGetCurrentDC();
 
307
    if (NULL == hdc)
 
308
        _wglGetLastError();
 
309
    HGLRC hglrc = wglGetCurrentContext();
 
310
    if (NULL == hglrc)
 
311
        _wglGetLastError();
 
312
    
 
313
    int iFormat = 0;
 
314
    unsigned int iNumFormats;
 
315
    
 
316
    if (_bCopyContext)
 
317
    {
 
318
        // Get the pixel format for the on-screen window.
 
319
        iFormat = GetPixelFormat(hdc);
 
320
        if (iFormat == 0)
 
321
        {
 
322
            fprintf(stderr, 
 
323
                    "RenderTexture Error: GetPixelFormat() failed.\n");
 
324
            return false;
 
325
        }
 
326
    }
 
327
    else 
 
328
    {
 
329
        if (!wglChoosePixelFormatARBPtr(hdc, &_pixelFormatAttribs[0], NULL, 
 
330
                                     1, &iFormat, &iNumFormats))
 
331
        {
 
332
            fprintf(stderr, 
 
333
                "RenderTexture Error: wglChoosePixelFormatARB() failed.\n");
 
334
            _wglGetLastError();
 
335
            return false;
 
336
        }
 
337
        if ( iNumFormats <= 0 )
 
338
        {
 
339
            fprintf(stderr, 
 
340
                    "RenderTexture Error: Couldn't find a suitable "
 
341
                    "pixel format.\n");
 
342
            _wglGetLastError();
 
343
            return false;
 
344
        }
 
345
    }
 
346
    
 
347
    // Create the p-buffer.    
 
348
    _hPBuffer = wglCreatePbufferARBPtr(hdc, iFormat, _iWidth, _iHeight, 
 
349
                                    &_pbufferAttribs[0]);
 
350
    if (!_hPBuffer)
 
351
    {
 
352
        fprintf(stderr, 
 
353
                "RenderTexture Error: wglCreatePbufferARB() failed.\n");
 
354
        _wglGetLastError();
 
355
        return false;
 
356
    }
 
357
    
 
358
    // Get the device context.
 
359
    _hDC = wglGetPbufferDCARBPtr( _hPBuffer);
 
360
    if ( !_hDC )
 
361
    {
 
362
        fprintf(stderr, 
 
363
                "RenderTexture Error: wglGetGetPbufferDCARB() failed.\n");
 
364
        _wglGetLastError();
 
365
        return false;
 
366
    }
 
367
    
 
368
    // Create a gl context for the p-buffer.
 
369
    if (_bCopyContext)
 
370
    {
 
371
        // Let's use the same gl context..
 
372
        // Since the device contexts are compatible (i.e. same pixelformat),
 
373
        // we should be able to use the same gl rendering context.
 
374
        _hGLContext = hglrc;
 
375
    }
 
376
    else
 
377
    {
 
378
        _hGLContext = wglCreateContext( _hDC );
 
379
        if ( !_hGLContext )
 
380
        {
 
381
            fprintf(stderr, 
 
382
                    "RenderTexture Error: wglCreateContext() failed.\n");
 
383
            _wglGetLastError();
 
384
            return false;
 
385
        }
 
386
    }
 
387
    
 
388
    // Share lists, texture objects, and program objects.
 
389
    if( _bShareObjects )
 
390
    {
 
391
        if( !wglShareLists(hglrc, _hGLContext) )
 
392
        {
 
393
            fprintf(stderr, 
 
394
                    "RenderTexture Error: wglShareLists() failed.\n");
 
395
            _wglGetLastError();
 
396
            return false;
 
397
        }
 
398
    }
 
399
    
 
400
    // Determine the actual width and height we were able to create.
 
401
    wglQueryPbufferARBPtr( _hPBuffer, WGL_PBUFFER_WIDTH_ARB, &_iWidth );
 
402
    wglQueryPbufferARBPtr( _hPBuffer, WGL_PBUFFER_HEIGHT_ARB, &_iHeight );
 
403
    
 
404
    _bInitialized = true;
 
405
    
 
406
    // get the actual number of bits allocated:
 
407
    int attrib = WGL_RED_BITS_ARB;
 
408
    //int bits[6];
 
409
    int value;
 
410
    _iNumColorBits[0] = 
 
411
        (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value)) 
 
412
        ? value : 0;
 
413
    attrib = WGL_GREEN_BITS_ARB;
 
414
    _iNumColorBits[1] = 
 
415
        (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value)) 
 
416
        ? value : 0;
 
417
    attrib = WGL_BLUE_BITS_ARB;
 
418
    _iNumColorBits[2] = 
 
419
        (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value)) 
 
420
        ? value : 0;
 
421
    attrib = WGL_ALPHA_BITS_ARB;
 
422
    _iNumColorBits[3] = 
 
423
        (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value)) 
 
424
        ? value : 0; 
 
425
    attrib = WGL_DEPTH_BITS_ARB;
 
426
    _iNumDepthBits = 
 
427
        (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value)) 
 
428
        ? value : 0; 
 
429
    attrib = WGL_STENCIL_BITS_ARB;
 
430
    _iNumStencilBits = 
 
431
        (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value)) 
 
432
        ? value : 0; 
 
433
    attrib = WGL_DOUBLE_BUFFER_ARB;
 
434
    _bDoubleBuffered = 
 
435
        (wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value)) 
 
436
        ? (value?true:false) : false; 
 
437
    
 
438
#if defined(_DEBUG) | defined(DEBUG)
 
439
    fprintf(stderr, "Created a %dx%d RenderTexture with BPP(%d, %d, %d, %d)",
 
440
        _iWidth, _iHeight, 
 
441
        _iNumColorBits[0], _iNumColorBits[1], 
 
442
        _iNumColorBits[2], _iNumColorBits[3]);
 
443
    if (_iNumDepthBits) fprintf(stderr, " depth=%d", _iNumDepthBits);
 
444
    if (_iNumStencilBits) fprintf(stderr, " stencil=%d", _iNumStencilBits);
 
445
    if (_bDoubleBuffered) fprintf(stderr, " double buffered");
 
446
    fprintf(stderr, "\n");
 
447
#endif
 
448
 
 
449
#elif defined( __APPLE__ )
 
450
#else // !_WIN32
 
451
    _pDisplay = glXGetCurrentDisplay();
 
452
    GLXContext context = glXGetCurrentContext();
 
453
    int screen = DefaultScreen(_pDisplay);
 
454
    XVisualInfo *visInfo;
 
455
    
 
456
    int iFormat = 0;
 
457
    int iNumFormats;
 
458
    int attrib = 0;
 
459
    
 
460
    GLXFBConfigSGIX *fbConfigs;
 
461
    int nConfigs;
 
462
    
 
463
    fbConfigs = glXChooseFBConfigSGIX(_pDisplay, screen, 
 
464
                                      &_pixelFormatAttribs[0], &nConfigs);
 
465
    
 
466
    if (nConfigs == 0 || !fbConfigs) 
 
467
    {
 
468
        fprintf(stderr,
 
469
            "RenderTexture Error: Couldn't find a suitable pixel format.\n");
 
470
        return false;
 
471
    }
 
472
    
 
473
    // Pick the first returned format that will return a pbuffer
 
474
    for (int i=0;i<nConfigs;i++)
 
475
    {
 
476
        _hPBuffer = glXCreateGLXPbufferSGIX(_pDisplay, fbConfigs[i], 
 
477
                                            _iWidth, _iHeight, NULL);
 
478
        if (_hPBuffer) 
 
479
        {
 
480
            _hGLContext = glXCreateContextWithConfigSGIX(_pDisplay, 
 
481
                                                         fbConfigs[i], 
 
482
                                                         GLX_RGBA_TYPE, 
 
483
                                                         _bShareObjects ? context : NULL, 
 
484
                                                         True);
 
485
            break;
 
486
        }
 
487
    }
 
488
    
 
489
    if (!_hPBuffer)
 
490
    {
 
491
        fprintf(stderr, 
 
492
                "RenderTexture Error: glXCreateGLXPbufferSGIX() failed.\n");
 
493
        return false;
 
494
    }
 
495
    
 
496
    if(!_hGLContext)
 
497
    {
 
498
        // Try indirect
 
499
        _hGLContext = glXCreateContext(_pDisplay, visInfo, 
 
500
                                       _bShareObjects ? context : NULL, False);
 
501
        if ( !_hGLContext )
 
502
        {
 
503
            fprintf(stderr, 
 
504
                    "RenderTexture Error: glXCreateContext() failed.\n");
 
505
            return false;
 
506
        }
 
507
    }
 
508
    
 
509
    glXQueryGLXPbufferSGIX(_pDisplay, _hPBuffer, GLX_WIDTH_SGIX, 
 
510
                           (GLuint*)&_iWidth);
 
511
    glXQueryGLXPbufferSGIX(_pDisplay, _hPBuffer, GLX_HEIGHT_SGIX, 
 
512
                           (GLuint*)&_iHeight);
 
513
    
 
514
    _bInitialized = true;
 
515
    
 
516
    // XXX Query the color format
 
517
    
 
518
#endif
 
519
 
 
520
    
 
521
    // Now that the pbuffer is created, allocate any texture objects needed,
 
522
    // and initialize them (for CTT updates only).  These must be allocated
 
523
    // in the context of the pbuffer, though, or the RT won't work without
 
524
    // wglShareLists.
 
525
#ifdef _WIN32
 
526
    if (false == wglMakeCurrent( _hDC, _hGLContext))
 
527
    {
 
528
        _wglGetLastError();
 
529
        return false;
 
530
    }
 
531
#elif defined( __APPLE__ )
 
532
#else
 
533
    _hPreviousContext = glXGetCurrentContext();
 
534
    _hPreviousDrawable = glXGetCurrentDrawable();
 
535
    
 
536
    if (False == glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext)) 
 
537
    {
 
538
        return false;
 
539
    }
 
540
#endif
 
541
    
 
542
    bool result = _InitializeTextures();   
 
543
#ifdef _WIN32
 
544
    BindBuffer(WGL_FRONT_LEFT_ARB);
 
545
    _BindDepthBuffer();
 
546
#endif
 
547
 
 
548
    
 
549
#ifdef _WIN32 
 
550
    // make the previous rendering context current 
 
551
    if (false == wglMakeCurrent( hdc, hglrc))
 
552
    {
 
553
        _wglGetLastError();
 
554
        return false;
 
555
    }
 
556
#elif defined( __APPLE__ )
 
557
#else
 
558
    if (False == glXMakeCurrent(_pDisplay, 
 
559
                                _hPreviousDrawable, _hPreviousContext))
 
560
    {
 
561
        return false;
 
562
    }
 
563
#endif
 
564
 
 
565
    return result;
 
566
}
 
567
 
 
568
 
 
569
//---------------------------------------------------------------------------
 
570
// Function             : RenderTexture::_Invalidate
 
571
// Description      : 
 
572
//---------------------------------------------------------------------------
 
573
/**
 
574
* @fn RenderTexture::_Invalidate()
 
575
* @brief Returns the pbuffer memory to the graphics device.
 
576
 
577
*/ 
 
578
bool RenderTexture::_Invalidate()
 
579
{
 
580
    _iNumColorBits[0] = _iNumColorBits[1] = 
 
581
        _iNumColorBits[2] = _iNumColorBits[3] = 0;
 
582
    _iNumDepthBits = 0;
 
583
    _iNumStencilBits = 0;
 
584
    
 
585
    if (_bIsTexture)
 
586
        glDeleteTextures(1, &_iTextureID);
 
587
    if (_bIsDepthTexture) 
 
588
    {
 
589
        // [Redge]
 
590
        if (!_bHasARBDepthTexture) delete[] _pPoorDepthTexture;
 
591
        // [/Redge]
 
592
        glDeleteTextures(1, &_iDepthTextureID);
 
593
    }
 
594
    
 
595
#ifdef _WIN32
 
596
    if ( _hPBuffer )
 
597
    {
 
598
        // Check if we are currently rendering in the pbuffer
 
599
        if (wglGetCurrentContext() == _hGLContext)
 
600
            wglMakeCurrent(0,0);
 
601
        if (!_bCopyContext) 
 
602
            wglDeleteContext( _hGLContext);
 
603
        wglReleasePbufferDCARBPtr( _hPBuffer, _hDC);
 
604
        wglDestroyPbufferARBPtr( _hPBuffer );
 
605
        _hPBuffer = 0;
 
606
        return true;
 
607
    }
 
608
#elif defined( __APPLE__ )
 
609
#else
 
610
    if ( _hPBuffer )
 
611
    {
 
612
        if(glXGetCurrentContext() == _hGLContext)
 
613
            // XXX I don't know if this is right at all
 
614
            glXMakeCurrent(_pDisplay, _hPBuffer, 0);
 
615
        glXDestroyGLXPbufferSGIX(_pDisplay, _hPBuffer);
 
616
        _hPBuffer = 0;
 
617
        return true;
 
618
    }
 
619
#endif
 
620
 
 
621
    // [WVB] do we need to call _ReleaseBoundBuffers() too?
 
622
    return false;
 
623
}
 
624
 
 
625
 
 
626
//---------------------------------------------------------------------------
 
627
// Function             : RenderTexture::Reset
 
628
// Description      : 
 
629
//---------------------------------------------------------------------------
 
630
/**
 
631
* @fn RenderTexture::Reset()
 
632
* @brief Resets the resolution of the offscreen buffer.
 
633
 
634
* Causes the buffer to delete itself.  User must call Initialize() again
 
635
* before use.
 
636
*/ 
 
637
bool RenderTexture::Reset(const char *strMode, ...)
 
638
{
 
639
    _iWidth = 0; _iHeight = 0; 
 
640
    _bIsTexture = false; _bIsDepthTexture = false,
 
641
    _bHasARBDepthTexture = true;
 
642
#ifdef _WIN32
 
643
    _eUpdateMode = RT_RENDER_TO_TEXTURE;
 
644
#else
 
645
    _eUpdateMode = RT_COPY_TO_TEXTURE;
 
646
#endif
 
647
    _bInitialized = false;
 
648
    _iNumAuxBuffers = 0; 
 
649
    _bIsBufferBound = false;
 
650
    _iCurrentBoundBuffer = 0;
 
651
    _iNumDepthBits = 0; _iNumStencilBits = 0;
 
652
    _bDoubleBuffered = false;
 
653
    _bFloat = false; _bPowerOf2 = true;
 
654
    _bRectangle = false; _bMipmap = false; 
 
655
    _bShareObjects = false; _bCopyContext = false; 
 
656
    _iTextureTarget = GL_NONE; _iTextureID = 0; 
 
657
    _iDepthTextureID = 0;
 
658
    _pPoorDepthTexture = 0;
 
659
    _pixelFormatAttribs.clear();
 
660
    _pbufferAttribs.clear();
 
661
 
 
662
    if (IsInitialized() && !_Invalidate())
 
663
    {
 
664
        fprintf(stderr, "RenderTexture::Reset(): failed to invalidate.\n");
 
665
        return false;
 
666
    }
 
667
    
 
668
    _iNumColorBits[0] = _iNumColorBits[1] = 
 
669
        _iNumColorBits[2] = _iNumColorBits[3] = 0;
 
670
 
 
671
#ifdef _WIN32
 
672
    _pixelFormatAttribs.push_back(WGL_DRAW_TO_PBUFFER_ARB);
 
673
    _pixelFormatAttribs.push_back(true);
 
674
    _pixelFormatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB);
 
675
    _pixelFormatAttribs.push_back(true);
 
676
    
 
677
    _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
 
678
    _pbufferAttribs.push_back(true);
 
679
#elif defined( __APPLE__ )
 
680
#else
 
681
    _pbufferAttribs.push_back(GLX_RENDER_TYPE_SGIX);
 
682
    _pbufferAttribs.push_back(GLX_RGBA_BIT_SGIX);
 
683
    _pbufferAttribs.push_back(GLX_DRAWABLE_TYPE_SGIX);
 
684
    _pbufferAttribs.push_back(GLX_PBUFFER_BIT_SGIX);
 
685
#endif
 
686
 
 
687
    va_list args;
 
688
    char strBuffer[256];
 
689
    va_start(args,strMode);
 
690
#if defined _WIN32 && !defined __CYGWIN__
 
691
    _vsnprintf( strBuffer, 256, strMode, args );
 
692
#else
 
693
    vsnprintf( strBuffer, 256, strMode, args );
 
694
#endif
 
695
    va_end(args);
 
696
 
 
697
    _ParseModeString(strBuffer, _pixelFormatAttribs, _pbufferAttribs);
 
698
 
 
699
#ifdef _WIN32
 
700
    _pixelFormatAttribs.push_back(0);
 
701
    _pbufferAttribs.push_back(0);
 
702
#else
 
703
    _pixelFormatAttribs.push_back(None);
 
704
#endif
 
705
    return true;
 
706
}
 
707
 
 
708
//------------------------------------------------------------------------------
 
709
// Function               : RenderTexture::Resize
 
710
// Description      : 
 
711
//------------------------------------------------------------------------------
 
712
/**
 
713
 * @fn RenderTexture::Resize(int iWidth, int iHeight)
 
714
 * @brief Changes the size of the offscreen buffer.
 
715
 * 
 
716
 * Like Reset() this causes the buffer to delete itself.  
 
717
 * But unlike Reset(), this call re-initializes the RenderTexture.
 
718
 * Note that Resize() will not work after calling Reset(), or before
 
719
 * calling Initialize() the first time.
 
720
 */ 
 
721
bool RenderTexture::Resize(int iWidth, int iHeight)
 
722
{
 
723
    if (!_bInitialized) {
 
724
        fprintf(stderr, "RenderTexture::Resize(): must Initialize() first.\n");
 
725
        return false;
 
726
    }
 
727
    if (iWidth == _iWidth && iHeight == _iHeight) {
 
728
        return true;
 
729
    }
 
730
    
 
731
    // Do same basic work as _Invalidate, but don't reset all our flags
 
732
    if (_bIsTexture)
 
733
        glDeleteTextures(1, &_iTextureID);
 
734
    if (_bIsDepthTexture)
 
735
        glDeleteTextures(1, &_iDepthTextureID);
 
736
#ifdef _WIN32
 
737
    if ( _hPBuffer )
 
738
    {
 
739
        // Check if we are currently rendering in the pbuffer
 
740
        if (wglGetCurrentContext() == _hGLContext)
 
741
            wglMakeCurrent(0,0);
 
742
        if (!_bCopyContext) 
 
743
            wglDeleteContext( _hGLContext);
 
744
        wglReleasePbufferDCARBPtr( _hPBuffer, _hDC);
 
745
        wglDestroyPbufferARBPtr( _hPBuffer );
 
746
        _hPBuffer = 0;
 
747
        return true;
 
748
    }
 
749
#elif defined( __APPLE__ )
 
750
#else
 
751
    if ( _hPBuffer )
 
752
    {
 
753
        if(glXGetCurrentContext() == _hGLContext)
 
754
            // XXX I don't know if this is right at all
 
755
            glXMakeCurrent(_pDisplay, _hPBuffer, 0);
 
756
        glXDestroyGLXPbufferSGIX(_pDisplay, _hPBuffer);
 
757
        _hPBuffer = 0;
 
758
    }
 
759
#endif
 
760
    else {
 
761
        fprintf(stderr, "RenderTexture::Resize(): failed to resize.\n");
 
762
        return false;
 
763
    }
 
764
    _bInitialized = false;
 
765
    return Initialize(iWidth, iHeight, _bShareObjects, _bCopyContext);
 
766
}
 
767
 
 
768
//---------------------------------------------------------------------------
 
769
// Function             : RenderTexture::BeginCapture
 
770
// Description      : 
 
771
//---------------------------------------------------------------------------
 
772
/**
 
773
* @fn RenderTexture::BeginCapture()
 
774
* @brief Activates rendering to the RenderTexture.
 
775
*/ 
 
776
bool RenderTexture::BeginCapture()
 
777
{
 
778
    if (!_bInitialized)
 
779
    {
 
780
        fprintf(stderr, 
 
781
                "RenderTexture::BeginCapture(): Texture is not initialized!\n");
 
782
        return false;
 
783
    }
 
784
#ifdef _WIN32
 
785
    // cache the current context so we can reset it when EndCapture() is called.
 
786
    _hPreviousDC      = wglGetCurrentDC();
 
787
    if (NULL == _hPreviousDC)
 
788
        _wglGetLastError();
 
789
    _hPreviousContext = wglGetCurrentContext();
 
790
    if (NULL == _hPreviousContext)
 
791
        _wglGetLastError();
 
792
#elif defined( __APPLE__ )
 
793
#else
 
794
    _hPreviousContext = glXGetCurrentContext();
 
795
    _hPreviousDrawable = glXGetCurrentDrawable();
 
796
#endif
 
797
 
 
798
    _ReleaseBoundBuffers();
 
799
 
 
800
    return _MakeCurrent();
 
801
}
 
802
 
 
803
 
 
804
//---------------------------------------------------------------------------
 
805
// Function             : RenderTexture::EndCapture
 
806
// Description      : 
 
807
//---------------------------------------------------------------------------
 
808
/**
 
809
* @fn RenderTexture::EndCapture()
 
810
* @brief Ends rendering to the RenderTexture.
 
811
*/ 
 
812
bool RenderTexture::EndCapture()
 
813
{    
 
814
    if (!_bInitialized)
 
815
    {
 
816
        fprintf(stderr, 
 
817
                "RenderTexture::EndCapture() : Texture is not initialized!\n");
 
818
        return false;
 
819
    }
 
820
 
 
821
    _MaybeCopyBuffer();
 
822
 
 
823
#ifdef _WIN32
 
824
    // make the previous rendering context current 
 
825
    if (FALSE == wglMakeCurrent( _hPreviousDC, _hPreviousContext))
 
826
    {
 
827
        _wglGetLastError();
 
828
        return false;
 
829
    }
 
830
#elif defined( __APPLE__ )
 
831
#else
 
832
    if (False == glXMakeCurrent(_pDisplay, _hPreviousDrawable, 
 
833
                                _hPreviousContext))
 
834
    {
 
835
        return false;
 
836
    }
 
837
#endif
 
838
 
 
839
    // rebind the textures to a buffers for RTT
 
840
    BindBuffer(_iCurrentBoundBuffer);
 
841
    _BindDepthBuffer();
 
842
 
 
843
    return true;
 
844
}
 
845
 
 
846
//---------------------------------------------------------------------------
 
847
// Function               : RenderTexture::BeginCapture(RenderTexture*)
 
848
// Description      : 
 
849
//---------------------------------------------------------------------------
 
850
/**
 
851
 * @fn RenderTexture::BeginCapture(RenderTexture* other)
 
852
 * @brief Ends capture of 'other', begins capture on 'this'
 
853
 *
 
854
 * When performing a series of operations where you modify one texture after 
 
855
 * another, it is more efficient to use this method instead of the equivalent
 
856
 * 'EndCapture'/'BeginCapture' pair.  This method switches directly to the 
 
857
 * new context rather than changing to the default context, and then to the 
 
858
 * new context.
 
859
 *
 
860
 * RenderTexture doesn't have any mechanism for determining if 
 
861
 * 'current' really is currently active, so no error will be thrown 
 
862
 * if it is not. 
 
863
 */ 
 
864
bool RenderTexture::BeginCapture(RenderTexture* current)
 
865
{
 
866
    bool bContextReset = false;
 
867
    
 
868
    if (current == this) {
 
869
        return true; // no switch necessary
 
870
    }
 
871
    if (!current) {
 
872
        // treat as normal Begin if current is 0.
 
873
        return BeginCapture();
 
874
    }
 
875
    if (!_bInitialized)
 
876
    {
 
877
        fprintf(stderr, 
 
878
            "RenderTexture::BeginCapture(RenderTexture*): Texture is not initialized!\n");
 
879
        return false;
 
880
    }
 
881
    if (!current->_bInitialized)
 
882
    {
 
883
        fprintf(stderr, 
 
884
            "RenderTexture::BeginCapture(RenderTexture): 'current' texture is not initialized!\n");
 
885
        return false;
 
886
    }
 
887
    
 
888
    // Sync current pbuffer with its CTT texture if necessary
 
889
    current->_MaybeCopyBuffer();
 
890
 
 
891
    // pass along the previous context so we can reset it when 
 
892
    // EndCapture() is called.
 
893
#ifdef _WIN32
 
894
    _hPreviousDC      = current->_hPreviousDC;
 
895
    if (NULL == _hPreviousDC)
 
896
        _wglGetLastError();
 
897
    _hPreviousContext = current->_hPreviousContext;
 
898
    if (NULL == _hPreviousContext)
 
899
        _wglGetLastError();
 
900
#elif defined( __APPLE__ )
 
901
#else
 
902
    _hPreviousContext = current->_hPreviousContext;
 
903
    _hPreviousDrawable = current->_hPreviousDrawable;
 
904
#endif    
 
905
 
 
906
    // Unbind textures before making context current
 
907
    if (!_ReleaseBoundBuffers()) 
 
908
      return false;
 
909
 
 
910
    // Make the pbuffer context current
 
911
    if (!_MakeCurrent())
 
912
        return false;
 
913
 
 
914
    // Rebind buffers of initial RenderTexture
 
915
    current->BindBuffer(_iCurrentBoundBuffer);
 
916
    current->_BindDepthBuffer();
 
917
    
 
918
    return true;
 
919
}
 
920
 
 
921
 
 
922
 
 
923
//---------------------------------------------------------------------------
 
924
// Function             : RenderTexture::Bind
 
925
// Description      : 
 
926
//---------------------------------------------------------------------------
 
927
/**
 
928
* @fn RenderTexture::Bind()
 
929
* @brief Binds RGB texture.
 
930
*/ 
 
931
void RenderTexture::Bind() const 
 
932
 
933
    if (_bInitialized && _bIsTexture) 
 
934
    {
 
935
        glBindTexture(_iTextureTarget, _iTextureID);
 
936
    }    
 
937
}
 
938
 
 
939
 
 
940
//---------------------------------------------------------------------------
 
941
// Function             : RenderTexture::BindDepth
 
942
// Description      : 
 
943
//---------------------------------------------------------------------------
 
944
/**
 
945
* @fn RenderTexture::BindDepth()
 
946
* @brief Binds depth texture.
 
947
*/ 
 
948
void RenderTexture::BindDepth() const 
 
949
 
950
    if (_bInitialized && _bIsDepthTexture) 
 
951
    {
 
952
        glBindTexture(_iTextureTarget, _iDepthTextureID); 
 
953
    }
 
954
}
 
955
 
 
956
 
 
957
//---------------------------------------------------------------------------
 
958
// Function             : RenderTexture::BindBuffer
 
959
// Description      : 
 
960
//---------------------------------------------------------------------------
 
961
/**
 
962
* @fn RenderTexture::BindBuffer()
 
963
* @brief Associate the RTT texture id with 'iBuffer' (e.g. WGL_FRONT_LEFT_ARB)
 
964
*/ 
 
965
bool RenderTexture::BindBuffer( int iBuffer )
 
966
 
967
    // Must bind the texture too
 
968
    if (_bInitialized && _bIsTexture) 
 
969
    {
 
970
        glBindTexture(_iTextureTarget, _iTextureID);
 
971
        
 
972
#ifdef _WIN32
 
973
        if (RT_RENDER_TO_TEXTURE == _eUpdateMode && _bIsTexture &&
 
974
            (!_bIsBufferBound || _iCurrentBoundBuffer != iBuffer))
 
975
        {
 
976
            if (FALSE == wglBindTexImageARBPtr(_hPBuffer, iBuffer))
 
977
            {
 
978
                //  WVB: WGL API considers binding twice to the same buffer
 
979
                //  to be an error.  But we don't want to 
 
980
                //_wglGetLastError();
 
981
                //return false;
 
982
                SetLastError(0);
 
983
            }
 
984
            _bIsBufferBound = true;
 
985
            _iCurrentBoundBuffer = iBuffer;
 
986
        }
 
987
#endif
 
988
    }    
 
989
    return true;
 
990
}
 
991
 
 
992
 
 
993
//---------------------------------------------------------------------------
 
994
// Function             : RenderTexture::BindBuffer
 
995
// Description      : 
 
996
//---------------------------------------------------------------------------
 
997
/**
 
998
* @fn RenderTexture::_BindDepthBuffer()
 
999
* @brief Associate the RTT depth texture id with the depth buffer
 
1000
*/ 
 
1001
bool RenderTexture::_BindDepthBuffer() const
 
1002
{
 
1003
#ifdef WIN32
 
1004
    if (_bInitialized && _bIsDepthTexture && 
 
1005
        RT_RENDER_TO_TEXTURE == _eUpdateMode)
 
1006
    {
 
1007
        glBindTexture(_iTextureTarget, _iDepthTextureID);
 
1008
        if (FALSE == wglBindTexImageARBPtr(_hPBuffer, WGL_DEPTH_COMPONENT_NV))
 
1009
        {
 
1010
            _wglGetLastError();
 
1011
            return false;
 
1012
        }
 
1013
    }
 
1014
#endif
 
1015
    return true;
 
1016
}
 
1017
 
 
1018
//---------------------------------------------------------------------------
 
1019
// Function             : RenderTexture::_ParseModeString
 
1020
// Description      : 
 
1021
//---------------------------------------------------------------------------
 
1022
/**
 
1023
* @fn RenderTexture::_ParseModeString()
 
1024
* @brief Parses the user-specified mode string for RenderTexture parameters.
 
1025
*/ 
 
1026
void RenderTexture::_ParseModeString(const char *modeString, 
 
1027
                                     vector<int> &pfAttribs, 
 
1028
                                     vector<int> &pbAttribs)
 
1029
{
 
1030
    if (!modeString || strcmp(modeString, "") == 0)
 
1031
        return;
 
1032
 
 
1033
        _iNumComponents = 0;
 
1034
#ifdef _WIN32
 
1035
    _eUpdateMode = RT_RENDER_TO_TEXTURE;
 
1036
#else
 
1037
    _eUpdateMode = RT_COPY_TO_TEXTURE;
 
1038
#endif
 
1039
    
 
1040
    int  iDepthBits = 0;
 
1041
    bool bHasStencil = false;
 
1042
    bool bBind2D   = false;
 
1043
    bool bBindRECT = false;
 
1044
    bool bBindCUBE = false;
 
1045
    
 
1046
    char *mode = strdup(modeString);
 
1047
    
 
1048
 
 
1049
    vector<string> tokens;
 
1050
    char *buf = strtok(mode, " ");
 
1051
    while (buf != NULL)
 
1052
    {
 
1053
        tokens.push_back(buf);
 
1054
        buf = strtok(NULL, " ");
 
1055
    }
 
1056
 
 
1057
    for (unsigned int i = 0; i < tokens.size(); i++)
 
1058
    {
 
1059
        string token = tokens[i];
 
1060
 
 
1061
        KeyVal kv = _GetKeyValuePair(token);
 
1062
        
 
1063
        
 
1064
        if (kv.first == "rgb" && (_iNumComponents <= 1))
 
1065
        {           
 
1066
            if (kv.second.find("f") != kv.second.npos)
 
1067
                _bFloat = true;
 
1068
 
 
1069
            vector<int> bitVec = _ParseBitVector(kv.second);
 
1070
 
 
1071
            if (bitVec.size() < 3) // expand the scalar to a vector
 
1072
            {
 
1073
                bitVec.push_back(bitVec[0]);
 
1074
                bitVec.push_back(bitVec[0]);
 
1075
            }
 
1076
 
 
1077
#ifdef _WIN32
 
1078
            pfAttribs.push_back(WGL_RED_BITS_ARB);
 
1079
            pfAttribs.push_back(bitVec[0]);
 
1080
            pfAttribs.push_back(WGL_GREEN_BITS_ARB);
 
1081
            pfAttribs.push_back(bitVec[1]);
 
1082
            pfAttribs.push_back(WGL_BLUE_BITS_ARB);
 
1083
            pfAttribs.push_back(bitVec[2]);
 
1084
#elif defined( __APPLE__ )
 
1085
            pfAttribs.push_back(AGL_RED_SIZE);
 
1086
            pfAttribs.push_back(bitVec[0]);
 
1087
            pfAttribs.push_back(AGL_GREEN_SIZE);
 
1088
            pfAttribs.push_back(bitVec[1]);
 
1089
            pfAttribs.push_back(AGL_BLUE_SIZE);
 
1090
            pfAttribs.push_back(bitVec[2]);
 
1091
#else
 
1092
# ifndef sgi
 
1093
            pfAttribs.push_back(GLX_RED_SIZE);
 
1094
            pfAttribs.push_back(bitVec[0]);
 
1095
            pfAttribs.push_back(GLX_GREEN_SIZE);
 
1096
            pfAttribs.push_back(bitVec[1]);
 
1097
            pfAttribs.push_back(GLX_BLUE_SIZE);
 
1098
            pfAttribs.push_back(bitVec[2]);
 
1099
# endif
 
1100
#endif
 
1101
                        _iNumComponents += 3;
 
1102
            continue;
 
1103
        }
 
1104
                else if (kv.first == "rgb") 
 
1105
            fprintf(stderr, 
 
1106
                    "RenderTexture Warning: mistake in components definition "
 
1107
                    "(rgb + %d).\n", 
 
1108
                    _iNumComponents);
 
1109
 
 
1110
        
 
1111
        if (kv.first == "rgba" && (_iNumComponents == 0))
 
1112
        {
 
1113
            if (kv.second.find("f") != kv.second.npos)
 
1114
                _bFloat = true;
 
1115
 
 
1116
            vector<int> bitVec = _ParseBitVector(kv.second);
 
1117
 
 
1118
            if (bitVec.size() < 4) // expand the scalar to a vector
 
1119
            {
 
1120
                bitVec.push_back(bitVec[0]);
 
1121
                bitVec.push_back(bitVec[0]);
 
1122
                bitVec.push_back(bitVec[0]);
 
1123
            }
 
1124
 
 
1125
#ifdef _WIN32
 
1126
            pfAttribs.push_back(WGL_RED_BITS_ARB);
 
1127
            pfAttribs.push_back(bitVec[0]);
 
1128
            pfAttribs.push_back(WGL_GREEN_BITS_ARB);
 
1129
            pfAttribs.push_back(bitVec[1]);
 
1130
            pfAttribs.push_back(WGL_BLUE_BITS_ARB);
 
1131
            pfAttribs.push_back(bitVec[2]);
 
1132
            pfAttribs.push_back(WGL_ALPHA_BITS_ARB);
 
1133
            pfAttribs.push_back(bitVec[3]);
 
1134
#elif defined( __APPLE__ )
 
1135
            pfAttribs.push_back(AGL_RED_SIZE);
 
1136
            pfAttribs.push_back(bitVec[0]);
 
1137
            pfAttribs.push_back(AGL_GREEN_SIZE);
 
1138
            pfAttribs.push_back(bitVec[1]);
 
1139
            pfAttribs.push_back(AGL_BLUE_SIZE);
 
1140
            pfAttribs.push_back(bitVec[2]);
 
1141
            pfAttribs.push_back(AGL_ALPHA_SIZE);
 
1142
            pfAttribs.push_back(bitVec[3]);
 
1143
#else
 
1144
# ifndef sgi
 
1145
            pfAttribs.push_back(GLX_RED_SIZE);
 
1146
            pfAttribs.push_back(bitVec[0]);
 
1147
            pfAttribs.push_back(GLX_GREEN_SIZE);
 
1148
            pfAttribs.push_back(bitVec[1]);
 
1149
            pfAttribs.push_back(GLX_BLUE_SIZE);
 
1150
            pfAttribs.push_back(bitVec[2]);
 
1151
            pfAttribs.push_back(GLX_ALPHA_SIZE);
 
1152
            pfAttribs.push_back(bitVec[3]);
 
1153
# endif
 
1154
#endif
 
1155
                        _iNumComponents = 4;
 
1156
            continue;
 
1157
        }
 
1158
                else if (kv.first == "rgba") 
 
1159
            fprintf(stderr, 
 
1160
                    "RenderTexture Warning: mistake in components definition "
 
1161
                    "(rgba + %d).\n", 
 
1162
                    _iNumComponents);
 
1163
        
 
1164
        if (kv.first == "r" && (_iNumComponents <= 1))
 
1165
        {
 
1166
            if (kv.second.find("f") != kv.second.npos)
 
1167
                _bFloat = true;
 
1168
 
 
1169
            vector<int> bitVec = _ParseBitVector(kv.second);
 
1170
 
 
1171
#ifdef _WIN32
 
1172
            pfAttribs.push_back(WGL_RED_BITS_ARB);
 
1173
            pfAttribs.push_back(bitVec[0]);
 
1174
#elif defined( __APPLE__ )
 
1175
            pfAttribs.push_back(AGL_RED_SIZE);
 
1176
            pfAttribs.push_back(bitVec[0]);
 
1177
#else
 
1178
            pfAttribs.push_back(GLX_RED_SIZE);
 
1179
            pfAttribs.push_back(bitVec[0]);
 
1180
#endif
 
1181
                        _iNumComponents++;
 
1182
            continue;
 
1183
        }
 
1184
                else if (kv.first == "r") 
 
1185
            fprintf(stderr, 
 
1186
                    "RenderTexture Warning: mistake in components definition "
 
1187
                    "(r + %d).\n", 
 
1188
                    _iNumComponents);
 
1189
 
 
1190
        if (kv.first == "rg" && (_iNumComponents <= 1))
 
1191
        {
 
1192
            if (kv.second.find("f") != kv.second.npos)
 
1193
                _bFloat = true;
 
1194
 
 
1195
            vector<int> bitVec = _ParseBitVector(kv.second);
 
1196
 
 
1197
            if (bitVec.size() < 2) // expand the scalar to a vector
 
1198
            {
 
1199
                bitVec.push_back(bitVec[0]);
 
1200
            }
 
1201
 
 
1202
#ifdef _WIN32
 
1203
            pfAttribs.push_back(WGL_RED_BITS_ARB);
 
1204
            pfAttribs.push_back(bitVec[0]);
 
1205
            pfAttribs.push_back(WGL_GREEN_BITS_ARB);
 
1206
            pfAttribs.push_back(bitVec[1]);
 
1207
#elif defined( __APPLE__ )
 
1208
            pfAttribs.push_back(AGL_RED_SIZE);
 
1209
            pfAttribs.push_back(bitVec[0]);
 
1210
            pfAttribs.push_back(AGL_GREEN_SIZE);
 
1211
            pfAttribs.push_back(bitVec[1]);
 
1212
#else
 
1213
            pfAttribs.push_back(GLX_RED_SIZE);
 
1214
            pfAttribs.push_back(bitVec[0]);
 
1215
            pfAttribs.push_back(GLX_GREEN_SIZE);
 
1216
            pfAttribs.push_back(bitVec[1]);
 
1217
#endif
 
1218
                        _iNumComponents += 2;
 
1219
            continue;
 
1220
        }
 
1221
                else if (kv.first == "rg") 
 
1222
            fprintf(stderr, 
 
1223
                    "RenderTexture Warning: mistake in components definition "
 
1224
                    "(rg + %d).\n", 
 
1225
                    _iNumComponents);
 
1226
 
 
1227
        if (kv.first == "depth")
 
1228
        {
 
1229
            if (kv.second == "")
 
1230
                iDepthBits = 24;
 
1231
            else
 
1232
                iDepthBits = strtol(kv.second.c_str(), 0, 10);
 
1233
            continue;
 
1234
        }
 
1235
 
 
1236
        if (kv.first == "stencil")
 
1237
        {
 
1238
            bHasStencil = true;
 
1239
#ifdef _WIN32
 
1240
            pfAttribs.push_back(WGL_STENCIL_BITS_ARB);
 
1241
#elif defined( __APPLE__ )
 
1242
            pfAttribs.push_back(AGL_STENCIL_SIZE);
 
1243
#else
 
1244
            pfAttribs.push_back(GLX_STENCIL_SIZE);
 
1245
#endif
 
1246
            if (kv.second == "")
 
1247
                pfAttribs.push_back(8);
 
1248
            else
 
1249
                pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
 
1250
            continue;
 
1251
        }
 
1252
 
 
1253
        if (kv.first == "samples")
 
1254
        {
 
1255
#ifdef _WIN32
 
1256
            pfAttribs.push_back(WGL_SAMPLE_BUFFERS_ARB);
 
1257
            pfAttribs.push_back(1);
 
1258
            pfAttribs.push_back(WGL_SAMPLES_ARB);
 
1259
            pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
 
1260
#elif defined( __APPLE__ )
 
1261
            pfAttribs.push_back(AGL_SAMPLE_BUFFERS_ARB);
 
1262
            pfAttribs.push_back(1);
 
1263
            pfAttribs.push_back(AGL_SAMPLES_ARB);
 
1264
            pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
 
1265
#else
 
1266
            pfAttribs.push_back(GL_SAMPLE_BUFFERS_ARB);
 
1267
            pfAttribs.push_back(1);
 
1268
            pfAttribs.push_back(GL_SAMPLES_ARB);
 
1269
            pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
 
1270
#endif
 
1271
            continue;
 
1272
 
 
1273
        }
 
1274
 
 
1275
        if (kv.first == "doublebuffer" || kv.first == "double")
 
1276
        {
 
1277
#ifdef _WIN32
 
1278
            pfAttribs.push_back(WGL_DOUBLE_BUFFER_ARB);
 
1279
            pfAttribs.push_back(true);
 
1280
#elif defined( __APPLE__ )
 
1281
            pfAttribs.push_back(AGL_DOUBLEBUFFER);
 
1282
            pfAttribs.push_back(True);
 
1283
#else
 
1284
            pfAttribs.push_back(GL_DOUBLEBUFFER);
 
1285
            pfAttribs.push_back(True);
 
1286
#endif
 
1287
            continue;
 
1288
        }  
 
1289
        
 
1290
        if (kv.first == "aux")
 
1291
        {
 
1292
#ifdef _WIN32
 
1293
            pfAttribs.push_back(WGL_AUX_BUFFERS_ARB);
 
1294
#elif defined( __APPLE__ )
 
1295
            pfAttribs.push_back(AGL_AUX_BUFFERS);
 
1296
#else
 
1297
            pfAttribs.push_back(GL_AUX_BUFFERS);
 
1298
#endif
 
1299
            if (kv.second == "")
 
1300
                pfAttribs.push_back(0);
 
1301
            else
 
1302
                pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
 
1303
            continue;
 
1304
        }
 
1305
        
 
1306
        if (token.find("tex") == 0)
 
1307
        {            
 
1308
            _bIsTexture = true;
 
1309
            
 
1310
            if ((kv.first == "texRECT") && GL_NV_texture_rectangle)
 
1311
            {
 
1312
                _bRectangle = true;
 
1313
                bBindRECT = true;
 
1314
            }
 
1315
            else if (kv.first == "texCUBE")
 
1316
            {
 
1317
                bBindCUBE = true;
 
1318
            }
 
1319
            else
 
1320
            {
 
1321
                bBind2D = true;
 
1322
            }
 
1323
 
 
1324
            continue;
 
1325
        }
 
1326
 
 
1327
        if (token.find("depthTex") == 0)
 
1328
        {
 
1329
            _bIsDepthTexture = true;
 
1330
            
 
1331
            if ((kv.first == "depthTexRECT") && GL_NV_texture_rectangle)
 
1332
            {
 
1333
                _bRectangle = true;
 
1334
                bBindRECT = true;
 
1335
            }
 
1336
            else if (kv.first == "depthTexCUBE")
 
1337
            {
 
1338
                bBindCUBE = true;
 
1339
            }
 
1340
            else
 
1341
            {
 
1342
                bBind2D = true;
 
1343
            }
 
1344
 
 
1345
            continue;
 
1346
        }
 
1347
 
 
1348
        if (kv.first == "mipmap")
 
1349
        {
 
1350
            _bMipmap = true;    
 
1351
            continue;
 
1352
        }
 
1353
 
 
1354
        if (kv.first == "rtt")
 
1355
        {
 
1356
            _eUpdateMode = RT_RENDER_TO_TEXTURE;
 
1357
            continue;
 
1358
        }
 
1359
        
 
1360
        if (kv.first == "ctt")
 
1361
        {
 
1362
            _eUpdateMode = RT_COPY_TO_TEXTURE;
 
1363
            continue;
 
1364
        }
 
1365
 
 
1366
        fprintf(stderr, 
 
1367
                "RenderTexture Error: Unknown pbuffer attribute: %s\n", 
 
1368
                token.c_str());
 
1369
    }
 
1370
 
 
1371
    // Processing of some options must be last because of interactions.
 
1372
 
 
1373
    // Check for inconsistent texture targets
 
1374
    if (_bIsTexture && _bIsDepthTexture && !(bBind2D ^ bBindRECT ^ bBindCUBE))
 
1375
    {
 
1376
        fprintf(stderr,
 
1377
                "RenderTexture Warning: Depth and Color texture targets "
 
1378
                "should match.\n");
 
1379
    }
 
1380
 
 
1381
    // Apply default bit format if none specified
 
1382
#ifdef _WIN32
 
1383
    if (0 == _iNumComponents)
 
1384
    {
 
1385
        pfAttribs.push_back(WGL_RED_BITS_ARB);
 
1386
        pfAttribs.push_back(8);
 
1387
        pfAttribs.push_back(WGL_GREEN_BITS_ARB);
 
1388
        pfAttribs.push_back(8);
 
1389
        pfAttribs.push_back(WGL_BLUE_BITS_ARB);
 
1390
        pfAttribs.push_back(8);
 
1391
        pfAttribs.push_back(WGL_ALPHA_BITS_ARB);
 
1392
        pfAttribs.push_back(8);
 
1393
        _iNumComponents = 4;
 
1394
    }
 
1395
#endif
 
1396
 
 
1397
    // Depth bits
 
1398
    if (_bIsDepthTexture && !iDepthBits)
 
1399
        iDepthBits = 24;
 
1400
 
 
1401
#ifdef _WIN32
 
1402
    pfAttribs.push_back(WGL_DEPTH_BITS_ARB);
 
1403
#elif defined( __APPLE__ )
 
1404
    pfAttribs.push_back(AGL_DEPTH_SIZE);
 
1405
#else
 
1406
    pfAttribs.push_back(GLX_DEPTH_SIZE);
 
1407
#endif
 
1408
    pfAttribs.push_back(iDepthBits); // default
 
1409
    
 
1410
    if (!bHasStencil)
 
1411
    {
 
1412
#ifdef _WIN32
 
1413
        pfAttribs.push_back(WGL_STENCIL_BITS_ARB);
 
1414
        pfAttribs.push_back(0);
 
1415
#elif defined( __APPLE__ )
 
1416
        pfAttribs.push_back(AGL_STENCIL_SIZE);
 
1417
        pfAttribs.push_back(0);
 
1418
#else
 
1419
        pfAttribs.push_back(GLX_STENCIL_SIZE);
 
1420
        pfAttribs.push_back(0);
 
1421
#endif
 
1422
 
 
1423
    }
 
1424
    if (_iNumComponents < 4)
 
1425
    {
 
1426
        // Can't do this right now -- on NVIDIA drivers, currently get 
 
1427
        // a non-functioning pbuffer if ALPHA_BITS=0 and 
 
1428
        // WGL_BIND_TO_TEXTURE_RGB_ARB=true
 
1429
        
 
1430
        //pfAttribs.push_back(WGL_ALPHA_BITS_ARB); 
 
1431
        //pfAttribs.push_back(0);
 
1432
    }
 
1433
 
 
1434
#ifdef _WIN32
 
1435
    if (!WGL_NV_render_depth_texture && _bIsDepthTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode))
 
1436
    {
 
1437
#if defined(DEBUG) || defined(_DEBUG)
 
1438
        fprintf(stderr, "RenderTexture Warning: No support found for "
 
1439
                "render to depth texture.\n");
 
1440
#endif
 
1441
        _bIsDepthTexture = false;
 
1442
    }
 
1443
#endif
 
1444
    
 
1445
    if ((_bIsTexture || _bIsDepthTexture) && 
 
1446
        (RT_RENDER_TO_TEXTURE == _eUpdateMode))
 
1447
    {
 
1448
#ifdef _WIN32                   
 
1449
        if (bBindRECT)
 
1450
        {
 
1451
            pbAttribs.push_back(WGL_TEXTURE_TARGET_ARB);
 
1452
            pbAttribs.push_back(WGL_TEXTURE_RECTANGLE_NV);
 
1453
        }
 
1454
        else if (bBindCUBE)
 
1455
        {
 
1456
            pbAttribs.push_back(WGL_TEXTURE_TARGET_ARB);
 
1457
            pbAttribs.push_back(WGL_TEXTURE_CUBE_MAP_ARB);
 
1458
        }
 
1459
        else if (bBind2D)
 
1460
        {
 
1461
            pbAttribs.push_back(WGL_TEXTURE_TARGET_ARB);
 
1462
            pbAttribs.push_back(WGL_TEXTURE_2D_ARB);
 
1463
        }
 
1464
            
 
1465
        if (_bMipmap)
 
1466
        {
 
1467
            pbAttribs.push_back(WGL_MIPMAP_TEXTURE_ARB);
 
1468
            pbAttribs.push_back(true);
 
1469
        }
 
1470
 
 
1471
#elif defined(DEBUG) || defined(_DEBUG)
 
1472
        printf("RenderTexture Error: Render to Texture not "
 
1473
               "supported in Linux\n");
 
1474
#endif  
 
1475
    }
 
1476
 
 
1477
    // Set the pixel type
 
1478
    if (_bFloat)
 
1479
    {
 
1480
#ifdef _WIN32
 
1481
        if (WGL_NV_float_buffer)
 
1482
        {
 
1483
            pfAttribs.push_back(WGL_PIXEL_TYPE_ARB);
 
1484
            pfAttribs.push_back(WGL_TYPE_RGBA_ARB);
 
1485
 
 
1486
            pfAttribs.push_back(WGL_FLOAT_COMPONENTS_NV);
 
1487
            pfAttribs.push_back(true);
 
1488
        }
 
1489
        else
 
1490
        {
 
1491
            pfAttribs.push_back(WGL_PIXEL_TYPE_ARB);
 
1492
            pfAttribs.push_back(WGL_TYPE_RGBA_FLOAT_ATI);
 
1493
        }
 
1494
#elif defined( __APPLE__ )
 
1495
#else
 
1496
        if (GL_NV_float_buffer)
 
1497
        {
 
1498
            pfAttribs.push_back(GLX_FLOAT_COMPONENTS_NV);
 
1499
            pfAttribs.push_back(1);
 
1500
        }
 
1501
#endif
 
1502
    }
 
1503
    else
 
1504
    {
 
1505
#ifdef _WIN32
 
1506
        pfAttribs.push_back(WGL_PIXEL_TYPE_ARB);
 
1507
        pfAttribs.push_back(WGL_TYPE_RGBA_ARB);
 
1508
#endif
 
1509
    }
 
1510
 
 
1511
    // Set up texture binding for render to texture
 
1512
    if (_bIsTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode))
 
1513
    {
 
1514
        
 
1515
#ifdef _WIN32
 
1516
        if (_bFloat)
 
1517
        {
 
1518
            if (WGL_NV_float_buffer)
 
1519
            {
 
1520
                switch(_iNumComponents)
 
1521
                {
 
1522
                case 1:
 
1523
                    pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV);
 
1524
                    pfAttribs.push_back(true);
 
1525
                    
 
1526
                    pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
 
1527
                    pbAttribs.push_back(WGL_TEXTURE_FLOAT_R_NV);
 
1528
                    break;
 
1529
                case 2:
 
1530
                    pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV);
 
1531
                    pfAttribs.push_back(true);
 
1532
                    
 
1533
                    pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
 
1534
                    pbAttribs.push_back(WGL_TEXTURE_FLOAT_RG_NV);
 
1535
                    break;
 
1536
                case 3:
 
1537
                    pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV);
 
1538
                    pfAttribs.push_back(true);
 
1539
                    
 
1540
                    pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
 
1541
                    pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGB_NV);
 
1542
                    break;
 
1543
                case 4:
 
1544
                    pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV);
 
1545
                    pfAttribs.push_back(true);
 
1546
                    
 
1547
                    pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
 
1548
                    pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGBA_NV);
 
1549
                    break;
 
1550
                default:
 
1551
                    fprintf(stderr, 
 
1552
                            "RenderTexture Warning: Bad number of components "
 
1553
                            "(r=1,rg=2,rgb=3,rgba=4): %d.\n", 
 
1554
                            _iNumComponents);
 
1555
                    break;
 
1556
                }
 
1557
            }
 
1558
            else
 
1559
            {
 
1560
                if (4 == _iNumComponents)
 
1561
                {
 
1562
                    pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
 
1563
                    pfAttribs.push_back(true);
 
1564
                    
 
1565
                    pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
 
1566
                    pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB);
 
1567
                }
 
1568
                else 
 
1569
                {
 
1570
                    // standard ARB_render_texture only supports 3 or 4 channels
 
1571
                    pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
 
1572
                    pfAttribs.push_back(true);
 
1573
                    
 
1574
                    pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
 
1575
                    pbAttribs.push_back(WGL_TEXTURE_RGB_ARB);
 
1576
                }
 
1577
            }
 
1578
            
 
1579
        } 
 
1580
        else
 
1581
        {
 
1582
            switch(_iNumComponents)
 
1583
            {
 
1584
            case 3:
 
1585
                pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
 
1586
                pfAttribs.push_back(true);
 
1587
                
 
1588
                pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
 
1589
                pbAttribs.push_back(WGL_TEXTURE_RGB_ARB);
 
1590
                break;
 
1591
            case 4:
 
1592
                pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
 
1593
                pfAttribs.push_back(true);
 
1594
                
 
1595
                pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
 
1596
                pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB);
 
1597
                break;
 
1598
            default:
 
1599
                fprintf(stderr, 
 
1600
                        "RenderTexture Warning: Bad number of components "
 
1601
                        "(r=1,rg=2,rgb=3,rgba=4): %d.\n", _iNumComponents);
 
1602
                break;
 
1603
            }
 
1604
        }         
 
1605
#elif defined(DEBUG) || defined(_DEBUG)
 
1606
        fprintf(stderr, 
 
1607
                "RenderTexture Error: Render to Texture not supported in "
 
1608
                "Linux\n");
 
1609
#endif  
 
1610
    }
 
1611
        
 
1612
    if (_bIsDepthTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode))
 
1613
    {  
 
1614
#ifdef _WIN32
 
1615
        if (_bRectangle)
 
1616
        {
 
1617
            pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV);
 
1618
            pfAttribs.push_back(true);
 
1619
        
 
1620
            pbAttribs.push_back(WGL_DEPTH_TEXTURE_FORMAT_NV);
 
1621
            pbAttribs.push_back(WGL_TEXTURE_DEPTH_COMPONENT_NV);
 
1622
        }
 
1623
        else 
 
1624
        {
 
1625
            pfAttribs.push_back(WGL_BIND_TO_TEXTURE_DEPTH_NV);
 
1626
            pfAttribs.push_back(true);
 
1627
        
 
1628
            pbAttribs.push_back(WGL_DEPTH_TEXTURE_FORMAT_NV);
 
1629
            pbAttribs.push_back(WGL_TEXTURE_DEPTH_COMPONENT_NV);
 
1630
        }
 
1631
#elif defined(DEBUG) || defined(_DEBUG)
 
1632
        printf("RenderTexture Error: Render to Texture not supported in "
 
1633
               "Linux\n");
 
1634
#endif 
 
1635
    }
 
1636
}
 
1637
 
 
1638
//---------------------------------------------------------------------------
 
1639
// Function             : RenderTexture::_GetKeyValuePair
 
1640
// Description      : 
 
1641
//---------------------------------------------------------------------------
 
1642
/**
 
1643
* @fn RenderTexture::_GetKeyValuePair()
 
1644
* @brief Parses expressions of the form "X=Y" into a pair (X,Y).
 
1645
*/ 
 
1646
RenderTexture::KeyVal RenderTexture::_GetKeyValuePair(string token)
 
1647
{
 
1648
    string::size_type pos = 0;
 
1649
    if ((pos = token.find("=")) != token.npos)
 
1650
    {
 
1651
        string key = token.substr(0, pos);
 
1652
        string value = token.substr(pos+1, token.length()-pos+1);
 
1653
        return KeyVal(key, value);
 
1654
    }
 
1655
    else
 
1656
        return KeyVal(token, "");
 
1657
}
 
1658
 
 
1659
//---------------------------------------------------------------------------
 
1660
// Function             : RenderTexture::_ParseBitVector
 
1661
// Description      : 
 
1662
//---------------------------------------------------------------------------
 
1663
/**
 
1664
* @fn RenderTexture::_ParseBitVector()
 
1665
* @brief Parses expressions of the form "=r,g,b,a" into a vector: (r,g,b,a)
 
1666
*/ 
 
1667
vector<int> RenderTexture::_ParseBitVector(string bitVector)
 
1668
{
 
1669
    vector<string> pieces;
 
1670
    vector<int> bits;
 
1671
 
 
1672
    if (bitVector == "")
 
1673
    {
 
1674
        bits.push_back(8);  // if a depth isn't specified, use default 8 bits
 
1675
        return bits;
 
1676
    }
 
1677
 
 
1678
    string::size_type pos = 0; 
 
1679
    string::size_type nextpos = 0;
 
1680
    do
 
1681
    { 
 
1682
        nextpos = bitVector.find_first_of(", \n", pos);
 
1683
        pieces.push_back(string(bitVector, pos, nextpos - pos)); 
 
1684
        pos = nextpos+1; 
 
1685
    } while (nextpos != bitVector.npos );
 
1686
 
 
1687
    for ( vector<string>::iterator it = pieces.begin(); it != pieces.end(); it++)
 
1688
    {
 
1689
        bits.push_back(strtol(it->c_str(), 0, 10));
 
1690
    }
 
1691
    
 
1692
    return bits;
 
1693
}
 
1694
 
 
1695
//---------------------------------------------------------------------------
 
1696
// Function             : RenderTexture::_VerifyExtensions
 
1697
// Description      : 
 
1698
//---------------------------------------------------------------------------
 
1699
/**
 
1700
* @fn RenderTexture::_VerifyExtensions()
 
1701
* @brief Checks that the necessary extensions are available based on RT mode.
 
1702
*/ 
 
1703
bool RenderTexture::_VerifyExtensions()
 
1704
{
 
1705
#ifdef _WIN32
 
1706
    if ( !fctPtrInited )
 
1707
    {
 
1708
        fctPtrInited = true;
 
1709
        wglGetExtensionsStringARBProc wglGetExtensionsStringARBPtr = (wglGetExtensionsStringARBProc)wglGetProcAddress( "wglGetExtensionsStringARB" );
 
1710
        if ( wglGetExtensionsStringARBPtr == 0 )
 
1711
        {
 
1712
            PrintExtensionError("WGL_ARB_extensions_string");
 
1713
            return false;
 
1714
        }
 
1715
        string wglExtensionsString = wglGetExtensionsStringARBPtr( wglGetCurrentDC() );
 
1716
        if ( SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ARB_pixel_format" ) )
 
1717
        {
 
1718
            wglChoosePixelFormatARBPtr = (wglChoosePixelFormatARBProc)SGLookupFunction("wglChoosePixelFormatARB");
 
1719
            wglGetPixelFormatAttribivARBPtr = (wglGetPixelFormatAttribivARBProc)SGLookupFunction("wglGetPixelFormatAttribivARB");
 
1720
        }
 
1721
        else
 
1722
        {
 
1723
            PrintExtensionError("WGL_ARB_pixel_format");
 
1724
            return false;
 
1725
        }
 
1726
        if ( SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ARB_pbuffer" ) )
 
1727
        {
 
1728
            wglCreatePbufferARBPtr = (wglCreatePbufferARBProc)SGLookupFunction("wglCreatePbufferARB");
 
1729
            wglGetPbufferDCARBPtr = (wglGetPbufferDCARBProc)SGLookupFunction("wglGetPbufferDCARB");
 
1730
            wglQueryPbufferARBPtr = (wglQueryPbufferARBProc)SGLookupFunction("wglQueryPbufferARB");
 
1731
            wglReleasePbufferDCARBPtr = (wglReleasePbufferDCARBProc)SGLookupFunction("wglReleasePbufferDCARB");
 
1732
            wglDestroyPbufferARBPtr = (wglDestroyPbufferARBProc)SGLookupFunction("wglDestroyPbufferARB");
 
1733
        }
 
1734
        else
 
1735
        {
 
1736
            PrintExtensionError("WGL_ARB_pbuffer");
 
1737
            return false;
 
1738
        }
 
1739
        if ( SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ARB_render_texture" ) )
 
1740
        {
 
1741
            wglBindTexImageARBPtr = (wglBindTexImageARBProc)SGLookupFunction("wglBindTexImageARB");
 
1742
            wglReleaseTexImageARBPtr = (wglReleaseTexImageARBProc)SGLookupFunction("wglReleaseTexImageARB");
 
1743
        }
 
1744
        else if ( _bIsTexture )
 
1745
        {
 
1746
            PrintExtensionError("WGL_ARB_render_texture");
 
1747
            return false;
 
1748
        }
 
1749
        if (_bRectangle && !SGIsOpenGLExtensionSupported( "GL_NV_texture_rectangle" ))
 
1750
        {
 
1751
            PrintExtensionError("GL_NV_texture_rectangle");
 
1752
            return false;
 
1753
        }
 
1754
        if (_bFloat && !(SGIsOpenGLExtensionSupported( "GL_NV_float_buffer" ) || SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ATI_pixel_format_float" )))
 
1755
        {
 
1756
            PrintExtensionError("GL_NV_float_buffer or GL_ATI_pixel_format_float");
 
1757
            return false;
 
1758
        
 
1759
        }
 
1760
        if (_bFloat && _bIsTexture && !(SGIsOpenGLExtensionSupported( "GL_NV_float_buffer" ) || SGIsOpenGLExtensionSupported( "GL_ATI_texture_float" )))
 
1761
        {
 
1762
            PrintExtensionError("NV_float_buffer or ATI_texture_float");
 
1763
        }
 
1764
        if (_bIsDepthTexture && !SGIsOpenGLExtensionSupported( "GL_ARB_depth_texture" ))
 
1765
        {
 
1766
            // [Redge]
 
1767
#if defined(_DEBUG) | defined(DEBUG)
 
1768
            fprintf(stderr, 
 
1769
                    "RenderTexture Warning: "
 
1770
                    "OpenGL extension GL_ARB_depth_texture not available.\n"
 
1771
                    "         Using glReadPixels() to emulate behavior.\n");
 
1772
#endif   
 
1773
            _bHasARBDepthTexture = false;
 
1774
            //PrintExtensionError("GL_ARB_depth_texture");
 
1775
            //return false;
 
1776
            // [/Redge]
 
1777
        }
 
1778
        SetLastError(0);
 
1779
    }
 
1780
#elif defined( __APPLE__ )
 
1781
#else
 
1782
    if (!GLX_SGIX_pbuffer)
 
1783
    {
 
1784
        PrintExtensionError("GL_SGIX_pbuffer");
 
1785
        return false;
 
1786
    }
 
1787
    if (!GLX_SGIX_fbconfig)
 
1788
    {
 
1789
        PrintExtensionError("GL_SGIX_fbconfig");
 
1790
        return false;
 
1791
    }
 
1792
    if (_bIsDepthTexture && !GL_ARB_depth_texture)
 
1793
    {
 
1794
        PrintExtensionError("GL_ARB_depth_texture");
 
1795
        return false;
 
1796
    }
 
1797
    if (_bFloat && _bIsTexture && !GL_NV_float_buffer)
 
1798
    {
 
1799
        PrintExtensionError("GL_NV_float_buffer");
 
1800
        return false;
 
1801
    }
 
1802
    if (_eUpdateMode == RT_RENDER_TO_TEXTURE)
 
1803
    {
 
1804
        PrintExtensionError("Some GLX render texture extension: FIXME!");
 
1805
        return false;
 
1806
    }
 
1807
#endif
 
1808
  
 
1809
    return true;
 
1810
}
 
1811
 
 
1812
//---------------------------------------------------------------------------
 
1813
// Function             : RenderTexture::_InitializeTextures
 
1814
// Description      : 
 
1815
//---------------------------------------------------------------------------
 
1816
/**
 
1817
* @fn RenderTexture::_InitializeTextures()
 
1818
* @brief Initializes the state of textures used by the RenderTexture.
 
1819
*/ 
 
1820
bool RenderTexture::_InitializeTextures()
 
1821
{
 
1822
    // Determine the appropriate texture formats and filtering modes.
 
1823
    if (_bIsTexture || _bIsDepthTexture)
 
1824
    {
 
1825
        if (_bRectangle && GL_NV_texture_rectangle)
 
1826
            _iTextureTarget = GL_TEXTURE_RECTANGLE_NV;
 
1827
        else
 
1828
            _iTextureTarget = GL_TEXTURE_2D;
 
1829
    }
 
1830
 
 
1831
    if (_bIsTexture)
 
1832
    {
 
1833
        glGenTextures(1, &_iTextureID);
 
1834
        glBindTexture(_iTextureTarget, _iTextureID);  
 
1835
        
 
1836
        // Use clamp to edge as the default texture wrap mode for all tex
 
1837
        glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 
1838
        glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
 
1839
        // Use NEAREST as the default texture filtering mode.
 
1840
        glTexParameteri(_iTextureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
1841
        glTexParameteri(_iTextureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
1842
 
 
1843
 
 
1844
        if (RT_COPY_TO_TEXTURE == _eUpdateMode)
 
1845
        {
 
1846
            GLuint iInternalFormat;
 
1847
            GLuint iFormat;
 
1848
 
 
1849
            if (_bFloat)
 
1850
            {                             
 
1851
                if (_bMipmap)
 
1852
                {
 
1853
                    fprintf(stderr, 
 
1854
                        "RenderTexture Error: mipmapped float textures not "
 
1855
                        "supported.\n");
 
1856
                    return false;
 
1857
                }
 
1858
            
 
1859
                switch(_iNumComponents) 
 
1860
                {
 
1861
                case 1:
 
1862
                    if (GL_NV_float_buffer)
 
1863
                    {
 
1864
                        iInternalFormat = (_iNumColorBits[0] > 16) ? 
 
1865
                            GL_FLOAT_R32_NV : GL_FLOAT_R16_NV;
 
1866
                    }
 
1867
                    else if (GL_ATI_texture_float)
 
1868
                    {
 
1869
                        iInternalFormat = (_iNumColorBits[0] > 16) ? 
 
1870
                            GL_LUMINANCE_FLOAT32_ATI : 
 
1871
                            GL_LUMINANCE_FLOAT16_ATI;
 
1872
                    }
 
1873
                    iFormat = GL_LUMINANCE;
 
1874
                        break;
 
1875
                case 2:
 
1876
                    if (GL_NV_float_buffer)
 
1877
                    {
 
1878
                        iInternalFormat = (_iNumColorBits[0] > 16) ? 
 
1879
                            GL_FLOAT_RG32_NV : GL_FLOAT_RG16_NV;
 
1880
                    }
 
1881
                    else if (GL_ATI_texture_float)
 
1882
                    {
 
1883
                        iInternalFormat = (_iNumColorBits[0] > 16) ? 
 
1884
                            GL_LUMINANCE_ALPHA_FLOAT32_ATI : 
 
1885
                            GL_LUMINANCE_ALPHA_FLOAT16_ATI;
 
1886
                    }
 
1887
                    iFormat = GL_LUMINANCE_ALPHA;
 
1888
                        break;
 
1889
                case 3:
 
1890
                    if (GL_NV_float_buffer)
 
1891
                    {
 
1892
                        iInternalFormat = (_iNumColorBits[0] > 16) ? 
 
1893
                            GL_FLOAT_RGB32_NV : GL_FLOAT_RGB16_NV;
 
1894
                    }
 
1895
                    else if (GL_ATI_texture_float)
 
1896
                    {
 
1897
                        iInternalFormat = (_iNumColorBits[0] > 16) ? 
 
1898
                            GL_RGB_FLOAT32_ATI : GL_RGB_FLOAT16_ATI;
 
1899
                    }
 
1900
                    iFormat = GL_RGB;
 
1901
                    break;
 
1902
                case 4:
 
1903
                    if (GL_NV_float_buffer)
 
1904
                    {
 
1905
                        iInternalFormat = (_iNumColorBits[0] > 16) ? 
 
1906
                            GL_FLOAT_RGBA32_NV : GL_FLOAT_RGBA16_NV;
 
1907
                    }
 
1908
                    else if (GL_ATI_texture_float)
 
1909
                    {
 
1910
                        iInternalFormat = (_iNumColorBits[0] > 16) ? 
 
1911
                            GL_RGBA_FLOAT32_ATI : GL_RGBA_FLOAT16_ATI;
 
1912
                    }
 
1913
                    iFormat = GL_RGBA;
 
1914
                    break;
 
1915
                default:
 
1916
                    printf("RenderTexture Error: "
 
1917
                           "Invalid number of components: %d\n", 
 
1918
                           _iNumComponents);
 
1919
                    return false;
 
1920
                }
 
1921
            }
 
1922
            else // non-float
 
1923
            {                        
 
1924
                if (4 == _iNumComponents)
 
1925
                {
 
1926
                    iInternalFormat = GL_RGBA8;
 
1927
                    iFormat = GL_RGBA;
 
1928
                }
 
1929
                else 
 
1930
                {
 
1931
                    iInternalFormat = GL_RGB8;
 
1932
                    iFormat = GL_RGB;
 
1933
                }
 
1934
            }
 
1935
        
 
1936
            // Allocate the texture image (but pass it no data for now).
 
1937
            glTexImage2D(_iTextureTarget, 0, iInternalFormat, 
 
1938
                         _iWidth, _iHeight, 0, iFormat, GL_FLOAT, NULL);
 
1939
        } 
 
1940
    }
 
1941
  
 
1942
    if (_bIsDepthTexture)
 
1943
    { 
 
1944
        glGenTextures(1, &_iDepthTextureID);
 
1945
        glBindTexture(_iTextureTarget, _iDepthTextureID);  
 
1946
        
 
1947
        // Use clamp to edge as the default texture wrap mode for all tex
 
1948
        glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 
1949
        glTexParameteri(_iTextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
 
1950
        // Use NEAREST as the default texture filtering mode.
 
1951
        glTexParameteri(_iTextureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
1952
        glTexParameteri(_iTextureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
1953
               
 
1954
        if (RT_COPY_TO_TEXTURE == _eUpdateMode)
 
1955
        {
 
1956
            // [Redge]
 
1957
            if (_bHasARBDepthTexture) 
 
1958
            {
 
1959
                // Allocate the texture image (but pass it no data for now).
 
1960
                glTexImage2D(_iTextureTarget, 0, GL_DEPTH_COMPONENT, 
 
1961
                             _iWidth, _iHeight, 0, GL_DEPTH_COMPONENT, 
 
1962
                             GL_FLOAT, NULL);
 
1963
            } 
 
1964
            else 
 
1965
            {
 
1966
                // allocate memory for depth texture
 
1967
                // Since this is slow, we warn the user in debug mode. (above)
 
1968
                _pPoorDepthTexture = new unsigned short[_iWidth * _iHeight];
 
1969
                glTexImage2D(_iTextureTarget, 0, GL_LUMINANCE16, 
 
1970
                             _iWidth, _iHeight, 0, GL_LUMINANCE, 
 
1971
                             GL_UNSIGNED_SHORT, _pPoorDepthTexture);
 
1972
            }
 
1973
            // [/Redge]
 
1974
        }
 
1975
    }
 
1976
 
 
1977
    return true;
 
1978
}
 
1979
 
 
1980
 
 
1981
//---------------------------------------------------------------------------
 
1982
// Function             : RenderTexture::_MaybeCopyBuffer
 
1983
// Description      : 
 
1984
//---------------------------------------------------------------------------
 
1985
/**
 
1986
* @fn RenderTexture::_MaybeCopyBuffer()
 
1987
* @brief Does the actual copying for RenderTextures with RT_COPY_TO_TEXTURE
 
1988
*/ 
 
1989
void RenderTexture::_MaybeCopyBuffer()
 
1990
{
 
1991
#ifdef _WIN32
 
1992
    if (RT_COPY_TO_TEXTURE == _eUpdateMode)
 
1993
    {
 
1994
        if (_bIsTexture)
 
1995
        {
 
1996
            glBindTexture(_iTextureTarget, _iTextureID);
 
1997
            glCopyTexSubImage2D(_iTextureTarget, 
 
1998
                                0, 0, 0, 0, 0, _iWidth, _iHeight);
 
1999
        }
 
2000
        if (_bIsDepthTexture)
 
2001
        {
 
2002
            glBindTexture(_iTextureTarget, _iDepthTextureID);
 
2003
            // HOW TO COPY DEPTH TEXTURE??? Supposedly this just magically works...
 
2004
            // [Redge]
 
2005
            if (_bHasARBDepthTexture) 
 
2006
            {
 
2007
                glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, 
 
2008
                                    _iWidth, _iHeight);
 
2009
            } 
 
2010
            else 
 
2011
            {
 
2012
                // no 'real' depth texture available, so behavior has to be emulated
 
2013
                // using glReadPixels (beware, this is (naturally) slow ...)
 
2014
                glReadPixels(0, 0, _iWidth, _iHeight, GL_DEPTH_COMPONENT, 
 
2015
                             GL_UNSIGNED_SHORT, _pPoorDepthTexture);
 
2016
                glTexImage2D(_iTextureTarget, 0, GL_LUMINANCE16,
 
2017
                             _iWidth, _iHeight, 0, GL_LUMINANCE, 
 
2018
                             GL_UNSIGNED_SHORT, _pPoorDepthTexture);
 
2019
            }
 
2020
            // [/Redge]
 
2021
        }
 
2022
    }
 
2023
    
 
2024
#else
 
2025
    if (_bIsTexture)
 
2026
    {
 
2027
      glBindTexture(_iTextureTarget, _iTextureID);
 
2028
      glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
 
2029
    }
 
2030
    if (_bIsDepthTexture)
 
2031
    {
 
2032
      glBindTexture(_iTextureTarget, _iDepthTextureID);
 
2033
      assert(_bHasARBDepthTexture);
 
2034
      glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
 
2035
    }
 
2036
#endif
 
2037
 
 
2038
}
 
2039
 
 
2040
//---------------------------------------------------------------------------
 
2041
// Function             : RenderTexture::_ReleaseBoundBuffers
 
2042
// Description      : 
 
2043
//---------------------------------------------------------------------------
 
2044
/**
 
2045
* @fn RenderTexture::_ReleaseBoundBuffers()
 
2046
* @brief Releases buffer bindings on RenderTextures with RT_RENDER_TO_TEXTURE
 
2047
*/ 
 
2048
bool RenderTexture::_ReleaseBoundBuffers()
 
2049
{
 
2050
#ifdef _WIN32
 
2051
    if (_bIsTexture && RT_RENDER_TO_TEXTURE == _eUpdateMode)
 
2052
    {
 
2053
        glBindTexture(_iTextureTarget, _iTextureID);
 
2054
        
 
2055
        // release the pbuffer from the render texture object
 
2056
        if (0 != _iCurrentBoundBuffer && _bIsBufferBound)
 
2057
        {
 
2058
            if (FALSE == wglReleaseTexImageARBPtr(_hPBuffer, _iCurrentBoundBuffer))
 
2059
            {
 
2060
                _wglGetLastError();
 
2061
                return false;
 
2062
            }
 
2063
            _bIsBufferBound = false;
 
2064
        }
 
2065
    }
 
2066
    
 
2067
    if (_bIsDepthTexture && RT_RENDER_TO_TEXTURE == _eUpdateMode)
 
2068
    {
 
2069
        glBindTexture(_iTextureTarget, _iDepthTextureID);
 
2070
        
 
2071
        // release the pbuffer from the render texture object
 
2072
        if (FALSE == wglReleaseTexImageARBPtr(_hPBuffer, WGL_DEPTH_COMPONENT_NV))
 
2073
        {
 
2074
            _wglGetLastError();
 
2075
            return false;
 
2076
        }
 
2077
    }
 
2078
    
 
2079
#else
 
2080
    // textures can't be bound in Linux
 
2081
#endif
 
2082
    return true;
 
2083
}
 
2084
 
 
2085
//---------------------------------------------------------------------------
 
2086
// Function             : RenderTexture::_MakeCurrent
 
2087
// Description      : 
 
2088
//---------------------------------------------------------------------------
 
2089
/**
 
2090
* @fn RenderTexture::_MakeCurrent()
 
2091
* @brief Makes the RenderTexture's context current
 
2092
*/ 
 
2093
 
 
2094
bool RenderTexture::_MakeCurrent() 
 
2095
{
 
2096
#ifdef _WIN32
 
2097
    // make the pbuffer's rendering context current.
 
2098
    if (FALSE == wglMakeCurrent( _hDC, _hGLContext))
 
2099
    {
 
2100
        _wglGetLastError();
 
2101
        return false;
 
2102
    }
 
2103
#elif defined( __APPLE__ )
 
2104
#else
 
2105
    if (false == glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext)) 
 
2106
    {
 
2107
        return false;
 
2108
    }
 
2109
#endif
 
2110
 
 
2111
    return true;
 
2112
}
 
2113
 
 
2114
/////////////////////////////////////////////////////////////////////////////
 
2115
//
 
2116
// Begin Deprecated Interface
 
2117
//
 
2118
/////////////////////////////////////////////////////////////////////////////
 
2119
 
 
2120
//---------------------------------------------------------------------------
 
2121
// Function      : RenderTexture::RenderTexture
 
2122
// Description   : 
 
2123
//---------------------------------------------------------------------------
 
2124
/**
 
2125
* @fn RenderTexture::RenderTexture()
 
2126
* @brief Constructor.
 
2127
*/ 
 
2128
RenderTexture::RenderTexture(int width, int height,
 
2129
                               bool bIsTexture /* = true */,
 
2130
                               bool bIsDepthTexture /* = false */)
 
2131
:   _iWidth(width), 
 
2132
    _iHeight(height), 
 
2133
    _bIsTexture(bIsTexture),
 
2134
    _bIsDepthTexture(bIsDepthTexture),
 
2135
    _bHasARBDepthTexture(true),            // [Redge]
 
2136
    _eUpdateMode(RT_RENDER_TO_TEXTURE),
 
2137
    _bInitialized(false),
 
2138
    _iNumAuxBuffers(0),
 
2139
    _iCurrentBoundBuffer(0),
 
2140
    _iNumDepthBits(0),
 
2141
    _iNumStencilBits(0),
 
2142
    _bFloat(false),
 
2143
    _bDoubleBuffered(false),
 
2144
    _bPowerOf2(true),
 
2145
    _bRectangle(false),
 
2146
    _bMipmap(false),
 
2147
    _bShareObjects(false),
 
2148
    _bCopyContext(false),
 
2149
#ifdef _WIN32
 
2150
    _hDC(NULL), 
 
2151
    _hGLContext(NULL), 
 
2152
    _hPBuffer(NULL),
 
2153
    _hPreviousDC(0),
 
2154
    _hPreviousContext(0),
 
2155
#elif defined( __APPLE__ )
 
2156
#else
 
2157
    _pDisplay(NULL),
 
2158
    _hGLContext(NULL),
 
2159
    _hPBuffer(0),
 
2160
    _hPreviousContext(0),
 
2161
    _hPreviousDrawable(0),
 
2162
#endif
 
2163
    _iTextureTarget(GL_NONE),
 
2164
    _iTextureID(0),
 
2165
    _iDepthTextureID(0),
 
2166
    _pPoorDepthTexture(0) // [Redge]
 
2167
{
 
2168
    assert(width > 0 && height > 0);
 
2169
#if defined DEBUG || defined _DEBUG
 
2170
    fprintf(stderr, 
 
2171
            "RenderTexture Warning: Deprecated Contructor interface used.\n");
 
2172
#endif
 
2173
    
 
2174
    _iNumColorBits[0] = _iNumColorBits[1] = 
 
2175
        _iNumColorBits[2] = _iNumColorBits[3] = 0;
 
2176
    _bPowerOf2 = IsPowerOfTwo(width) && IsPowerOfTwo(height);
 
2177
}
 
2178
 
 
2179
//------------------------------------------------------------------------------
 
2180
// Function             : RenderTexture::Initialize
 
2181
// Description      : 
 
2182
//------------------------------------------------------------------------------
 
2183
/**
 
2184
* @fn RenderTexture::Initialize(bool bShare, bool bDepth, bool bStencil, bool bMipmap, unsigned int iRBits, unsigned int iGBits, unsigned int iBBits, unsigned int iABits);
 
2185
* @brief Initializes the RenderTexture, sharing display lists and textures if specified.
 
2186
 
2187
* This function actually does the creation of the p-buffer.  It can only be called 
 
2188
* once a GL context has already been created.  Note that if the texture is not
 
2189
* power of two dimensioned, or has more than 8 bits per channel, enabling mipmapping
 
2190
* will cause an error.
 
2191
*/ 
 
2192
bool RenderTexture::Initialize(bool         bShare       /* = true */, 
 
2193
                                bool         bDepth       /* = false */, 
 
2194
                                bool         bStencil     /* = false */, 
 
2195
                                bool         bMipmap      /* = false */, 
 
2196
                                bool         bAnisoFilter /* = false */,
 
2197
                                unsigned int iRBits       /* = 8 */, 
 
2198
                                unsigned int iGBits       /* = 8 */, 
 
2199
                                unsigned int iBBits       /* = 8 */, 
 
2200
                                unsigned int iABits       /* = 8 */,
 
2201
                                UpdateMode   updateMode   /* = RT_RENDER_TO_TEXTURE */)
 
2202
{   
 
2203
    if (0 == _iWidth || 0 == _iHeight)
 
2204
        return false;
 
2205
 
 
2206
#if defined DEBUG || defined _DEBUG
 
2207
    fprintf(stderr, 
 
2208
            "RenderTexture Warning: Deprecated Initialize() interface used.\n");
 
2209
#endif   
 
2210
 
 
2211
    // create a mode string.
 
2212
    string mode = "";
 
2213
    if (bDepth)
 
2214
        mode.append("depth ");
 
2215
    if (bStencil)
 
2216
        mode.append("stencil ");
 
2217
    if (bMipmap)
 
2218
        mode.append("mipmap ");
 
2219
    if (iRBits + iGBits + iBBits + iABits > 0)
 
2220
    {
 
2221
        if (iRBits > 0)
 
2222
            mode.append("r");
 
2223
        if (iGBits > 0)
 
2224
            mode.append("g");
 
2225
        if (iBBits > 0)
 
2226
            mode.append("b");
 
2227
        if (iABits > 0)
 
2228
            mode.append("a");
 
2229
        mode.append("=");
 
2230
        char bitVector[100];
 
2231
        sprintf(bitVector,
 
2232
            "%d%s,%d%s,%d%s,%d%s",
 
2233
            iRBits, (iRBits >= 16) ? "f" : "",
 
2234
            iGBits, (iGBits >= 16) ? "f" : "",
 
2235
            iBBits, (iBBits >= 16) ? "f" : "",
 
2236
            iABits, (iABits >= 16) ? "f" : "");
 
2237
        mode.append(bitVector);
 
2238
        mode.append(" ");
 
2239
    }
 
2240
    if (_bIsTexture)
 
2241
    {
 
2242
        if (GL_NV_texture_rectangle && 
 
2243
            ((!IsPowerOfTwo(_iWidth) || !IsPowerOfTwo(_iHeight))
 
2244
              || iRBits >= 16 || iGBits > 16 || iBBits > 16 || iABits >= 16))
 
2245
            mode.append("texRECT ");
 
2246
        else
 
2247
            mode.append("tex2D ");
 
2248
    }
 
2249
    if (_bIsDepthTexture)
 
2250
    {
 
2251
        if (GL_NV_texture_rectangle && 
 
2252
            ((!IsPowerOfTwo(_iWidth) || !IsPowerOfTwo(_iHeight))
 
2253
              || iRBits >= 16 || iGBits > 16 || iBBits > 16 || iABits >= 16))
 
2254
            mode.append("texRECT ");
 
2255
        else
 
2256
            mode.append("tex2D ");
 
2257
    }
 
2258
    if (RT_COPY_TO_TEXTURE == updateMode)
 
2259
        mode.append("ctt");
 
2260
 
 
2261
    _pixelFormatAttribs.clear();
 
2262
    _pbufferAttribs.clear();
 
2263
 
 
2264
#ifdef _WIN32
 
2265
    _pixelFormatAttribs.push_back(WGL_DRAW_TO_PBUFFER_ARB);
 
2266
    _pixelFormatAttribs.push_back(true);
 
2267
    _pixelFormatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB);
 
2268
    _pixelFormatAttribs.push_back(true);
 
2269
    
 
2270
    _pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
 
2271
    _pbufferAttribs.push_back(true);
 
2272
#elif defined( __APPLE__ )
 
2273
#else
 
2274
    _pixelFormatAttribs.push_back(GLX_RENDER_TYPE_SGIX);
 
2275
    _pixelFormatAttribs.push_back(GLX_RGBA_BIT_SGIX);
 
2276
    _pixelFormatAttribs.push_back(GLX_DRAWABLE_TYPE_SGIX);
 
2277
    _pixelFormatAttribs.push_back(GLX_PBUFFER_BIT_SGIX);
 
2278
#endif
 
2279
 
 
2280
    _ParseModeString(mode.c_str(), _pixelFormatAttribs, _pbufferAttribs);
 
2281
 
 
2282
#ifdef _WIN32
 
2283
    _pixelFormatAttribs.push_back(0);
 
2284
    _pbufferAttribs.push_back(0);
 
2285
#else
 
2286
    _pixelFormatAttribs.push_back(None);
 
2287
#endif
 
2288
 
 
2289
    Initialize(_iWidth, _iHeight, bShare);
 
2290
    
 
2291
    return true;
 
2292
}
 
2293
 
 
2294
 
 
2295
//---------------------------------------------------------------------------
 
2296
// Function             : RenderTexture::Reset
 
2297
// Description      : 
 
2298
//---------------------------------------------------------------------------
 
2299
/**
 
2300
* @fn RenderTexture::Reset(int iWidth, int iHeight, unsigned int iMode, bool bIsTexture, bool bIsDepthTexture)
 
2301
* @brief Resets the resolution of the offscreen buffer.
 
2302
 
2303
* Causes the buffer to delete itself.  User must call Initialize() again
 
2304
* before use.
 
2305
*/ 
 
2306
bool RenderTexture::Reset(int iWidth, int iHeight)
 
2307
{
 
2308
    fprintf(stderr, 
 
2309
            "RenderTexture Warning: Deprecated Reset() interface used.\n");
 
2310
 
 
2311
    if (!_Invalidate())
 
2312
    {
 
2313
        fprintf(stderr, "RenderTexture::Reset(): failed to invalidate.\n");
 
2314
        return false;
 
2315
    }
 
2316
    _iWidth     = iWidth;
 
2317
    _iHeight    = iHeight;
 
2318
    
 
2319
    return true;
 
2320
}