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