FrameBufferObject 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
  2. *
  3. * This library is open source and may be redistributed and/or modified under
  4. * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  5. * (at your option) any later version. The full license is in LICENSE file
  6. * included with this distribution, and on the openscenegraph.org website.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * OpenSceneGraph Public License for more details.
  12. */
  13. // initial FBO support written by Marco Jez, June 2005.
  14. #ifndef OSG_FRAMEBUFFEROBJECT
  15. #define OSG_FRAMEBUFFEROBJECT 1
  16. #include <osg/GL>
  17. #include <osg/Texture>
  18. #include <osg/buffered_value>
  19. #include <osg/Camera>
  20. #ifndef GL_EXT_framebuffer_object
  21. #define GL_EXT_framebuffer_object 1
  22. #define GL_FRAMEBUFFER_EXT 0x8D40
  23. #define GL_RENDERBUFFER_EXT 0x8D41
  24. // #define GL_STENCIL_INDEX_EXT 0x8D45 // removed in rev. #114 of the spec
  25. #define GL_STENCIL_INDEX1_EXT 0x8D46
  26. #define GL_STENCIL_INDEX4_EXT 0x8D47
  27. #define GL_STENCIL_INDEX8_EXT 0x8D48
  28. #define GL_STENCIL_INDEX16_EXT 0x8D49
  29. #define GL_RENDERBUFFER_WIDTH_EXT 0x8D42
  30. #define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43
  31. #define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
  32. #define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50
  33. #define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51
  34. #define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52
  35. #define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53
  36. #define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54
  37. #define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55
  38. #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0
  39. #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1
  40. #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2
  41. #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
  42. #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4
  43. #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4
  44. #define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
  45. #define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
  46. #define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
  47. #define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
  48. #define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
  49. #define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
  50. #define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
  51. #define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
  52. #define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
  53. #define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
  54. #define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
  55. #define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
  56. #define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
  57. #define GL_COLOR_ATTACHMENT13_EXT 0x8CED
  58. #define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
  59. #define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
  60. #define GL_DEPTH_ATTACHMENT_EXT 0x8D00
  61. #define GL_STENCIL_ATTACHMENT_EXT 0x8D20
  62. #define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
  63. #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6
  64. #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
  65. #define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8
  66. #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9
  67. #define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA
  68. #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB
  69. #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
  70. #define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD
  71. #define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6
  72. #define GL_RENDERBUFFER_BINDING_EXT 0x8CA7
  73. #define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
  74. #define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
  75. #define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
  76. #endif
  77. #ifndef GL_EXT_framebuffer_blit
  78. #define GL_EXT_framebuffer_blit 1
  79. #define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6
  80. #define GL_READ_FRAMEBUFFER_EXT 0x8CA8
  81. #define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
  82. #define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA
  83. #endif
  84. #ifndef GL_EXT_framebuffer_multisample
  85. #define GL_EXT_framebuffer_multisample 1
  86. #define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
  87. #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
  88. #define GL_MAX_SAMPLES_EXT 0x8D57
  89. #endif
  90. #ifndef GL_MAX_SAMPLES_EXT
  91. // Workaround for Centos 5 and other distros that define
  92. // GL_EXT_framebuffer_multisample but not GL_MAX_SAMPLES_EXT
  93. #define GL_MAX_SAMPLES_EXT 0x8D57
  94. #endif
  95. #ifndef GL_NV_framebuffer_multisample_coverage
  96. #define GL_NV_framebuffer_multisample_coverage 1
  97. #define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB
  98. #define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10
  99. #define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11
  100. #define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12
  101. #endif
  102. #ifndef GL_EXT_packed_depth_stencil
  103. #define GL_EXT_packed_depth_stencil 1
  104. #define GL_DEPTH_STENCIL_EXT 0x84F9
  105. #define GL_UNSIGNED_INT_24_8_EXT 0x84FA
  106. #define GL_DEPTH24_STENCIL8_EXT 0x88F0
  107. #define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
  108. #endif
  109. namespace osg
  110. {
  111. /**************************************************************************
  112. * RenderBuffer
  113. **************************************************************************/
  114. class OSG_EXPORT RenderBuffer: public Object
  115. {
  116. public:
  117. RenderBuffer();
  118. RenderBuffer(int width, int height, GLenum internalFormat, int samples=0, int colorSamples=0);
  119. RenderBuffer(const RenderBuffer& copy, const CopyOp& copyop = CopyOp::SHALLOW_COPY);
  120. META_Object(osg, RenderBuffer);
  121. inline int getWidth() const;
  122. inline int getHeight() const;
  123. inline void setWidth(int w);
  124. inline void setHeight(int h);
  125. inline void setSize(int w, int h);
  126. inline GLenum getInternalFormat() const;
  127. inline void setInternalFormat(GLenum format);
  128. inline int getSamples() const;
  129. inline int getColorSamples() const;
  130. inline void setSamples(int samples);
  131. inline void setColorSamples(int colorSamples);
  132. GLuint getObjectID(unsigned int contextID, const GLExtensions *ext) const;
  133. inline int compare(const RenderBuffer &rb) const;
  134. static int getMaxSamples(unsigned int contextID, const GLExtensions* ext);
  135. /** Resize any per context GLObject buffers to specified size. */
  136. virtual void resizeGLObjectBuffers(unsigned int maxSize);
  137. /** If State is non-zero, this function releases any associated OpenGL objects for
  138. * the specified graphics context. Otherwise, releases OpenGL objexts
  139. * for all graphics contexts. */
  140. virtual void releaseGLObjects(osg::State* = 0) const;
  141. protected:
  142. virtual ~RenderBuffer();
  143. RenderBuffer &operator=(const RenderBuffer &) { return *this; }
  144. inline void dirtyAll() const;
  145. private:
  146. mutable buffered_value<GLuint> _objectID;
  147. mutable buffered_value<int> _dirty;
  148. GLenum _internalFormat;
  149. int _width;
  150. int _height;
  151. // "samples" in the framebuffer_multisample extension is equivalent to
  152. // "coverageSamples" in the framebuffer_multisample_coverage extension.
  153. int _samples;
  154. int _colorSamples;
  155. };
  156. // INLINE METHODS
  157. inline int RenderBuffer::getWidth() const
  158. {
  159. return _width;
  160. }
  161. inline int RenderBuffer::getHeight() const
  162. {
  163. return _height;
  164. }
  165. inline void RenderBuffer::setWidth(int w)
  166. {
  167. _width = w;
  168. dirtyAll();
  169. }
  170. inline void RenderBuffer::setHeight(int h)
  171. {
  172. _height = h;
  173. dirtyAll();
  174. }
  175. inline void RenderBuffer::setSize(int w, int h)
  176. {
  177. _width = w;
  178. _height = h;
  179. dirtyAll();
  180. }
  181. inline GLenum RenderBuffer::getInternalFormat() const
  182. {
  183. return _internalFormat;
  184. }
  185. inline void RenderBuffer::setInternalFormat(GLenum format)
  186. {
  187. _internalFormat = format;
  188. dirtyAll();
  189. }
  190. inline int RenderBuffer::getSamples() const
  191. {
  192. return _samples;
  193. }
  194. inline int RenderBuffer::getColorSamples() const
  195. {
  196. return _colorSamples;
  197. }
  198. inline void RenderBuffer::setSamples(int samples)
  199. {
  200. _samples = samples;
  201. dirtyAll();
  202. }
  203. inline void RenderBuffer::setColorSamples(int colorSamples)
  204. {
  205. _colorSamples = colorSamples;
  206. dirtyAll();
  207. }
  208. inline void RenderBuffer::dirtyAll() const
  209. {
  210. _dirty.setAllElementsTo(1);
  211. }
  212. inline int RenderBuffer::compare(const RenderBuffer &rb) const
  213. {
  214. if (&rb == this) return 0;
  215. if (_internalFormat < rb._internalFormat) return -1;
  216. if (_internalFormat > rb._internalFormat) return 1;
  217. if (_width < rb._width) return -1;
  218. if (_width > rb._width) return 1;
  219. if (_height < rb._height) return -1;
  220. if (_height > rb._height) return 1;
  221. return 0;
  222. }
  223. /**************************************************************************
  224. * FrameBufferAttachement
  225. **************************************************************************/
  226. class Texture1D;
  227. class Texture2D;
  228. class Texture2DMultisample;
  229. class Texture3D;
  230. class Texture2DArray;
  231. class TextureCubeMap;
  232. class TextureRectangle;
  233. class OSG_EXPORT FrameBufferAttachment
  234. {
  235. public:
  236. FrameBufferAttachment();
  237. FrameBufferAttachment(const FrameBufferAttachment& copy);
  238. explicit FrameBufferAttachment(RenderBuffer* target);
  239. explicit FrameBufferAttachment(Texture1D* target, unsigned int level = 0);
  240. explicit FrameBufferAttachment(Texture2D* target, unsigned int level = 0);
  241. explicit FrameBufferAttachment(Texture2DMultisample* target, unsigned int level = 0);
  242. explicit FrameBufferAttachment(Texture3D* target, unsigned int zoffset, unsigned int level = 0);
  243. explicit FrameBufferAttachment(Texture2DArray* target, unsigned int layer, unsigned int level = 0);
  244. explicit FrameBufferAttachment(TextureCubeMap* target, unsigned int face, unsigned int level = 0);
  245. explicit FrameBufferAttachment(TextureRectangle* target);
  246. explicit FrameBufferAttachment(Camera::Attachment& attachment);
  247. ~FrameBufferAttachment();
  248. FrameBufferAttachment&operator = (const FrameBufferAttachment& copy);
  249. bool isMultisample() const;
  250. void createRequiredTexturesAndApplyGenerateMipMap(State& state, const GLExtensions* ext) const;
  251. void attach(State &state, GLenum target, GLenum attachment_point, const GLExtensions* ext) const;
  252. int compare(const FrameBufferAttachment &fa) const;
  253. RenderBuffer* getRenderBuffer();
  254. const RenderBuffer* getRenderBuffer() const;
  255. Texture* getTexture();
  256. const Texture* getTexture() const;
  257. unsigned int getCubeMapFace() const;
  258. unsigned int getTextureLevel() const;
  259. unsigned int getTexture3DZOffset() const;
  260. unsigned int getTextureArrayLayer() const;
  261. void resizeGLObjectBuffers(unsigned int maxSize);
  262. void releaseGLObjects(osg::State* = 0) const;
  263. private:
  264. // use the Pimpl idiom to avoid dependency from
  265. // all Texture* headers
  266. struct Pimpl;
  267. Pimpl* _ximpl;
  268. };
  269. /**************************************************************************
  270. * FrameBufferObject
  271. **************************************************************************/
  272. class OSG_EXPORT FrameBufferObject: public StateAttribute
  273. {
  274. public:
  275. typedef std::map<Camera::BufferComponent, FrameBufferAttachment> AttachmentMap;
  276. typedef std::vector<GLenum> MultipleRenderingTargets;
  277. typedef Camera::BufferComponent BufferComponent;
  278. FrameBufferObject();
  279. FrameBufferObject(const FrameBufferObject& copy, const CopyOp& copyop = CopyOp::SHALLOW_COPY);
  280. META_StateAttribute(osg, FrameBufferObject, FRAME_BUFFER_OBJECT);
  281. inline const AttachmentMap& getAttachmentMap() const;
  282. void setAttachment(BufferComponent attachment_point, const FrameBufferAttachment &attachment);
  283. inline const FrameBufferAttachment& getAttachment(BufferComponent attachment_point) const;
  284. inline bool hasAttachment(BufferComponent attachment_point) const;
  285. inline bool hasMultipleRenderingTargets() const { return !_drawBuffers.empty(); }
  286. inline const MultipleRenderingTargets& getMultipleRenderingTargets() const { return _drawBuffers; }
  287. bool isMultisample() const;
  288. int compare(const StateAttribute &sa) const;
  289. void apply(State &state) const;
  290. inline GLuint getHandle(unsigned int contextID) const
  291. {
  292. return _fboID[contextID];
  293. }
  294. enum BindTarget
  295. {
  296. READ_FRAMEBUFFER = GL_READ_FRAMEBUFFER_EXT,
  297. DRAW_FRAMEBUFFER = GL_DRAW_FRAMEBUFFER_EXT,
  298. READ_DRAW_FRAMEBUFFER = GL_FRAMEBUFFER_EXT
  299. };
  300. /** Bind the FBO as either the read or draw target, or both. */
  301. void apply(State &state, BindTarget target) const;
  302. /** Resize any per context GLObject buffers to specified size. */
  303. virtual void resizeGLObjectBuffers(unsigned int maxSize);
  304. /** If State is non-zero, this function releases any associated OpenGL objects for
  305. * the specified graphics context. Otherwise, releases OpenGL objexts
  306. * for all graphics contexts. */
  307. virtual void releaseGLObjects(osg::State* = 0) const;
  308. protected:
  309. virtual ~FrameBufferObject();
  310. FrameBufferObject& operator = (const FrameBufferObject&) { return *this; }
  311. void updateDrawBuffers();
  312. inline void dirtyAll();
  313. GLenum convertBufferComponentToGLenum(BufferComponent attachment_point) const;
  314. private:
  315. AttachmentMap _attachments;
  316. // Buffers passed to glDrawBuffers when using multiple render targets.
  317. MultipleRenderingTargets _drawBuffers;
  318. mutable buffered_value<int> _dirtyAttachmentList;
  319. mutable buffered_value<int> _unsupported;
  320. mutable buffered_value<GLuint> _fboID;
  321. };
  322. // INLINE METHODS
  323. inline const FrameBufferObject::AttachmentMap &FrameBufferObject::getAttachmentMap() const
  324. {
  325. return _attachments;
  326. }
  327. inline bool FrameBufferObject::hasAttachment(FrameBufferObject::BufferComponent attachment_point) const
  328. {
  329. return _attachments.find(attachment_point) != _attachments.end();
  330. }
  331. inline const FrameBufferAttachment &FrameBufferObject::getAttachment(FrameBufferObject::BufferComponent attachment_point) const
  332. {
  333. return _attachments.find(attachment_point)->second;
  334. }
  335. inline void FrameBufferObject::dirtyAll()
  336. {
  337. _dirtyAttachmentList.setAllElementsTo(1);
  338. }
  339. class OSG_EXPORT GLRenderBufferManager : public GLObjectManager
  340. {
  341. public:
  342. GLRenderBufferManager(unsigned int contextID);
  343. virtual void deleteGLObject(GLuint globj);
  344. };
  345. class OSG_EXPORT GLFrameBufferObjectManager : public GLObjectManager
  346. {
  347. public:
  348. GLFrameBufferObjectManager(unsigned int contextID);
  349. virtual void deleteGLObject(GLuint globj);
  350. };
  351. }
  352. #endif