improve srgb control

main
Dominik Madarász 2024-03-26 19:13:55 +01:00
parent b27b265a8f
commit 5f31dd100c
18 changed files with 111 additions and 27 deletions

View File

@ -2040,6 +2040,8 @@ enum WINDOW_FLAGS {
void window_loop_exit(); void window_loop_exit();
void window_title(const char *title); void window_title(const char *title);
void window_color(unsigned color); void window_color(unsigned color);
void window_gamma(float gamma);
float window_get_gamma();
vec2 window_canvas(); vec2 window_canvas();
void* window_handle(); void* window_handle();
char* window_stats(); char* window_stats();

View File

@ -2,6 +2,7 @@
int main() { int main() {
window_create(75.0, WINDOW_MSAA8); window_create(75.0, WINDOW_MSAA8);
window_gamma(0); // @fixme: disable gamma correction for now
// style: our aliases // style: our aliases
#define FONT_REGULAR FONT_FACE1 #define FONT_REGULAR FONT_FACE1

View File

@ -37,8 +37,8 @@ int main() {
// load model // load model
model_t m1 = model("suzanne.obj", MODEL_NO_ANIMATIONS); model_t m1 = model("suzanne.obj", MODEL_NO_ANIMATIONS);
model_t m2 = model("suzanne.obj", MODEL_NO_ANIMATIONS|MODEL_MATCAPS); model_t m2 = model("suzanne.obj", MODEL_NO_ANIMATIONS|MODEL_MATCAPS);
// model_t m3 = model("damagedhelmet.gltf", MODEL_NO_ANIMATIONS|MODEL_PBR); model_t m3 = model("damagedhelmet.gltf", MODEL_NO_ANIMATIONS|MODEL_PBR);
model_t m3 = model("Scutum_low.fbx", MODEL_NO_ANIMATIONS|MODEL_PBR); // model_t m3 = model("Scutum_low.fbx", MODEL_NO_ANIMATIONS|MODEL_PBR);
// model_t m4 = model("avp/scene.gltf", MODEL_NO_ANIMATIONS|MODEL_PBR); // model_t m4 = model("avp/scene.gltf", MODEL_NO_ANIMATIONS|MODEL_PBR);
// model_t m3 = model("Cerberus_LP.FBX", MODEL_NO_ANIMATIONS|MODEL_PBR); // model_t m3 = model("Cerberus_LP.FBX", MODEL_NO_ANIMATIONS|MODEL_PBR);

View File

@ -447,8 +447,6 @@ void main() {
vec3 col = u_rimcolor*(pow(smoothstep(1.0-u_rimrange.x,u_rimrange.y,rim), u_rimrange.z)); vec3 col = u_rimcolor*(pow(smoothstep(1.0-u_rimrange.x,u_rimrange.y,rim), u_rimrange.z));
fragcolor += vec4(col, 1.0);} fragcolor += vec4(col, 1.0);}
#endif #endif
fragcolor.rgb = pow( fragcolor.rgb, vec3(1. / 2.2) );
} }
#endif #endif
#ifdef SHADING_PBR #ifdef SHADING_PBR
@ -705,7 +703,6 @@ void main(void)
// gamma correction // gamma correction
color = pow( color, vec3(1. / 2.2) ); color = pow( color, vec3(1. / 2.2) );
#endif #endif
color = pow( color, vec3(1. / 2.2) );
// Technically this alpha may be too transparent, if there is a lot of reflected light we wouldn't // Technically this alpha may be too transparent, if there is a lot of reflected light we wouldn't
// see the background, maybe we can approximate it well enough by adding a fresnel term // see the background, maybe we can approximate it well enough by adding a fresnel term

View File

@ -1,11 +1,8 @@
uniform samplerCube u_cubemap; uniform samplerCube u_cubemap;
in vec3 v_direction; in vec3 v_direction;
out vec4 fragcolor; out vec4 fragcolor;
void main() { void main() {
fragcolor = vec4(texture(u_cubemap, v_direction).rgb, 1.0); fragcolor = vec4(texture(u_cubemap, v_direction).rgb, 1.0);
fragcolor.rgb = pow(fragcolor.rgb, vec3(1.0/2.2));
} }

View File

@ -8,7 +8,7 @@ uniform float uMieScattering;
uniform float uRayleighScaleHeight; uniform float uRayleighScaleHeight;
uniform float uMieScaleHeight; uniform float uMieScaleHeight;
uniform float uMiePreferredDirection; uniform float uMiePreferredDirection;
uniform float gamma; /// set:2.2
in vec3 v_direction; in vec3 v_direction;
out vec4 fragcolor; out vec4 fragcolor;
@ -36,6 +36,7 @@ void main() {
color = 1.0 - exp(-1.0 * color); color = 1.0 - exp(-1.0 * color);
fragcolor = vec4(color, 1); fragcolor = vec4(color, 1);
fragcolor.rgb = pow(fragcolor.rgb, vec3(gamma));
} }

View File

@ -4,6 +4,7 @@ in float color_index;
uniform sampler2D sampler_font; uniform sampler2D sampler_font;
uniform sampler1D sampler_colors; uniform sampler1D sampler_colors;
uniform float num_colors; uniform float num_colors;
uniform float gamma; /// set:2.2
out vec4 outColor; out vec4 outColor;
@ -11,4 +12,5 @@ void main() {
vec4 col = texture(sampler_colors, (color_index+0.5)/num_colors); vec4 col = texture(sampler_colors, (color_index+0.5)/num_colors);
float s = texture(sampler_font, uv).r; float s = texture(sampler_font, uv).r;
outColor = vec4(col.rgb, s*col.a); outColor = vec4(col.rgb, s*col.a);
outColor.rgb = pow(outColor.rgb, vec3(gamma));
} }

View File

@ -18688,6 +18688,8 @@ API void window_loop_exit(); // exit from main loop function (emscripten onl
API void window_title(const char *title); API void window_title(const char *title);
API void window_color(unsigned color); API void window_color(unsigned color);
API void window_gamma(float gamma); // 2.2 - standard, 0.0 - disables postfx pass
API float window_get_gamma();
API vec2 window_canvas(); API vec2 window_canvas();
API void* window_handle(); API void* window_handle();
API char* window_stats(); API char* window_stats();
@ -363502,6 +363504,7 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact
glUniform1f(glGetUniformLocation(f->program, "scale_factor"), factor); glUniform1f(glGetUniformLocation(f->program, "scale_factor"), factor);
glUniform2fv(glGetUniformLocation(f->program, "string_offset"), 1, &offset.x); glUniform2fv(glGetUniformLocation(f->program, "string_offset"), 1, &offset.x);
glUniform1f(glGetUniformLocation(f->program, "offset_firstline"), f->ascent*f->factor); glUniform1f(glGetUniformLocation(f->program, "offset_firstline"), f->ascent*f->factor);
glUniform1f(glGetUniformLocation(f->program, "gamma"), (window_get_gamma() + !window_get_gamma()));
GLint dims[4] = {0}; GLint dims[4] = {0};
glGetIntegerv(GL_VIEWPORT, dims); glGetIntegerv(GL_VIEWPORT, dims);
@ -364091,8 +364094,8 @@ API void gui_drawrect( texture_t spritesheet, vec2 tex_start, vec2 tex_end, int
#define v42v2(rect) vec2(rect.x,rect.y), vec2(rect.z,rect.w) #define v42v2(rect) vec2(rect.x,rect.y), vec2(rect.z,rect.w)
void gui_drawrect( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, vec2 start, vec2 end ) { void gui_drawrect( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, vec2 start, vec2 end ) {
float gamma = 1;
static int program = -1, vbo = -1, vao = -1, u_inv_gamma = -1, u_tint = -1, u_has_tex = -1, u_window_width = -1, u_window_height = -1; static int program = -1, vbo = -1, vao = -1, u_inv_gamma = -1, u_tint = -1, u_has_tex = -1, u_window_width = -1, u_window_height = -1;
float gamma = window_get_gamma();
vec2 dpi = ifdef(osx, window_dpi(), vec2(1,1)); vec2 dpi = ifdef(osx, window_dpi(), vec2(1,1));
if( program < 0 ) { if( program < 0 ) {
const char* vs = vfs_read("shaders/rect_2d.vs"); const char* vs = vfs_read("shaders/rect_2d.vs");
@ -364119,7 +364122,7 @@ void gui_drawrect( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, ve
GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D; GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
glUseProgram( program ); glUseProgram( program );
glUniform1f( u_inv_gamma, 1.0f / (gamma + !gamma) ); glUniform1f( u_inv_gamma, (gamma + !gamma) );
glBindVertexArray( vao ); glBindVertexArray( vao );
@ -371664,7 +371667,7 @@ skybox_t skybox(const char *asset, int flags) {
if( asset ) { if( asset ) {
int is_panorama = vfs_size( asset ); int is_panorama = vfs_size( asset );
if( is_panorama ) { // is file if( is_panorama ) { // is file
// stbi_hdr_to_ldr_gamma(1.2f); stbi_hdr_to_ldr_gamma(1.2f);
image_t panorama = image( asset, IMAGE_RGBA ); image_t panorama = image( asset, IMAGE_RGBA );
sky.cubemap = cubemap( panorama, 0 ); // RGBA required sky.cubemap = cubemap( panorama, 0 ); // RGBA required
image_destroy(&panorama); image_destroy(&panorama);
@ -372393,12 +372396,12 @@ bool postfx_begin(postfx *fx, int width, int height) {
fbo_destroy(fx->fb[1]); fbo_destroy(fx->fb[1]);
// create texture, set texture parameters and content // create texture, set texture parameters and content
fx->diffuse[0] = texture_create(width, height, 4, NULL, TEXTURE_RGBA); fx->diffuse[0] = texture_create(width, height, 4, NULL, TEXTURE_RGBA|TEXTURE_FLOAT);
fx->depth[0] = texture_create(width, height, 1, NULL, TEXTURE_DEPTH|TEXTURE_FLOAT); fx->depth[0] = texture_create(width, height, 1, NULL, TEXTURE_DEPTH|TEXTURE_FLOAT);
fx->fb[0] = fbo(fx->diffuse[0].id, fx->depth[0].id, 0); fx->fb[0] = fbo(fx->diffuse[0].id, fx->depth[0].id, 0);
// create texture, set texture parameters and content // create texture, set texture parameters and content
fx->diffuse[1] = texture_create(width, height, 4, NULL, TEXTURE_RGBA); fx->diffuse[1] = texture_create(width, height, 4, NULL, TEXTURE_RGBA|TEXTURE_FLOAT);
fx->depth[1] = texture_create(width, height, 1, NULL, TEXTURE_DEPTH|TEXTURE_FLOAT); fx->depth[1] = texture_create(width, height, 1, NULL, TEXTURE_DEPTH|TEXTURE_FLOAT);
fx->fb[1] = fbo(fx->diffuse[1].id, fx->depth[1].id, 0); fx->fb[1] = fbo(fx->diffuse[1].id, fx->depth[1].id, 0);
} }
@ -372501,7 +372504,7 @@ bool postfx_end(postfx *fx) {
return true; return true;
} }
static postfx fx; static postfx fx, gamma_fx;
int fx_load_from_mem(const char *nameid, const char *content) { int fx_load_from_mem(const char *nameid, const char *content) {
do_once postfx_create(&fx, 0); do_once postfx_create(&fx, 0);
return postfx_load_from_mem(&fx, nameid, content); return postfx_load_from_mem(&fx, nameid, content);
@ -374029,8 +374032,10 @@ static const char *dd_fs = "//" FILELINE "\n"
// "precision mediump float;\n" // "precision mediump float;\n"
"in vec3 out_color;\n" "in vec3 out_color;\n"
"out vec4 fragcolor;\n" "out vec4 fragcolor;\n"
"uniform float gamma; /// set:2.2\n"
"void main() {\n" "void main() {\n"
" fragcolor = vec4(out_color, 1.0);\n" " fragcolor = vec4(out_color, 1.0);\n"
" fragcolor.rgb = pow(fragcolor.rgb, vec3(gamma));\n"
"}"; "}";
#define X(x) RGBX(x,255) #define X(x) RGBX(x,255)
@ -374090,6 +374095,7 @@ void ddraw_flush_projview(mat44 proj, mat44 view) {
glUseProgram(dd_program); glUseProgram(dd_program);
glUniformMatrix4fv(glGetUniformLocation(dd_program, "u_MVP"), 1, GL_FALSE, mvp); glUniformMatrix4fv(glGetUniformLocation(dd_program, "u_MVP"), 1, GL_FALSE, mvp);
glUniform1f(glGetUniformLocation(dd_program, "gamma"), (window_get_gamma() + !window_get_gamma()));
static GLuint vao, vbo; static GLuint vao, vbo;
if(!vao) glGenVertexArrays(1, &vao); glBindVertexArray(vao); if(!vao) glGenVertexArrays(1, &vao); glBindVertexArray(vao);
@ -379321,6 +379327,7 @@ static char title[128] = {0};
static char screenshot_file[DIR_MAX]; static char screenshot_file[DIR_MAX];
static int locked_aspect_ratio = 0; static int locked_aspect_ratio = 0;
static vec4 winbgcolor = {0,0,0,1}; static vec4 winbgcolor = {0,0,0,1};
static float gamma = 2.2f;
vec4 window_getcolor_() { return winbgcolor; } // internal vec4 window_getcolor_() { return winbgcolor; } // internal
@ -379791,6 +379798,10 @@ int window_frame_begin() {
void input_update(); void input_update();
input_update(); input_update();
if (gamma) {
postfx_begin(&gamma_fx, window_width(), window_height());
}
return 1; return 1;
} }
@ -379807,6 +379818,10 @@ void window_frame_end() {
glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT);
dd_ontop = 1; dd_ontop = 1;
ddraw_flush(); ddraw_flush();
if (gamma) {
postfx_end(&gamma_fx);
}
ui_render(); ui_render();
} }
@ -379995,6 +380010,14 @@ void window_color(unsigned color) {
unsigned a = (color >> 24) & 255; unsigned a = (color >> 24) & 255;
winbgcolor = vec4(r / 255.0, g / 255.0, b / 255.0, a / 255.0); winbgcolor = vec4(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
} }
void window_gamma(float _gamma) {
gamma = _gamma;
shader_bind(gamma_fx.pass[postfx_find(&gamma_fx, "fxGamma.fs")].program);
shader_float("gamma", gamma);
}
float window_get_gamma() {
return gamma;
}
static int has_icon; static int has_icon;
int window_has_icon() { int window_has_icon() {
return has_icon; return has_icon;
@ -382604,6 +382627,11 @@ static void v4k_post_init(float refresh_rate) {
hz = refresh_rate; hz = refresh_rate;
// t = glfwGetTime(); // t = glfwGetTime();
do_once {
postfx_load_from_mem(&gamma_fx, "fxGamma.fs", vfs_read("fxGamma.fs"));
postfx_enable(&gamma_fx, 0, 1);
window_gamma(2.2f);
}
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -1957,6 +1957,7 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact
glUniform1f(glGetUniformLocation(f->program, "scale_factor"), factor); glUniform1f(glGetUniformLocation(f->program, "scale_factor"), factor);
glUniform2fv(glGetUniformLocation(f->program, "string_offset"), 1, &offset.x); glUniform2fv(glGetUniformLocation(f->program, "string_offset"), 1, &offset.x);
glUniform1f(glGetUniformLocation(f->program, "offset_firstline"), f->ascent*f->factor); glUniform1f(glGetUniformLocation(f->program, "offset_firstline"), f->ascent*f->factor);
glUniform1f(glGetUniformLocation(f->program, "gamma"), (window_get_gamma() + !window_get_gamma()));
GLint dims[4] = {0}; GLint dims[4] = {0};
glGetIntegerv(GL_VIEWPORT, dims); glGetIntegerv(GL_VIEWPORT, dims);

View File

@ -6,8 +6,8 @@ API void gui_drawrect( texture_t spritesheet, vec2 tex_start, vec2 tex_end, int
#define v42v2(rect) vec2(rect.x,rect.y), vec2(rect.z,rect.w) #define v42v2(rect) vec2(rect.x,rect.y), vec2(rect.z,rect.w)
void gui_drawrect( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, vec2 start, vec2 end ) { void gui_drawrect( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, vec2 start, vec2 end ) {
float gamma = 1;
static int program = -1, vbo = -1, vao = -1, u_inv_gamma = -1, u_tint = -1, u_has_tex = -1, u_window_width = -1, u_window_height = -1; static int program = -1, vbo = -1, vao = -1, u_inv_gamma = -1, u_tint = -1, u_has_tex = -1, u_window_width = -1, u_window_height = -1;
float gamma = window_get_gamma();
vec2 dpi = ifdef(osx, window_dpi(), vec2(1,1)); vec2 dpi = ifdef(osx, window_dpi(), vec2(1,1));
if( program < 0 ) { if( program < 0 ) {
const char* vs = vfs_read("shaders/rect_2d.vs"); const char* vs = vfs_read("shaders/rect_2d.vs");
@ -34,7 +34,7 @@ void gui_drawrect( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, ve
GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D; GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
glUseProgram( program ); glUseProgram( program );
glUniform1f( u_inv_gamma, 1.0f / (gamma + !gamma) ); glUniform1f( u_inv_gamma, (gamma + !gamma) );
glBindVertexArray( vao ); glBindVertexArray( vao );

View File

@ -48,6 +48,11 @@ static void v4k_post_init(float refresh_rate) {
hz = refresh_rate; hz = refresh_rate;
// t = glfwGetTime(); // t = glfwGetTime();
do_once {
postfx_load_from_mem(&gamma_fx, "fxGamma.fs", vfs_read("fxGamma.fs"));
postfx_enable(&gamma_fx, 0, 1);
window_gamma(2.2f);
}
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -1647,7 +1647,7 @@ skybox_t skybox(const char *asset, int flags) {
if( asset ) { if( asset ) {
int is_panorama = vfs_size( asset ); int is_panorama = vfs_size( asset );
if( is_panorama ) { // is file if( is_panorama ) { // is file
// stbi_hdr_to_ldr_gamma(1.2f); stbi_hdr_to_ldr_gamma(1.2f);
image_t panorama = image( asset, IMAGE_RGBA ); image_t panorama = image( asset, IMAGE_RGBA );
sky.cubemap = cubemap( panorama, 0 ); // RGBA required sky.cubemap = cubemap( panorama, 0 ); // RGBA required
image_destroy(&panorama); image_destroy(&panorama);
@ -2376,12 +2376,12 @@ bool postfx_begin(postfx *fx, int width, int height) {
fbo_destroy(fx->fb[1]); fbo_destroy(fx->fb[1]);
// create texture, set texture parameters and content // create texture, set texture parameters and content
fx->diffuse[0] = texture_create(width, height, 4, NULL, TEXTURE_RGBA); fx->diffuse[0] = texture_create(width, height, 4, NULL, TEXTURE_RGBA|TEXTURE_FLOAT);
fx->depth[0] = texture_create(width, height, 1, NULL, TEXTURE_DEPTH|TEXTURE_FLOAT); fx->depth[0] = texture_create(width, height, 1, NULL, TEXTURE_DEPTH|TEXTURE_FLOAT);
fx->fb[0] = fbo(fx->diffuse[0].id, fx->depth[0].id, 0); fx->fb[0] = fbo(fx->diffuse[0].id, fx->depth[0].id, 0);
// create texture, set texture parameters and content // create texture, set texture parameters and content
fx->diffuse[1] = texture_create(width, height, 4, NULL, TEXTURE_RGBA); fx->diffuse[1] = texture_create(width, height, 4, NULL, TEXTURE_RGBA|TEXTURE_FLOAT);
fx->depth[1] = texture_create(width, height, 1, NULL, TEXTURE_DEPTH|TEXTURE_FLOAT); fx->depth[1] = texture_create(width, height, 1, NULL, TEXTURE_DEPTH|TEXTURE_FLOAT);
fx->fb[1] = fbo(fx->diffuse[1].id, fx->depth[1].id, 0); fx->fb[1] = fbo(fx->diffuse[1].id, fx->depth[1].id, 0);
} }
@ -2484,7 +2484,7 @@ bool postfx_end(postfx *fx) {
return true; return true;
} }
static postfx fx; static postfx fx, gamma_fx;
int fx_load_from_mem(const char *nameid, const char *content) { int fx_load_from_mem(const char *nameid, const char *content) {
do_once postfx_create(&fx, 0); do_once postfx_create(&fx, 0);
return postfx_load_from_mem(&fx, nameid, content); return postfx_load_from_mem(&fx, nameid, content);

View File

@ -13,8 +13,10 @@ static const char *dd_fs = "//" FILELINE "\n"
// "precision mediump float;\n" // "precision mediump float;\n"
"in vec3 out_color;\n" "in vec3 out_color;\n"
"out vec4 fragcolor;\n" "out vec4 fragcolor;\n"
"uniform float gamma; /// set:2.2\n"
"void main() {\n" "void main() {\n"
" fragcolor = vec4(out_color, 1.0);\n" " fragcolor = vec4(out_color, 1.0);\n"
" fragcolor.rgb = pow(fragcolor.rgb, vec3(gamma));\n"
"}"; "}";
#define X(x) RGBX(x,255) #define X(x) RGBX(x,255)
@ -74,6 +76,7 @@ void ddraw_flush_projview(mat44 proj, mat44 view) {
glUseProgram(dd_program); glUseProgram(dd_program);
glUniformMatrix4fv(glGetUniformLocation(dd_program, "u_MVP"), 1, GL_FALSE, mvp); glUniformMatrix4fv(glGetUniformLocation(dd_program, "u_MVP"), 1, GL_FALSE, mvp);
glUniform1f(glGetUniformLocation(dd_program, "gamma"), (window_get_gamma() + !window_get_gamma()));
static GLuint vao, vbo; static GLuint vao, vbo;
if(!vao) glGenVertexArrays(1, &vao); glBindVertexArray(vao); if(!vao) glGenVertexArrays(1, &vao); glBindVertexArray(vao);

View File

@ -107,6 +107,7 @@ static char title[128] = {0};
static char screenshot_file[DIR_MAX]; static char screenshot_file[DIR_MAX];
static int locked_aspect_ratio = 0; static int locked_aspect_ratio = 0;
static vec4 winbgcolor = {0,0,0,1}; static vec4 winbgcolor = {0,0,0,1};
static float gamma = 2.2f;
vec4 window_getcolor_() { return winbgcolor; } // internal vec4 window_getcolor_() { return winbgcolor; } // internal
@ -577,6 +578,10 @@ int window_frame_begin() {
void input_update(); void input_update();
input_update(); input_update();
if (gamma) {
postfx_begin(&gamma_fx, window_width(), window_height());
}
return 1; return 1;
} }
@ -593,6 +598,10 @@ void window_frame_end() {
glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT);
dd_ontop = 1; dd_ontop = 1;
ddraw_flush(); ddraw_flush();
if (gamma) {
postfx_end(&gamma_fx);
}
ui_render(); ui_render();
} }
@ -781,6 +790,14 @@ void window_color(unsigned color) {
unsigned a = (color >> 24) & 255; unsigned a = (color >> 24) & 255;
winbgcolor = vec4(r / 255.0, g / 255.0, b / 255.0, a / 255.0); winbgcolor = vec4(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
} }
void window_gamma(float _gamma) {
gamma = _gamma;
shader_bind(gamma_fx.pass[postfx_find(&gamma_fx, "fxGamma.fs")].program);
shader_float("gamma", gamma);
}
float window_get_gamma() {
return gamma;
}
static int has_icon; static int has_icon;
int window_has_icon() { int window_has_icon() {
return has_icon; return has_icon;

View File

@ -38,6 +38,8 @@ API void window_loop_exit(); // exit from main loop function (emscripten onl
API void window_title(const char *title); API void window_title(const char *title);
API void window_color(unsigned color); API void window_color(unsigned color);
API void window_gamma(float gamma); // 2.2 - standard, 0.0 - disables postfx pass
API float window_get_gamma();
API vec2 window_canvas(); API vec2 window_canvas();
API void* window_handle(); API void* window_handle();
API char* window_stats(); API char* window_stats();

View File

@ -10659,6 +10659,7 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact
glUniform1f(glGetUniformLocation(f->program, "scale_factor"), factor); glUniform1f(glGetUniformLocation(f->program, "scale_factor"), factor);
glUniform2fv(glGetUniformLocation(f->program, "string_offset"), 1, &offset.x); glUniform2fv(glGetUniformLocation(f->program, "string_offset"), 1, &offset.x);
glUniform1f(glGetUniformLocation(f->program, "offset_firstline"), f->ascent*f->factor); glUniform1f(glGetUniformLocation(f->program, "offset_firstline"), f->ascent*f->factor);
glUniform1f(glGetUniformLocation(f->program, "gamma"), (window_get_gamma() + !window_get_gamma()));
GLint dims[4] = {0}; GLint dims[4] = {0};
glGetIntegerv(GL_VIEWPORT, dims); glGetIntegerv(GL_VIEWPORT, dims);
@ -11248,8 +11249,8 @@ API void gui_drawrect( texture_t spritesheet, vec2 tex_start, vec2 tex_end, int
#define v42v2(rect) vec2(rect.x,rect.y), vec2(rect.z,rect.w) #define v42v2(rect) vec2(rect.x,rect.y), vec2(rect.z,rect.w)
void gui_drawrect( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, vec2 start, vec2 end ) { void gui_drawrect( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, vec2 start, vec2 end ) {
float gamma = 1;
static int program = -1, vbo = -1, vao = -1, u_inv_gamma = -1, u_tint = -1, u_has_tex = -1, u_window_width = -1, u_window_height = -1; static int program = -1, vbo = -1, vao = -1, u_inv_gamma = -1, u_tint = -1, u_has_tex = -1, u_window_width = -1, u_window_height = -1;
float gamma = window_get_gamma();
vec2 dpi = ifdef(osx, window_dpi(), vec2(1,1)); vec2 dpi = ifdef(osx, window_dpi(), vec2(1,1));
if( program < 0 ) { if( program < 0 ) {
const char* vs = vfs_read("shaders/rect_2d.vs"); const char* vs = vfs_read("shaders/rect_2d.vs");
@ -11276,7 +11277,7 @@ void gui_drawrect( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, ve
GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D; GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
glUseProgram( program ); glUseProgram( program );
glUniform1f( u_inv_gamma, 1.0f / (gamma + !gamma) ); glUniform1f( u_inv_gamma, (gamma + !gamma) );
glBindVertexArray( vao ); glBindVertexArray( vao );
@ -18821,7 +18822,7 @@ skybox_t skybox(const char *asset, int flags) {
if( asset ) { if( asset ) {
int is_panorama = vfs_size( asset ); int is_panorama = vfs_size( asset );
if( is_panorama ) { // is file if( is_panorama ) { // is file
// stbi_hdr_to_ldr_gamma(1.2f); stbi_hdr_to_ldr_gamma(1.2f);
image_t panorama = image( asset, IMAGE_RGBA ); image_t panorama = image( asset, IMAGE_RGBA );
sky.cubemap = cubemap( panorama, 0 ); // RGBA required sky.cubemap = cubemap( panorama, 0 ); // RGBA required
image_destroy(&panorama); image_destroy(&panorama);
@ -19550,12 +19551,12 @@ bool postfx_begin(postfx *fx, int width, int height) {
fbo_destroy(fx->fb[1]); fbo_destroy(fx->fb[1]);
// create texture, set texture parameters and content // create texture, set texture parameters and content
fx->diffuse[0] = texture_create(width, height, 4, NULL, TEXTURE_RGBA); fx->diffuse[0] = texture_create(width, height, 4, NULL, TEXTURE_RGBA|TEXTURE_FLOAT);
fx->depth[0] = texture_create(width, height, 1, NULL, TEXTURE_DEPTH|TEXTURE_FLOAT); fx->depth[0] = texture_create(width, height, 1, NULL, TEXTURE_DEPTH|TEXTURE_FLOAT);
fx->fb[0] = fbo(fx->diffuse[0].id, fx->depth[0].id, 0); fx->fb[0] = fbo(fx->diffuse[0].id, fx->depth[0].id, 0);
// create texture, set texture parameters and content // create texture, set texture parameters and content
fx->diffuse[1] = texture_create(width, height, 4, NULL, TEXTURE_RGBA); fx->diffuse[1] = texture_create(width, height, 4, NULL, TEXTURE_RGBA|TEXTURE_FLOAT);
fx->depth[1] = texture_create(width, height, 1, NULL, TEXTURE_DEPTH|TEXTURE_FLOAT); fx->depth[1] = texture_create(width, height, 1, NULL, TEXTURE_DEPTH|TEXTURE_FLOAT);
fx->fb[1] = fbo(fx->diffuse[1].id, fx->depth[1].id, 0); fx->fb[1] = fbo(fx->diffuse[1].id, fx->depth[1].id, 0);
} }
@ -19658,7 +19659,7 @@ bool postfx_end(postfx *fx) {
return true; return true;
} }
static postfx fx; static postfx fx, gamma_fx;
int fx_load_from_mem(const char *nameid, const char *content) { int fx_load_from_mem(const char *nameid, const char *content) {
do_once postfx_create(&fx, 0); do_once postfx_create(&fx, 0);
return postfx_load_from_mem(&fx, nameid, content); return postfx_load_from_mem(&fx, nameid, content);
@ -21186,8 +21187,10 @@ static const char *dd_fs = "//" FILELINE "\n"
// "precision mediump float;\n" // "precision mediump float;\n"
"in vec3 out_color;\n" "in vec3 out_color;\n"
"out vec4 fragcolor;\n" "out vec4 fragcolor;\n"
"uniform float gamma; /// set:2.2\n"
"void main() {\n" "void main() {\n"
" fragcolor = vec4(out_color, 1.0);\n" " fragcolor = vec4(out_color, 1.0);\n"
" fragcolor.rgb = pow(fragcolor.rgb, vec3(gamma));\n"
"}"; "}";
#define X(x) RGBX(x,255) #define X(x) RGBX(x,255)
@ -21247,6 +21250,7 @@ void ddraw_flush_projview(mat44 proj, mat44 view) {
glUseProgram(dd_program); glUseProgram(dd_program);
glUniformMatrix4fv(glGetUniformLocation(dd_program, "u_MVP"), 1, GL_FALSE, mvp); glUniformMatrix4fv(glGetUniformLocation(dd_program, "u_MVP"), 1, GL_FALSE, mvp);
glUniform1f(glGetUniformLocation(dd_program, "gamma"), (window_get_gamma() + !window_get_gamma()));
static GLuint vao, vbo; static GLuint vao, vbo;
if(!vao) glGenVertexArrays(1, &vao); glBindVertexArray(vao); if(!vao) glGenVertexArrays(1, &vao); glBindVertexArray(vao);
@ -26478,6 +26482,7 @@ static char title[128] = {0};
static char screenshot_file[DIR_MAX]; static char screenshot_file[DIR_MAX];
static int locked_aspect_ratio = 0; static int locked_aspect_ratio = 0;
static vec4 winbgcolor = {0,0,0,1}; static vec4 winbgcolor = {0,0,0,1};
static float gamma = 2.2f;
vec4 window_getcolor_() { return winbgcolor; } // internal vec4 window_getcolor_() { return winbgcolor; } // internal
@ -26948,6 +26953,10 @@ int window_frame_begin() {
void input_update(); void input_update();
input_update(); input_update();
if (gamma) {
postfx_begin(&gamma_fx, window_width(), window_height());
}
return 1; return 1;
} }
@ -26964,6 +26973,10 @@ void window_frame_end() {
glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT);
dd_ontop = 1; dd_ontop = 1;
ddraw_flush(); ddraw_flush();
if (gamma) {
postfx_end(&gamma_fx);
}
ui_render(); ui_render();
} }
@ -27152,6 +27165,14 @@ void window_color(unsigned color) {
unsigned a = (color >> 24) & 255; unsigned a = (color >> 24) & 255;
winbgcolor = vec4(r / 255.0, g / 255.0, b / 255.0, a / 255.0); winbgcolor = vec4(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
} }
void window_gamma(float _gamma) {
gamma = _gamma;
shader_bind(gamma_fx.pass[postfx_find(&gamma_fx, "fxGamma.fs")].program);
shader_float("gamma", gamma);
}
float window_get_gamma() {
return gamma;
}
static int has_icon; static int has_icon;
int window_has_icon() { int window_has_icon() {
return has_icon; return has_icon;
@ -29761,6 +29782,11 @@ static void v4k_post_init(float refresh_rate) {
hz = refresh_rate; hz = refresh_rate;
// t = glfwGetTime(); // t = glfwGetTime();
do_once {
postfx_load_from_mem(&gamma_fx, "fxGamma.fs", vfs_read("fxGamma.fs"));
postfx_enable(&gamma_fx, 0, 1);
window_gamma(2.2f);
}
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -4755,6 +4755,8 @@ API void window_loop_exit(); // exit from main loop function (emscripten onl
API void window_title(const char *title); API void window_title(const char *title);
API void window_color(unsigned color); API void window_color(unsigned color);
API void window_gamma(float gamma); // 2.2 - standard, 0.0 - disables postfx pass
API float window_get_gamma();
API vec2 window_canvas(); API vec2 window_canvas();
API void* window_handle(); API void* window_handle();
API char* window_stats(); API char* window_stats();