Added support for creation of a stencil attachment and multisampling to sf::RenderTexture.
This commit is contained in:
parent
b0f3611ab9
commit
421e8bb812
@ -31,6 +31,7 @@
|
||||
#include <SFML/Graphics/Export.hpp>
|
||||
#include <SFML/Graphics/Texture.hpp>
|
||||
#include <SFML/Graphics/RenderTarget.hpp>
|
||||
#include <SFML/Window/ContextSettings.hpp>
|
||||
|
||||
|
||||
namespace sf
|
||||
@ -82,8 +83,38 @@ public:
|
||||
///
|
||||
/// \return True if creation has been successful
|
||||
///
|
||||
/// \deprecated Use create(unsigned int, unsigned int, const ContextSettings&) instead.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool create(unsigned int width, unsigned int height, bool depthBuffer = false);
|
||||
SFML_DEPRECATED bool create(unsigned int width, unsigned int height, bool depthBuffer);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create the render-texture
|
||||
///
|
||||
/// Before calling this function, the render-texture is in
|
||||
/// an invalid state, thus it is mandatory to call it before
|
||||
/// doing anything with the render-texture.
|
||||
/// The last parameter, \a settings, is useful if you want to enable
|
||||
/// multi-sampling or use the render-texture for OpenGL rendering that
|
||||
/// requires a depth or stencil buffer. Otherwise it is unnecessary, and
|
||||
/// you should leave this parameter at its default value.
|
||||
///
|
||||
/// \param width Width of the render-texture
|
||||
/// \param height Height of the render-texture
|
||||
/// \param settings Additional settings for the underlying OpenGL texture and context
|
||||
///
|
||||
/// \return True if creation has been successful
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool create(unsigned int width, unsigned int height, const ContextSettings& settings = ContextSettings());
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the maximum anti-aliasing level supported by the system
|
||||
///
|
||||
/// \return The maximum anti-aliasing level supported by the system
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static unsigned int getMaximumAntialiasingLevel();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Enable or disable texture smoothing
|
||||
|
@ -124,9 +124,15 @@
|
||||
#define GLEXT_GL_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING_OES
|
||||
#define GLEXT_GL_INVALID_FRAMEBUFFER_OPERATION GL_INVALID_FRAMEBUFFER_OPERATION_OES
|
||||
|
||||
// Core since 3.0
|
||||
#define GLEXT_packed_depth_stencil false
|
||||
|
||||
// Core since 3.0
|
||||
#define GLEXT_framebuffer_blit false
|
||||
|
||||
// Core since 3.0
|
||||
#define GLEXT_framebuffer_multisample false
|
||||
|
||||
// Core since 3.0 - NV_copy_buffer
|
||||
#define GLEXT_copy_buffer false
|
||||
|
||||
@ -277,6 +283,11 @@
|
||||
#define GLEXT_GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_EXT
|
||||
#define GLEXT_GL_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING_EXT
|
||||
#define GLEXT_GL_INVALID_FRAMEBUFFER_OPERATION GL_INVALID_FRAMEBUFFER_OPERATION_EXT
|
||||
#define GLEXT_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_EXT
|
||||
|
||||
// Core since 3.0 - EXT_packed_depth_stencil
|
||||
#define GLEXT_packed_depth_stencil sfogl_ext_EXT_packed_depth_stencil
|
||||
#define GLEXT_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_EXT
|
||||
|
||||
// Core since 3.0 - EXT_framebuffer_blit
|
||||
#define GLEXT_framebuffer_blit sfogl_ext_EXT_framebuffer_blit
|
||||
@ -286,6 +297,11 @@
|
||||
#define GLEXT_GL_DRAW_FRAMEBUFFER_BINDING GL_DRAW_FRAMEBUFFER_BINDING_EXT
|
||||
#define GLEXT_GL_READ_FRAMEBUFFER_BINDING GL_READ_FRAMEBUFFER_BINDING_EXT
|
||||
|
||||
// Core since 3.0 - EXT_framebuffer_multisample
|
||||
#define GLEXT_framebuffer_multisample sfogl_ext_EXT_framebuffer_multisample
|
||||
#define GLEXT_glRenderbufferStorageMultisample glRenderbufferStorageMultisampleEXT
|
||||
#define GLEXT_GL_MAX_SAMPLES GL_MAX_SAMPLES_EXT
|
||||
|
||||
// Core since 3.1 - ARB_copy_buffer
|
||||
#define GLEXT_copy_buffer sfogl_ext_ARB_copy_buffer
|
||||
#define GLEXT_GL_COPY_READ_BUFFER GL_COPY_READ_BUFFER
|
||||
|
@ -16,6 +16,8 @@ ARB_texture_non_power_of_two
|
||||
EXT_blend_equation_separate
|
||||
EXT_texture_sRGB
|
||||
EXT_framebuffer_object
|
||||
EXT_packed_depth_stencil
|
||||
EXT_framebuffer_blit
|
||||
EXT_framebuffer_multisample
|
||||
ARB_copy_buffer
|
||||
ARB_geometry_shader4
|
||||
|
@ -48,7 +48,9 @@ int sfogl_ext_ARB_texture_non_power_of_two = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_EXT_blend_equation_separate = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_EXT_texture_sRGB = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_EXT_framebuffer_object = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_EXT_packed_depth_stencil = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_EXT_framebuffer_blit = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_EXT_framebuffer_multisample = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_ARB_copy_buffer = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_ARB_geometry_shader4 = sfogl_LOAD_FAILED;
|
||||
|
||||
@ -879,6 +881,19 @@ static int Load_EXT_framebuffer_blit()
|
||||
return numFailed;
|
||||
}
|
||||
|
||||
void (GL_FUNCPTR *sf_ptrc_glRenderbufferStorageMultisampleEXT)(GLenum, GLsizei, GLenum, GLsizei, GLsizei) = NULL;
|
||||
|
||||
static int Load_EXT_framebuffer_multisample()
|
||||
{
|
||||
int numFailed = 0;
|
||||
|
||||
sf_ptrc_glRenderbufferStorageMultisampleEXT = reinterpret_cast<void (GL_FUNCPTR *)(GLenum, GLsizei, GLenum, GLsizei, GLsizei)>(glLoaderGetProcAddress("glRenderbufferStorageMultisampleEXT"));
|
||||
if (!sf_ptrc_glRenderbufferStorageMultisampleEXT)
|
||||
numFailed++;
|
||||
|
||||
return numFailed;
|
||||
}
|
||||
|
||||
void (GL_FUNCPTR *sf_ptrc_glCopyBufferSubData)(GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr) = NULL;
|
||||
|
||||
static int Load_ARB_copy_buffer()
|
||||
@ -928,7 +943,7 @@ typedef struct sfogl_StrToExtMap_s
|
||||
PFN_LOADFUNCPOINTERS LoadExtension;
|
||||
} sfogl_StrToExtMap;
|
||||
|
||||
static sfogl_StrToExtMap ExtensionMap[18] = {
|
||||
static sfogl_StrToExtMap ExtensionMap[20] = {
|
||||
{"GL_SGIS_texture_edge_clamp", &sfogl_ext_SGIS_texture_edge_clamp, NULL},
|
||||
{"GL_EXT_texture_edge_clamp", &sfogl_ext_EXT_texture_edge_clamp, NULL},
|
||||
{"GL_EXT_blend_minmax", &sfogl_ext_EXT_blend_minmax, Load_EXT_blend_minmax},
|
||||
@ -944,12 +959,14 @@ static sfogl_StrToExtMap ExtensionMap[18] = {
|
||||
{"GL_EXT_blend_equation_separate", &sfogl_ext_EXT_blend_equation_separate, Load_EXT_blend_equation_separate},
|
||||
{"GL_EXT_texture_sRGB", &sfogl_ext_EXT_texture_sRGB, NULL},
|
||||
{"GL_EXT_framebuffer_object", &sfogl_ext_EXT_framebuffer_object, Load_EXT_framebuffer_object},
|
||||
{"GL_EXT_packed_depth_stencil", &sfogl_ext_EXT_packed_depth_stencil, NULL},
|
||||
{"GL_EXT_framebuffer_blit", &sfogl_ext_EXT_framebuffer_blit, Load_EXT_framebuffer_blit},
|
||||
{"GL_EXT_framebuffer_multisample", &sfogl_ext_EXT_framebuffer_multisample, Load_EXT_framebuffer_multisample},
|
||||
{"GL_ARB_copy_buffer", &sfogl_ext_ARB_copy_buffer, Load_ARB_copy_buffer},
|
||||
{"GL_ARB_geometry_shader4", &sfogl_ext_ARB_geometry_shader4, Load_ARB_geometry_shader4}
|
||||
};
|
||||
|
||||
static int g_extensionMapSize = 18;
|
||||
static int g_extensionMapSize = 20;
|
||||
|
||||
|
||||
static void ClearExtensionVars()
|
||||
@ -969,7 +986,9 @@ static void ClearExtensionVars()
|
||||
sfogl_ext_EXT_blend_equation_separate = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_EXT_texture_sRGB = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_EXT_framebuffer_object = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_EXT_packed_depth_stencil = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_EXT_framebuffer_blit = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_EXT_framebuffer_multisample = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_ARB_copy_buffer = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_ARB_geometry_shader4 = sfogl_LOAD_FAILED;
|
||||
}
|
||||
|
@ -185,7 +185,9 @@ extern int sfogl_ext_ARB_texture_non_power_of_two;
|
||||
extern int sfogl_ext_EXT_blend_equation_separate;
|
||||
extern int sfogl_ext_EXT_texture_sRGB;
|
||||
extern int sfogl_ext_EXT_framebuffer_object;
|
||||
extern int sfogl_ext_EXT_packed_depth_stencil;
|
||||
extern int sfogl_ext_EXT_framebuffer_blit;
|
||||
extern int sfogl_ext_EXT_framebuffer_multisample;
|
||||
extern int sfogl_ext_ARB_copy_buffer;
|
||||
extern int sfogl_ext_ARB_geometry_shader4;
|
||||
|
||||
@ -414,11 +416,20 @@ extern int sfogl_ext_ARB_geometry_shader4;
|
||||
#define GL_STENCIL_INDEX4_EXT 0x8D47
|
||||
#define GL_STENCIL_INDEX8_EXT 0x8D48
|
||||
|
||||
#define GL_DEPTH24_STENCIL8_EXT 0x88F0
|
||||
#define GL_DEPTH_STENCIL_EXT 0x84F9
|
||||
#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
|
||||
#define GL_UNSIGNED_INT_24_8_EXT 0x84FA
|
||||
|
||||
#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6
|
||||
#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
|
||||
#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA
|
||||
#define GL_READ_FRAMEBUFFER_EXT 0x8CA8
|
||||
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
|
||||
#define GL_MAX_SAMPLES_EXT 0x8D57
|
||||
#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
|
||||
|
||||
#define GL_COPY_READ_BUFFER 0x8F36
|
||||
#define GL_COPY_WRITE_BUFFER 0x8F37
|
||||
|
||||
@ -1311,12 +1322,19 @@ extern void (GL_FUNCPTR *sf_ptrc_glRenderbufferStorageEXT)(GLenum, GLenum, GLsiz
|
||||
#define glRenderbufferStorageEXT sf_ptrc_glRenderbufferStorageEXT
|
||||
#endif // GL_EXT_framebuffer_object
|
||||
|
||||
|
||||
#ifndef GL_EXT_framebuffer_blit
|
||||
#define GL_EXT_framebuffer_blit 1
|
||||
extern void (GL_FUNCPTR *sf_ptrc_glBlitFramebufferEXT)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum);
|
||||
#define glBlitFramebufferEXT sf_ptrc_glBlitFramebufferEXT
|
||||
#endif // GL_EXT_framebuffer_blit
|
||||
|
||||
#ifndef GL_EXT_framebuffer_multisample
|
||||
#define GL_EXT_framebuffer_multisample 1
|
||||
extern void (GL_FUNCPTR *sf_ptrc_glRenderbufferStorageMultisampleEXT)(GLenum, GLsizei, GLenum, GLsizei, GLsizei);
|
||||
#define glRenderbufferStorageMultisampleEXT sf_ptrc_glRenderbufferStorageMultisampleEXT
|
||||
#endif // GL_EXT_framebuffer_multisample
|
||||
|
||||
#ifndef GL_ARB_copy_buffer
|
||||
#define GL_ARB_copy_buffer 1
|
||||
extern void (GL_FUNCPTR *sf_ptrc_glCopyBufferSubData)(GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr);
|
||||
|
@ -50,6 +50,13 @@ RenderTexture::~RenderTexture()
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderTexture::create(unsigned int width, unsigned int height, bool depthBuffer)
|
||||
{
|
||||
return create(width, height, ContextSettings(depthBuffer ? 32 : 0));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderTexture::create(unsigned int width, unsigned int height, const ContextSettings& settings)
|
||||
{
|
||||
// Create the texture
|
||||
if (!m_texture.create(width, height))
|
||||
@ -78,7 +85,7 @@ bool RenderTexture::create(unsigned int width, unsigned int height, bool depthBu
|
||||
}
|
||||
|
||||
// Initialize the render texture
|
||||
if (!m_impl->create(width, height, m_texture.m_texture, depthBuffer))
|
||||
if (!m_impl->create(width, height, m_texture.m_texture, settings))
|
||||
return false;
|
||||
|
||||
// We can now initialize the render target part
|
||||
@ -88,6 +95,20 @@ bool RenderTexture::create(unsigned int width, unsigned int height, bool depthBu
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int RenderTexture::getMaximumAntialiasingLevel()
|
||||
{
|
||||
if (priv::RenderTextureImplFBO::isAvailable())
|
||||
{
|
||||
return priv::RenderTextureImplFBO::getMaximumAntialiasingLevel();
|
||||
}
|
||||
else
|
||||
{
|
||||
return priv::RenderTextureImplDefault::getMaximumAntialiasingLevel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void RenderTexture::setSmooth(bool smooth)
|
||||
{
|
||||
|
@ -33,6 +33,9 @@
|
||||
|
||||
namespace sf
|
||||
{
|
||||
|
||||
struct ContextSettings;
|
||||
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -52,15 +55,15 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create the render texture implementation
|
||||
///
|
||||
/// \param width Width of the texture to render to
|
||||
/// \param height Height of the texture to render to
|
||||
/// \param textureId OpenGL identifier of the target texture
|
||||
/// \param depthBuffer Is a depth buffer requested?
|
||||
/// \param width Width of the texture to render to
|
||||
/// \param height Height of the texture to render to
|
||||
/// \param textureId OpenGL identifier of the target texture
|
||||
/// \param settings Context settings to create render-texture with
|
||||
///
|
||||
/// \return True if creation has been successful
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool create(unsigned int width, unsigned int height, unsigned int textureId, bool depthBuffer) = 0;
|
||||
virtual bool create(unsigned int width, unsigned int height, unsigned int textureId, const ContextSettings& settings) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Activate or deactivate the render texture for rendering
|
||||
|
@ -55,14 +55,24 @@ RenderTextureImplDefault::~RenderTextureImplDefault()
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderTextureImplDefault::create(unsigned int width, unsigned int height, unsigned int, bool depthBuffer)
|
||||
unsigned int RenderTextureImplDefault::getMaximumAntialiasingLevel()
|
||||
{
|
||||
// If the system is so old that it doesn't support FBOs, chances are it is
|
||||
// also using either a software renderer or some CPU emulated support for AA
|
||||
// In order to not cripple performance in this rare case, we just return 0 here
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderTextureImplDefault::create(unsigned int width, unsigned int height, unsigned int, const ContextSettings& settings)
|
||||
{
|
||||
// Store the dimensions
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
|
||||
// Create the in-memory OpenGL context
|
||||
m_context = new Context(ContextSettings(depthBuffer ? 32 : 0), width, height);
|
||||
m_context = new Context(settings, width, height);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -58,20 +58,28 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
~RenderTextureImplDefault();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the maximum anti-aliasing level supported by the system
|
||||
///
|
||||
/// \return The maximum anti-aliasing level supported by the system
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static unsigned int getMaximumAntialiasingLevel();
|
||||
|
||||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create the render texture implementation
|
||||
///
|
||||
/// \param width Width of the texture to render to
|
||||
/// \param height Height of the texture to render to
|
||||
/// \param textureId OpenGL identifier of the target texture
|
||||
/// \param depthBuffer Is a depth buffer requested?
|
||||
/// \param width Width of the texture to render to
|
||||
/// \param height Height of the texture to render to
|
||||
/// \param textureId OpenGL identifier of the target texture
|
||||
/// \param settings Context settings to create render-texture with
|
||||
///
|
||||
/// \return True if creation has been successful
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool create(unsigned int width, unsigned int height, unsigned int textureId, bool depthBuffer);
|
||||
virtual bool create(unsigned int width, unsigned int height, unsigned int textureId, const ContextSettings& settings);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Activate or deactivate the render texture for rendering
|
||||
|
@ -37,9 +37,13 @@ namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderTextureImplFBO::RenderTextureImplFBO() :
|
||||
m_context (NULL),
|
||||
m_frameBuffer(0),
|
||||
m_depthBuffer(0)
|
||||
m_context (NULL),
|
||||
m_frameBuffer (0),
|
||||
m_multisampleFrameBuffer(0),
|
||||
m_depthStencilBuffer (0),
|
||||
m_colorBuffer (0),
|
||||
m_width (0),
|
||||
m_height (0)
|
||||
{
|
||||
|
||||
}
|
||||
@ -50,11 +54,25 @@ RenderTextureImplFBO::~RenderTextureImplFBO()
|
||||
{
|
||||
m_context->setActive(true);
|
||||
|
||||
// Destroy the depth buffer
|
||||
if (m_depthBuffer)
|
||||
// Destroy the color buffer
|
||||
if (m_colorBuffer)
|
||||
{
|
||||
GLuint depthBuffer = static_cast<GLuint>(m_depthBuffer);
|
||||
glCheck(GLEXT_glDeleteRenderbuffers(1, &depthBuffer));
|
||||
GLuint colorBuffer = static_cast<GLuint>(m_colorBuffer);
|
||||
glCheck(GLEXT_glDeleteRenderbuffers(1, &colorBuffer));
|
||||
}
|
||||
|
||||
// Destroy the depth/stencil buffer
|
||||
if (m_depthStencilBuffer)
|
||||
{
|
||||
GLuint depthStencilBuffer = static_cast<GLuint>(m_depthStencilBuffer);
|
||||
glCheck(GLEXT_glDeleteRenderbuffers(1, &depthStencilBuffer));
|
||||
}
|
||||
|
||||
// Destroy the multisample frame buffer
|
||||
if (m_multisampleFrameBuffer)
|
||||
{
|
||||
GLuint multisampleFrameBuffer = static_cast<GLuint>(m_multisampleFrameBuffer);
|
||||
glCheck(GLEXT_glDeleteFramebuffers(1, &multisampleFrameBuffer));
|
||||
}
|
||||
|
||||
// Destroy the frame buffer
|
||||
@ -82,52 +100,233 @@ bool RenderTextureImplFBO::isAvailable()
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderTextureImplFBO::create(unsigned int width, unsigned int height, unsigned int textureId, bool depthBuffer)
|
||||
unsigned int RenderTextureImplFBO::getMaximumAntialiasingLevel()
|
||||
{
|
||||
GLint samples = 0;
|
||||
|
||||
#ifndef SFML_OPENGL_ES
|
||||
|
||||
glCheck(glGetIntegerv(GLEXT_GL_MAX_SAMPLES, &samples));
|
||||
|
||||
#endif
|
||||
|
||||
return static_cast<unsigned int>(samples);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderTextureImplFBO::create(unsigned int width, unsigned int height, unsigned int textureId, const ContextSettings& settings)
|
||||
{
|
||||
// Store the dimensions
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
|
||||
// Disable creation of depth/stencil surfaces in the context
|
||||
ContextSettings contextSettings(settings);
|
||||
contextSettings.depthBits = 0;
|
||||
contextSettings.stencilBits = 0;
|
||||
contextSettings.antialiasingLevel = 0;
|
||||
contextSettings.sRgbCapable = false;
|
||||
|
||||
// Create the context
|
||||
m_context = new Context;
|
||||
m_context = new Context(contextSettings, 1, 1);
|
||||
|
||||
// Create the framebuffer object
|
||||
GLuint frameBuffer = 0;
|
||||
glCheck(GLEXT_glGenFramebuffers(1, &frameBuffer));
|
||||
m_frameBuffer = static_cast<unsigned int>(frameBuffer);
|
||||
if (!m_frameBuffer)
|
||||
{
|
||||
err() << "Impossible to create render texture (failed to create the frame buffer object)" << std::endl;
|
||||
if (settings.antialiasingLevel && !(GLEXT_framebuffer_multisample && GLEXT_framebuffer_blit))
|
||||
return false;
|
||||
}
|
||||
glCheck(GLEXT_glBindFramebuffer(GLEXT_GL_FRAMEBUFFER, m_frameBuffer));
|
||||
|
||||
// Create the depth buffer if requested
|
||||
if (depthBuffer)
|
||||
if (settings.stencilBits && !GLEXT_packed_depth_stencil)
|
||||
return false;
|
||||
|
||||
#ifndef SFML_OPENGL_ES
|
||||
|
||||
// Check if the requested anti-aliasing level is supported
|
||||
if (settings.antialiasingLevel)
|
||||
{
|
||||
GLuint depth = 0;
|
||||
glCheck(GLEXT_glGenRenderbuffers(1, &depth));
|
||||
m_depthBuffer = static_cast<unsigned int>(depth);
|
||||
if (!m_depthBuffer)
|
||||
GLint samples = 0;
|
||||
glCheck(glGetIntegerv(GLEXT_GL_MAX_SAMPLES, &samples));
|
||||
|
||||
if (settings.antialiasingLevel > static_cast<unsigned int>(samples))
|
||||
{
|
||||
err() << "Impossible to create render texture (failed to create the attached depth buffer)" << std::endl;
|
||||
err() << "Impossible to create render texture (unsupported anti-aliasing level)";
|
||||
err() << " Requested: " << settings.antialiasingLevel << " Maximum supported: " << samples << std::endl;
|
||||
return false;
|
||||
}
|
||||
glCheck(GLEXT_glBindRenderbuffer(GLEXT_GL_RENDERBUFFER, m_depthBuffer));
|
||||
glCheck(GLEXT_glRenderbufferStorage(GLEXT_GL_RENDERBUFFER, GLEXT_GL_DEPTH_COMPONENT, width, height));
|
||||
glCheck(GLEXT_glFramebufferRenderbuffer(GLEXT_GL_FRAMEBUFFER, GLEXT_GL_DEPTH_ATTACHMENT, GLEXT_GL_RENDERBUFFER, m_depthBuffer));
|
||||
}
|
||||
|
||||
// Link the texture to the frame buffer
|
||||
glCheck(GLEXT_glFramebufferTexture2D(GLEXT_GL_FRAMEBUFFER, GLEXT_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0));
|
||||
#endif
|
||||
|
||||
// A final check, just to be sure...
|
||||
GLenum status;
|
||||
glCheck(status = GLEXT_glCheckFramebufferStatus(GLEXT_GL_FRAMEBUFFER));
|
||||
if (status != GLEXT_GL_FRAMEBUFFER_COMPLETE)
|
||||
if (!settings.antialiasingLevel)
|
||||
{
|
||||
glCheck(GLEXT_glBindFramebuffer(GLEXT_GL_FRAMEBUFFER, 0));
|
||||
err() << "Impossible to create render texture (failed to link the target texture to the frame buffer)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
// Create the framebuffer object
|
||||
GLuint frameBuffer = 0;
|
||||
glCheck(GLEXT_glGenFramebuffers(1, &frameBuffer));
|
||||
m_frameBuffer = static_cast<unsigned int>(frameBuffer);
|
||||
if (!m_frameBuffer)
|
||||
{
|
||||
err() << "Impossible to create render texture (failed to create the frame buffer object)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
glCheck(GLEXT_glBindFramebuffer(GLEXT_GL_FRAMEBUFFER, m_frameBuffer));
|
||||
|
||||
return true;
|
||||
// Create the depth/stencil buffer if requested
|
||||
if (settings.stencilBits)
|
||||
{
|
||||
|
||||
#ifndef SFML_OPENGL_ES
|
||||
|
||||
GLuint depthStencil = 0;
|
||||
glCheck(GLEXT_glGenRenderbuffers(1, &depthStencil));
|
||||
m_depthStencilBuffer = static_cast<unsigned int>(depthStencil);
|
||||
if (!m_depthStencilBuffer)
|
||||
{
|
||||
err() << "Impossible to create render texture (failed to create the attached depth/stencil buffer)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
glCheck(GLEXT_glBindRenderbuffer(GLEXT_GL_RENDERBUFFER, m_depthStencilBuffer));
|
||||
glCheck(GLEXT_glRenderbufferStorage(GLEXT_GL_RENDERBUFFER, GLEXT_GL_DEPTH24_STENCIL8, width, height));
|
||||
glCheck(GLEXT_glFramebufferRenderbuffer(GLEXT_GL_FRAMEBUFFER, GLEXT_GL_DEPTH_ATTACHMENT, GLEXT_GL_RENDERBUFFER, m_depthStencilBuffer));
|
||||
glCheck(GLEXT_glFramebufferRenderbuffer(GLEXT_GL_FRAMEBUFFER, GLEXT_GL_STENCIL_ATTACHMENT, GLEXT_GL_RENDERBUFFER, m_depthStencilBuffer));
|
||||
#else
|
||||
|
||||
err() << "Impossible to create render texture (failed to create the attached depth/stencil buffer)" << std::endl;
|
||||
return false;
|
||||
|
||||
#endif // SFML_OPENGL_ES
|
||||
|
||||
}
|
||||
else if (settings.depthBits)
|
||||
{
|
||||
GLuint depthStencil = 0;
|
||||
glCheck(GLEXT_glGenRenderbuffers(1, &depthStencil));
|
||||
m_depthStencilBuffer = static_cast<unsigned int>(depthStencil);
|
||||
if (!m_depthStencilBuffer)
|
||||
{
|
||||
err() << "Impossible to create render texture (failed to create the attached depth buffer)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
glCheck(GLEXT_glBindRenderbuffer(GLEXT_GL_RENDERBUFFER, m_depthStencilBuffer));
|
||||
glCheck(GLEXT_glRenderbufferStorage(GLEXT_GL_RENDERBUFFER, GLEXT_GL_DEPTH_COMPONENT, width, height));
|
||||
glCheck(GLEXT_glFramebufferRenderbuffer(GLEXT_GL_FRAMEBUFFER, GLEXT_GL_DEPTH_ATTACHMENT, GLEXT_GL_RENDERBUFFER, m_depthStencilBuffer));
|
||||
}
|
||||
|
||||
// Link the texture to the frame buffer
|
||||
glCheck(GLEXT_glFramebufferTexture2D(GLEXT_GL_FRAMEBUFFER, GLEXT_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0));
|
||||
|
||||
// A final check, just to be sure...
|
||||
GLenum status;
|
||||
glCheck(status = GLEXT_glCheckFramebufferStatus(GLEXT_GL_FRAMEBUFFER));
|
||||
if (status != GLEXT_GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
glCheck(GLEXT_glBindFramebuffer(GLEXT_GL_FRAMEBUFFER, 0));
|
||||
err() << "Impossible to create render texture (frame buffer incomplete)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#ifndef SFML_OPENGL_ES
|
||||
|
||||
// Create the framebuffer object
|
||||
GLuint frameBuffer = 0;
|
||||
glCheck(GLEXT_glGenFramebuffers(1, &frameBuffer));
|
||||
m_frameBuffer = static_cast<unsigned int>(frameBuffer);
|
||||
if (!m_frameBuffer)
|
||||
{
|
||||
err() << "Impossible to create render texture (failed to create the frame buffer object)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
glCheck(GLEXT_glBindFramebuffer(GLEXT_GL_FRAMEBUFFER, m_frameBuffer));
|
||||
|
||||
// Link the texture to the frame buffer
|
||||
glCheck(GLEXT_glFramebufferTexture2D(GLEXT_GL_FRAMEBUFFER, GLEXT_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0));
|
||||
|
||||
// A final check, just to be sure...
|
||||
GLenum status;
|
||||
glCheck(status = GLEXT_glCheckFramebufferStatus(GLEXT_GL_FRAMEBUFFER));
|
||||
if (status != GLEXT_GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
glCheck(GLEXT_glBindFramebuffer(GLEXT_GL_FRAMEBUFFER, 0));
|
||||
err() << "Impossible to create render texture (frame buffer incomplete)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the multisample framebuffer object
|
||||
frameBuffer = 0;
|
||||
glCheck(GLEXT_glGenFramebuffers(1, &frameBuffer));
|
||||
m_multisampleFrameBuffer = static_cast<unsigned int>(frameBuffer);
|
||||
if (!m_multisampleFrameBuffer)
|
||||
{
|
||||
err() << "Impossible to create render texture (failed to create the multisample frame buffer object)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
glCheck(GLEXT_glBindFramebuffer(GLEXT_GL_FRAMEBUFFER, m_multisampleFrameBuffer));
|
||||
|
||||
// Create the multisample color buffer
|
||||
GLuint color = 0;
|
||||
glCheck(GLEXT_glGenRenderbuffers(1, &color));
|
||||
m_colorBuffer = static_cast<unsigned int>(color);
|
||||
if (!m_colorBuffer)
|
||||
{
|
||||
err() << "Impossible to create render texture (failed to create the attached multisample color buffer)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
glCheck(GLEXT_glBindRenderbuffer(GLEXT_GL_RENDERBUFFER, m_colorBuffer));
|
||||
glCheck(GLEXT_glRenderbufferStorageMultisample(GLEXT_GL_RENDERBUFFER, settings.antialiasingLevel, GL_RGBA, width, height));
|
||||
glCheck(GLEXT_glFramebufferRenderbuffer(GLEXT_GL_FRAMEBUFFER, GLEXT_GL_COLOR_ATTACHMENT0, GLEXT_GL_RENDERBUFFER, m_colorBuffer));
|
||||
|
||||
// Create the multisample depth/stencil buffer if requested
|
||||
if (settings.stencilBits)
|
||||
{
|
||||
GLuint depthStencil = 0;
|
||||
glCheck(GLEXT_glGenRenderbuffers(1, &depthStencil));
|
||||
m_depthStencilBuffer = static_cast<unsigned int>(depthStencil);
|
||||
if (!m_depthStencilBuffer)
|
||||
{
|
||||
err() << "Impossible to create render texture (failed to create the attached multisample depth/stencil buffer)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
glCheck(GLEXT_glBindRenderbuffer(GLEXT_GL_RENDERBUFFER, m_depthStencilBuffer));
|
||||
glCheck(GLEXT_glRenderbufferStorageMultisample(GLEXT_GL_RENDERBUFFER, settings.antialiasingLevel, GLEXT_GL_DEPTH24_STENCIL8, width, height));
|
||||
glCheck(GLEXT_glFramebufferRenderbuffer(GLEXT_GL_FRAMEBUFFER, GLEXT_GL_DEPTH_ATTACHMENT, GLEXT_GL_RENDERBUFFER, m_depthStencilBuffer));
|
||||
glCheck(GLEXT_glFramebufferRenderbuffer(GLEXT_GL_FRAMEBUFFER, GLEXT_GL_STENCIL_ATTACHMENT, GLEXT_GL_RENDERBUFFER, m_depthStencilBuffer));
|
||||
}
|
||||
else if (settings.depthBits)
|
||||
{
|
||||
GLuint depthStencil = 0;
|
||||
glCheck(GLEXT_glGenRenderbuffers(1, &depthStencil));
|
||||
m_depthStencilBuffer = static_cast<unsigned int>(depthStencil);
|
||||
if (!m_depthStencilBuffer)
|
||||
{
|
||||
err() << "Impossible to create render texture (failed to create the attached multisample depth buffer)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
glCheck(GLEXT_glBindRenderbuffer(GLEXT_GL_RENDERBUFFER, m_depthStencilBuffer));
|
||||
glCheck(GLEXT_glRenderbufferStorageMultisample(GLEXT_GL_RENDERBUFFER, settings.antialiasingLevel, GLEXT_GL_DEPTH_COMPONENT, width, height));
|
||||
glCheck(GLEXT_glFramebufferRenderbuffer(GLEXT_GL_FRAMEBUFFER, GLEXT_GL_DEPTH_ATTACHMENT, GLEXT_GL_RENDERBUFFER, m_depthStencilBuffer));
|
||||
}
|
||||
|
||||
// A final check, just to be sure...
|
||||
glCheck(status = GLEXT_glCheckFramebufferStatus(GLEXT_GL_FRAMEBUFFER));
|
||||
if (status != GLEXT_GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
glCheck(GLEXT_glBindFramebuffer(GLEXT_GL_FRAMEBUFFER, 0));
|
||||
err() << "Impossible to create render texture (multisample frame buffer incomplete)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
#else
|
||||
|
||||
err() << "Impossible to create render texture (failed to create the multisample frame buffer object)" << std::endl;
|
||||
return false;
|
||||
|
||||
#endif // SFML_OPENGL_ES
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -141,6 +340,18 @@ bool RenderTextureImplFBO::activate(bool active)
|
||||
////////////////////////////////////////////////////////////
|
||||
void RenderTextureImplFBO::updateTexture(unsigned int)
|
||||
{
|
||||
|
||||
#ifndef SFML_OPENGL_ES
|
||||
|
||||
if (m_multisampleFrameBuffer)
|
||||
{
|
||||
glCheck(GLEXT_glBindFramebuffer(GLEXT_GL_DRAW_FRAMEBUFFER, m_frameBuffer));
|
||||
glCheck(GLEXT_glBlitFramebuffer(0, 0, m_width, m_height, 0, 0, m_width, m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST));
|
||||
glCheck(GLEXT_glBindFramebuffer(GLEXT_GL_DRAW_FRAMEBUFFER, m_multisampleFrameBuffer));
|
||||
}
|
||||
|
||||
#endif // SFML_OPENGL_ES
|
||||
|
||||
glCheck(glFlush());
|
||||
}
|
||||
|
||||
|
@ -66,20 +66,28 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool isAvailable();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the maximum anti-aliasing level supported by the system
|
||||
///
|
||||
/// \return The maximum anti-aliasing level supported by the system
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static unsigned int getMaximumAntialiasingLevel();
|
||||
|
||||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create the render texture implementation
|
||||
///
|
||||
/// \param width Width of the texture to render to
|
||||
/// \param height Height of the texture to render to
|
||||
/// \param textureId OpenGL identifier of the target texture
|
||||
/// \param depthBuffer Is a depth buffer requested?
|
||||
/// \param width Width of the texture to render to
|
||||
/// \param height Height of the texture to render to
|
||||
/// \param textureId OpenGL identifier of the target texture
|
||||
/// \param settings Context settings to create render-texture with
|
||||
///
|
||||
/// \return True if creation has been successful
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool create(unsigned int width, unsigned int height, unsigned int textureId, bool depthBuffer);
|
||||
virtual bool create(unsigned int width, unsigned int height, unsigned int textureId, const ContextSettings& settings);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Activate or deactivate the render texture for rendering
|
||||
@ -102,9 +110,13 @@ private:
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
Context* m_context; ///< Needs a separate OpenGL context for not messing up the other ones
|
||||
unsigned int m_frameBuffer; ///< OpenGL frame buffer object
|
||||
unsigned int m_depthBuffer; ///< Optional depth buffer attached to the frame buffer
|
||||
Context* m_context; ///< Needs a separate OpenGL context for not messing up the other ones
|
||||
unsigned int m_frameBuffer; ///< OpenGL frame buffer object
|
||||
unsigned int m_multisampleFrameBuffer; ///< Optional OpenGL frame buffer object with multisample attachments
|
||||
unsigned int m_depthStencilBuffer; ///< Optional depth/stencil buffer attached to the frame buffer
|
||||
unsigned int m_colorBuffer; ///< Optional multisample color buffer attached to the frame buffer
|
||||
unsigned int m_width; ///< Width of the attachments
|
||||
unsigned int m_height; ///< Height of the attachments
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
Loading…
Reference in New Issue
Block a user