From Michael Platings and Paul Palumbo, multi-sample FBO support

This commit is contained in:
Robert Osfield
2008-06-18 14:09:11 +00:00
parent 7bef1bd16a
commit 90ea0bd95f
6 changed files with 439 additions and 79 deletions

View File

@@ -332,14 +332,18 @@ class OSG_EXPORT Camera : public Transform, public CullSettings
/** Attach a buffer with specified OpenGL internal format.*/
void attach(BufferComponent buffer, GLenum internalFormat);
/** Attach a Texture to specified buffer component.
* The level parameter controls the mip map level of the texture that is attached.
* The face parameter controls the face of texture cube map or z level of 3d texture.
/** Attach a Texture to specified buffer component.
* The level parameter controls the mip map level of the texture that is attached.
* The face parameter controls the face of texture cube map or z level of 3d texture.
* The mipMapGeneration flag controls whether mipmap generation should be done for texture.*/
void attach(BufferComponent buffer, osg::Texture* texture, unsigned int level = 0, unsigned int face=0, bool mipMapGeneration=false);
void attach(BufferComponent buffer, osg::Texture* texture, unsigned int level = 0, unsigned int face=0, bool mipMapGeneration=false,
unsigned int multisampleSamples = 0,
unsigned int multisampleColorSamples = 0);
/** Attach a Image to specified buffer component.*/
void attach(BufferComponent buffer, osg::Image* image);
void attach(BufferComponent buffer, osg::Image* image,
unsigned int multisampleSamples = 0,
unsigned int multisampleColorSamples = 0);
/** Detach specified buffer component.*/
void detach(BufferComponent buffer);
@@ -350,7 +354,9 @@ class OSG_EXPORT Camera : public Transform, public CullSettings
_internalFormat(GL_NONE),
_level(0),
_face(0),
_mipMapGeneration(false) {}
_mipMapGeneration(false),
_multisampleSamples(0),
_multisampleColorSamples(0) {}
int width() const
{
@@ -379,6 +385,8 @@ class OSG_EXPORT Camera : public Transform, public CullSettings
unsigned int _level;
unsigned int _face;
bool _mipMapGeneration;
unsigned int _multisampleSamples;
unsigned int _multisampleColorSamples;
};
typedef std::map< BufferComponent, Attachment> BufferAttachmentMap;
@@ -388,8 +396,8 @@ class OSG_EXPORT Camera : public Transform, public CullSettings
/** Get the const BufferAttachmentMap, used to configure frame buffer objects, pbuffers and texture reads.*/
const BufferAttachmentMap& getBufferAttachmentMap() const { return _bufferAttachmentMap; }
/** Create a operation thread for this camera.*/
void createCameraThread();
@@ -442,11 +450,11 @@ class OSG_EXPORT Camera : public Transform, public CullSettings
DrawCallback(const DrawCallback&,const CopyOp&) {}
META_Object(osg,DrawCallback)
/** Functor method called by rendering thread. Users will typically override this method to carry tasks such as screen capture.*/
/** Functor method called by rendering thread. Users will typically override this method to carry tasks such as screen capture.*/
virtual void operator () (osg::RenderInfo& renderInfo) const;
/** Functor method, provided for backwards compatibility, called by operator() (osg::RenderInfo& renderInfo) method.*/
/** Functor method, provided for backwards compatibility, called by operator() (osg::RenderInfo& renderInfo) method.*/
virtual void operator () (const osg::Camera& /*camera*/) const {}
};

View File

@@ -79,6 +79,14 @@
#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
#endif
#ifndef GL_EXT_framebuffer_blit
#define GL_EXT_framebuffer_blit 1
#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6
#define GL_READ_FRAMEBUFFER_EXT 0x8CA8
#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA
#endif
#ifndef GL_VERSION_1_4
#define GL_DEPTH_COMPONENT16 0x81A5
#define GL_DEPTH_COMPONENT24 0x81A6
@@ -99,6 +107,8 @@ namespace osg
typedef void APIENTRY TglDeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers);
typedef void APIENTRY TglGenRenderbuffersEXT(GLsizei, GLuint *);
typedef void APIENTRY TglRenderbufferStorageEXT(GLenum, GLenum, GLsizei, GLsizei);
typedef void APIENTRY TglRenderbufferStorageMultisampleEXT(GLenum, GLsizei, GLenum, GLsizei, GLsizei);
typedef void APIENTRY TglRenderbufferStorageMultisampleCoverageNV(GLenum, GLsizei, GLsizei, GLenum, GLsizei, GLsizei);
typedef void APIENTRY TglBindFramebufferEXT(GLenum, GLuint);
typedef void APIENTRY TglDeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers);
typedef void APIENTRY TglGenFramebuffersEXT(GLsizei, GLuint *);
@@ -109,12 +119,13 @@ namespace osg
typedef void APIENTRY TglFramebufferTextureLayerEXT(GLenum, GLenum, GLuint, GLint, GLint);
typedef void APIENTRY TglFramebufferRenderbufferEXT(GLenum, GLenum, GLenum, GLuint);
typedef void APIENTRY TglGenerateMipmapEXT(GLenum);
typedef void APIENTRY TglRenderbufferStorageMultisampleCoverageNV(GLenum, GLuint, GLuint, GLenum, GLuint, GLuint);
typedef void APIENTRY TglBlitFramebufferEXT(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum);
TglBindRenderbufferEXT* glBindRenderbufferEXT;
TglGenRenderbuffersEXT* glGenRenderbuffersEXT;
TglDeleteRenderbuffersEXT* glDeleteRenderbuffersEXT;
TglRenderbufferStorageEXT* glRenderbufferStorageEXT;
TglRenderbufferStorageMultisampleEXT* glRenderbufferStorageMultisampleEXT;
TglRenderbufferStorageMultisampleCoverageNV* glRenderbufferStorageMultisampleCoverageNV;
TglBindFramebufferEXT* glBindFramebufferEXT;
TglDeleteFramebuffersEXT* glDeleteFramebuffersEXT;
@@ -126,10 +137,13 @@ namespace osg
TglFramebufferTextureLayerEXT* glFramebufferTextureLayerEXT;
TglFramebufferRenderbufferEXT* glFramebufferRenderbufferEXT;
TglGenerateMipmapEXT* glGenerateMipmapEXT;
TglBlitFramebufferEXT* glBlitFramebufferEXT;
static FBOExtensions* instance(unsigned contextID, bool createIfNotInitalized);
bool isSupported() const { return _supported; }
bool isMultisampleSupported() const { return glRenderbufferStorageMultisampleEXT != 0; }
bool isMultisampleCoverageSupported() const { return glRenderbufferStorageMultisampleCoverageNV != 0; }
protected:
FBOExtensions(unsigned int contextID);
@@ -146,7 +160,7 @@ namespace osg
{
public:
RenderBuffer();
RenderBuffer(int width, int height, GLenum internalFormat);
RenderBuffer(int width, int height, GLenum internalFormat, int samples=0, int colorSamples=0);
RenderBuffer(const RenderBuffer& copy, const CopyOp& copyop = CopyOp::SHALLOW_COPY);
META_Object(osg, RenderBuffer);
@@ -158,6 +172,10 @@ namespace osg
inline void setSize(int w, int h);
inline GLenum getInternalFormat() const;
inline void setInternalFormat(GLenum format);
inline int getSamples() const;
inline int getColorSamples() const;
inline void setSamples(int samples);
inline void setColorSamples(int colorSamples);
GLuint getObjectID(unsigned int contextID, const FBOExtensions *ext) const;
inline int compare(const RenderBuffer &rb) const;
@@ -185,9 +203,14 @@ namespace osg
private:
mutable buffered_value<GLuint> _objectID;
mutable buffered_value<int> _dirty;
GLenum _internalFormat;
int _width;
int _height;
// "samples" in the framebuffer_multisample extension is equivalent to
// "coverageSamples" in the framebuffer_multisample_coverage extension.
int _samples;
int _colorSamples;
};
// INLINE METHODS
@@ -232,6 +255,28 @@ namespace osg
dirtyAll();
}
inline int RenderBuffer::getSamples() const
{
return _samples;
}
inline int RenderBuffer::getColorSamples() const
{
return _colorSamples;
}
inline void RenderBuffer::setSamples(int samples)
{
_samples = samples;
dirtyAll();
}
inline void RenderBuffer::setColorSamples(int colorSamples)
{
_colorSamples = colorSamples;
dirtyAll();
}
inline void RenderBuffer::dirtyAll() const
{
_dirty.setAllElementsTo(1);
@@ -278,8 +323,9 @@ namespace osg
FrameBufferAttachment&operator = (const FrameBufferAttachment& copy);
bool isMultisample() const;
void createRequiredTexturesAndApplyGenerateMipMap(State& state, const FBOExtensions* ext) const;
void attach(State &state, GLenum attachment_point, const FBOExtensions* ext) const;
void attach(State &state, GLenum target, GLenum attachment_point, const FBOExtensions* ext) const;
int compare(const FrameBufferAttachment &fa) const;
private:
@@ -323,10 +369,22 @@ namespace osg
inline bool hasMultipleRenderingTargets() const { return !_drawBuffers.empty(); }
inline const MultipleRenderingTargets& getMultipleRenderingTargets() const { return _drawBuffers; }
bool isMultisample() const;
int compare(const StateAttribute &sa) const;
void apply(State &state) const;
enum BindTarget
{
READ_FRAMEBUFFER = GL_READ_FRAMEBUFFER_EXT,
DRAW_FRAMEBUFFER = GL_DRAW_FRAMEBUFFER_EXT,
READ_DRAW_FRAMEBUFFER = GL_FRAMEBUFFER_EXT
};
/** Bind the FBO as either the read or draw target, or both. */
void apply(State &state, BindTarget target) const;
/** Mark internal FBO for deletion.
* Deletion requests are queued until they can be executed
* in the proper GL context. */

View File

@@ -138,11 +138,28 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin
void setImageReadPixelDataType(GLenum type) { _imageReadPixelDataType = type; }
GLenum getImageReadPixelDataType() const { return _imageReadPixelDataType; }
/** Set a framebuffer object to render into. It is permissible for the
* framebuffer object to be multisampled, in which case you should also
* set a resolve framebuffer object - see setMultisampleResolveFramebufferObject(). */
void setFrameBufferObject(osg::FrameBufferObject* fbo) { _fbo = fbo; }
osg::FrameBufferObject* getFrameBufferObject() { return _fbo.get(); }
const osg::FrameBufferObject* getFrameBufferObject() const { return _fbo.get(); }
/** Sets the destination framebuffer object for glBlitFramebufferEXT to
* resolve a multisampled framebuffer object after the RenderStage is
* drawn. The resolve framebuffer object must not be multisampled. The
* resolve framebuffer object is only necessary if the primary framebuffer
* object is multisampled, if not then leave it set to null. */
void setMultisampleResolveFramebufferObject(osg::FrameBufferObject* fbo);
osg::FrameBufferObject* getMultisampleResolveFramebufferObject() { return _resolveFbo.get(); }
const osg::FrameBufferObject* getMultisampleResolveFramebufferObject() const { return _resolveFbo.get(); }
/** Set whether the framebuffer object should be unbound after
* rendering. By default this is set to true. Set it to false if the
* unbinding is not required. */
void setDisableFboAfterRender(bool disable) {_disableFboAfterRender = disable;}
bool getDisableFboAfterRender() const {return _disableFboAfterRender;}
void setGraphicsContext(osg::GraphicsContext* context) { _graphicsContext = context; }
osg::GraphicsContext* getGraphicsContext() { return _graphicsContext.get(); }
const osg::GraphicsContext* getGraphicsContext() const { return _graphicsContext.get(); }
@@ -247,7 +264,9 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin
std::map< osg::Camera::BufferComponent, Attachment> _bufferAttachmentMap;
osg::ref_ptr<osg::FrameBufferObject> _fbo;
osg::ref_ptr<osg::FrameBufferObject> _resolveFbo;
osg::ref_ptr<osg::GraphicsContext> _graphicsContext;
bool _disableFboAfterRender;
mutable osg::Matrix _inheritedPositionalStateContainerMatrix;
mutable osg::ref_ptr<PositionalStateContainer> _inheritedPositionalStateContainer;