]> git.mxchange.org Git - simgear.git/blob - simgear/screen/RenderTexture.h
- remove the SG_GLxxxx_H #defines, since OSG provides its own versions
[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 #include <osg/GL>
54
55 #if defined( __APPLE__)
56 #  include <OpenGL/OpenGL.h>
57 #endif
58
59 #if !defined( _WIN32 ) && !defined( __APPLE__ )
60 #  include <X11/Xlib.h>
61 #  include <GL/glx.h>
62 #endif
63
64 #include <string>
65 #include <vector>
66
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:
69 *
70 * To specify the pixel format, use the following syntax.
71 *   <channels>=<bits>
72 * <channels> must match one of the following.
73 *
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
78 *
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.
85 *   r=32f
86 *   rg=16f
87 *   rgb=8
88 *   rgb=5,6,5
89 *
90 * The following other attributes are supported.
91 *
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
97
98 * tex2D
99 * texRECT
100 * texCUBE  - must support binding pbuffer as texture to specified target
101 *          - binding the depth buffer is also supported by specifying
102 * depthTex2D
103 * depthTexRECT
104 * depthTexCUBE
105 *          - Both depth and color texture binding, may be specified, but
106 *            the targets must match!
107 *            For example: "tex2D depthTex2D" or "texRECT depthTexRECT"
108 *
109 * rtt
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. 
116
117 *
118 *---------------------------------------------------------------------------
119 *
120 * USAGE NOTES:
121 *
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.
128 *
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.
136 *
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>);
141 */
142 class RenderTexture
143 {
144 public: // enums
145     enum UpdateMode
146     {
147         RT_RENDER_TO_TEXTURE,
148         RT_COPY_TO_TEXTURE
149     };
150     
151 public: // interface
152     // ctor / dtor
153     RenderTexture(const char *strMode="rgb tex2D");
154     ~RenderTexture();
155     
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);
162
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);
167     
168     // !Begin drawing to the texture. (i.e. use as "output" texture)
169     bool BeginCapture();
170     // !Ends drawing to 'current', begins drawing to this RenderTexture
171     bool BeginCapture(RenderTexture* current);
172     // !End drawing to the texture.
173     bool EndCapture();
174     
175     // !Bind the texture to the active texture unit for use as an "input" texture
176     void Bind() const;
177
178     // !Bind the depth texture to the active texture unit for use as an "input" texture
179     void BindDepth() const; 
180
181     // !Associate the RTT texture with 'iBuffer' (default is WGL_FRONT_LEFT_ARB) 
182     bool BindBuffer( int iBuffer );
183
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); }
190     
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;}     
199     
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; }                  
208     
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]; }
217
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; }
222     
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; }
242
243     /**
244     * @fn IsPowerOfTwo(int n)
245     * @brief Returns true if /param n is an integer power of 2.
246     * 
247     * Taken from Steve Baker's Cute Code Collection. 
248     * http://www.sjbaker.org/steve/software/cute_code.html
249     */ 
250     static bool IsPowerOfTwo(int n) { return ((n&(n-1))==0); }
251
252
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);
260     //
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, 
265                     bool bDepth              = false, 
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
274 #ifdef _WIN32
275                     UpdateMode   updateMode = RT_RENDER_TO_TEXTURE
276 #else
277                     UpdateMode   updateMode = RT_COPY_TO_TEXTURE
278 #endif
279                     );
280     // !Change the render texture resolution. [deprecated]
281     bool Reset(int iWidth, int iHeight);
282     //
283     /////////////////////////////////////////////////////////////////////////
284
285
286 protected: // methods
287     bool         _Invalidate();
288
289     typedef std::pair<std::string, std::string> KeyVal;
290
291     void _ParseModeString(const char *modeString, 
292                           std::vector<int> &pixelFormatAttribs, 
293                           std::vector<int> &pbufferAttribs);
294
295     std::vector<int> _ParseBitVector(std::string bitVector);
296     KeyVal _GetKeyValuePair(std::string token);
297
298
299     bool _VerifyExtensions();
300     bool _InitializeTextures();
301     
302     void _MaybeCopyBuffer();
303     bool _ReleaseBoundBuffers();
304     bool _MakeCurrent();
305     bool _BindDepthBuffer( ) const;
306
307 protected: // data
308     int          _iWidth;     // width of the pbuffer
309     int          _iHeight;    // height of the pbuffer
310     
311     bool         _bIsTexture;
312     bool         _bIsDepthTexture;
313     bool         _bHasARBDepthTexture; // [Redge]
314     
315     UpdateMode   _eUpdateMode;
316         
317     bool         _bInitialized;
318     
319     unsigned int _iNumAuxBuffers;
320     bool         _bIsBufferBound;
321     int          _iCurrentBoundBuffer;
322     
323     unsigned int _iNumComponents;
324     unsigned int _iNumColorBits[4];
325     unsigned int _iNumDepthBits;
326     unsigned int _iNumStencilBits;
327
328     
329     bool         _bFloat;
330     bool         _bDoubleBuffered;
331     bool         _bPowerOf2;
332     bool         _bRectangle;
333     bool         _bMipmap;
334     
335     bool         _bShareObjects;
336     bool         _bCopyContext;
337     
338 #ifdef _WIN32
339     HDC          _hDC;        // Handle to a device context.
340     HGLRC        _hGLContext; // Handle to a GL context.
341     HPBUFFERARB  _hPBuffer;   // Handle to a pbuffer.
342     
343     HDC          _hPreviousDC;
344     HGLRC        _hPreviousContext;
345 #elif defined( __MACH__ )
346     CGLContextObj      _hGLContext;
347     CGLPBufferObj   _hPBuffer;
348    
349     CGLContextObj      _hPreviousContext;
350 #else
351     Display     *_pDisplay;
352     GLXContext   _hGLContext;
353     GLXPbuffer   _hPBuffer;
354     
355     GLXDrawable  _hPreviousDrawable;
356     GLXContext   _hPreviousContext;
357 #endif
358     
359     // Texture stuff
360     GLenum       _iTextureTarget;
361     GLuint       _iTextureID;
362     GLuint       _iDepthTextureID;
363     
364     unsigned short* _pPoorDepthTexture; // [Redge]
365
366     std::vector<int> _pixelFormatAttribs;
367     std::vector<int> _pbufferAttribs;
368
369 private:
370     // Using these could lead to some odd behavior
371     RenderTexture(const RenderTexture&);
372     RenderTexture& operator=(const RenderTexture&);
373 };
374
375 #endif //__RENDERTEXTURE2_HPP__