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.
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:
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.
19
// 2. Altered source versions must be plainly marked as such, and
20
// must not be misrepresented as being the original software.
22
// 3. This notice may not be removed or altered from any source
25
// --------------------------------------------------------------------------
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
33
// --------------------------------------------------------------------------
35
* @file RenderTexture.cpp
37
* Implementation of class RenderTexture. A multi-format render to
40
#pragma warning(disable:4786)
45
* Jan. 2005, Removed GLEW dependencies, Erik Hofman, Fred Bouvier
48
#include <simgear/compiler.h>
52
# define GLX_GLXEXT_PROTOTYPES
58
#elif defined UL_WIN32
59
# include <windows.h> // MUST be before SG_GL_H and all other GL related include directive
62
#include "extensions.hxx"
63
#include "RenderTexture.h"
71
#pragma comment(lib, "gdi32.lib") // required for GetPixelFormat()
77
static bool fctPtrInited = false;
78
/* WGL_ARB_pixel_format */
79
static wglChoosePixelFormatARBProc wglChoosePixelFormatARBPtr = 0;
80
static wglGetPixelFormatAttribivARBProc wglGetPixelFormatAttribivARBPtr = 0;
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;
92
//---------------------------------------------------------------------------
93
// Function : RenderTexture::RenderTexture
95
//---------------------------------------------------------------------------
97
* @fn RenderTexture::RenderTexture()
98
* @brief Mode-string-based Constructor.
100
RenderTexture::RenderTexture(const char *strMode)
104
_bIsDepthTexture(false),
105
_bHasARBDepthTexture(true), // [Redge]
107
_eUpdateMode(RT_RENDER_TO_TEXTURE),
109
_eUpdateMode(RT_COPY_TO_TEXTURE),
111
_bInitialized(false),
113
_bIsBufferBound(false),
114
_iCurrentBoundBuffer(0),
118
_bDoubleBuffered(false),
122
_bShareObjects(false),
123
_bCopyContext(false),
129
_hPreviousContext(0),
130
#elif defined( __APPLE__ )
135
_hPreviousContext(0),
136
_hPreviousDrawable(0),
138
_iTextureTarget(GL_NONE),
141
_pPoorDepthTexture(0) // [Redge]
143
_iNumColorBits[0] = _iNumColorBits[1] =
144
_iNumColorBits[2] = _iNumColorBits[3] = 0;
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);
152
_pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
153
_pbufferAttribs.push_back(true);
154
#elif defined( __APPLE__ )
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);
162
_ParseModeString(strMode, _pixelFormatAttribs, _pbufferAttribs);
165
_pixelFormatAttribs.push_back(0);
166
_pbufferAttribs.push_back(0);
168
_pixelFormatAttribs.push_back(None);
173
//---------------------------------------------------------------------------
174
// Function : RenderTexture::~RenderTexture
176
//---------------------------------------------------------------------------
178
* @fn RenderTexture::~RenderTexture()
181
RenderTexture::~RenderTexture()
187
//---------------------------------------------------------------------------
188
// Function : _wglGetLastError
190
//---------------------------------------------------------------------------
192
* @fn wglGetLastError()
193
* @brief Returns the last windows error generated.
196
void _wglGetLastError()
200
DWORD err = GetLastError();
203
case ERROR_INVALID_PIXEL_FORMAT:
205
"RenderTexture Win32 Error: ERROR_INVALID_PIXEL_FORMAT\n");
207
case ERROR_NO_SYSTEM_RESOURCES:
209
"RenderTexture Win32 Error: ERROR_NO_SYSTEM_RESOURCES\n");
211
case ERROR_INVALID_DATA:
213
"RenderTexture Win32 Error: ERROR_INVALID_DATA\n");
215
case ERROR_INVALID_WINDOW_HANDLE:
217
"RenderTexture Win32 Error: ERROR_INVALID_WINDOW_HANDLE\n");
219
case ERROR_RESOURCE_TYPE_NOT_FOUND:
221
"RenderTexture Win32 Error: ERROR_RESOURCE_TYPE_NOT_FOUND\n");
228
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
229
FORMAT_MESSAGE_FROM_SYSTEM |
230
FORMAT_MESSAGE_IGNORE_INSERTS,
233
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
238
fprintf(stderr, "RenderTexture Win32 Error %d: %s\n", err, lpMsgBuf);
239
LocalFree( lpMsgBuf );
248
//---------------------------------------------------------------------------
249
// Function : PrintExtensionError
251
//---------------------------------------------------------------------------
253
* @fn PrintExtensionError( char* strMsg, ... )
254
* @brief Prints an error about missing OpenGL extensions.
256
void PrintExtensionError( char* strMsg, ... )
259
"Error: RenderTexture requires the following unsupported "
260
"OpenGL extensions: \n");
263
va_start(args, strMsg);
264
#if defined _WIN32 && !defined __CYGWIN__
265
_vsnprintf( strBuffer, 512, strMsg, args );
267
vsnprintf( strBuffer, 512, strMsg, args );
271
fprintf(stderr, strMsg);
274
//---------------------------------------------------------------------------
275
// Function : RenderTexture::Initialize
277
//---------------------------------------------------------------------------
279
* @fn RenderTexture::Initialize(int width, int height, bool shareObjects, bool copyContext);
280
* @brief Initializes the RenderTexture, sharing display lists and textures if specified.
282
* This function creates of the p-buffer. It can only be called once a GL
283
* context has already been created.
285
bool RenderTexture::Initialize(int width, int height,
286
bool shareObjects /* = true */,
287
bool copyContext /* = false */)
289
assert(width > 0 && height > 0);
291
_iWidth = width; _iHeight = height;
292
_bPowerOf2 = IsPowerOfTwo(width) && IsPowerOfTwo(height);
294
_bShareObjects = shareObjects;
295
_bCopyContext = copyContext;
297
// Check if this is an NVXX GPU and verify necessary extensions.
298
if (!_VerifyExtensions())
305
// Get the current context.
306
HDC hdc = wglGetCurrentDC();
309
HGLRC hglrc = wglGetCurrentContext();
314
unsigned int iNumFormats;
318
// Get the pixel format for the on-screen window.
319
iFormat = GetPixelFormat(hdc);
323
"RenderTexture Error: GetPixelFormat() failed.\n");
329
if (!wglChoosePixelFormatARBPtr(hdc, &_pixelFormatAttribs[0], NULL,
330
1, &iFormat, &iNumFormats))
333
"RenderTexture Error: wglChoosePixelFormatARB() failed.\n");
337
if ( iNumFormats <= 0 )
340
"RenderTexture Error: Couldn't find a suitable "
347
// Create the p-buffer.
348
_hPBuffer = wglCreatePbufferARBPtr(hdc, iFormat, _iWidth, _iHeight,
349
&_pbufferAttribs[0]);
353
"RenderTexture Error: wglCreatePbufferARB() failed.\n");
358
// Get the device context.
359
_hDC = wglGetPbufferDCARBPtr( _hPBuffer);
363
"RenderTexture Error: wglGetGetPbufferDCARB() failed.\n");
368
// Create a gl context for the p-buffer.
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.
378
_hGLContext = wglCreateContext( _hDC );
382
"RenderTexture Error: wglCreateContext() failed.\n");
388
// Share lists, texture objects, and program objects.
391
if( !wglShareLists(hglrc, _hGLContext) )
394
"RenderTexture Error: wglShareLists() failed.\n");
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 );
404
_bInitialized = true;
406
// get the actual number of bits allocated:
407
int attrib = WGL_RED_BITS_ARB;
411
(wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
413
attrib = WGL_GREEN_BITS_ARB;
415
(wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
417
attrib = WGL_BLUE_BITS_ARB;
419
(wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
421
attrib = WGL_ALPHA_BITS_ARB;
423
(wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
425
attrib = WGL_DEPTH_BITS_ARB;
427
(wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
429
attrib = WGL_STENCIL_BITS_ARB;
431
(wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
433
attrib = WGL_DOUBLE_BUFFER_ARB;
435
(wglGetPixelFormatAttribivARBPtr(_hDC, iFormat, 0, 1, &attrib, &value))
436
? (value?true:false) : false;
438
#if defined(_DEBUG) | defined(DEBUG)
439
fprintf(stderr, "Created a %dx%d RenderTexture with BPP(%d, %d, %d, %d)",
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");
449
#elif defined( __APPLE__ )
451
_pDisplay = glXGetCurrentDisplay();
452
GLXContext context = glXGetCurrentContext();
453
int screen = DefaultScreen(_pDisplay);
454
XVisualInfo *visInfo;
460
GLXFBConfigSGIX *fbConfigs;
463
fbConfigs = glXChooseFBConfigSGIX(_pDisplay, screen,
464
&_pixelFormatAttribs[0], &nConfigs);
466
if (nConfigs == 0 || !fbConfigs)
469
"RenderTexture Error: Couldn't find a suitable pixel format.\n");
473
// Pick the first returned format that will return a pbuffer
474
for (int i=0;i<nConfigs;i++)
476
_hPBuffer = glXCreateGLXPbufferSGIX(_pDisplay, fbConfigs[i],
477
_iWidth, _iHeight, NULL);
480
_hGLContext = glXCreateContextWithConfigSGIX(_pDisplay,
483
_bShareObjects ? context : NULL,
492
"RenderTexture Error: glXCreateGLXPbufferSGIX() failed.\n");
499
_hGLContext = glXCreateContext(_pDisplay, visInfo,
500
_bShareObjects ? context : NULL, False);
504
"RenderTexture Error: glXCreateContext() failed.\n");
509
glXQueryGLXPbufferSGIX(_pDisplay, _hPBuffer, GLX_WIDTH_SGIX,
511
glXQueryGLXPbufferSGIX(_pDisplay, _hPBuffer, GLX_HEIGHT_SGIX,
514
_bInitialized = true;
516
// XXX Query the color format
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
526
if (false == wglMakeCurrent( _hDC, _hGLContext))
531
#elif defined( __APPLE__ )
533
_hPreviousContext = glXGetCurrentContext();
534
_hPreviousDrawable = glXGetCurrentDrawable();
536
if (False == glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext))
542
bool result = _InitializeTextures();
544
BindBuffer(WGL_FRONT_LEFT_ARB);
550
// make the previous rendering context current
551
if (false == wglMakeCurrent( hdc, hglrc))
556
#elif defined( __APPLE__ )
558
if (False == glXMakeCurrent(_pDisplay,
559
_hPreviousDrawable, _hPreviousContext))
569
//---------------------------------------------------------------------------
570
// Function : RenderTexture::_Invalidate
572
//---------------------------------------------------------------------------
574
* @fn RenderTexture::_Invalidate()
575
* @brief Returns the pbuffer memory to the graphics device.
578
bool RenderTexture::_Invalidate()
580
_iNumColorBits[0] = _iNumColorBits[1] =
581
_iNumColorBits[2] = _iNumColorBits[3] = 0;
583
_iNumStencilBits = 0;
586
glDeleteTextures(1, &_iTextureID);
587
if (_bIsDepthTexture)
590
if (!_bHasARBDepthTexture) delete[] _pPoorDepthTexture;
592
glDeleteTextures(1, &_iDepthTextureID);
598
// Check if we are currently rendering in the pbuffer
599
if (wglGetCurrentContext() == _hGLContext)
602
wglDeleteContext( _hGLContext);
603
wglReleasePbufferDCARBPtr( _hPBuffer, _hDC);
604
wglDestroyPbufferARBPtr( _hPBuffer );
608
#elif defined( __APPLE__ )
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);
621
// [WVB] do we need to call _ReleaseBoundBuffers() too?
626
//---------------------------------------------------------------------------
627
// Function : RenderTexture::Reset
629
//---------------------------------------------------------------------------
631
* @fn RenderTexture::Reset()
632
* @brief Resets the resolution of the offscreen buffer.
634
* Causes the buffer to delete itself. User must call Initialize() again
637
bool RenderTexture::Reset(const char *strMode, ...)
639
_iWidth = 0; _iHeight = 0;
640
_bIsTexture = false; _bIsDepthTexture = false,
641
_bHasARBDepthTexture = true;
643
_eUpdateMode = RT_RENDER_TO_TEXTURE;
645
_eUpdateMode = RT_COPY_TO_TEXTURE;
647
_bInitialized = false;
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();
662
if (IsInitialized() && !_Invalidate())
664
fprintf(stderr, "RenderTexture::Reset(): failed to invalidate.\n");
668
_iNumColorBits[0] = _iNumColorBits[1] =
669
_iNumColorBits[2] = _iNumColorBits[3] = 0;
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);
677
_pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
678
_pbufferAttribs.push_back(true);
679
#elif defined( __APPLE__ )
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);
689
va_start(args,strMode);
690
#if defined _WIN32 && !defined __CYGWIN__
691
_vsnprintf( strBuffer, 256, strMode, args );
693
vsnprintf( strBuffer, 256, strMode, args );
697
_ParseModeString(strBuffer, _pixelFormatAttribs, _pbufferAttribs);
700
_pixelFormatAttribs.push_back(0);
701
_pbufferAttribs.push_back(0);
703
_pixelFormatAttribs.push_back(None);
708
//------------------------------------------------------------------------------
709
// Function : RenderTexture::Resize
711
//------------------------------------------------------------------------------
713
* @fn RenderTexture::Resize(int iWidth, int iHeight)
714
* @brief Changes the size of the offscreen buffer.
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.
721
bool RenderTexture::Resize(int iWidth, int iHeight)
723
if (!_bInitialized) {
724
fprintf(stderr, "RenderTexture::Resize(): must Initialize() first.\n");
727
if (iWidth == _iWidth && iHeight == _iHeight) {
731
// Do same basic work as _Invalidate, but don't reset all our flags
733
glDeleteTextures(1, &_iTextureID);
734
if (_bIsDepthTexture)
735
glDeleteTextures(1, &_iDepthTextureID);
739
// Check if we are currently rendering in the pbuffer
740
if (wglGetCurrentContext() == _hGLContext)
743
wglDeleteContext( _hGLContext);
744
wglReleasePbufferDCARBPtr( _hPBuffer, _hDC);
745
wglDestroyPbufferARBPtr( _hPBuffer );
749
#elif defined( __APPLE__ )
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);
761
fprintf(stderr, "RenderTexture::Resize(): failed to resize.\n");
764
_bInitialized = false;
765
return Initialize(iWidth, iHeight, _bShareObjects, _bCopyContext);
768
//---------------------------------------------------------------------------
769
// Function : RenderTexture::BeginCapture
771
//---------------------------------------------------------------------------
773
* @fn RenderTexture::BeginCapture()
774
* @brief Activates rendering to the RenderTexture.
776
bool RenderTexture::BeginCapture()
781
"RenderTexture::BeginCapture(): Texture is not initialized!\n");
785
// cache the current context so we can reset it when EndCapture() is called.
786
_hPreviousDC = wglGetCurrentDC();
787
if (NULL == _hPreviousDC)
789
_hPreviousContext = wglGetCurrentContext();
790
if (NULL == _hPreviousContext)
792
#elif defined( __APPLE__ )
794
_hPreviousContext = glXGetCurrentContext();
795
_hPreviousDrawable = glXGetCurrentDrawable();
798
_ReleaseBoundBuffers();
800
return _MakeCurrent();
804
//---------------------------------------------------------------------------
805
// Function : RenderTexture::EndCapture
807
//---------------------------------------------------------------------------
809
* @fn RenderTexture::EndCapture()
810
* @brief Ends rendering to the RenderTexture.
812
bool RenderTexture::EndCapture()
817
"RenderTexture::EndCapture() : Texture is not initialized!\n");
824
// make the previous rendering context current
825
if (FALSE == wglMakeCurrent( _hPreviousDC, _hPreviousContext))
830
#elif defined( __APPLE__ )
832
if (False == glXMakeCurrent(_pDisplay, _hPreviousDrawable,
839
// rebind the textures to a buffers for RTT
840
BindBuffer(_iCurrentBoundBuffer);
846
//---------------------------------------------------------------------------
847
// Function : RenderTexture::BeginCapture(RenderTexture*)
849
//---------------------------------------------------------------------------
851
* @fn RenderTexture::BeginCapture(RenderTexture* other)
852
* @brief Ends capture of 'other', begins capture on 'this'
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
860
* RenderTexture doesn't have any mechanism for determining if
861
* 'current' really is currently active, so no error will be thrown
864
bool RenderTexture::BeginCapture(RenderTexture* current)
866
bool bContextReset = false;
868
if (current == this) {
869
return true; // no switch necessary
872
// treat as normal Begin if current is 0.
873
return BeginCapture();
878
"RenderTexture::BeginCapture(RenderTexture*): Texture is not initialized!\n");
881
if (!current->_bInitialized)
884
"RenderTexture::BeginCapture(RenderTexture): 'current' texture is not initialized!\n");
888
// Sync current pbuffer with its CTT texture if necessary
889
current->_MaybeCopyBuffer();
891
// pass along the previous context so we can reset it when
892
// EndCapture() is called.
894
_hPreviousDC = current->_hPreviousDC;
895
if (NULL == _hPreviousDC)
897
_hPreviousContext = current->_hPreviousContext;
898
if (NULL == _hPreviousContext)
900
#elif defined( __APPLE__ )
902
_hPreviousContext = current->_hPreviousContext;
903
_hPreviousDrawable = current->_hPreviousDrawable;
906
// Unbind textures before making context current
907
if (!_ReleaseBoundBuffers())
910
// Make the pbuffer context current
914
// Rebind buffers of initial RenderTexture
915
current->BindBuffer(_iCurrentBoundBuffer);
916
current->_BindDepthBuffer();
923
//---------------------------------------------------------------------------
924
// Function : RenderTexture::Bind
926
//---------------------------------------------------------------------------
928
* @fn RenderTexture::Bind()
929
* @brief Binds RGB texture.
931
void RenderTexture::Bind() const
933
if (_bInitialized && _bIsTexture)
935
glBindTexture(_iTextureTarget, _iTextureID);
940
//---------------------------------------------------------------------------
941
// Function : RenderTexture::BindDepth
943
//---------------------------------------------------------------------------
945
* @fn RenderTexture::BindDepth()
946
* @brief Binds depth texture.
948
void RenderTexture::BindDepth() const
950
if (_bInitialized && _bIsDepthTexture)
952
glBindTexture(_iTextureTarget, _iDepthTextureID);
957
//---------------------------------------------------------------------------
958
// Function : RenderTexture::BindBuffer
960
//---------------------------------------------------------------------------
962
* @fn RenderTexture::BindBuffer()
963
* @brief Associate the RTT texture id with 'iBuffer' (e.g. WGL_FRONT_LEFT_ARB)
965
bool RenderTexture::BindBuffer( int iBuffer )
967
// Must bind the texture too
968
if (_bInitialized && _bIsTexture)
970
glBindTexture(_iTextureTarget, _iTextureID);
973
if (RT_RENDER_TO_TEXTURE == _eUpdateMode && _bIsTexture &&
974
(!_bIsBufferBound || _iCurrentBoundBuffer != iBuffer))
976
if (FALSE == wglBindTexImageARBPtr(_hPBuffer, iBuffer))
978
// WVB: WGL API considers binding twice to the same buffer
979
// to be an error. But we don't want to
980
//_wglGetLastError();
984
_bIsBufferBound = true;
985
_iCurrentBoundBuffer = iBuffer;
993
//---------------------------------------------------------------------------
994
// Function : RenderTexture::BindBuffer
996
//---------------------------------------------------------------------------
998
* @fn RenderTexture::_BindDepthBuffer()
999
* @brief Associate the RTT depth texture id with the depth buffer
1001
bool RenderTexture::_BindDepthBuffer() const
1004
if (_bInitialized && _bIsDepthTexture &&
1005
RT_RENDER_TO_TEXTURE == _eUpdateMode)
1007
glBindTexture(_iTextureTarget, _iDepthTextureID);
1008
if (FALSE == wglBindTexImageARBPtr(_hPBuffer, WGL_DEPTH_COMPONENT_NV))
1018
//---------------------------------------------------------------------------
1019
// Function : RenderTexture::_ParseModeString
1021
//---------------------------------------------------------------------------
1023
* @fn RenderTexture::_ParseModeString()
1024
* @brief Parses the user-specified mode string for RenderTexture parameters.
1026
void RenderTexture::_ParseModeString(const char *modeString,
1027
vector<int> &pfAttribs,
1028
vector<int> &pbAttribs)
1030
if (!modeString || strcmp(modeString, "") == 0)
1033
_iNumComponents = 0;
1035
_eUpdateMode = RT_RENDER_TO_TEXTURE;
1037
_eUpdateMode = RT_COPY_TO_TEXTURE;
1041
bool bHasStencil = false;
1042
bool bBind2D = false;
1043
bool bBindRECT = false;
1044
bool bBindCUBE = false;
1046
char *mode = strdup(modeString);
1049
vector<string> tokens;
1050
char *buf = strtok(mode, " ");
1053
tokens.push_back(buf);
1054
buf = strtok(NULL, " ");
1057
for (unsigned int i = 0; i < tokens.size(); i++)
1059
string token = tokens[i];
1061
KeyVal kv = _GetKeyValuePair(token);
1064
if (kv.first == "rgb" && (_iNumComponents <= 1))
1066
if (kv.second.find("f") != kv.second.npos)
1069
vector<int> bitVec = _ParseBitVector(kv.second);
1071
if (bitVec.size() < 3) // expand the scalar to a vector
1073
bitVec.push_back(bitVec[0]);
1074
bitVec.push_back(bitVec[0]);
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]);
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]);
1101
_iNumComponents += 3;
1104
else if (kv.first == "rgb")
1106
"RenderTexture Warning: mistake in components definition "
1111
if (kv.first == "rgba" && (_iNumComponents == 0))
1113
if (kv.second.find("f") != kv.second.npos)
1116
vector<int> bitVec = _ParseBitVector(kv.second);
1118
if (bitVec.size() < 4) // expand the scalar to a vector
1120
bitVec.push_back(bitVec[0]);
1121
bitVec.push_back(bitVec[0]);
1122
bitVec.push_back(bitVec[0]);
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]);
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]);
1155
_iNumComponents = 4;
1158
else if (kv.first == "rgba")
1160
"RenderTexture Warning: mistake in components definition "
1164
if (kv.first == "r" && (_iNumComponents <= 1))
1166
if (kv.second.find("f") != kv.second.npos)
1169
vector<int> bitVec = _ParseBitVector(kv.second);
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]);
1178
pfAttribs.push_back(GLX_RED_SIZE);
1179
pfAttribs.push_back(bitVec[0]);
1184
else if (kv.first == "r")
1186
"RenderTexture Warning: mistake in components definition "
1190
if (kv.first == "rg" && (_iNumComponents <= 1))
1192
if (kv.second.find("f") != kv.second.npos)
1195
vector<int> bitVec = _ParseBitVector(kv.second);
1197
if (bitVec.size() < 2) // expand the scalar to a vector
1199
bitVec.push_back(bitVec[0]);
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]);
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]);
1218
_iNumComponents += 2;
1221
else if (kv.first == "rg")
1223
"RenderTexture Warning: mistake in components definition "
1227
if (kv.first == "depth")
1229
if (kv.second == "")
1232
iDepthBits = strtol(kv.second.c_str(), 0, 10);
1236
if (kv.first == "stencil")
1240
pfAttribs.push_back(WGL_STENCIL_BITS_ARB);
1241
#elif defined( __APPLE__ )
1242
pfAttribs.push_back(AGL_STENCIL_SIZE);
1244
pfAttribs.push_back(GLX_STENCIL_SIZE);
1246
if (kv.second == "")
1247
pfAttribs.push_back(8);
1249
pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
1253
if (kv.first == "samples")
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));
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));
1275
if (kv.first == "doublebuffer" || kv.first == "double")
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);
1284
pfAttribs.push_back(GL_DOUBLEBUFFER);
1285
pfAttribs.push_back(True);
1290
if (kv.first == "aux")
1293
pfAttribs.push_back(WGL_AUX_BUFFERS_ARB);
1294
#elif defined( __APPLE__ )
1295
pfAttribs.push_back(AGL_AUX_BUFFERS);
1297
pfAttribs.push_back(GL_AUX_BUFFERS);
1299
if (kv.second == "")
1300
pfAttribs.push_back(0);
1302
pfAttribs.push_back(strtol(kv.second.c_str(), 0, 10));
1306
if (token.find("tex") == 0)
1310
if ((kv.first == "texRECT") && GL_NV_texture_rectangle)
1315
else if (kv.first == "texCUBE")
1327
if (token.find("depthTex") == 0)
1329
_bIsDepthTexture = true;
1331
if ((kv.first == "depthTexRECT") && GL_NV_texture_rectangle)
1336
else if (kv.first == "depthTexCUBE")
1348
if (kv.first == "mipmap")
1354
if (kv.first == "rtt")
1356
_eUpdateMode = RT_RENDER_TO_TEXTURE;
1360
if (kv.first == "ctt")
1362
_eUpdateMode = RT_COPY_TO_TEXTURE;
1367
"RenderTexture Error: Unknown pbuffer attribute: %s\n",
1371
// Processing of some options must be last because of interactions.
1373
// Check for inconsistent texture targets
1374
if (_bIsTexture && _bIsDepthTexture && !(bBind2D ^ bBindRECT ^ bBindCUBE))
1377
"RenderTexture Warning: Depth and Color texture targets "
1381
// Apply default bit format if none specified
1383
if (0 == _iNumComponents)
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;
1398
if (_bIsDepthTexture && !iDepthBits)
1402
pfAttribs.push_back(WGL_DEPTH_BITS_ARB);
1403
#elif defined( __APPLE__ )
1404
pfAttribs.push_back(AGL_DEPTH_SIZE);
1406
pfAttribs.push_back(GLX_DEPTH_SIZE);
1408
pfAttribs.push_back(iDepthBits); // default
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);
1419
pfAttribs.push_back(GLX_STENCIL_SIZE);
1420
pfAttribs.push_back(0);
1424
if (_iNumComponents < 4)
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
1430
//pfAttribs.push_back(WGL_ALPHA_BITS_ARB);
1431
//pfAttribs.push_back(0);
1435
if (!WGL_NV_render_depth_texture && _bIsDepthTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode))
1437
#if defined(DEBUG) || defined(_DEBUG)
1438
fprintf(stderr, "RenderTexture Warning: No support found for "
1439
"render to depth texture.\n");
1441
_bIsDepthTexture = false;
1445
if ((_bIsTexture || _bIsDepthTexture) &&
1446
(RT_RENDER_TO_TEXTURE == _eUpdateMode))
1451
pbAttribs.push_back(WGL_TEXTURE_TARGET_ARB);
1452
pbAttribs.push_back(WGL_TEXTURE_RECTANGLE_NV);
1456
pbAttribs.push_back(WGL_TEXTURE_TARGET_ARB);
1457
pbAttribs.push_back(WGL_TEXTURE_CUBE_MAP_ARB);
1461
pbAttribs.push_back(WGL_TEXTURE_TARGET_ARB);
1462
pbAttribs.push_back(WGL_TEXTURE_2D_ARB);
1467
pbAttribs.push_back(WGL_MIPMAP_TEXTURE_ARB);
1468
pbAttribs.push_back(true);
1471
#elif defined(DEBUG) || defined(_DEBUG)
1472
printf("RenderTexture Error: Render to Texture not "
1473
"supported in Linux\n");
1477
// Set the pixel type
1481
if (WGL_NV_float_buffer)
1483
pfAttribs.push_back(WGL_PIXEL_TYPE_ARB);
1484
pfAttribs.push_back(WGL_TYPE_RGBA_ARB);
1486
pfAttribs.push_back(WGL_FLOAT_COMPONENTS_NV);
1487
pfAttribs.push_back(true);
1491
pfAttribs.push_back(WGL_PIXEL_TYPE_ARB);
1492
pfAttribs.push_back(WGL_TYPE_RGBA_FLOAT_ATI);
1494
#elif defined( __APPLE__ )
1496
if (GL_NV_float_buffer)
1498
pfAttribs.push_back(GLX_FLOAT_COMPONENTS_NV);
1499
pfAttribs.push_back(1);
1506
pfAttribs.push_back(WGL_PIXEL_TYPE_ARB);
1507
pfAttribs.push_back(WGL_TYPE_RGBA_ARB);
1511
// Set up texture binding for render to texture
1512
if (_bIsTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode))
1518
if (WGL_NV_float_buffer)
1520
switch(_iNumComponents)
1523
pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV);
1524
pfAttribs.push_back(true);
1526
pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
1527
pbAttribs.push_back(WGL_TEXTURE_FLOAT_R_NV);
1530
pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV);
1531
pfAttribs.push_back(true);
1533
pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
1534
pbAttribs.push_back(WGL_TEXTURE_FLOAT_RG_NV);
1537
pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV);
1538
pfAttribs.push_back(true);
1540
pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
1541
pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGB_NV);
1544
pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV);
1545
pfAttribs.push_back(true);
1547
pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
1548
pbAttribs.push_back(WGL_TEXTURE_FLOAT_RGBA_NV);
1552
"RenderTexture Warning: Bad number of components "
1553
"(r=1,rg=2,rgb=3,rgba=4): %d.\n",
1560
if (4 == _iNumComponents)
1562
pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
1563
pfAttribs.push_back(true);
1565
pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
1566
pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB);
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);
1574
pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
1575
pbAttribs.push_back(WGL_TEXTURE_RGB_ARB);
1582
switch(_iNumComponents)
1585
pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGB_ARB);
1586
pfAttribs.push_back(true);
1588
pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
1589
pbAttribs.push_back(WGL_TEXTURE_RGB_ARB);
1592
pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RGBA_ARB);
1593
pfAttribs.push_back(true);
1595
pbAttribs.push_back(WGL_TEXTURE_FORMAT_ARB);
1596
pbAttribs.push_back(WGL_TEXTURE_RGBA_ARB);
1600
"RenderTexture Warning: Bad number of components "
1601
"(r=1,rg=2,rgb=3,rgba=4): %d.\n", _iNumComponents);
1605
#elif defined(DEBUG) || defined(_DEBUG)
1607
"RenderTexture Error: Render to Texture not supported in "
1612
if (_bIsDepthTexture && (RT_RENDER_TO_TEXTURE == _eUpdateMode))
1617
pfAttribs.push_back(WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV);
1618
pfAttribs.push_back(true);
1620
pbAttribs.push_back(WGL_DEPTH_TEXTURE_FORMAT_NV);
1621
pbAttribs.push_back(WGL_TEXTURE_DEPTH_COMPONENT_NV);
1625
pfAttribs.push_back(WGL_BIND_TO_TEXTURE_DEPTH_NV);
1626
pfAttribs.push_back(true);
1628
pbAttribs.push_back(WGL_DEPTH_TEXTURE_FORMAT_NV);
1629
pbAttribs.push_back(WGL_TEXTURE_DEPTH_COMPONENT_NV);
1631
#elif defined(DEBUG) || defined(_DEBUG)
1632
printf("RenderTexture Error: Render to Texture not supported in "
1638
//---------------------------------------------------------------------------
1639
// Function : RenderTexture::_GetKeyValuePair
1641
//---------------------------------------------------------------------------
1643
* @fn RenderTexture::_GetKeyValuePair()
1644
* @brief Parses expressions of the form "X=Y" into a pair (X,Y).
1646
RenderTexture::KeyVal RenderTexture::_GetKeyValuePair(string token)
1648
string::size_type pos = 0;
1649
if ((pos = token.find("=")) != token.npos)
1651
string key = token.substr(0, pos);
1652
string value = token.substr(pos+1, token.length()-pos+1);
1653
return KeyVal(key, value);
1656
return KeyVal(token, "");
1659
//---------------------------------------------------------------------------
1660
// Function : RenderTexture::_ParseBitVector
1662
//---------------------------------------------------------------------------
1664
* @fn RenderTexture::_ParseBitVector()
1665
* @brief Parses expressions of the form "=r,g,b,a" into a vector: (r,g,b,a)
1667
vector<int> RenderTexture::_ParseBitVector(string bitVector)
1669
vector<string> pieces;
1672
if (bitVector == "")
1674
bits.push_back(8); // if a depth isn't specified, use default 8 bits
1678
string::size_type pos = 0;
1679
string::size_type nextpos = 0;
1682
nextpos = bitVector.find_first_of(", \n", pos);
1683
pieces.push_back(string(bitVector, pos, nextpos - pos));
1685
} while (nextpos != bitVector.npos );
1687
for ( vector<string>::iterator it = pieces.begin(); it != pieces.end(); it++)
1689
bits.push_back(strtol(it->c_str(), 0, 10));
1695
//---------------------------------------------------------------------------
1696
// Function : RenderTexture::_VerifyExtensions
1698
//---------------------------------------------------------------------------
1700
* @fn RenderTexture::_VerifyExtensions()
1701
* @brief Checks that the necessary extensions are available based on RT mode.
1703
bool RenderTexture::_VerifyExtensions()
1706
if ( !fctPtrInited )
1708
fctPtrInited = true;
1709
wglGetExtensionsStringARBProc wglGetExtensionsStringARBPtr = (wglGetExtensionsStringARBProc)wglGetProcAddress( "wglGetExtensionsStringARB" );
1710
if ( wglGetExtensionsStringARBPtr == 0 )
1712
PrintExtensionError("WGL_ARB_extensions_string");
1715
string wglExtensionsString = wglGetExtensionsStringARBPtr( wglGetCurrentDC() );
1716
if ( SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ARB_pixel_format" ) )
1718
wglChoosePixelFormatARBPtr = (wglChoosePixelFormatARBProc)SGLookupFunction("wglChoosePixelFormatARB");
1719
wglGetPixelFormatAttribivARBPtr = (wglGetPixelFormatAttribivARBProc)SGLookupFunction("wglGetPixelFormatAttribivARB");
1723
PrintExtensionError("WGL_ARB_pixel_format");
1726
if ( SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ARB_pbuffer" ) )
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");
1736
PrintExtensionError("WGL_ARB_pbuffer");
1739
if ( SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ARB_render_texture" ) )
1741
wglBindTexImageARBPtr = (wglBindTexImageARBProc)SGLookupFunction("wglBindTexImageARB");
1742
wglReleaseTexImageARBPtr = (wglReleaseTexImageARBProc)SGLookupFunction("wglReleaseTexImageARB");
1744
else if ( _bIsTexture )
1746
PrintExtensionError("WGL_ARB_render_texture");
1749
if (_bRectangle && !SGIsOpenGLExtensionSupported( "GL_NV_texture_rectangle" ))
1751
PrintExtensionError("GL_NV_texture_rectangle");
1754
if (_bFloat && !(SGIsOpenGLExtensionSupported( "GL_NV_float_buffer" ) || SGSearchExtensionsString( wglExtensionsString.c_str(), "WGL_ATI_pixel_format_float" )))
1756
PrintExtensionError("GL_NV_float_buffer or GL_ATI_pixel_format_float");
1760
if (_bFloat && _bIsTexture && !(SGIsOpenGLExtensionSupported( "GL_NV_float_buffer" ) || SGIsOpenGLExtensionSupported( "GL_ATI_texture_float" )))
1762
PrintExtensionError("NV_float_buffer or ATI_texture_float");
1764
if (_bIsDepthTexture && !SGIsOpenGLExtensionSupported( "GL_ARB_depth_texture" ))
1767
#if defined(_DEBUG) | defined(DEBUG)
1769
"RenderTexture Warning: "
1770
"OpenGL extension GL_ARB_depth_texture not available.\n"
1771
" Using glReadPixels() to emulate behavior.\n");
1773
_bHasARBDepthTexture = false;
1774
//PrintExtensionError("GL_ARB_depth_texture");
1780
#elif defined( __APPLE__ )
1782
if (!GLX_SGIX_pbuffer)
1784
PrintExtensionError("GL_SGIX_pbuffer");
1787
if (!GLX_SGIX_fbconfig)
1789
PrintExtensionError("GL_SGIX_fbconfig");
1792
if (_bIsDepthTexture && !GL_ARB_depth_texture)
1794
PrintExtensionError("GL_ARB_depth_texture");
1797
if (_bFloat && _bIsTexture && !GL_NV_float_buffer)
1799
PrintExtensionError("GL_NV_float_buffer");
1802
if (_eUpdateMode == RT_RENDER_TO_TEXTURE)
1804
PrintExtensionError("Some GLX render texture extension: FIXME!");
1812
//---------------------------------------------------------------------------
1813
// Function : RenderTexture::_InitializeTextures
1815
//---------------------------------------------------------------------------
1817
* @fn RenderTexture::_InitializeTextures()
1818
* @brief Initializes the state of textures used by the RenderTexture.
1820
bool RenderTexture::_InitializeTextures()
1822
// Determine the appropriate texture formats and filtering modes.
1823
if (_bIsTexture || _bIsDepthTexture)
1825
if (_bRectangle && GL_NV_texture_rectangle)
1826
_iTextureTarget = GL_TEXTURE_RECTANGLE_NV;
1828
_iTextureTarget = GL_TEXTURE_2D;
1833
glGenTextures(1, &_iTextureID);
1834
glBindTexture(_iTextureTarget, _iTextureID);
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);
1844
if (RT_COPY_TO_TEXTURE == _eUpdateMode)
1846
GLuint iInternalFormat;
1854
"RenderTexture Error: mipmapped float textures not "
1859
switch(_iNumComponents)
1862
if (GL_NV_float_buffer)
1864
iInternalFormat = (_iNumColorBits[0] > 16) ?
1865
GL_FLOAT_R32_NV : GL_FLOAT_R16_NV;
1867
else if (GL_ATI_texture_float)
1869
iInternalFormat = (_iNumColorBits[0] > 16) ?
1870
GL_LUMINANCE_FLOAT32_ATI :
1871
GL_LUMINANCE_FLOAT16_ATI;
1873
iFormat = GL_LUMINANCE;
1876
if (GL_NV_float_buffer)
1878
iInternalFormat = (_iNumColorBits[0] > 16) ?
1879
GL_FLOAT_RG32_NV : GL_FLOAT_RG16_NV;
1881
else if (GL_ATI_texture_float)
1883
iInternalFormat = (_iNumColorBits[0] > 16) ?
1884
GL_LUMINANCE_ALPHA_FLOAT32_ATI :
1885
GL_LUMINANCE_ALPHA_FLOAT16_ATI;
1887
iFormat = GL_LUMINANCE_ALPHA;
1890
if (GL_NV_float_buffer)
1892
iInternalFormat = (_iNumColorBits[0] > 16) ?
1893
GL_FLOAT_RGB32_NV : GL_FLOAT_RGB16_NV;
1895
else if (GL_ATI_texture_float)
1897
iInternalFormat = (_iNumColorBits[0] > 16) ?
1898
GL_RGB_FLOAT32_ATI : GL_RGB_FLOAT16_ATI;
1903
if (GL_NV_float_buffer)
1905
iInternalFormat = (_iNumColorBits[0] > 16) ?
1906
GL_FLOAT_RGBA32_NV : GL_FLOAT_RGBA16_NV;
1908
else if (GL_ATI_texture_float)
1910
iInternalFormat = (_iNumColorBits[0] > 16) ?
1911
GL_RGBA_FLOAT32_ATI : GL_RGBA_FLOAT16_ATI;
1916
printf("RenderTexture Error: "
1917
"Invalid number of components: %d\n",
1924
if (4 == _iNumComponents)
1926
iInternalFormat = GL_RGBA8;
1931
iInternalFormat = GL_RGB8;
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);
1942
if (_bIsDepthTexture)
1944
glGenTextures(1, &_iDepthTextureID);
1945
glBindTexture(_iTextureTarget, _iDepthTextureID);
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);
1954
if (RT_COPY_TO_TEXTURE == _eUpdateMode)
1957
if (_bHasARBDepthTexture)
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,
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);
1981
//---------------------------------------------------------------------------
1982
// Function : RenderTexture::_MaybeCopyBuffer
1984
//---------------------------------------------------------------------------
1986
* @fn RenderTexture::_MaybeCopyBuffer()
1987
* @brief Does the actual copying for RenderTextures with RT_COPY_TO_TEXTURE
1989
void RenderTexture::_MaybeCopyBuffer()
1992
if (RT_COPY_TO_TEXTURE == _eUpdateMode)
1996
glBindTexture(_iTextureTarget, _iTextureID);
1997
glCopyTexSubImage2D(_iTextureTarget,
1998
0, 0, 0, 0, 0, _iWidth, _iHeight);
2000
if (_bIsDepthTexture)
2002
glBindTexture(_iTextureTarget, _iDepthTextureID);
2003
// HOW TO COPY DEPTH TEXTURE??? Supposedly this just magically works...
2005
if (_bHasARBDepthTexture)
2007
glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0,
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);
2027
glBindTexture(_iTextureTarget, _iTextureID);
2028
glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
2030
if (_bIsDepthTexture)
2032
glBindTexture(_iTextureTarget, _iDepthTextureID);
2033
assert(_bHasARBDepthTexture);
2034
glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, _iWidth, _iHeight);
2040
//---------------------------------------------------------------------------
2041
// Function : RenderTexture::_ReleaseBoundBuffers
2043
//---------------------------------------------------------------------------
2045
* @fn RenderTexture::_ReleaseBoundBuffers()
2046
* @brief Releases buffer bindings on RenderTextures with RT_RENDER_TO_TEXTURE
2048
bool RenderTexture::_ReleaseBoundBuffers()
2051
if (_bIsTexture && RT_RENDER_TO_TEXTURE == _eUpdateMode)
2053
glBindTexture(_iTextureTarget, _iTextureID);
2055
// release the pbuffer from the render texture object
2056
if (0 != _iCurrentBoundBuffer && _bIsBufferBound)
2058
if (FALSE == wglReleaseTexImageARBPtr(_hPBuffer, _iCurrentBoundBuffer))
2063
_bIsBufferBound = false;
2067
if (_bIsDepthTexture && RT_RENDER_TO_TEXTURE == _eUpdateMode)
2069
glBindTexture(_iTextureTarget, _iDepthTextureID);
2071
// release the pbuffer from the render texture object
2072
if (FALSE == wglReleaseTexImageARBPtr(_hPBuffer, WGL_DEPTH_COMPONENT_NV))
2080
// textures can't be bound in Linux
2085
//---------------------------------------------------------------------------
2086
// Function : RenderTexture::_MakeCurrent
2088
//---------------------------------------------------------------------------
2090
* @fn RenderTexture::_MakeCurrent()
2091
* @brief Makes the RenderTexture's context current
2094
bool RenderTexture::_MakeCurrent()
2097
// make the pbuffer's rendering context current.
2098
if (FALSE == wglMakeCurrent( _hDC, _hGLContext))
2103
#elif defined( __APPLE__ )
2105
if (false == glXMakeCurrent(_pDisplay, _hPBuffer, _hGLContext))
2114
/////////////////////////////////////////////////////////////////////////////
2116
// Begin Deprecated Interface
2118
/////////////////////////////////////////////////////////////////////////////
2120
//---------------------------------------------------------------------------
2121
// Function : RenderTexture::RenderTexture
2123
//---------------------------------------------------------------------------
2125
* @fn RenderTexture::RenderTexture()
2126
* @brief Constructor.
2128
RenderTexture::RenderTexture(int width, int height,
2129
bool bIsTexture /* = true */,
2130
bool bIsDepthTexture /* = false */)
2133
_bIsTexture(bIsTexture),
2134
_bIsDepthTexture(bIsDepthTexture),
2135
_bHasARBDepthTexture(true), // [Redge]
2136
_eUpdateMode(RT_RENDER_TO_TEXTURE),
2137
_bInitialized(false),
2139
_iCurrentBoundBuffer(0),
2141
_iNumStencilBits(0),
2143
_bDoubleBuffered(false),
2147
_bShareObjects(false),
2148
_bCopyContext(false),
2154
_hPreviousContext(0),
2155
#elif defined( __APPLE__ )
2160
_hPreviousContext(0),
2161
_hPreviousDrawable(0),
2163
_iTextureTarget(GL_NONE),
2165
_iDepthTextureID(0),
2166
_pPoorDepthTexture(0) // [Redge]
2168
assert(width > 0 && height > 0);
2169
#if defined DEBUG || defined _DEBUG
2171
"RenderTexture Warning: Deprecated Contructor interface used.\n");
2174
_iNumColorBits[0] = _iNumColorBits[1] =
2175
_iNumColorBits[2] = _iNumColorBits[3] = 0;
2176
_bPowerOf2 = IsPowerOfTwo(width) && IsPowerOfTwo(height);
2179
//------------------------------------------------------------------------------
2180
// Function : RenderTexture::Initialize
2182
//------------------------------------------------------------------------------
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.
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.
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 */)
2203
if (0 == _iWidth || 0 == _iHeight)
2206
#if defined DEBUG || defined _DEBUG
2208
"RenderTexture Warning: Deprecated Initialize() interface used.\n");
2211
// create a mode string.
2214
mode.append("depth ");
2216
mode.append("stencil ");
2218
mode.append("mipmap ");
2219
if (iRBits + iGBits + iBBits + iABits > 0)
2230
char bitVector[100];
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);
2242
if (GL_NV_texture_rectangle &&
2243
((!IsPowerOfTwo(_iWidth) || !IsPowerOfTwo(_iHeight))
2244
|| iRBits >= 16 || iGBits > 16 || iBBits > 16 || iABits >= 16))
2245
mode.append("texRECT ");
2247
mode.append("tex2D ");
2249
if (_bIsDepthTexture)
2251
if (GL_NV_texture_rectangle &&
2252
((!IsPowerOfTwo(_iWidth) || !IsPowerOfTwo(_iHeight))
2253
|| iRBits >= 16 || iGBits > 16 || iBBits > 16 || iABits >= 16))
2254
mode.append("texRECT ");
2256
mode.append("tex2D ");
2258
if (RT_COPY_TO_TEXTURE == updateMode)
2261
_pixelFormatAttribs.clear();
2262
_pbufferAttribs.clear();
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);
2270
_pbufferAttribs.push_back(WGL_PBUFFER_LARGEST_ARB);
2271
_pbufferAttribs.push_back(true);
2272
#elif defined( __APPLE__ )
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);
2280
_ParseModeString(mode.c_str(), _pixelFormatAttribs, _pbufferAttribs);
2283
_pixelFormatAttribs.push_back(0);
2284
_pbufferAttribs.push_back(0);
2286
_pixelFormatAttribs.push_back(None);
2289
Initialize(_iWidth, _iHeight, bShare);
2295
//---------------------------------------------------------------------------
2296
// Function : RenderTexture::Reset
2298
//---------------------------------------------------------------------------
2300
* @fn RenderTexture::Reset(int iWidth, int iHeight, unsigned int iMode, bool bIsTexture, bool bIsDepthTexture)
2301
* @brief Resets the resolution of the offscreen buffer.
2303
* Causes the buffer to delete itself. User must call Initialize() again
2306
bool RenderTexture::Reset(int iWidth, int iHeight)
2309
"RenderTexture Warning: Deprecated Reset() interface used.\n");
2313
fprintf(stderr, "RenderTexture::Reset(): failed to invalidate.\n");