diff --git a/examples/opengl/OpenGL.cpp b/examples/opengl/OpenGL.cpp index 26d611d52..6f927d80a 100644 --- a/examples/opengl/OpenGL.cpp +++ b/examples/opengl/OpenGL.cpp @@ -5,6 +5,10 @@ #include #include +#ifndef GL_SRGB8_ALPHA8 +#define GL_SRGB8_ALPHA8 0x8C43 +#endif + //////////////////////////////////////////////////////////// /// Entry point of application @@ -14,178 +18,203 @@ //////////////////////////////////////////////////////////// int main() { - // Request a 24-bits depth buffer when creating the window - sf::ContextSettings contextSettings; - contextSettings.depthBits = 24; + bool exit = false; + bool sRgb = false; - // Create the main window - sf::RenderWindow window(sf::VideoMode(800, 600), "SFML graphics with OpenGL", sf::Style::Default, contextSettings); - window.setVerticalSyncEnabled(true); - - // Create a sprite for the background - sf::Texture backgroundTexture; - if (!backgroundTexture.loadFromFile("resources/background.jpg")) - return EXIT_FAILURE; - sf::Sprite background(backgroundTexture); - - // Create some text to draw on top of our OpenGL object - sf::Font font; - if (!font.loadFromFile("resources/sansation.ttf")) - return EXIT_FAILURE; - sf::Text text("SFML / OpenGL demo", font); - text.setColor(sf::Color(255, 255, 255, 170)); - text.setPosition(250.f, 450.f); - - // Load an OpenGL texture. - // We could directly use a sf::Texture as an OpenGL texture (with its Bind() member function), - // but here we want more control on it (generate mipmaps, ...) so we create a new one from an image - GLuint texture = 0; + while(!exit) { - sf::Image image; - if (!image.loadFromFile("resources/texture.jpg")) + // 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); + window.setVerticalSyncEnabled(true); + + // Create a sprite for the background + sf::Texture backgroundTexture; + backgroundTexture.setSrgb(sRgb); + if (!backgroundTexture.loadFromFile("resources/background.jpg")) 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()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } + sf::Sprite background(backgroundTexture); - // Enable Z-buffer read and write - glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); - glClearDepth(1.f); + // Create some text to draw on top of our OpenGL object + sf::Font font; + 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); - // Disable lighting - glDisable(GL_LIGHTING); - - // Configure the viewport (the same size as the window) - glViewport(0, 0, window.getSize().x, window.getSize().y); - - // Setup a perspective projection - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - GLfloat ratio = static_cast(window.getSize().x) / window.getSize().y; - glFrustum(-ratio, ratio, -1.f, 1.f, 1.f, 500.f); - - // Bind the texture - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, texture); - - // Define a 3D cube (6 faces made of 2 triangles composed by 3 vertices) - static const GLfloat cube[] = - { - // positions // texture coordinates - -20, -20, -20, 0, 0, - -20, 20, -20, 1, 0, - -20, -20, 20, 0, 1, - -20, -20, 20, 0, 1, - -20, 20, -20, 1, 0, - -20, 20, 20, 1, 1, - - 20, -20, -20, 0, 0, - 20, 20, -20, 1, 0, - 20, -20, 20, 0, 1, - 20, -20, 20, 0, 1, - 20, 20, -20, 1, 0, - 20, 20, 20, 1, 1, - - -20, -20, -20, 0, 0, - 20, -20, -20, 1, 0, - -20, -20, 20, 0, 1, - -20, -20, 20, 0, 1, - 20, -20, -20, 1, 0, - 20, -20, 20, 1, 1, - - -20, 20, -20, 0, 0, - 20, 20, -20, 1, 0, - -20, 20, 20, 0, 1, - -20, 20, 20, 0, 1, - 20, 20, -20, 1, 0, - 20, 20, 20, 1, 1, - - -20, -20, -20, 0, 0, - 20, -20, -20, 1, 0, - -20, 20, -20, 0, 1, - -20, 20, -20, 0, 1, - 20, -20, -20, 1, 0, - 20, 20, -20, 1, 1, - - -20, -20, 20, 0, 0, - 20, -20, 20, 1, 0, - -20, 20, 20, 0, 1, - -20, 20, 20, 0, 1, - 20, -20, 20, 1, 0, - 20, 20, 20, 1, 1 - }; - - // Enable position and texture coordinates vertex components - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), cube); - glTexCoordPointer(2, GL_FLOAT, 5 * sizeof(GLfloat), cube + 3); - - // Disable normal and color vertex components - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - // Create a clock for measuring the time elapsed - sf::Clock clock; - - // Start game loop - while (window.isOpen()) - { - // Process events - sf::Event event; - while (window.pollEvent(event)) + // Load an OpenGL texture. + // We could directly use a sf::Texture as an OpenGL texture (with its Bind() member function), + // but here we want more control on it (generate mipmaps, ...) so we create a new one from an image + GLuint texture = 0; { - // Close window: exit - if (event.type == sf::Event::Closed) - window.close(); - - // Escape key: exit - if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape)) - window.close(); - - // Adjust the viewport when the window is resized - if (event.type == sf::Event::Resized) - glViewport(0, 0, event.size.width, event.size.height); + sf::Image image; + if (!image.loadFromFile("resources/texture.jpg")) + return EXIT_FAILURE; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + 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); } - // Draw the background - window.pushGLStates(); - window.draw(background); - window.popGLStates(); + // Enable Z-buffer read and write + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + glClearDepth(1.f); - // Clear the depth buffer - glClear(GL_DEPTH_BUFFER_BIT); + // Disable lighting + glDisable(GL_LIGHTING); - // We get the position of the mouse cursor, so that we can move the box accordingly - float x = sf::Mouse::getPosition(window).x * 200.f / window.getSize().x - 100.f; - float y = -sf::Mouse::getPosition(window).y * 200.f / window.getSize().y + 100.f; + // Configure the viewport (the same size as the window) + glViewport(0, 0, window.getSize().x, window.getSize().y); - // Apply some transformations - glMatrixMode(GL_MODELVIEW); + // Setup a perspective projection + glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glTranslatef(x, y, -100.f); - glRotatef(clock.getElapsedTime().asSeconds() * 50.f, 1.f, 0.f, 0.f); - glRotatef(clock.getElapsedTime().asSeconds() * 30.f, 0.f, 1.f, 0.f); - glRotatef(clock.getElapsedTime().asSeconds() * 90.f, 0.f, 0.f, 1.f); + GLfloat ratio = static_cast(window.getSize().x) / window.getSize().y; + glFrustum(-ratio, ratio, -1.f, 1.f, 1.f, 500.f); - // Draw the cube - glDrawArrays(GL_TRIANGLES, 0, 36); + // Bind the texture + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, texture); - // Draw some text on top of our OpenGL object - window.pushGLStates(); - window.draw(text); - window.popGLStates(); + // Define a 3D cube (6 faces made of 2 triangles composed by 3 vertices) + static const GLfloat cube[] = + { + // positions // texture coordinates + -20, -20, -20, 0, 0, + -20, 20, -20, 1, 0, + -20, -20, 20, 0, 1, + -20, -20, 20, 0, 1, + -20, 20, -20, 1, 0, + -20, 20, 20, 1, 1, - // Finally, display the rendered frame on screen - window.display(); + 20, -20, -20, 0, 0, + 20, 20, -20, 1, 0, + 20, -20, 20, 0, 1, + 20, -20, 20, 0, 1, + 20, 20, -20, 1, 0, + 20, 20, 20, 1, 1, + + -20, -20, -20, 0, 0, + 20, -20, -20, 1, 0, + -20, -20, 20, 0, 1, + -20, -20, 20, 0, 1, + 20, -20, -20, 1, 0, + 20, -20, 20, 1, 1, + + -20, 20, -20, 0, 0, + 20, 20, -20, 1, 0, + -20, 20, 20, 0, 1, + -20, 20, 20, 0, 1, + 20, 20, -20, 1, 0, + 20, 20, 20, 1, 1, + + -20, -20, -20, 0, 0, + 20, -20, -20, 1, 0, + -20, 20, -20, 0, 1, + -20, 20, -20, 0, 1, + 20, -20, -20, 1, 0, + 20, 20, -20, 1, 1, + + -20, -20, 20, 0, 0, + 20, -20, 20, 1, 0, + -20, 20, 20, 0, 1, + -20, 20, 20, 0, 1, + 20, -20, 20, 1, 0, + 20, 20, 20, 1, 1 + }; + + // Enable position and texture coordinates vertex components + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), cube); + glTexCoordPointer(2, GL_FLOAT, 5 * sizeof(GLfloat), cube + 3); + + // Disable normal and color vertex components + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + // Create a clock for measuring the time elapsed + sf::Clock clock; + + // Start game loop + while (window.isOpen()) + { + // Process events + sf::Event event; + while (window.pollEvent(event)) + { + // 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) + glViewport(0, 0, event.size.width, event.size.height); + } + + // Draw the background + window.pushGLStates(); + window.draw(background); + window.popGLStates(); + + // Clear the depth buffer + glClear(GL_DEPTH_BUFFER_BIT); + + // We get the position of the mouse cursor, so that we can move the box accordingly + float x = sf::Mouse::getPosition(window).x * 200.f / window.getSize().x - 100.f; + float y = -sf::Mouse::getPosition(window).y * 200.f / window.getSize().y + 100.f; + + // Apply some transformations + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(x, y, -100.f); + glRotatef(clock.getElapsedTime().asSeconds() * 50.f, 1.f, 0.f, 0.f); + glRotatef(clock.getElapsedTime().asSeconds() * 30.f, 0.f, 1.f, 0.f); + glRotatef(clock.getElapsedTime().asSeconds() * 90.f, 0.f, 0.f, 1.f); + + // Draw the cube + glDrawArrays(GL_TRIANGLES, 0, 36); + + // 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 + window.display(); + } + + // Don't forget to destroy our texture + glDeleteTextures(1, &texture); } - // Don't forget to destroy our texture - glDeleteTextures(1, &texture); - return EXIT_SUCCESS; } diff --git a/include/SFML/Graphics/Texture.hpp b/include/SFML/Graphics/Texture.hpp index 39e312ee4..e9e97afe6 100644 --- a/include/SFML/Graphics/Texture.hpp +++ b/include/SFML/Graphics/Texture.hpp @@ -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? diff --git a/include/SFML/Window/ContextSettings.hpp b/include/SFML/Window/ContextSettings.hpp index 26ea91005..66375a4fd 100644 --- a/include/SFML/Window/ContextSettings.hpp +++ b/include/SFML/Window/ContextSettings.hpp @@ -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 diff --git a/src/SFML/Graphics/GLExtensions.hpp b/src/SFML/Graphics/GLExtensions.hpp index 9dfa8d7fd..b63ea9993 100644 --- a/src/SFML/Graphics/GLExtensions.hpp +++ b/src/SFML/Graphics/GLExtensions.hpp @@ -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 @@ -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 diff --git a/src/SFML/Graphics/GLExtensions.txt b/src/SFML/Graphics/GLExtensions.txt index a2447cbea..5b620278f 100644 --- a/src/SFML/Graphics/GLExtensions.txt +++ b/src/SFML/Graphics/GLExtensions.txt @@ -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 diff --git a/src/SFML/Graphics/GLLoader.cpp b/src/SFML/Graphics/GLLoader.cpp index d7635920d..209520dbd 100644 --- a/src/SFML/Graphics/GLLoader.cpp +++ b/src/SFML/Graphics/GLLoader.cpp @@ -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; } diff --git a/src/SFML/Graphics/GLLoader.hpp b/src/SFML/Graphics/GLLoader.hpp index 588ba5a40..ac1bfdfc4 100644 --- a/src/SFML/Graphics/GLLoader.hpp +++ b/src/SFML/Graphics/GLLoader.hpp @@ -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); diff --git a/src/SFML/Graphics/Texture.cpp b/src/SFML/Graphics/Texture.cpp index d939cff94..ac610db1c 100644 --- a/src/SFML/Graphics/Texture.cpp +++ b/src/SFML/Graphics/Texture.cpp @@ -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) { diff --git a/src/SFML/Window/GlContext.cpp b/src/SFML/Window/GlContext.cpp index 2bd9bf5f7..525d16a00 100644 --- a/src/SFML/Window/GlContext.cpp +++ b/src/SFML/Window/GlContext.cpp @@ -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(bitsPerPixel) - colorBits; int depthDiff = static_cast(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,9 +476,32 @@ 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; + } } @@ -496,10 +527,11 @@ void GlContext::checkSettings(const ContextSettings& requestedSettings) int requestedVersion = requestedSettings.majorVersion * 10 + requestedSettings.minorVersion; if ((m_settings.attributeFlags != requestedSettings.attributeFlags) || - (version < requestedVersion) || + (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; } } diff --git a/src/SFML/Window/GlContext.hpp b/src/SFML/Window/GlContext.hpp index f9225cd8d..b5a8b9689 100644 --- a/src/SFML/Window/GlContext.hpp +++ b/src/SFML/Window/GlContext.hpp @@ -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 diff --git a/src/SFML/Window/OSX/SFContext.mm b/src/SFML/Window/OSX/SFContext.mm index 4c24d0307..09c577212 100644 --- a/src/SFML/Window/OSX/SFContext.mm +++ b/src/SFML/Window/OSX/SFContext.mm @@ -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]]; diff --git a/src/SFML/Window/Unix/GlxContext.cpp b/src/SFML/Window/Unix/GlxContext.cpp index e988476dd..4dc207f2d 100644 --- a/src/SFML/Window/Unix/GlxContext.cpp +++ b/src/SFML/Window/Unix/GlxContext.cpp @@ -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(depth); m_settings.stencilBits = static_cast(stencil); m_settings.antialiasingLevel = multiSampling ? samples : 0; + m_settings.sRgbCapable = (sRgb == True); } diff --git a/src/SFML/Window/Unix/GlxExtensions.cpp b/src/SFML/Window/Unix/GlxExtensions.cpp index 96ddbaf28..e20e4bf0f 100644 --- a/src/SFML/Window/Unix/GlxExtensions.cpp +++ b/src/SFML/Window/Unix/GlxExtensions.cpp @@ -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; diff --git a/src/SFML/Window/Unix/GlxExtensions.hpp b/src/SFML/Window/Unix/GlxExtensions.hpp index cc68bb547..28e159e78 100644 --- a/src/SFML/Window/Unix/GlxExtensions.hpp +++ b/src/SFML/Window/Unix/GlxExtensions.hpp @@ -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 diff --git a/src/SFML/Window/Unix/GlxExtensions.txt b/src/SFML/Window/Unix/GlxExtensions.txt index 4c54582d6..9c8a64197 100644 --- a/src/SFML/Window/Unix/GlxExtensions.txt +++ b/src/SFML/Window/Unix/GlxExtensions.txt @@ -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 diff --git a/src/SFML/Window/Win32/WglContext.cpp b/src/SFML/Window/Win32/WglContext.cpp index 04182f0ca..a1ddad2e8 100644 --- a/src/SFML/Window/Win32/WglContext.cpp +++ b/src/SFML/Window/Win32/WglContext.cpp @@ -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 { diff --git a/src/SFML/Window/Win32/WglExtensions.cpp b/src/SFML/Window/Win32/WglExtensions.cpp index 832cf357e..9ba446d95 100644 --- a/src/SFML/Window/Win32/WglExtensions.cpp +++ b/src/SFML/Window/Win32/WglExtensions.cpp @@ -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; diff --git a/src/SFML/Window/Win32/WglExtensions.hpp b/src/SFML/Window/Win32/WglExtensions.hpp index 4c08d8ca9..f3ebfe552 100644 --- a/src/SFML/Window/Win32/WglExtensions.hpp +++ b/src/SFML/Window/Win32/WglExtensions.hpp @@ -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 diff --git a/src/SFML/Window/Win32/WglExtensions.txt b/src/SFML/Window/Win32/WglExtensions.txt index 0ac0ad03a..667c85361 100644 --- a/src/SFML/Window/Win32/WglExtensions.txt +++ b/src/SFML/Window/Win32/WglExtensions.txt @@ -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