Reputation: 11496
I am trying to understand how to enable sRGB profile for default frame buffers on Android.Android SDK is not clear about how to do it practically.For example,here a guy states that it is enough to set texture internal format to sRGB. But he is clearly wrong,because I tried that and it changes nothing.
Khronos provides this extension as a part of EGL.I have tried to add these flags to surface configs:
final int EGL_GL_COLORSPACE_KHR = 0x309D;
final int EGL_GL_COLORSPACE_SRGB_KHR = 0x3089;
int attribs[] = {
EGL10.EGL_LEVEL, 0,
EGL10.EGL_RENDERABLE_TYPE,EGLExt.EGL_OPENGL_ES3_BIT_KHR,
EGL10.EGL_COLOR_BUFFER_TYPE, EGL10.EGL_RGB_BUFFER,
EGL10.EGL_RED_SIZE, 8,
EGL10.EGL_GREEN_SIZE, 8,
EGL10.EGL_BLUE_SIZE, 8,
EGL10.EGL_DEPTH_SIZE, maxDepth,
EGL10.EGL_SAMPLE_BUFFERS, 1,
EGL10.EGL_SAMPLES, 4,
EGL_GL_COLORSPACE_KHR ,EGL_GL_COLORSPACE_SRGB_KHR //<--
EGL10.EGL_NONE
};
But in this case the devices I am testing on (Google NEXUS 6) crashes the app. Running OpenGL extension viewer I see the device doesn't support
EGL_KHR_gl_colorspace
extension.
In fact,I found here and on other online demos,that this setup is actually used.Also,iOS allows to configure default FBO to be sRGB with a flag :
kEAGLColorFormatSRGBA8
Is there another way to turn on sRGB on a Android device than that extension?(Of course another alternative is to gamma correct in shader,but that's exactly what I don't wanna do)
Upvotes: 2
Views: 1188
Reputation: 1
https://github.com/facebook/igl/pull/207
We need create a sRGB surface in GLSurfaceView.
The prerequisite is that the device needs to support the EGL_KHR_gl_colorspace extension.
setEGLWindowSurfaceFactory(new SurfaceFactory(getHolder()));
private static class SurfaceFactory implements GLSurfaceView.EGLWindowSurfaceFactory{
private SurfaceHolder surfaceHolder_;
public SurfaceFactory(SurfaceHolder surfaceHolder){
surfaceHolder_ = surfaceHolder;
}
final int EGL_GL_COLORSPACE_KHR = 0x309D;
final int EGL_GL_COLORSPACE_SRGB_KHR = 0x3089;
final int EGL_GL_COLORSPACE_LINEAR_KHR = 0x308A;
final int[] configAttribs = {
EGL_GL_COLORSPACE_KHR ,EGL_GL_COLORSPACE_SRGB_KHR,
EGL10.EGL_NONE
};
@Override
public EGLSurface createWindowSurface(EGL10 egl10, EGLDisplay eglDisplay, EGLConfig eglConfig, Object o) {
return egl10.eglCreateWindowSurface(eglDisplay, eglConfig, surfaceHolder_, configAttribs);
}
@Override
public void destroySurface(EGL10 egl10, EGLDisplay eglDisplay, EGLSurface eglSurface) {
egl10.eglDestroySurface(eglDisplay, eglSurface);
}
}
Upvotes: 0
Reputation: 4325
No, there is unfortunately no other way to create an sRGB default framebuffer.
What you could do is use a workaround: render to a texture with internal format GL_SRGB8_ALPHA8
and treat that as your framebuffer, then at the end draw a full-screen quad to the default framebuffer, using the aforementioned texture and a gamma correction shader. (You will get values in linear RGB when reading from the texture, so you need to compress them back to sRGB when writing out to the default framebuffer; the framebuffer is ostensibly linear, but the values in it will be interpreted as sRGB by the display.)
"The other guy" was entirely correct, but the default framebuffer is not a texture and you can't directly set its internal format.
Upvotes: 1