]> git.mxchange.org Git - simgear.git/blob - simgear/screen/RenderTexture.h
Alexander Powell:
[simgear.git] / simgear / screen / RenderTexture.h
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.
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 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 
32 //                    Bill Baxter
33 //
34 // -----------------------------------------------------------------------------
35 /**
36 * @file RenderTexture.h
37
38 * Interface definition for class RenderTexture.  A multi-format render to 
39 * texture wrapper.
40 */
41 #ifndef __RENDERTEXTURE2_HPP__
42 #define __RENDERTEXTURE2_HPP__
43
44
45 /*
46  * Changelog:
47  *
48  * Jan. 2005, Removed GLEW dependencies, Erik Hofman
49  * Mar. 2006, Added MAC OS X support, Alexander Powell
50  */
51 #include <simgear/compiler.h>
52
53 #if !defined( _WIN32 ) && !defined( __MACH__ )
54 #  include <X11/Xlib.h>
55 #endif
56 #include SG_GL_H
57 #ifndef _WIN32
58 #  include SG_GLX_H
59 #endif
60 #ifdef __MACH__
61 #  ifndef None
62 #     define None false
63 #  endif
64 #  ifndef True
65 #     define True true
66 #  endif
67 #endif 
68
69 #include <string>
70 #include <vector>
71
72 /* The pixel format for the pbuffer is controlled by the mode string passed
73 * into the PBuffer constructor. This string can have the following attributes:
74 *
75 * To specify the pixel format, use the following syntax.
76 *   <channels>=<bits>
77 * <channels> must match one of the following.
78 *
79 * r                        - r pixel format (for float buffer).
80 * rg               - rg pixel format (for float buffer).
81 * rgb          - rgb pixel format. 8 bit or 16/32 bit in float buffer mode
82 * rgba         - same as "rgb alpha" string
83 *
84 * <bits> can either be a scalar--meaning the same bit depth for each 
85 * channel-- or a 2-, 3-, 4-component vector matching the specified number of 
86 * channels. Vector components should be comma separated. An optional 'f' 
87 * suffix on the bit depth specifies float components.  In this case <bits> 
88 * must be either "32f" or "16f".  If <bits> is empty, the default 8 bits per
89 * channel will be used.
90 *   r=32f
91 *   rg=16f
92 *   rgb=8
93 *   rgb=5,6,5
94 *
95 * The following other attributes are supported.
96 *
97 * depth=n      - must have n-bit depth buffer, omit n for default (24 bits)
98 * stencil=n    - must have n-bit stencil buffer, omit n for default (8 bits)
99 * samples=n    - must support n-sample antialiasing (n can be 2 or 4)
100 * aux=n        - must have n AUX buffers
101 * doublebuffer - must support double buffered rendering
102
103 * tex2D
104 * texRECT
105 * texCUBE  - must support binding pbuffer as texture to specified target
106 *          - binding the depth buffer is also supported by specifying
107 * depthTex2D
108 * depthTexRECT
109 * depthTexCUBE
110 *          - Both depth and color texture binding, may be specified, but
111 *            the targets must match!
112 *            For example: "tex2D depthTex2D" or "texRECT depthTexRECT"
113 *
114 * rtt
115 * ctt      - These mutually exclusive options specify the update method used
116 *            for render textures that support texture binding. "rtt"
117 *            indicates that render to texture will be used to update the 
118 *            texture. "ctt" indicates that copy to texture will be used 
119 *            (i.e. glCopyTexSubImage2D()). "rtt" is the default if neither is 
120 *            specified, and one of the "tex*" options above is. 
121
122 *
123 *---------------------------------------------------------------------------
124 *
125 * USAGE NOTES:
126 *
127 * * Texture Parameters:
128 *   The default texture wrap mode is GL_CLAMP_TO_EDGE for all textures, and
129 *   the default texture filtering modes (min and mag) are GL_NEAREST. 
130 *   To change these parameters, simply bind the RenderTexture (using the
131 *   Bind() method), and set them the way you would for any GL texture object.
132 *   The same goes for depth textures.
133 *
134 * * Enabling Mipmapping:
135 *   This is similar to the texture parameters above.  When "rtt" is specified
136 *   in the mode string, "mipmap" must also be specified in order to enable
137 *   a mipmapped pbuffer.  Then, the mipmaps must be created by enabling the
138 *   GL_SGIS_GENERATE_MIPMAP texture parameter in the same way as above, and
139 *   the min filter mode must be set to a mipmap filter mode, as with any
140 *   mipmapped texture object.
141 *
142 * * Enabling Anisotropic Filtering  
143 *   As with the texture parameters above, except as in the following code:
144 *   glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, max);
145 *   glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, <value < max>);
146 */
147 class RenderTexture
148 {
149 public: // enums
150     enum UpdateMode
151     {
152         RT_RENDER_TO_TEXTURE,
153         RT_COPY_TO_TEXTURE
154     };
155     
156 public: // interface
157     // ctor / dtor
158     RenderTexture(const char *strMode="rgb tex2D");
159     ~RenderTexture();
160     
161     //! Call this once before use.  Set bShare to true to share lists, textures, 
162     //! and program objects between the render texture context and the 
163     //! current active GL context.
164     bool Initialize(int width, int height, 
165                     bool shareObjects=true, 
166                     bool copyContext=false);
167
168     // !Change the render texture format.
169     bool Reset(const char* strMode,...);
170     // !Change the size of the render texture.
171     bool Resize(int width, int height);
172     
173     // !Begin drawing to the texture. (i.e. use as "output" texture)
174     bool BeginCapture();
175     // !Ends drawing to 'current', begins drawing to this RenderTexture
176     bool BeginCapture(RenderTexture* current);
177     // !End drawing to the texture.
178     bool EndCapture();
179     
180     // !Bind the texture to the active texture unit for use as an "input" texture
181     void Bind() const;
182
183     // !Bind the depth texture to the active texture unit for use as an "input" texture
184     void BindDepth() const; 
185
186     // !Associate the RTT texture with 'iBuffer' (default is WGL_FRONT_LEFT_ARB) 
187     bool BindBuffer( int iBuffer );
188
189     //! Enables the texture target appropriate for this render texture.
190     void EnableTextureTarget() const 
191     { if (_bInitialized) glEnable(_iTextureTarget); }
192     //! Disables the texture target appropriate for this render texture.
193     void DisableTextureTarget() const 
194     { if (_bInitialized) glDisable(_iTextureTarget); }
195     
196     //! Returns the texture ID.  Useful in Cg applications.
197     unsigned int GetTextureID() const  { return _iTextureID; }
198     //! Returns the depth texture ID.  Useful in Cg applications.
199     unsigned int GetDepthTextureID() const { return _iDepthTextureID; }
200     //! Returns the texture target this texture is bound to.
201     unsigned int GetTextureTarget() const { return _iTextureTarget; }
202     //! Conversion operator allows RenderTexture to be passed to GL calls
203     operator unsigned int()const{return _iTextureID;}     
204     
205     //! Returns the width of the offscreen buffer.
206     int GetWidth() const            { return _iWidth;  } 
207     //! Returns the width of the offscreen buffer.
208     int GetHeight() const           { return _iHeight; }
209     //! Returns the maximum S texture coordinate.
210     int GetMaxS() const      { return IsRectangleTexture() ? _iWidth : 1; }                  
211     //! Returns the maximum T texture coordinate.
212     int GetMaxT() const      { return IsRectangleTexture() ? _iHeight : 1; }                  
213     
214     //! Returns the number of red bits allocated.
215     int GetRedBits() const          { return _iNumColorBits[0]; }
216     //! Returns the number of green bits allocated.
217     int GetGreenBits() const        { return _iNumColorBits[1]; }
218     //! Returns the number of blue bits allocated.
219     int GetBlueBits() const         { return _iNumColorBits[2]; }
220     //! Returns the number of alpha bits allocated.
221     int GetAlphaBits() const        { return _iNumColorBits[3]; }
222
223     //! Returns the number of depth bits allocated.
224     int GetDepthBits() const        { return _iNumDepthBits; }
225     //! Returns the number of stencil bits allocated.
226     int GetStencilBits() const      { return _iNumStencilBits; }
227     
228     //! True if this RenderTexture has been properly initialized.
229     bool IsInitialized() const      { return _bInitialized; }
230     //! True if this is a texture and not just an offscreen buffer.
231     bool IsTexture() const          { return _bIsTexture; }
232     //! True if this is a depth texture and not just an offscreen buffer.
233     bool IsDepthTexture() const     { return _bIsDepthTexture; }
234     //! True if this is a floating point buffer / texture.
235     bool IsFloatTexture() const     { return _bFloat; }
236     //! True if this is a double-buffered pbuffer
237     bool IsDoubleBuffered() const   { return _bDoubleBuffered; }
238     //! True if this texture has non-power-of-two dimensions.
239     bool IsRectangleTexture() const { return _bRectangle; }
240     //! True if this texture has non-power-of-two dimensions.
241     //! True if this pbuffer has a depth buffer.
242     bool HasDepth() const           { return (_iNumDepthBits > 0); }
243     //! True if this pbuffer has a stencil buffer.
244     bool HasStencil() const         { return (_iNumStencilBits > 0); }
245     //! True if this texture has mipmaps.
246     bool IsMipmapped() const        { return _bMipmap; }
247
248     /**
249     * @fn IsPowerOfTwo(int n)
250     * @brief Returns true if /param n is an integer power of 2.
251     * 
252     * Taken from Steve Baker's Cute Code Collection. 
253     * http://www.sjbaker.org/steve/software/cute_code.html
254     */ 
255     static bool IsPowerOfTwo(int n) { return ((n&(n-1))==0); }
256
257
258     /////////////////////////////////////////////////////////////////////////
259     // This is the deprecated (old) interface.  It will likely be removed
260     // in a future version, so it is recommended that you transition to the 
261     // new mode-string-based interface.
262     RenderTexture(int width, int height,
263                    bool bIsTexture = true,
264                    bool bIsDepthTexture = false);
265     //
266     // Call this once before use.  Set bShare to true to share lists, 
267     // textures, and program objects between the render texture context 
268     // and the current active GL context. [deprecated]
269     bool Initialize(bool bShare              = true, 
270                     bool bDepth              = false, 
271                     bool bStencil            = false,
272                     bool bMipmap             = false, 
273                     bool bAnisoFilter        = false,
274                     unsigned int iRBits      = 8,
275                     unsigned int iGBits      = 8,
276                     unsigned int iBBits      = 8,
277                     unsigned int iABits      = 8,
278 // Only Win32 has RT now, so only make it default there
279 #ifdef _WIN32
280                     UpdateMode   updateMode = RT_RENDER_TO_TEXTURE
281 #else
282                     UpdateMode   updateMode = RT_COPY_TO_TEXTURE
283 #endif
284                     );
285     // !Change the render texture resolution. [deprecated]
286     bool Reset(int iWidth, int iHeight);
287     //
288     /////////////////////////////////////////////////////////////////////////
289
290
291 protected: // methods
292     bool         _Invalidate();
293
294     typedef std::pair<std::string, std::string> KeyVal;
295
296     void _ParseModeString(const char *modeString, 
297                           std::vector<int> &pixelFormatAttribs, 
298                           std::vector<int> &pbufferAttribs);
299
300     std::vector<int> _ParseBitVector(std::string bitVector);
301     KeyVal _GetKeyValuePair(std::string token);
302
303
304     bool _VerifyExtensions();
305     bool _InitializeTextures();
306     
307     void _MaybeCopyBuffer();
308     bool _ReleaseBoundBuffers();
309     bool _MakeCurrent();
310     bool _BindDepthBuffer( ) const;
311
312 protected: // data
313     int          _iWidth;     // width of the pbuffer
314     int          _iHeight;    // height of the pbuffer
315     
316     bool         _bIsTexture;
317     bool         _bIsDepthTexture;
318     bool         _bHasARBDepthTexture; // [Redge]
319     
320     UpdateMode   _eUpdateMode;
321         
322     bool         _bInitialized;
323     
324     unsigned int _iNumAuxBuffers;
325     bool         _bIsBufferBound;
326     int          _iCurrentBoundBuffer;
327     
328     unsigned int _iNumComponents;
329     unsigned int _iNumColorBits[4];
330     unsigned int _iNumDepthBits;
331     unsigned int _iNumStencilBits;
332
333     
334     bool         _bFloat;
335     bool         _bDoubleBuffered;
336     bool         _bPowerOf2;
337     bool         _bRectangle;
338     bool         _bMipmap;
339     
340     bool         _bShareObjects;
341     bool         _bCopyContext;
342     
343 #ifdef _WIN32
344     HDC          _hDC;        // Handle to a device context.
345     HGLRC        _hGLContext; // Handle to a GL context.
346     HPBUFFERARB  _hPBuffer;   // Handle to a pbuffer.
347     
348     HDC          _hPreviousDC;
349     HGLRC        _hPreviousContext;
350 #elif defined( __MACH__ )
351     CGLContextObj      _hGLContext;
352     CGLPBufferObj   _hPBuffer;
353    
354     CGLContextObj      _hPreviousContext;
355 #else
356     Display     *_pDisplay;
357     GLXContext   _hGLContext;
358     GLXPbuffer   _hPBuffer;
359     
360     GLXDrawable  _hPreviousDrawable;
361     GLXContext   _hPreviousContext;
362 #endif
363     
364     // Texture stuff
365     GLenum       _iTextureTarget;
366     GLuint       _iTextureID;
367     GLuint       _iDepthTextureID;
368     
369     unsigned short* _pPoorDepthTexture; // [Redge]
370
371     std::vector<int> _pixelFormatAttribs;
372     std::vector<int> _pbufferAttribs;
373
374 private:
375     // Using these could lead to some odd behavior
376     RenderTexture(const RenderTexture&);
377     RenderTexture& operator=(const RenderTexture&);
378 };
379
380 #endif //__RENDERTEXTURE2_HPP__