vtkFrameBufferObject2.h 11.5 KB
Newer Older
Ken Martin's avatar
Ken Martin committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkFrameBufferObject2.h

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
/**
 * @class   vtkFrameBufferObject2
 * @brief   Interface to OpenGL framebuffer object.
 *
 * A light and efficient interface to an OpenGL Frame Buffer Object.
 * Use is very simillalry to directly calling OpenGL, but as vtkObject
 * it may safely stored, shared, or passed around. It supports FBO Blit
 * and transfer to Pixel Buffer Object.
 *
 * Typical use case:
 *\code{.cpp}
 * vtkFrameBufferObject2 *fbo = this->Internals->FBO;
 * fbo->SaveCurrentBindings();
 * fbo->Bind(vtkgl::FRAMEBUFFER_EXT);
 * fbo->AddDepthAttachment(vtkgl::DRAW_FRAMEBUFFER_EXT, depthBuffer);
 * fbo->AddColorAttachment(vtkgl::DRAW_FRAMEBUFFER_EXT, 0U, colorTex1);
 * fbo->AddColorAttachment(vtkgl::DRAW_FRAMEBUFFER_EXT, 1U, colorTex2);
 * fbo->AddColorAttachment(vtkgl::DRAW_FRAMEBUFFER_EXT, 2U, colorTex3);
 * fbo->ActivateDrawBuffers(3);
 * vtkCheckFrameBufferStatusMacro(vtkgl::FRAMEBUFFER_EXT);
 *
 * ...
 *
 * fbo->UnBind(vtkgl::FRAMEBUFFER_EXT);
 *\endcode
 *
 * @sa
 * vtkRenderbuffer, vtkPixelBufferObject
*/
Ken Martin's avatar
Ken Martin committed
44 45 46 47

#ifndef vtkFrameBufferObject2_h
#define vtkFrameBufferObject2_h

48
#include "vtkFrameBufferObjectBase.h"
Ken Martin's avatar
Ken Martin committed
49 50 51 52
#include "vtkRenderingOpenGL2Module.h" // For export macro
#include "vtkSmartPointer.h" // needed for vtkSmartPointer.
#include "vtkWeakPointer.h" // needed for vtkWeakPointer.

53 54 55 56 57 58
/**
 * A variant of vtkErrorMacro that is used to verify framebuffer
 * object completeness. It's provided so that reporting may include
 * the file and line number of the offending code. In release mode
 * the macro does nothing.
 */
Ken Martin's avatar
Ken Martin committed
59 60 61 62 63 64 65 66 67
#ifdef NDEBUG
# define vtkCheckFrameBufferStatusMacro(mode)
# define vtkStaticCheckFrameBufferStatusMacro(mode)
#else
# define vtkCheckFrameBufferStatusMacroImpl(macro, mode)           \
{                                                                  \
const char *eStr;                                                  \
bool ok = vtkFrameBufferObject2::GetFrameBufferStatus(mode, eStr); \
if (!ok)                                                           \
68
{                                                                \
Ken Martin's avatar
Ken Martin committed
69 70
  macro(                                                           \
    << "OpenGL ERROR. The FBO is incomplete : " << eStr);          \
71
}                                                                \
Ken Martin's avatar
Ken Martin committed
72 73 74 75 76 77 78 79 80 81 82 83 84
 }
# define vtkCheckFrameBufferStatusMacro(mode) \
    vtkCheckFrameBufferStatusMacroImpl(vtkErrorMacro, mode)
# define vtkStaticCheckFrameBufferStatusMacro(mode) \
    vtkCheckFrameBufferStatusMacroImpl(vtkGenericWarningMacro, mode)
#endif

class vtkRenderWindow;
class vtkTextureObject;
class vtkRenderbuffer;
class vtkPixelBufferObject;
class vtkOpenGLRenderWindow;

85
class VTKRENDERINGOPENGL2_EXPORT vtkFrameBufferObject2 : public vtkFrameBufferObjectBase
Ken Martin's avatar
Ken Martin committed
86 87 88
{
public:
  static vtkFrameBufferObject2* New();
89
  vtkTypeMacro(vtkFrameBufferObject2, vtkFrameBufferObjectBase);
Ken Martin's avatar
Ken Martin committed
90 91
  void PrintSelf(ostream& os, vtkIndent indent);

92 93 94 95 96 97 98 99
  //@{
  /**
   * Get/Set the context. Context must be a vtkOpenGLRenderWindow.
   * This does not increase the reference count of the
   * context to avoid reference loops.
   * SetContext() may raise an error is the OpenGL context does not support the
   * required OpenGL extensions.
   */
Ken Martin's avatar
Ken Martin committed
100 101
  void SetContext(vtkRenderWindow *context);
  vtkRenderWindow *GetContext();
102
  //@}
Ken Martin's avatar
Ken Martin committed
103

104 105 106 107
  /**
   * Returns if the context supports the required extensions.
   * Extension will be loaded when the conetxt is set.
   */
Ken Martin's avatar
Ken Martin committed
108 109
  static bool IsSupported(vtkRenderWindow *renWin);

110 111 112 113 114 115
  /**
   * Bind FBO to FRAMEBUFFER,  DRAW_FRAMEBUFFER or READ_FRAMEBUFFER
   * The current binding is not saved, nor restored. (see glBindFramebuffer)
   * This method can be used to prepare for FBO Blit or buffer ping-pong.
   * Low level api.
   */
Ken Martin's avatar
Ken Martin committed
116 117
  void Bind(unsigned int mode);

118 119 120 121 122
  /**
   * Bind saved FBO (see SaveCurrentBindings) for DRAW or READ (see glBindFramebuffer)
   * If no bindings were saved bind to default FBO.
   * Low level api.
   */
Ken Martin's avatar
Ken Martin committed
123 124
  void UnBind(unsigned int mode);

125 126 127 128 129 130 131
  /**
   * Store the current framebuffer bindings. If this method
   * is called then UnBind will restore the saved value accoring
   * to its mode (DRAW_FRAMEBUFFER,READ_FRAMEBUFFER,FRAMEBUFFER)
   * Restoration occurs in UnBind.
   * Low level api
   */
Ken Martin's avatar
Ken Martin committed
132 133
  void SaveCurrentBindings();

134 135 136 137 138 139 140 141
  //@{
  /**
   * Store the current draw and read buffers. When restored
   * only the buffers matching mode are modified.
   * DRAW_FRAMEBUFFER -> glDrawBuffer
   * READ_FRAMEBUFFER -> glReadBuffer
   * FRAMEBUFFER -> both
   */
Ken Martin's avatar
Ken Martin committed
142 143
  void SaveCurrentBuffers();
  void RestorePreviousBuffers(unsigned int mode);
144
  //@}
Ken Martin's avatar
Ken Martin committed
145

146 147 148
  /**
   * Directly assign/remove a texture to color attachments.
   */
Ken Martin's avatar
Ken Martin committed
149 150 151 152 153 154 155 156 157 158 159 160 161 162
  void AddColorAttachment(
        unsigned int mode,
        unsigned int attId,
        vtkTextureObject* tex);

  void AddTexColorAttachment(
        unsigned int mode,
        unsigned int attId,
        unsigned int handle);

  void RemoveTexColorAttachments(unsigned int mode, unsigned int num);
  void RemoveTexColorAttachment(unsigned int mode, unsigned int attId)
    { this->AddTexColorAttachment(mode, attId, 0U); }

163 164 165
  /**
   * Directly assign/remove a renderbuffer to color attachments.
   */
Ken Martin's avatar
Ken Martin committed
166 167 168 169 170 171 172 173 174 175 176 177 178 179
  void AddColorAttachment(
        unsigned int mode,
        unsigned int attId,
        vtkRenderbuffer* tex);

  void AddRenColorAttachment(
        unsigned int mode,
        unsigned int attId,
        unsigned int handle);

  void RemoveRenColorAttachments(unsigned int mode, unsigned int num);
  void RemoveRenColorAttachment(unsigned int mode, unsigned int attId)
    { this->AddRenColorAttachment(mode, attId, 0U); }

180 181 182 183
  //@{
  /**
   * Directly assign/remove a texture/renderbuffer to depth attachments.
   */
Ken Martin's avatar
Ken Martin committed
184 185 186 187
  void AddDepthAttachment(unsigned int mode, vtkTextureObject* tex);
  void AddTexDepthAttachment(unsigned int mode, unsigned int handle);
  void RemoveTexDepthAttachment(unsigned int mode)
    { this->AddTexDepthAttachment(mode, 0U); }
188
  //@}
Ken Martin's avatar
Ken Martin committed
189

190 191 192 193
  //@{
  /**
   * Directly assign/remove a renderbuffer to depth attachments.
   */
Ken Martin's avatar
Ken Martin committed
194 195 196 197
  void AddDepthAttachment(unsigned int mode, vtkRenderbuffer* tex);
  void AddRenDepthAttachment(unsigned int mode, unsigned int handle);
  void RemoveRenDepthAttachment(unsigned int mode)
    { this->AddRenDepthAttachment(mode, 0U); }
198
  //@}
Ken Martin's avatar
Ken Martin committed
199

200 201 202 203
  //@{
  /**
   * Select a single specific draw or read buffer (zero based)
   */
Ken Martin's avatar
Ken Martin committed
204 205 206
  void ActivateDrawBuffer(unsigned int id);
  void ActivateReadBuffer(unsigned int id);
  void DeactivateReadBuffer();
207
  //@}
Ken Martin's avatar
Ken Martin committed
208

209 210 211 212 213
  //@{
  /**
   * Select n consecutive write attachments.
   * Low level api.
   */
Ken Martin's avatar
Ken Martin committed
214 215 216
  void ActivateDrawBuffers(unsigned int n);
  void ActivateDrawBuffers(unsigned int *ids, int n);
  void DeactivateDrawBuffers();
217 218 219 220 221 222 223 224
  //@}

  /**
   * Set up ortho viewport with scissor, lighting, blend, and depth
   * disabled. The method affects the current bound FBO. The method is
   * static so that it may be used on the default FBO without an instance.
   * Low level api.
   */
Ken Martin's avatar
Ken Martin committed
225 226 227
  static
  void InitializeViewport(int width, int height);

228 229 230 231 232
  /**
   * Validate the current FBO configuration (attachments, formats, etc)
   * prints detected errors to vtkErrorMacro.
   * Low level api.
   */
Ken Martin's avatar
Ken Martin committed
233 234
  int CheckFrameBufferStatus(unsigned int mode);

235 236 237 238 239 240
  /**
   * Validate the current FBO configuration (attachments, formats, etc)
   * return false if the FBO is incomplete. Assigns description a literal
   * containing a description of the status.
   * Low level api.
   */
Ken Martin's avatar
Ken Martin committed
241 242 243 244 245
  static
  bool GetFrameBufferStatus(
        unsigned int mode,
        const char *&desc);

246 247 248 249 250 251
  /**
   * Copy from the currently bound READ FBO to the currently
   * bound DRAW FBO. The method is static so that one doesn't
   * need to ccreate an instance when transfering between attachments
   * in the default FBO.
   */
Ken Martin's avatar
Ken Martin committed
252 253 254 255 256 257 258
  static
  int Blit(
        int srcExt[4],
        int destExt[4],
        unsigned int bits,
        unsigned int mapping);

259 260 261 262 263 264 265 266
  /**
   * Download data from the read color attachment of the currently
   * bound FBO into the retruned PBO. The PBO must be free'd when
   * you are finished with it. The number of components in the
   * PBO is the same as in the name of the specific  download fucntion.
   * When downloading a single color channel, the channel must be
   * identified by index, 1->red, 2->green, 3-> blue.
   */
Ken Martin's avatar
Ken Martin committed
267 268 269 270 271 272 273 274 275 276 277 278 279
  vtkPixelBufferObject *DownloadColor1(
        int extent[4],
        int vtkType,
        int channel);

  vtkPixelBufferObject *DownloadColor3(
        int extent[4],
        int vtkType);

  vtkPixelBufferObject *DownloadColor4(
        int extent[4],
        int vtkType);

280 281 282 283 284
  /**
   * Download data from the depth attachment of the currently
   * bound FBO. The returned PBO must be Delete'd by the caller.
   * The retruned PBO has one component.
   */
Ken Martin's avatar
Ken Martin committed
285 286 287 288
  vtkPixelBufferObject *DownloadDepth(
        int extent[4],
        int vtkType);

289 290 291 292 293 294 295
  /**
   * Download data from the read buffer of the current FBO. These
   * are low level meothds. In the static variant a PBO must be
   * passed in since we don't have access to a context. The static
   * method is provided so that one may download from the default
   * FBO.
   */
Ken Martin's avatar
Ken Martin committed
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
  vtkPixelBufferObject *Download(
        int extent[4],
        int vtkType,
        int nComps,
        int oglType,
        int oglFormat);

  static
  void Download(
        int extent[4],
        int vtkType,
        int nComps,
        int oglType,
        int oglFormat,
        vtkPixelBufferObject *pbo);

312 313 314 315 316 317 318 319
  //@{
  /**
   * Dimensions in pixels of the framebuffer. Given that InitializeViewport
   * is static, these methods query the viewport size directly from GL. The
   * cached size (LastViewportSize) will appear uninitialized (-1) until one
   * one of these methods has been called. As with InitializeViewport, the
   * methods affect the currently bound FBO (user must bind first).
   */
320 321 322
  virtual int* GetLastSize();
  virtual void GetLastSize(int &width, int &height);
  virtual void GetLastSize(int size[2]);
323 324 325 326 327 328 329 330
  //@}

  /**
   * Additional overload which lets the user decide whether the returned size
   * should be the currently cached value or first be updated from GL. As with
   * InitializeViewport, the method affects the currently bound FBO (user must
   * bind first).
   */
331 332
  int* GetLastSize(bool forceUpdate);

Ken Martin's avatar
Ken Martin committed
333
protected:
334 335 336
  /**
   * Load all necessary extensions.
   */
Ken Martin's avatar
Ken Martin committed
337 338 339 340 341 342 343 344 345
  static
  bool LoadRequiredExtensions(vtkRenderWindow *renWin);

  // gen buffer (occurs when context is set)
  void CreateFBO();

  // delete buffer (occurs during destruction or context swicth)
  void DestroyFBO();

346 347 348
  /**
   * Given a vtk type get a compatible open gl type.
   */
Ken Martin's avatar
Ken Martin committed
349 350 351 352 353 354 355 356 357 358 359 360
  int GetOpenGLType(int vtkType);

  vtkFrameBufferObject2();
  ~vtkFrameBufferObject2();

  vtkWeakPointer<vtkRenderWindow> Context;

  unsigned int FBOIndex;
  unsigned int PreviousDrawFBO;
  unsigned int PreviousReadFBO;
  unsigned int PreviousDrawBuffer;
  unsigned int PreviousReadBuffer;
361
  int LastViewportSize[2];
Ken Martin's avatar
Ken Martin committed
362 363

private:
364 365 366
  /**
   * Queries viewport dimensions from GL.
   */
367 368
  inline void QueryViewportSize();

369
  vtkFrameBufferObject2(const vtkFrameBufferObject2&) VTK_DELETE_FUNCTION;
370
  void operator=(const vtkFrameBufferObject2&) VTK_DELETE_FUNCTION;
Ken Martin's avatar
Ken Martin committed
371 372

  friend class vtkRenderbuffer; // needs access to LoadRequiredExtentsions
373

Ken Martin's avatar
Ken Martin committed
374 375 376
};

#endif