From: John Tsiombikas Date: Tue, 15 Nov 2016 05:13:25 +0000 (+0200) Subject: do gamma correction on post if we don't have an sRGB framebuffer X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=laserbrain_demo;a=commitdiff_plain;h=3aacec4aee795e703e8eb9d6852ca47a3be065ee do gamma correction on post if we don't have an sRGB framebuffer --- diff --git a/sdr/post_gamma.p.glsl b/sdr/post_gamma.p.glsl new file mode 100644 index 0000000..6b323f8 --- /dev/null +++ b/sdr/post_gamma.p.glsl @@ -0,0 +1,10 @@ +uniform sampler2D tex; + +void main() +{ + const vec3 invgamma3 = vec3(1.0 / 2.2); + vec3 texel = texture2D(tex, gl_TexCoord[0].st).xyz; + + gl_FragColor.rgb = pow(texel, invgamma3); + gl_FragColor.a = 1.0; +} diff --git a/sdr/post_gamma.v.glsl b/sdr/post_gamma.v.glsl new file mode 100644 index 0000000..a8fb0cf --- /dev/null +++ b/sdr/post_gamma.v.glsl @@ -0,0 +1,5 @@ +void main() +{ + gl_Position = gl_Vertex; + gl_TexCoord[0] = gl_MultiTexCoord0; +} diff --git a/src/app.cc b/src/app.cc index d3b5657..096bf4e 100644 --- a/src/app.cc +++ b/src/app.cc @@ -12,6 +12,7 @@ #include "datamap.h" #include "ui.h" #include "opt.h" +#include "post.h" #define NEAR_CLIP 5.0 #define FAR_CLIP 10000.0 @@ -21,6 +22,7 @@ static void draw_scene(); long time_msec; int win_width, win_height; float win_aspect; +bool fb_srgb; bool opt_gear_wireframe; static float cam_dist = 0.0; @@ -41,7 +43,7 @@ static bool keystate[256]; static Mat4 view_matrix, mouse_view_matrix, proj_matrix; static TextureSet texman; static Scene *scn; -static unsigned int sdr; +static unsigned int sdr, sdr_post_gamma; static long prev_msec; @@ -69,7 +71,12 @@ bool app_init(int argc, char **argv) goatvr_recenter(); } + int srgb_capable; + glGetIntegerv(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &srgb_capable); + printf("Framebuffer %s sRGB-capable\n", srgb_capable ? "is" : "is not"); + fb_srgb = srgb_capable != 0; glEnable(GL_FRAMEBUFFER_SRGB); + glEnable(GL_MULTISAMPLE); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); @@ -105,6 +112,10 @@ bool app_init(int argc, char **argv) set_uniform_int(sdr, "texmap", 0); set_uniform_int(sdr, "lightmap", 1); + if(!fb_srgb) { + sdr_post_gamma = create_program_load("sdr/post_gamma.v.glsl", "sdr/post_gamma.p.glsl"); + } + glUseProgram(0); if(opt.vr || opt.fullscreen) { @@ -266,6 +277,10 @@ void app_display() draw_scene(); + if(!fb_srgb && sdr_post_gamma) { + slow_post(sdr_post_gamma); + glUseProgram(0); + } app_swap_buffers(); } assert(glGetError() == GL_NO_ERROR); @@ -344,6 +359,13 @@ void app_keyboard(int key, bool pressed) } break; + case 'p': + if(mod & MOD_CTRL) { + fb_srgb = !fb_srgb; + show_message("gamma correction for non-sRGB framebuffers: %s\n", fb_srgb ? "off" : "on"); + } + break; + case '=': walk_speed *= 1.25; show_message("walk speed: %g", walk_speed); @@ -370,8 +392,9 @@ void app_mouse_button(int bn, bool pressed, int x, int y) static inline void mouse_look(int dx, int dy) { - cam_theta += dx * 0.5; - cam_phi += dy * 0.5; + float scrsz = (float)win_height; + cam_theta += dx * 512.0 / scrsz; + cam_phi += dy * 512.0 / scrsz; if(cam_phi < -90) cam_phi = -90; if(cam_phi > 90) cam_phi = 90; diff --git a/src/app.h b/src/app.h index 02db8db..5e65394 100644 --- a/src/app.h +++ b/src/app.h @@ -5,6 +5,7 @@ extern long time_msec; extern int win_width, win_height; extern float win_aspect; extern bool opt_gear_wireframe; +extern bool fb_srgb; enum { MOD_SHIFT = 1, diff --git a/src/main.cc b/src/main.cc index 01c9d12..fb8a2e2 100644 --- a/src/main.cc +++ b/src/main.cc @@ -41,7 +41,11 @@ int main(int argc, char **argv) SDL_Quit(); return 1; } + fprintf(stderr, "failed to get an sRGB framebuffer.\n"); } + int val; + SDL_GL_GetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, &val); + printf("SDL says we %s an sRGB framebuffer\n", val ? "got" : "didn't get"); if(!(ctx = SDL_GL_CreateContext(win))) { fprintf(stderr, "failed to create OpenGL context\n"); @@ -113,8 +117,11 @@ bool app_is_fullscreen() void app_grab_mouse(bool grab) { - SDL_SetWindowGrab(win, grab ? SDL_TRUE : SDL_FALSE); - SDL_ShowCursor(grab ? 1 : 0); + if(grab) { + SDL_WarpMouseInWindow(win, win_width / 2, win_height / 2); + } + //SDL_SetWindowGrab(win, grab ? SDL_TRUE : SDL_FALSE); + //SDL_ShowCursor(grab ? 1 : 0); SDL_SetRelativeMouseMode(grab ? SDL_TRUE : SDL_FALSE); mouse_grabbed = grab; } @@ -164,7 +171,8 @@ static void process_event(SDL_Event *ev) case SDL_MOUSEMOTION: if(mouse_grabbed) { - app_mouse_delta(ev->motion.xrel, ev->motion.yrel); + // XXX xrel/yrel seems faster by default + app_mouse_delta(ev->motion.xrel * 0.5, ev->motion.yrel * 0.5); } else { app_mouse_motion(ev->motion.x * scale_factor, ev->motion.y * scale_factor); } diff --git a/src/post.cc b/src/post.cc new file mode 100644 index 0000000..b675f5b --- /dev/null +++ b/src/post.cc @@ -0,0 +1,67 @@ +#include "opengl.h" +#include "app.h" + +static void update_fbtex(); + +static unsigned int fb_tex; +static int fb_tex_width, fb_tex_height; + +void slow_post(unsigned int sdr) +{ + update_fbtex(); + + glBindTexture(GL_TEXTURE_2D, fb_tex); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, win_width, win_height); + + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + + glUseProgram(sdr); + + float umax = (float)win_width / (float)fb_tex_width; + float vmax = (float)win_height / (float)fb_tex_height; + + glBegin(GL_QUADS); + glTexCoord2f(0, 0); + glVertex2f(-1, -1); + glTexCoord2f(umax, 0); + glVertex2f(1, -1); + glTexCoord2f(umax, vmax); + glVertex2f(1, 1); + glTexCoord2f(0, vmax); + glVertex2f(-1, 1); + glEnd(); + + glPopAttrib(); +} + +static int next_pow2(int x) +{ + x--; + x = (x >> 1) | x; + x = (x >> 2) | x; + x = (x >> 4) | x; + x = (x >> 8) | x; + x = (x >> 16) | x; + return x + 1; +} + +static void update_fbtex() +{ + if(win_width <= fb_tex_width && win_height <= fb_tex_height) { + return; // nothing to do + } + if(!fb_tex) { + glGenTextures(1, &fb_tex); + glBindTexture(GL_TEXTURE_2D, fb_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } else { + glBindTexture(GL_TEXTURE_2D, fb_tex); + } + + fb_tex_width = next_pow2(win_width); + fb_tex_height = next_pow2(win_height); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fb_tex_width, fb_tex_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); +} diff --git a/src/post.h b/src/post.h new file mode 100644 index 0000000..737cb02 --- /dev/null +++ b/src/post.h @@ -0,0 +1,6 @@ +#ifndef POST_H_ +#define POST_H_ + +void slow_post(unsigned int sdr); + +#endif // POST_H_