diff --git a/include/osg/FrameBufferObject b/include/osg/FrameBufferObject index 4fb3c3074..0305e19d9 100644 --- a/include/osg/FrameBufferObject +++ b/include/osg/FrameBufferObject @@ -87,6 +87,21 @@ #define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA #endif +#ifndef GL_EXT_framebuffer_multisample +#define GL_EXT_framebuffer_multisample 1 +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +#endif + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_NV_framebuffer_multisample_coverage 1 +#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB +#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 +#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 +#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 +#endif + #ifndef GL_VERSION_1_4 #define GL_DEPTH_COMPONENT16 0x81A5 #define GL_DEPTH_COMPONENT24 0x81A6 @@ -194,6 +209,8 @@ namespace osg * this call is useful for when an OpenGL context has been destroyed. */ static void discardDeletedRenderBuffers(unsigned int contextID); + static int getMaxSamples(unsigned int contextID, const FBOExtensions *ext); + protected: virtual ~RenderBuffer(); RenderBuffer &operator=(const RenderBuffer &) { return *this; } diff --git a/src/osg/FrameBufferObject.cpp b/src/osg/FrameBufferObject.cpp index d3c014053..b51f282a8 100644 --- a/src/osg/FrameBufferObject.cpp +++ b/src/osg/FrameBufferObject.cpp @@ -210,6 +210,20 @@ RenderBuffer::~RenderBuffer() } } +int RenderBuffer::getMaxSamples(unsigned int contextID, const FBOExtensions *ext) +{ + static osg::buffered_value maxSamplesList; + + GLint& maxSamples = maxSamplesList[contextID]; + + if (!maxSamples && ext->isMultisampleSupported()) + { + glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples); + } + + return maxSamples; +} + GLuint RenderBuffer::getObjectID(unsigned int contextID, const FBOExtensions *ext) const { GLuint &objectID = _objectID[contextID]; @@ -240,13 +254,18 @@ GLuint RenderBuffer::getObjectID(unsigned int contextID, const FBOExtensions *ex if (_samples > 0 && ext->isMultisampleCoverageSupported()) { + int samples = minimum(_samples, getMaxSamples(contextID, ext)); + int colorSamples = minimum(_colorSamples, samples); + ext->glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, - _samples, _colorSamples, _internalFormat, _width, _height); + samples, colorSamples, _internalFormat, _width, _height); } else if (_samples > 0 && ext->isMultisampleSupported()) { + int samples = minimum(_samples, getMaxSamples(contextID, ext)); + ext->glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, - _samples, _internalFormat, _width, _height); + samples, _internalFormat, _width, _height); } else {