Added the concept of colorspace to the SDL renderer
This allows color operations to happen in linear space between sRGB input and sRGB output. This is currently supported on the direct3d11, direct3d12 and opengl renderers. This is a good resource on blending in linear space vs sRGB space: https://blog.johnnovak.net/2016/09/21/what-every-coder-should-know-about-gamma/ Also added testcolorspace to verify colorspace changes
This commit is contained in:
parent
554f0625d3
commit
f257eb4481
9 changed files with 648 additions and 40 deletions
|
@ -49,8 +49,6 @@
|
|||
http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_texturedata/opengl_texturedata.html
|
||||
*/
|
||||
|
||||
static const float inv255f = 1.0f / 255.0f;
|
||||
|
||||
typedef struct GL_FBOList GL_FBOList;
|
||||
|
||||
struct GL_FBOList
|
||||
|
@ -403,19 +401,27 @@ static SDL_bool GL_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode blend
|
|||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static SDL_bool convert_format(GL_RenderData *renderdata, Uint32 pixel_format,
|
||||
static SDL_bool convert_format(Uint32 pixel_format, Uint32 colorspace, SDL_bool colorspace_conversion,
|
||||
GLint *internalFormat, GLenum *format, GLenum *type)
|
||||
{
|
||||
switch (pixel_format) {
|
||||
case SDL_PIXELFORMAT_ARGB8888:
|
||||
case SDL_PIXELFORMAT_XRGB8888:
|
||||
*internalFormat = GL_RGBA8;
|
||||
if (colorspace_conversion && colorspace == SDL_COLORSPACE_SRGB) {
|
||||
*internalFormat = GL_SRGB8_ALPHA8;
|
||||
} else {
|
||||
*internalFormat = GL_RGBA8;
|
||||
}
|
||||
*format = GL_BGRA;
|
||||
*type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_ABGR8888:
|
||||
case SDL_PIXELFORMAT_XBGR8888:
|
||||
*internalFormat = GL_RGBA8;
|
||||
if (colorspace_conversion && colorspace == SDL_COLORSPACE_SRGB) {
|
||||
*internalFormat = GL_SRGB8_ALPHA8;
|
||||
} else {
|
||||
*internalFormat = GL_RGBA8;
|
||||
}
|
||||
*format = GL_RGBA;
|
||||
*type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
break;
|
||||
|
@ -460,8 +466,8 @@ static int GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Pr
|
|||
return SDL_SetError("Render targets not supported by OpenGL");
|
||||
}
|
||||
|
||||
if (!convert_format(renderdata, texture->format, &internalFormat,
|
||||
&format, &type)) {
|
||||
if (!convert_format(texture->format, texture->colorspace, renderer->colorspace_conversion,
|
||||
&internalFormat, &format, &type)) {
|
||||
return SDL_SetError("Texture format %s not supported by OpenGL",
|
||||
SDL_GetPixelFormatName(texture->format));
|
||||
}
|
||||
|
@ -1475,7 +1481,8 @@ static int GL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
|||
|
||||
GL_ActivateRenderer(renderer);
|
||||
|
||||
if (!convert_format(data, temp_format, &internalFormat, &format, &type)) {
|
||||
if (!convert_format(temp_format, renderer->input_colorspace, renderer->colorspace_conversion,
|
||||
&internalFormat, &format, &type)) {
|
||||
return SDL_SetError("Texture format %s not supported by OpenGL",
|
||||
SDL_GetPixelFormatName(temp_format));
|
||||
}
|
||||
|
@ -1709,6 +1716,8 @@ static SDL_Renderer *GL_CreateRenderer(SDL_Window *window, SDL_PropertiesID crea
|
|||
goto error;
|
||||
}
|
||||
|
||||
SDL_SetupRendererColorspace(renderer, create_props);
|
||||
|
||||
renderer->WindowEvent = GL_WindowEvent;
|
||||
renderer->SupportsBlendMode = GL_SupportsBlendMode;
|
||||
renderer->CreateTexture = GL_CreateTexture;
|
||||
|
@ -1910,6 +1919,9 @@ static SDL_Renderer *GL_CreateRenderer(SDL_Window *window, SDL_PropertiesID crea
|
|||
data->glDisable(data->textype);
|
||||
data->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
if (renderer->colorspace_conversion && renderer->output_colorspace == SDL_COLORSPACE_SRGB) {
|
||||
data->glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
/* This ended up causing video discrepancies between OpenGL and Direct3D */
|
||||
/* data->glEnable(GL_LINE_SMOOTH); */
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue