1 //------------------------------------------------------------------------------
2 // File : RenderTexture.h
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 code: Mark J. Harris
28 // Original Render-to-depth-texture support: Thorsten Scheuermann
29 // Linux Copy-to-texture: Eric Werness
30 // OS X: Alexander Powell (someone please help)
31 // Various Bug Fixes: Daniel (Redge) Sperl
34 // -----------------------------------------------------------------------------
36 * @file RenderTexture.h
38 * Interface definition for class RenderTexture. A multi-format render to
41 #ifndef __RENDERTEXTURE2_HPP__
42 #define __RENDERTEXTURE2_HPP__
48 * Jan. 2005, Removed GLEW dependencies, Erik Hofman
49 * Mar. 2006, Added MAC OS X support, Alexander Powell
51 #include <simgear/compiler.h>
53 #if !defined( _WIN32 ) && !defined( __MACH__ )
54 # include <X11/Xlib.h>
57 #if defined( __MACH__)
58 # include <OpenGL/OpenGL.h>
67 /* The pixel format for the pbuffer is controlled by the mode string passed
68 * into the PBuffer constructor. This string can have the following attributes:
70 * To specify the pixel format, use the following syntax.
72 * <channels> must match one of the following.
74 * r - r pixel format (for float buffer).
75 * rg - rg pixel format (for float buffer).
76 * rgb - rgb pixel format. 8 bit or 16/32 bit in float buffer mode
77 * rgba - same as "rgb alpha" string
79 * <bits> can either be a scalar--meaning the same bit depth for each
80 * channel-- or a 2-, 3-, 4-component vector matching the specified number of
81 * channels. Vector components should be comma separated. An optional 'f'
82 * suffix on the bit depth specifies float components. In this case <bits>
83 * must be either "32f" or "16f". If <bits> is empty, the default 8 bits per
84 * channel will be used.
90 * The following other attributes are supported.
92 * depth=n - must have n-bit depth buffer, omit n for default (24 bits)
93 * stencil=n - must have n-bit stencil buffer, omit n for default (8 bits)
94 * samples=n - must support n-sample antialiasing (n can be 2 or 4)
95 * aux=n - must have n AUX buffers
96 * doublebuffer - must support double buffered rendering
100 * texCUBE - must support binding pbuffer as texture to specified target
101 * - binding the depth buffer is also supported by specifying
105 * - Both depth and color texture binding, may be specified, but
106 * the targets must match!
107 * For example: "tex2D depthTex2D" or "texRECT depthTexRECT"
110 * ctt - These mutually exclusive options specify the update method used
111 * for render textures that support texture binding. "rtt"
112 * indicates that render to texture will be used to update the
113 * texture. "ctt" indicates that copy to texture will be used
114 * (i.e. glCopyTexSubImage2D()). "rtt" is the default if neither is
115 * specified, and one of the "tex*" options above is.
118 *---------------------------------------------------------------------------
122 * * Texture Parameters:
123 * The default texture wrap mode is GL_CLAMP_TO_EDGE for all textures, and
124 * the default texture filtering modes (min and mag) are GL_NEAREST.
125 * To change these parameters, simply bind the RenderTexture (using the
126 * Bind() method), and set them the way you would for any GL texture object.
127 * The same goes for depth textures.
129 * * Enabling Mipmapping:
130 * This is similar to the texture parameters above. When "rtt" is specified
131 * in the mode string, "mipmap" must also be specified in order to enable
132 * a mipmapped pbuffer. Then, the mipmaps must be created by enabling the
133 * GL_SGIS_GENERATE_MIPMAP texture parameter in the same way as above, and
134 * the min filter mode must be set to a mipmap filter mode, as with any
135 * mipmapped texture object.
137 * * Enabling Anisotropic Filtering
138 * As with the texture parameters above, except as in the following code:
139 * glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, max);
140 * glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, <value < max>);
147 RT_RENDER_TO_TEXTURE,
153 RenderTexture(const char *strMode="rgb tex2D");
156 //! Call this once before use. Set bShare to true to share lists, textures,
157 //! and program objects between the render texture context and the
158 //! current active GL context.
159 bool Initialize(int width, int height,
160 bool shareObjects=true,
161 bool copyContext=false);
163 // !Change the render texture format.
164 bool Reset(const char* strMode,...);
165 // !Change the size of the render texture.
166 bool Resize(int width, int height);
168 // !Begin drawing to the texture. (i.e. use as "output" texture)
170 // !Ends drawing to 'current', begins drawing to this RenderTexture
171 bool BeginCapture(RenderTexture* current);
172 // !End drawing to the texture.
175 // !Bind the texture to the active texture unit for use as an "input" texture
178 // !Bind the depth texture to the active texture unit for use as an "input" texture
179 void BindDepth() const;
181 // !Associate the RTT texture with 'iBuffer' (default is WGL_FRONT_LEFT_ARB)
182 bool BindBuffer( int iBuffer );
184 //! Enables the texture target appropriate for this render texture.
185 void EnableTextureTarget() const
186 { if (_bInitialized) glEnable(_iTextureTarget); }
187 //! Disables the texture target appropriate for this render texture.
188 void DisableTextureTarget() const
189 { if (_bInitialized) glDisable(_iTextureTarget); }
191 //! Returns the texture ID. Useful in Cg applications.
192 unsigned int GetTextureID() const { return _iTextureID; }
193 //! Returns the depth texture ID. Useful in Cg applications.
194 unsigned int GetDepthTextureID() const { return _iDepthTextureID; }
195 //! Returns the texture target this texture is bound to.
196 unsigned int GetTextureTarget() const { return _iTextureTarget; }
197 //! Conversion operator allows RenderTexture to be passed to GL calls
198 operator unsigned int()const{return _iTextureID;}
200 //! Returns the width of the offscreen buffer.
201 int GetWidth() const { return _iWidth; }
202 //! Returns the width of the offscreen buffer.
203 int GetHeight() const { return _iHeight; }
204 //! Returns the maximum S texture coordinate.
205 int GetMaxS() const { return IsRectangleTexture() ? _iWidth : 1; }
206 //! Returns the maximum T texture coordinate.
207 int GetMaxT() const { return IsRectangleTexture() ? _iHeight : 1; }
209 //! Returns the number of red bits allocated.
210 int GetRedBits() const { return _iNumColorBits[0]; }
211 //! Returns the number of green bits allocated.
212 int GetGreenBits() const { return _iNumColorBits[1]; }
213 //! Returns the number of blue bits allocated.
214 int GetBlueBits() const { return _iNumColorBits[2]; }
215 //! Returns the number of alpha bits allocated.
216 int GetAlphaBits() const { return _iNumColorBits[3]; }
218 //! Returns the number of depth bits allocated.
219 int GetDepthBits() const { return _iNumDepthBits; }
220 //! Returns the number of stencil bits allocated.
221 int GetStencilBits() const { return _iNumStencilBits; }
223 //! True if this RenderTexture has been properly initialized.
224 bool IsInitialized() const { return _bInitialized; }
225 //! True if this is a texture and not just an offscreen buffer.
226 bool IsTexture() const { return _bIsTexture; }
227 //! True if this is a depth texture and not just an offscreen buffer.
228 bool IsDepthTexture() const { return _bIsDepthTexture; }
229 //! True if this is a floating point buffer / texture.
230 bool IsFloatTexture() const { return _bFloat; }
231 //! True if this is a double-buffered pbuffer
232 bool IsDoubleBuffered() const { return _bDoubleBuffered; }
233 //! True if this texture has non-power-of-two dimensions.
234 bool IsRectangleTexture() const { return _bRectangle; }
235 //! True if this texture has non-power-of-two dimensions.
236 //! True if this pbuffer has a depth buffer.
237 bool HasDepth() const { return (_iNumDepthBits > 0); }
238 //! True if this pbuffer has a stencil buffer.
239 bool HasStencil() const { return (_iNumStencilBits > 0); }
240 //! True if this texture has mipmaps.
241 bool IsMipmapped() const { return _bMipmap; }
244 * @fn IsPowerOfTwo(int n)
245 * @brief Returns true if /param n is an integer power of 2.
247 * Taken from Steve Baker's Cute Code Collection.
248 * http://www.sjbaker.org/steve/software/cute_code.html
250 static bool IsPowerOfTwo(int n) { return ((n&(n-1))==0); }
253 /////////////////////////////////////////////////////////////////////////
254 // This is the deprecated (old) interface. It will likely be removed
255 // in a future version, so it is recommended that you transition to the
256 // new mode-string-based interface.
257 RenderTexture(int width, int height,
258 bool bIsTexture = true,
259 bool bIsDepthTexture = false);
261 // Call this once before use. Set bShare to true to share lists,
262 // textures, and program objects between the render texture context
263 // and the current active GL context. [deprecated]
264 bool Initialize(bool bShare = true,
266 bool bStencil = false,
267 bool bMipmap = false,
268 bool bAnisoFilter = false,
269 unsigned int iRBits = 8,
270 unsigned int iGBits = 8,
271 unsigned int iBBits = 8,
272 unsigned int iABits = 8,
273 // Only Win32 has RT now, so only make it default there
275 UpdateMode updateMode = RT_RENDER_TO_TEXTURE
277 UpdateMode updateMode = RT_COPY_TO_TEXTURE
280 // !Change the render texture resolution. [deprecated]
281 bool Reset(int iWidth, int iHeight);
283 /////////////////////////////////////////////////////////////////////////
286 protected: // methods
289 typedef std::pair<std::string, std::string> KeyVal;
291 void _ParseModeString(const char *modeString,
292 std::vector<int> &pixelFormatAttribs,
293 std::vector<int> &pbufferAttribs);
295 std::vector<int> _ParseBitVector(std::string bitVector);
296 KeyVal _GetKeyValuePair(std::string token);
299 bool _VerifyExtensions();
300 bool _InitializeTextures();
302 void _MaybeCopyBuffer();
303 bool _ReleaseBoundBuffers();
305 bool _BindDepthBuffer( ) const;
308 int _iWidth; // width of the pbuffer
309 int _iHeight; // height of the pbuffer
312 bool _bIsDepthTexture;
313 bool _bHasARBDepthTexture; // [Redge]
315 UpdateMode _eUpdateMode;
319 unsigned int _iNumAuxBuffers;
320 bool _bIsBufferBound;
321 int _iCurrentBoundBuffer;
323 unsigned int _iNumComponents;
324 unsigned int _iNumColorBits[4];
325 unsigned int _iNumDepthBits;
326 unsigned int _iNumStencilBits;
330 bool _bDoubleBuffered;
339 HDC _hDC; // Handle to a device context.
340 HGLRC _hGLContext; // Handle to a GL context.
341 HPBUFFERARB _hPBuffer; // Handle to a pbuffer.
344 HGLRC _hPreviousContext;
345 #elif defined( __MACH__ )
346 CGLContextObj _hGLContext;
347 CGLPBufferObj _hPBuffer;
349 CGLContextObj _hPreviousContext;
352 GLXContext _hGLContext;
353 GLXPbuffer _hPBuffer;
355 GLXDrawable _hPreviousDrawable;
356 GLXContext _hPreviousContext;
360 GLenum _iTextureTarget;
362 GLuint _iDepthTextureID;
364 unsigned short* _pPoorDepthTexture; // [Redge]
366 std::vector<int> _pixelFormatAttribs;
367 std::vector<int> _pbufferAttribs;
370 // Using these could lead to some odd behavior
371 RenderTexture(const RenderTexture&);
372 RenderTexture& operator=(const RenderTexture&);
375 #endif //__RENDERTEXTURE2_HPP__