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