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