mirror of
https://github.com/SFML/SFML.git
synced 2024-11-28 14:21:04 +08:00
Add support for sRGB capable framebuffers. (#175)
This commit is contained in:
parent
c4956857fa
commit
e00d160224
@ -5,6 +5,10 @@
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <SFML/OpenGL.hpp>
|
||||
|
||||
#ifndef GL_SRGB8_ALPHA8
|
||||
#define GL_SRGB8_ALPHA8 0x8C43
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Entry point of application
|
||||
@ -13,10 +17,16 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
int main()
|
||||
{
|
||||
bool exit = false;
|
||||
bool sRgb = false;
|
||||
|
||||
while(!exit)
|
||||
{
|
||||
// Request a 24-bits depth buffer when creating the window
|
||||
sf::ContextSettings contextSettings;
|
||||
contextSettings.depthBits = 24;
|
||||
contextSettings.sRgbCapable = sRgb;
|
||||
|
||||
// Create the main window
|
||||
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML graphics with OpenGL", sf::Style::Default, contextSettings);
|
||||
@ -24,6 +34,7 @@ int main()
|
||||
|
||||
// Create a sprite for the background
|
||||
sf::Texture backgroundTexture;
|
||||
backgroundTexture.setSrgb(sRgb);
|
||||
if (!backgroundTexture.loadFromFile("resources/background.jpg"))
|
||||
return EXIT_FAILURE;
|
||||
sf::Sprite background(backgroundTexture);
|
||||
@ -33,8 +44,11 @@ int main()
|
||||
if (!font.loadFromFile("resources/sansation.ttf"))
|
||||
return EXIT_FAILURE;
|
||||
sf::Text text("SFML / OpenGL demo", font);
|
||||
sf::Text instructions("Press space to toggle sRGB conversion", font);
|
||||
text.setColor(sf::Color(255, 255, 255, 170));
|
||||
instructions.setColor(sf::Color(255, 255, 255, 170));
|
||||
text.setPosition(250.f, 450.f);
|
||||
instructions.setPosition(150.f, 500.f);
|
||||
|
||||
// Load an OpenGL texture.
|
||||
// We could directly use a sf::Texture as an OpenGL texture (with its Bind() member function),
|
||||
@ -46,7 +60,7 @@ int main()
|
||||
return EXIT_FAILURE;
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.getSize().x, image.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, sRgb ? GL_SRGB8_ALPHA8 : GL_RGBA, image.getSize().x, image.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
@ -141,11 +155,24 @@ int main()
|
||||
{
|
||||
// Close window: exit
|
||||
if (event.type == sf::Event::Closed)
|
||||
{
|
||||
exit = true;
|
||||
window.close();
|
||||
}
|
||||
|
||||
// Escape key: exit
|
||||
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
|
||||
{
|
||||
exit = true;
|
||||
window.close();
|
||||
}
|
||||
|
||||
// Space key: toggle sRGB conversion
|
||||
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Space))
|
||||
{
|
||||
sRgb = !sRgb;
|
||||
window.close();
|
||||
}
|
||||
|
||||
// Adjust the viewport when the window is resized
|
||||
if (event.type == sf::Event::Resized)
|
||||
@ -178,6 +205,7 @@ int main()
|
||||
// Draw some text on top of our OpenGL object
|
||||
window.pushGLStates();
|
||||
window.draw(text);
|
||||
window.draw(instructions);
|
||||
window.popGLStates();
|
||||
|
||||
// Finally, display the rendered frame on screen
|
||||
@ -186,6 +214,7 @@ int main()
|
||||
|
||||
// Don't forget to destroy our texture
|
||||
glDeleteTextures(1, &texture);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -376,6 +376,41 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
bool isSmooth() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Enable or disable conversion from sRGB
|
||||
///
|
||||
/// When providing texture data from an image file or memory, it can
|
||||
/// either be stored in a linear color space or an sRGB color space.
|
||||
/// Most digital images account for gamma correction already, so they
|
||||
/// would need to be "uncorrected" back to linear color space before
|
||||
/// being processed by the hardware. The hardware can automatically
|
||||
/// convert it from the sRGB color space to a linear color space when
|
||||
/// it gets sampled. When the rendered image gets output to the final
|
||||
/// framebuffer, it gets converted back to sRGB.
|
||||
///
|
||||
/// After enabling or disabling sRGB conversion, make sure to reload
|
||||
/// the texture data in order for the setting to take effect.
|
||||
///
|
||||
/// This option is only useful in conjunction with an sRGB capable
|
||||
/// framebuffer. This can be requested during window creation.
|
||||
///
|
||||
/// \param sRgb True to enable sRGB conversion, false to disable it
|
||||
///
|
||||
/// \see isSrgb
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void setSrgb(bool sRgb);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Tell whether the texture source is converted from sRGB or not
|
||||
///
|
||||
/// \return True if the texture source is converted from sRGB, false if not
|
||||
///
|
||||
/// \see setSrgb
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool isSrgb() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Enable or disable repeating
|
||||
///
|
||||
@ -504,6 +539,7 @@ private:
|
||||
Vector2u m_actualSize; ///< Actual texture size (can be greater than public size because of padding)
|
||||
unsigned int m_texture; ///< Internal texture identifier
|
||||
bool m_isSmooth; ///< Status of the smooth filter
|
||||
bool m_sRgb; ///< Should the texture source be converted from sRGB?
|
||||
bool m_isRepeated; ///< Is the texture in repeat mode?
|
||||
mutable bool m_pixelsFlipped; ///< To work around the inconsistency in Y orientation
|
||||
bool m_fboAttachment; ///< Is this texture owned by a framebuffer object?
|
||||
|
@ -55,15 +55,17 @@ struct ContextSettings
|
||||
/// \param major Major number of the context version
|
||||
/// \param minor Minor number of the context version
|
||||
/// \param attributes Attribute flags of the context
|
||||
/// \param sRgb sRGB capable framebuffer
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
explicit ContextSettings(unsigned int depth = 0, unsigned int stencil = 0, unsigned int antialiasing = 0, unsigned int major = 1, unsigned int minor = 1, unsigned int attributes = Default) :
|
||||
explicit ContextSettings(unsigned int depth = 0, unsigned int stencil = 0, unsigned int antialiasing = 0, unsigned int major = 1, unsigned int minor = 1, unsigned int attributes = Default, bool sRgb = false) :
|
||||
depthBits (depth),
|
||||
stencilBits (stencil),
|
||||
antialiasingLevel(antialiasing),
|
||||
majorVersion (major),
|
||||
minorVersion (minor),
|
||||
attributeFlags (attributes)
|
||||
attributeFlags (attributes),
|
||||
sRgbCapable (sRgb)
|
||||
{
|
||||
}
|
||||
|
||||
@ -76,6 +78,7 @@ struct ContextSettings
|
||||
unsigned int majorVersion; ///< Major number of the context version to create
|
||||
unsigned int minorVersion; ///< Minor number of the context version to create
|
||||
Uint32 attributeFlags; ///< The attribute flags to create the context with
|
||||
bool sRgbCapable; ///< Whether the context framebuffer is sRGB capable
|
||||
};
|
||||
|
||||
} // namespace sf
|
||||
|
@ -110,6 +110,10 @@
|
||||
#define GLEXT_GL_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING_OES
|
||||
#define GLEXT_GL_INVALID_FRAMEBUFFER_OPERATION GL_INVALID_FRAMEBUFFER_OPERATION_OES
|
||||
|
||||
// Core since 3.0 - EXT_sRGB
|
||||
#define GLEXT_texture_sRGB GL_EXT_sRGB
|
||||
#define GLEXT_GL_SRGB8_ALPHA8 GL_SRGB8_ALPHA8_EXT
|
||||
|
||||
#else
|
||||
|
||||
#include <SFML/Graphics/GLLoader.hpp>
|
||||
@ -208,6 +212,10 @@
|
||||
#define GLEXT_blend_equation_separate sfogl_ext_EXT_blend_equation_separate
|
||||
#define GLEXT_glBlendEquationSeparate glBlendEquationSeparateEXT
|
||||
|
||||
// Core since 2.1 - EXT_texture_sRGB
|
||||
#define GLEXT_texture_sRGB sfogl_ext_EXT_texture_sRGB
|
||||
#define GLEXT_GL_SRGB8_ALPHA8 GL_SRGB8_ALPHA8_EXT
|
||||
|
||||
// Core since 3.0 - EXT_framebuffer_object
|
||||
#define GLEXT_framebuffer_object sfogl_ext_EXT_framebuffer_object
|
||||
#define GLEXT_glBindRenderbuffer glBindRenderbufferEXT
|
||||
|
@ -13,5 +13,6 @@ ARB_vertex_shader
|
||||
ARB_fragment_shader
|
||||
ARB_texture_non_power_of_two
|
||||
EXT_blend_equation_separate
|
||||
EXT_texture_sRGB
|
||||
EXT_framebuffer_object
|
||||
ARB_geometry_shader4
|
||||
|
@ -45,6 +45,7 @@ int sfogl_ext_ARB_vertex_shader = sfogl_LOAD_FAILED;
|
||||
int sfogl_ext_ARB_fragment_shader = sfogl_LOAD_FAILED;
|
||||
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_ARB_geometry_shader4 = sfogl_LOAD_FAILED;
|
||||
|
||||
@ -835,7 +836,7 @@ typedef struct sfogl_StrToExtMap_s
|
||||
PFN_LOADFUNCPOINTERS LoadExtension;
|
||||
} sfogl_StrToExtMap;
|
||||
|
||||
static sfogl_StrToExtMap ExtensionMap[14] = {
|
||||
static sfogl_StrToExtMap ExtensionMap[15] = {
|
||||
{"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},
|
||||
@ -848,11 +849,12 @@ static sfogl_StrToExtMap ExtensionMap[14] = {
|
||||
{"GL_ARB_fragment_shader", &sfogl_ext_ARB_fragment_shader, NULL},
|
||||
{"GL_ARB_texture_non_power_of_two", &sfogl_ext_ARB_texture_non_power_of_two, NULL},
|
||||
{"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_ARB_geometry_shader4", &sfogl_ext_ARB_geometry_shader4, Load_ARB_geometry_shader4}
|
||||
};
|
||||
|
||||
static int g_extensionMapSize = 14;
|
||||
static int g_extensionMapSize = 15;
|
||||
|
||||
|
||||
static void ClearExtensionVars()
|
||||
@ -869,6 +871,7 @@ static void ClearExtensionVars()
|
||||
sfogl_ext_ARB_fragment_shader = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_ARB_texture_non_power_of_two = sfogl_LOAD_FAILED;
|
||||
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_ARB_geometry_shader4 = sfogl_LOAD_FAILED;
|
||||
}
|
||||
|
@ -182,6 +182,7 @@ extern int sfogl_ext_ARB_vertex_shader;
|
||||
extern int sfogl_ext_ARB_fragment_shader;
|
||||
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_ARB_geometry_shader4;
|
||||
|
||||
@ -309,6 +310,23 @@ extern int sfogl_ext_ARB_geometry_shader4;
|
||||
#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D
|
||||
#define GL_BLEND_EQUATION_RGB_EXT 0x8009
|
||||
|
||||
#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
|
||||
#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
|
||||
#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
|
||||
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
|
||||
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
|
||||
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
|
||||
#define GL_COMPRESSED_SRGB_EXT 0x8C48
|
||||
#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
|
||||
#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45
|
||||
#define GL_SLUMINANCE8_EXT 0x8C47
|
||||
#define GL_SLUMINANCE_ALPHA_EXT 0x8C44
|
||||
#define GL_SLUMINANCE_EXT 0x8C46
|
||||
#define GL_SRGB8_ALPHA8_EXT 0x8C43
|
||||
#define GL_SRGB8_EXT 0x8C41
|
||||
#define GL_SRGB_ALPHA_EXT 0x8C42
|
||||
#define GL_SRGB_EXT 0x8C40
|
||||
|
||||
#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
|
||||
#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
|
||||
#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
|
||||
@ -1185,6 +1203,7 @@ extern void (GL_FUNCPTR *sf_ptrc_glBlendEquationSeparateEXT)(GLenum, GLenum);
|
||||
#define glBlendEquationSeparateEXT sf_ptrc_glBlendEquationSeparateEXT
|
||||
#endif // GL_EXT_blend_equation_separate
|
||||
|
||||
|
||||
#ifndef GL_EXT_framebuffer_object
|
||||
#define GL_EXT_framebuffer_object 1
|
||||
extern void (GL_FUNCPTR *sf_ptrc_glBindFramebufferEXT)(GLenum, GLuint);
|
||||
|
@ -84,6 +84,7 @@ m_size (0, 0),
|
||||
m_actualSize (0, 0),
|
||||
m_texture (0),
|
||||
m_isSmooth (false),
|
||||
m_sRgb (false),
|
||||
m_isRepeated (false),
|
||||
m_pixelsFlipped(false),
|
||||
m_fboAttachment(false),
|
||||
@ -98,6 +99,7 @@ m_size (0, 0),
|
||||
m_actualSize (0, 0),
|
||||
m_texture (0),
|
||||
m_isSmooth (copy.m_isSmooth),
|
||||
m_sRgb (copy.m_sRgb),
|
||||
m_isRepeated (copy.m_isRepeated),
|
||||
m_pixelsFlipped(false),
|
||||
m_fboAttachment(false),
|
||||
@ -185,9 +187,30 @@ bool Texture::create(unsigned int width, unsigned int height)
|
||||
}
|
||||
}
|
||||
|
||||
static bool textureSrgb = GLEXT_texture_sRGB;
|
||||
|
||||
if (m_sRgb && !textureSrgb)
|
||||
{
|
||||
static bool warned = false;
|
||||
|
||||
if (!warned)
|
||||
{
|
||||
#ifndef SFML_OPENGL_ES
|
||||
err() << "OpenGL extension EXT_texture_sRGB unavailable" << std::endl;
|
||||
#else
|
||||
err() << "OpenGL ES extension EXT_sRGB unavailable" << std::endl;
|
||||
#endif
|
||||
err() << "Automatic sRGB to linear conversion disabled" << std::endl;
|
||||
|
||||
warned = true;
|
||||
}
|
||||
|
||||
m_sRgb = false;
|
||||
}
|
||||
|
||||
// Initialize the texture
|
||||
glCheck(glBindTexture(GL_TEXTURE_2D, m_texture));
|
||||
glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_actualSize.x, m_actualSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
|
||||
glCheck(glTexImage2D(GL_TEXTURE_2D, 0, (m_sRgb ? GLEXT_GL_SRGB8_ALPHA8 : GL_RGBA), m_actualSize.x, m_actualSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
|
||||
glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_isRepeated ? GL_REPEAT : (textureEdgeClamp ? GLEXT_GL_CLAMP_TO_EDGE : GLEXT_GL_CLAMP)));
|
||||
glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_isRepeated ? GL_REPEAT : (textureEdgeClamp ? GLEXT_GL_CLAMP_TO_EDGE : GLEXT_GL_CLAMP)));
|
||||
glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST));
|
||||
@ -479,6 +502,20 @@ bool Texture::isSmooth() const
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Texture::setSrgb(bool sRgb)
|
||||
{
|
||||
m_sRgb = sRgb;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Texture::isSrgb() const
|
||||
{
|
||||
return m_sRgb;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Texture::setRepeated(bool repeated)
|
||||
{
|
||||
|
@ -100,6 +100,10 @@
|
||||
#define GL_CONTEXT_FLAGS 0x821E
|
||||
#endif
|
||||
|
||||
#if !defined(GL_FRAMEBUFFER_SRGB)
|
||||
#define GL_FRAMEBUFFER_SRGB 0x8DB9
|
||||
#endif
|
||||
|
||||
#if !defined(GL_CONTEXT_FLAG_DEBUG_BIT)
|
||||
#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
|
||||
#endif
|
||||
@ -176,7 +180,7 @@ void GlContext::globalInit()
|
||||
|
||||
// Create the shared context
|
||||
sharedContext = new ContextType(NULL);
|
||||
sharedContext->initialize();
|
||||
sharedContext->initialize(ContextSettings());
|
||||
|
||||
// This call makes sure that:
|
||||
// - the shared context is inactive (it must never be)
|
||||
@ -221,7 +225,7 @@ GlContext* GlContext::create()
|
||||
|
||||
// Create the context
|
||||
GlContext* context = new ContextType(sharedContext);
|
||||
context->initialize();
|
||||
context->initialize(ContextSettings());
|
||||
|
||||
return context;
|
||||
}
|
||||
@ -237,7 +241,7 @@ GlContext* GlContext::create(const ContextSettings& settings, const WindowImpl*
|
||||
|
||||
// Create the context
|
||||
GlContext* context = new ContextType(sharedContext, settings, owner, bitsPerPixel);
|
||||
context->initialize();
|
||||
context->initialize(settings);
|
||||
context->checkSettings(settings);
|
||||
|
||||
return context;
|
||||
@ -254,7 +258,7 @@ GlContext* GlContext::create(const ContextSettings& settings, unsigned int width
|
||||
|
||||
// Create the context
|
||||
GlContext* context = new ContextType(sharedContext, settings, width, height);
|
||||
context->initialize();
|
||||
context->initialize(settings);
|
||||
context->checkSettings(settings);
|
||||
|
||||
return context;
|
||||
@ -346,7 +350,7 @@ GlContext::GlContext()
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
int GlContext::evaluateFormat(unsigned int bitsPerPixel, const ContextSettings& settings, int colorBits, int depthBits, int stencilBits, int antialiasing, bool accelerated)
|
||||
int GlContext::evaluateFormat(unsigned int bitsPerPixel, const ContextSettings& settings, int colorBits, int depthBits, int stencilBits, int antialiasing, bool accelerated, bool sRgb)
|
||||
{
|
||||
int colorDiff = static_cast<int>(bitsPerPixel) - colorBits;
|
||||
int depthDiff = static_cast<int>(settings.depthBits) - depthBits;
|
||||
@ -362,6 +366,10 @@ int GlContext::evaluateFormat(unsigned int bitsPerPixel, const ContextSettings&
|
||||
// Aggregate the scores
|
||||
int score = std::abs(colorDiff) + std::abs(depthDiff) + std::abs(stencilDiff) + std::abs(antialiasingDiff);
|
||||
|
||||
// If the user wants an sRGB capable format, try really hard to get one
|
||||
if (settings.sRgbCapable && !sRgb)
|
||||
score += 10000000;
|
||||
|
||||
// Make sure we prefer hardware acceleration over features
|
||||
if (!accelerated)
|
||||
score += 100000000;
|
||||
@ -371,7 +379,7 @@ int GlContext::evaluateFormat(unsigned int bitsPerPixel, const ContextSettings&
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void GlContext::initialize()
|
||||
void GlContext::initialize(const ContextSettings& requestedSettings)
|
||||
{
|
||||
// Activate the context
|
||||
setActive(true);
|
||||
@ -468,10 +476,33 @@ void GlContext::initialize()
|
||||
}
|
||||
}
|
||||
|
||||
// Enable antialiasing if needed
|
||||
if (m_settings.antialiasingLevel > 0)
|
||||
// Enable anti-aliasing if requested by the user and supported
|
||||
if ((requestedSettings.antialiasingLevel > 0) && (m_settings.antialiasingLevel > 0))
|
||||
{
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings.antialiasingLevel = 0;
|
||||
}
|
||||
|
||||
// Enable sRGB if requested by the user and supported
|
||||
if (requestedSettings.sRgbCapable && m_settings.sRgbCapable)
|
||||
{
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
|
||||
// Check to see if the enable was successful
|
||||
if (glIsEnabled(GL_FRAMEBUFFER_SRGB) == GL_FALSE)
|
||||
{
|
||||
err() << "Warning: Failed to enable GL_FRAMEBUFFER_SRGB" << std::endl;
|
||||
m_settings.sRgbCapable = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings.sRgbCapable = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -499,7 +530,8 @@ void GlContext::checkSettings(const ContextSettings& requestedSettings)
|
||||
(version < requestedVersion) ||
|
||||
(m_settings.stencilBits < requestedSettings.stencilBits) ||
|
||||
(m_settings.antialiasingLevel < requestedSettings.antialiasingLevel) ||
|
||||
(m_settings.depthBits < requestedSettings.depthBits))
|
||||
(m_settings.depthBits < requestedSettings.depthBits) ||
|
||||
(!m_settings.sRgbCapable && requestedSettings.sRgbCapable))
|
||||
{
|
||||
err() << "Warning: The created OpenGL context does not fully meet the settings that were requested" << std::endl;
|
||||
err() << "Requested: version = " << requestedSettings.majorVersion << "." << requestedSettings.minorVersion
|
||||
@ -509,6 +541,7 @@ void GlContext::checkSettings(const ContextSettings& requestedSettings)
|
||||
<< std::boolalpha
|
||||
<< " ; core = " << ((requestedSettings.attributeFlags & ContextSettings::Core) != 0)
|
||||
<< " ; debug = " << ((requestedSettings.attributeFlags & ContextSettings::Debug) != 0)
|
||||
<< " ; sRGB = " << requestedSettings.sRgbCapable
|
||||
<< std::noboolalpha << std::endl;
|
||||
err() << "Created: version = " << m_settings.majorVersion << "." << m_settings.minorVersion
|
||||
<< " ; depth bits = " << m_settings.depthBits
|
||||
@ -517,6 +550,7 @@ void GlContext::checkSettings(const ContextSettings& requestedSettings)
|
||||
<< std::boolalpha
|
||||
<< " ; core = " << ((m_settings.attributeFlags & ContextSettings::Core) != 0)
|
||||
<< " ; debug = " << ((m_settings.attributeFlags & ContextSettings::Debug) != 0)
|
||||
<< " ; sRGB = " << m_settings.sRgbCapable
|
||||
<< std::noboolalpha << std::endl;
|
||||
}
|
||||
}
|
||||
|
@ -217,11 +217,12 @@ protected:
|
||||
/// \param stencilBits Stencil bits of the configuration to evaluate
|
||||
/// \param antialiasing Antialiasing level of the configuration to evaluate
|
||||
/// \param accelerated Whether the pixel format is hardware accelerated
|
||||
/// \param sRgb Whether the pixel format is sRGB capable
|
||||
///
|
||||
/// \return Score of the configuration
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static int evaluateFormat(unsigned int bitsPerPixel, const ContextSettings& settings, int colorBits, int depthBits, int stencilBits, int antialiasing, bool accelerated);
|
||||
static int evaluateFormat(unsigned int bitsPerPixel, const ContextSettings& settings, int colorBits, int depthBits, int stencilBits, int antialiasing, bool accelerated, bool sRgb);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
@ -232,9 +233,10 @@ private:
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Perform various initializations after the context construction
|
||||
/// \param requestedSettings Requested settings during context creation
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void initialize();
|
||||
void initialize(const ContextSettings& requestedSettings);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Check whether the context is compatible with the requested settings
|
||||
|
@ -242,6 +242,9 @@ void SFContext::createContext(SFContext* shared,
|
||||
|
||||
attrs.push_back((NSOpenGLPixelFormatAttribute)0); // end of array
|
||||
|
||||
// All OS X pixel formats are sRGB capable
|
||||
m_settings.sRgbCapable = true;
|
||||
|
||||
// Create the pixel format.
|
||||
NSOpenGLPixelFormat* pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attrs[0]];
|
||||
|
||||
|
@ -320,7 +320,7 @@ XVisualInfo GlxContext::selectBestVisual(::Display* display, unsigned int bitsPe
|
||||
continue;
|
||||
|
||||
// Extract the components of the current visual
|
||||
int red, green, blue, alpha, depth, stencil, multiSampling, samples;
|
||||
int red, green, blue, alpha, depth, stencil, multiSampling, samples, sRgb;
|
||||
glXGetConfig(display, &visuals[i], GLX_RED_SIZE, &red);
|
||||
glXGetConfig(display, &visuals[i], GLX_GREEN_SIZE, &green);
|
||||
glXGetConfig(display, &visuals[i], GLX_BLUE_SIZE, &blue);
|
||||
@ -339,12 +339,21 @@ XVisualInfo GlxContext::selectBestVisual(::Display* display, unsigned int bitsPe
|
||||
samples = 0;
|
||||
}
|
||||
|
||||
if ((sfglx_ext_EXT_framebuffer_sRGB == sfglx_LOAD_SUCCEEDED) || (sfglx_ext_ARB_framebuffer_sRGB == sfglx_LOAD_SUCCEEDED))
|
||||
{
|
||||
glXGetConfig(display, &visuals[i], GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, &sRgb);
|
||||
}
|
||||
else
|
||||
{
|
||||
sRgb = 0;
|
||||
}
|
||||
|
||||
// TODO: Replace this with proper acceleration detection
|
||||
bool accelerated = true;
|
||||
|
||||
// Evaluate the visual
|
||||
int color = red + green + blue + alpha;
|
||||
int score = evaluateFormat(bitsPerPixel, settings, color, depth, stencil, multiSampling ? samples : 0, accelerated);
|
||||
int score = evaluateFormat(bitsPerPixel, settings, color, depth, stencil, multiSampling ? samples : 0, accelerated, sRgb == True);
|
||||
|
||||
// If it's better than the current best, make it the new best
|
||||
if (score < bestScore)
|
||||
@ -373,7 +382,7 @@ XVisualInfo GlxContext::selectBestVisual(::Display* display, unsigned int bitsPe
|
||||
void GlxContext::updateSettingsFromVisualInfo(XVisualInfo* visualInfo)
|
||||
{
|
||||
// Update the creation settings from the chosen format
|
||||
int depth, stencil, multiSampling, samples;
|
||||
int depth, stencil, multiSampling, samples, sRgb;
|
||||
glXGetConfig(m_display, visualInfo, GLX_DEPTH_SIZE, &depth);
|
||||
glXGetConfig(m_display, visualInfo, GLX_STENCIL_SIZE, &stencil);
|
||||
|
||||
@ -388,9 +397,19 @@ void GlxContext::updateSettingsFromVisualInfo(XVisualInfo* visualInfo)
|
||||
samples = 0;
|
||||
}
|
||||
|
||||
if ((sfglx_ext_EXT_framebuffer_sRGB == sfglx_LOAD_SUCCEEDED) || (sfglx_ext_ARB_framebuffer_sRGB == sfglx_LOAD_SUCCEEDED))
|
||||
{
|
||||
glXGetConfig(m_display, visualInfo, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, &sRgb);
|
||||
}
|
||||
else
|
||||
{
|
||||
sRgb = 0;
|
||||
}
|
||||
|
||||
m_settings.depthBits = static_cast<unsigned int>(depth);
|
||||
m_settings.stencilBits = static_cast<unsigned int>(stencil);
|
||||
m_settings.antialiasingLevel = multiSampling ? samples : 0;
|
||||
m_settings.sRgbCapable = (sRgb == True);
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,6 +40,8 @@ static sf::GlFunctionPointer IntGetProcAddress(const char* name)
|
||||
int sfglx_ext_EXT_swap_control = sfglx_LOAD_FAILED;
|
||||
int sfglx_ext_MESA_swap_control = sfglx_LOAD_FAILED;
|
||||
int sfglx_ext_SGI_swap_control = sfglx_LOAD_FAILED;
|
||||
int sfglx_ext_EXT_framebuffer_sRGB = sfglx_LOAD_FAILED;
|
||||
int sfglx_ext_ARB_framebuffer_sRGB = sfglx_LOAD_FAILED;
|
||||
int sfglx_ext_ARB_multisample = sfglx_LOAD_FAILED;
|
||||
int sfglx_ext_SGIX_pbuffer = sfglx_LOAD_FAILED;
|
||||
int sfglx_ext_ARB_create_context = sfglx_LOAD_FAILED;
|
||||
@ -124,17 +126,19 @@ typedef struct sfglx_StrToExtMap_s
|
||||
PFN_LOADFUNCPOINTERS LoadExtension;
|
||||
} sfglx_StrToExtMap;
|
||||
|
||||
static sfglx_StrToExtMap ExtensionMap[7] = {
|
||||
static sfglx_StrToExtMap ExtensionMap[9] = {
|
||||
{"GLX_EXT_swap_control", &sfglx_ext_EXT_swap_control, Load_EXT_swap_control},
|
||||
{"GLX_MESA_swap_control", &sfglx_ext_MESA_swap_control, Load_MESA_swap_control},
|
||||
{"GLX_SGI_swap_control", &sfglx_ext_SGI_swap_control, Load_SGI_swap_control},
|
||||
{"GLX_EXT_framebuffer_sRGB", &sfglx_ext_EXT_framebuffer_sRGB, NULL},
|
||||
{"GLX_ARB_framebuffer_sRGB", &sfglx_ext_ARB_framebuffer_sRGB, NULL},
|
||||
{"GLX_ARB_multisample", &sfglx_ext_ARB_multisample, NULL},
|
||||
{"GLX_SGIX_pbuffer", &sfglx_ext_SGIX_pbuffer, Load_SGIX_pbuffer},
|
||||
{"GLX_ARB_create_context", &sfglx_ext_ARB_create_context, Load_ARB_create_context},
|
||||
{"GLX_ARB_create_context_profile", &sfglx_ext_ARB_create_context_profile, NULL},
|
||||
{"GLX_ARB_create_context_profile", &sfglx_ext_ARB_create_context_profile, NULL}
|
||||
};
|
||||
|
||||
static int g_extensionMapSize = 7;
|
||||
static int g_extensionMapSize = 9;
|
||||
|
||||
|
||||
static sfglx_StrToExtMap* FindExtEntry(const char* extensionName)
|
||||
@ -155,6 +159,8 @@ static void ClearExtensionVars(void)
|
||||
sfglx_ext_EXT_swap_control = sfglx_LOAD_FAILED;
|
||||
sfglx_ext_MESA_swap_control = sfglx_LOAD_FAILED;
|
||||
sfglx_ext_SGI_swap_control = sfglx_LOAD_FAILED;
|
||||
sfglx_ext_EXT_framebuffer_sRGB = sfglx_LOAD_FAILED;
|
||||
sfglx_ext_ARB_framebuffer_sRGB = sfglx_LOAD_FAILED;
|
||||
sfglx_ext_ARB_multisample = sfglx_LOAD_FAILED;
|
||||
sfglx_ext_SGIX_pbuffer = sfglx_LOAD_FAILED;
|
||||
sfglx_ext_ARB_create_context = sfglx_LOAD_FAILED;
|
||||
|
@ -144,6 +144,8 @@ extern "C" {
|
||||
extern int sfglx_ext_EXT_swap_control;
|
||||
extern int sfglx_ext_MESA_swap_control;
|
||||
extern int sfglx_ext_SGI_swap_control;
|
||||
extern int sfglx_ext_EXT_framebuffer_sRGB;
|
||||
extern int sfglx_ext_ARB_framebuffer_sRGB;
|
||||
extern int sfglx_ext_ARB_multisample;
|
||||
extern int sfglx_ext_SGIX_pbuffer;
|
||||
extern int sfglx_ext_ARB_create_context;
|
||||
@ -152,6 +154,10 @@ extern int sfglx_ext_ARB_create_context_profile;
|
||||
#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
|
||||
#define GLX_SWAP_INTERVAL_EXT 0x20F1
|
||||
|
||||
#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2
|
||||
|
||||
#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2
|
||||
|
||||
#define GLX_SAMPLES_ARB 100001
|
||||
#define GLX_SAMPLE_BUFFERS_ARB 100000
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
EXT_swap_control
|
||||
// MESA_swap_control
|
||||
SGI_swap_control
|
||||
EXT_framebuffer_sRGB
|
||||
ARB_framebuffer_sRGB
|
||||
GLX_ARB_multisample
|
||||
GLX_SGIX_pbuffer
|
||||
GLX_ARB_create_context
|
||||
|
@ -303,6 +303,18 @@ int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPix
|
||||
}
|
||||
}
|
||||
|
||||
int sRgbCapableValue = 0;
|
||||
if ((sfwgl_ext_ARB_framebuffer_sRGB == sfwgl_LOAD_SUCCEEDED) || (sfwgl_ext_EXT_framebuffer_sRGB == sfwgl_LOAD_SUCCEEDED))
|
||||
{
|
||||
const int sRgbCapableAttribute = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB;
|
||||
|
||||
if (!wglGetPixelFormatAttribivARB(deviceContext, formats[i], PFD_MAIN_PLANE, 1, &sRgbCapableAttribute, &sRgbCapableValue))
|
||||
{
|
||||
err() << "Failed to retrieve pixel format sRGB capability information: " << getErrorString(GetLastError()).toAnsiString() << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pbuffer)
|
||||
{
|
||||
const int pbufferAttributes[] =
|
||||
@ -324,7 +336,7 @@ int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPix
|
||||
|
||||
// Evaluate the current configuration
|
||||
int color = values[0] + values[1] + values[2] + values[3];
|
||||
int score = evaluateFormat(bitsPerPixel, settings, color, values[4], values[5], sampleValues[0] ? sampleValues[1] : 0, values[6] == WGL_FULL_ACCELERATION_ARB);
|
||||
int score = evaluateFormat(bitsPerPixel, settings, color, values[4], values[5], sampleValues[0] ? sampleValues[1] : 0, values[6] == WGL_FULL_ACCELERATION_ARB, sRgbCapableValue == TRUE);
|
||||
|
||||
// Keep it if it's better than the current best
|
||||
if (score < bestScore)
|
||||
@ -444,6 +456,26 @@ void WglContext::updateSettingsFromPixelFormat()
|
||||
{
|
||||
m_settings.antialiasingLevel = 0;
|
||||
}
|
||||
|
||||
if ((sfwgl_ext_ARB_framebuffer_sRGB == sfwgl_LOAD_SUCCEEDED) || (sfwgl_ext_EXT_framebuffer_sRGB == sfwgl_LOAD_SUCCEEDED))
|
||||
{
|
||||
const int sRgbCapableAttribute = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB;
|
||||
int sRgbCapableValue = 0;
|
||||
|
||||
if (wglGetPixelFormatAttribivARB(m_deviceContext, format, PFD_MAIN_PLANE, 1, &sRgbCapableAttribute, &sRgbCapableValue))
|
||||
{
|
||||
m_settings.sRgbCapable = (sRgbCapableValue == TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
err() << "Failed to retrieve pixel format sRGB capability information: " << getErrorString(GetLastError()).toAnsiString() << std::endl;
|
||||
m_settings.sRgbCapable = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings.sRgbCapable = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -38,6 +38,8 @@ static sf::GlFunctionPointer IntGetProcAddress(const char* name)
|
||||
}
|
||||
|
||||
int sfwgl_ext_EXT_swap_control = sfwgl_LOAD_FAILED;
|
||||
int sfwgl_ext_EXT_framebuffer_sRGB = sfwgl_LOAD_FAILED;
|
||||
int sfwgl_ext_ARB_framebuffer_sRGB = sfwgl_LOAD_FAILED;
|
||||
int sfwgl_ext_ARB_multisample = sfwgl_LOAD_FAILED;
|
||||
int sfwgl_ext_ARB_pixel_format = sfwgl_LOAD_FAILED;
|
||||
int sfwgl_ext_ARB_pbuffer = sfwgl_LOAD_FAILED;
|
||||
@ -127,16 +129,18 @@ typedef struct sfwgl_StrToExtMap_s
|
||||
PFN_LOADFUNCPOINTERS LoadExtension;
|
||||
} sfwgl_StrToExtMap;
|
||||
|
||||
static sfwgl_StrToExtMap ExtensionMap[6] = {
|
||||
static sfwgl_StrToExtMap ExtensionMap[8] = {
|
||||
{"WGL_EXT_swap_control", &sfwgl_ext_EXT_swap_control, Load_EXT_swap_control},
|
||||
{"WGL_EXT_framebuffer_sRGB", &sfwgl_ext_EXT_framebuffer_sRGB, NULL},
|
||||
{"WGL_ARB_framebuffer_sRGB", &sfwgl_ext_ARB_framebuffer_sRGB, NULL},
|
||||
{"WGL_ARB_multisample", &sfwgl_ext_ARB_multisample, NULL},
|
||||
{"WGL_ARB_pixel_format", &sfwgl_ext_ARB_pixel_format, Load_ARB_pixel_format},
|
||||
{"WGL_ARB_pbuffer", &sfwgl_ext_ARB_pbuffer, Load_ARB_pbuffer},
|
||||
{"WGL_ARB_create_context", &sfwgl_ext_ARB_create_context, Load_ARB_create_context},
|
||||
{"WGL_ARB_create_context_profile", &sfwgl_ext_ARB_create_context_profile, NULL},
|
||||
{"WGL_ARB_create_context_profile", &sfwgl_ext_ARB_create_context_profile, NULL}
|
||||
};
|
||||
|
||||
static int g_extensionMapSize = 6;
|
||||
static int g_extensionMapSize = 8;
|
||||
|
||||
|
||||
static sfwgl_StrToExtMap* FindExtEntry(const char* extensionName)
|
||||
@ -155,6 +159,8 @@ static sfwgl_StrToExtMap* FindExtEntry(const char* extensionName)
|
||||
static void ClearExtensionVars(void)
|
||||
{
|
||||
sfwgl_ext_EXT_swap_control = sfwgl_LOAD_FAILED;
|
||||
sfwgl_ext_EXT_framebuffer_sRGB = sfwgl_LOAD_FAILED;
|
||||
sfwgl_ext_ARB_framebuffer_sRGB = sfwgl_LOAD_FAILED;
|
||||
sfwgl_ext_ARB_multisample = sfwgl_LOAD_FAILED;
|
||||
sfwgl_ext_ARB_pixel_format = sfwgl_LOAD_FAILED;
|
||||
sfwgl_ext_ARB_pbuffer = sfwgl_LOAD_FAILED;
|
||||
|
@ -93,12 +93,18 @@ extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
extern int sfwgl_ext_EXT_swap_control;
|
||||
extern int sfwgl_ext_EXT_framebuffer_sRGB;
|
||||
extern int sfwgl_ext_ARB_framebuffer_sRGB;
|
||||
extern int sfwgl_ext_ARB_multisample;
|
||||
extern int sfwgl_ext_ARB_pixel_format;
|
||||
extern int sfwgl_ext_ARB_pbuffer;
|
||||
extern int sfwgl_ext_ARB_create_context;
|
||||
extern int sfwgl_ext_ARB_create_context_profile;
|
||||
|
||||
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
|
||||
|
||||
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
|
||||
|
||||
#define WGL_SAMPLES_ARB 0x2042
|
||||
#define WGL_SAMPLE_BUFFERS_ARB 0x2041
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
// lua LoadGen.lua -style=pointer_c -spec=wgl -indent=space -prefix=sf -extfile=WglExtensions.txt WglExtensions
|
||||
|
||||
EXT_swap_control
|
||||
EXT_framebuffer_sRGB
|
||||
ARB_framebuffer_sRGB
|
||||
WGL_ARB_multisample
|
||||
WGL_ARB_pixel_format
|
||||
WGL_ARB_pbuffer
|
||||
|
Loading…
Reference in New Issue
Block a user