Page 2 of 3

Re: GL Gamma Correction

Posted: Tue May 07, 2013 12:00 am
by Spike
gl_brightness and gl_contrast are supposed to exist in fte, but whether they're identical to the gamma+contrast cvars is a different matter. If it ain't exact, it ain't gamma. :s

Re: GL Gamma Correction

Posted: Tue May 07, 2013 12:59 am
by Baker
reckless wrote:Hmm an interresting non shader based gamma function i have from one of mh's older engines.

Code: Select all

/*
===================
SCR_SetBrightness

Enables setting of brightness without having to do any mondo fancy shite.
It's assumed that we're in the 2D view for this...

Basically, what it does is multiply framebuffer colours by an incoming constant between 0 and 2
===================
*/
void SCR_SetBrightness (float brightfactor)
{
    // divide by 2 cos the blendfunc will sum src and dst
    const GLfloat brightblendcolour[4] = {0, 0, 0, 0.5f * brightfactor};
    const GLfloat constantwhite[4] = {1, 1, 1, 1};

    // don't trust == with floats, don;t bother if it's 1 cos it does nothing to the end result!!!
    if (brightfactor > 0.99 && brightfactor < 1.01)
    {
        return;
    }

    glColor4fv (constantwhite);
    glEnable (GL_BLEND);
    glDisable (GL_ALPHA_TEST);
    glBlendFunc (GL_DST_COLOR, GL_SRC_COLOR);

    // combine hack...
    // this is weird cos it uses a texture but actually doesn't - the parameters of the
    // combiner function only use the incoming fragment colour and a constant colour...
    // you could actually bind any texture you care to mention and get the very same result...
    // i've decided not to bind any at all...
    glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
    glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
    glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_CONSTANT);
    glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_ALPHA);
    glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
    glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
    glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, brightblendcolour);

    glBegin (GL_QUADS);

    glTexCoord2f (0, 0);
    glVertex2f (0, 0);

    glTexCoord2f (0, 1);
    glVertex2f (0, GL_State.OrthoHeight);

    glTexCoord2f (1, 1);
    glVertex2f (GL_State.OrthoWidth, GL_State.OrthoHeight);

    glTexCoord2f (1, 0);
    glVertex2f (GL_State.OrthoWidth, 0);

    glEnd ();

    // restore combiner function colour to white so as not to mess up texture state
    glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constantwhite);

    glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    glDisable (GL_BLEND);
    glEnable (GL_ALPHA_TEST);
    glColor4fv (constantwhite);
}
uses opengl's combine extention so will not Work for the software client.
Reckless, I don't think that does real gamma. But if It really does real gamma, feel free to smack me upside the head and point out how it does.

To me that looks similar to the "draw a brightness poly over the whole 2D surface" method.

Re: GL Gamma Correction

Posted: Tue May 07, 2013 9:26 am
by revelator
Indeed what it does is a bit like doing overbright but it emulates gamma amazingly well though ;)
Also easy to use as it uses the v_gamma cvar directly.

Re: GL Gamma Correction

Posted: Wed May 08, 2013 3:42 pm
by jitspoe
Barnes wrote:ahh yes!!!
photoshop math on glsl and hlsl (im use some things)
http://mouaif.wordpress.com/2009/01/05/ ... l-shaders/
Hey, my coworker wrote those! Small world. :)



As for the GL_COMBINE stuff, that effectively just multiplies the output. It's actually pretty useful when blending lightmaps with textures, as it's effectively a "free" way to brighten things up. I use this in Paintball2 (gl_overbright is the cvar to enable/disable it). If that's not bright enough, I've also got the method posted above, where it draws a quad over the whole screen to brighten it (gl_brightness cvar). Downside to that is it's a pretty big fillrate hit, since it has to make another pass over the whole screen. I'm not sure if that's more or less expensive than a shader (I would imagine less), but it will be compatible with more video cards. It does not, however, behave like gamma. It just scales the brightness of everything up.

Re: GL Gamma Correction

Posted: Wed May 08, 2013 7:06 pm
by Spike
GL_RGB_SCALE does scale the output, yes (overbrights etc). Activate it when drawing everything else and you can double the contrast of the screen, but you have to be really careful with blend modes.
contrast is easy to implement - just double the colour values.
brightness is also easy - just add to the colour values.
actual gamma requires exponents, however. luckily, it should be possible to just multiply the values enough times. the down side is that doing that will loose precision. a lot of precision.

Re: GL Gamma Correction

Posted: Wed May 08, 2013 7:33 pm
by Barnes
jitspoe wrote:
Barnes wrote:ahh yes!!!
photoshop math on glsl and hlsl (im use some things)
http://mouaif.wordpress.com/2009/01/05/ ... l-shaders/
Hey, my coworker wrote those! Small world. :)
Damn! Real small world! Image

Re: GL Gamma Correction

Posted: Thu May 09, 2013 12:34 am
by revelator
Aye its not true gamma :) but if someone can use it for whatever its easy to implement call the function from the same place as the old gamma and give it a cvar as argument for the bright factor.
Small note it uses negative values so if you want to use it with the standard quake menu you have to invert the menu scales. Maybe nice for a scalable overbright setting hmm :) ?.

Re: GL Gamma Correction

Posted: Thu May 09, 2013 6:00 am
by Baker
reckless wrote:Aye its not true gamma :) but if someone can use it for whatever its easy to implement call the function from the same place as the old gamma and give it a cvar as argument for the bright factor.
Small note it uses negative values so if you want to use it with the standard quake menu you have to invert the menu scales. Maybe nice for a scalable overbright setting hmm :) ?.
Shockingly enough, I'm only getting a 4 FPS hit off this and it works pretty well.

Now I'm trying to debate what to do. Damn you reckless! :D

Re: GL Gamma Correction

Posted: Thu May 09, 2013 8:03 am
by Baker
Sat on fence then went with this.

Reasons:
1. Loss of 4 fps 223 fps to 219 fps on my $300 windows laptop (this $300 laptop is incredible ... it's terrific and I'm picky)
2. No need for gamma and contrast. Just brightness. Winner.
3. No more platform specific hardware gamma code.
4. Screenshots don't need gamma correction applied (not that I did that). Neither does video capture.
5. Affects only the Window itself.

Drawbacks:
1. Slightly narrower capabilities of brightening the screen. Hardware gamma has more brightening power.
2. Slight loss of FPS and fps matters (within reason). But 1%-2% loss is nothing.

I had rewritten all the Windows hardware gamma code really nice and orderly. And now I'm throwing it away. A bit ironic, but I'll take this total solution over hardware gamma every day.

Since "gamma" is a standard Quake cvar (some mods even use it for brightness effects like flash grenades ... although they shouldn't have used the cvar) I internally call it scr_brightness but keeps same external cvar name.

Re: GL Gamma Correction

Posted: Thu May 09, 2013 12:39 pm
by revelator
Happy that it found a use :) fps hit is as you say minimal and it Works rather well so i thought someone might find it interresting even though its not real gamma ;).
Heh funny i use the same cvar name small World indeed.

Re: GL Gamma Correction

Posted: Fri May 10, 2013 1:34 am
by jitspoe
In a lot of cases, we don't actually want gamma - we just want things brighter, so it's ideal for that. If things are simply too dark, using gamma to brighten them can result in washed-out visuals (loss of contrast and saturation). If you want brightness in the standard case, you can use this when combining the lightmap and textures to avoid the 4fps hit, though it would require modifying a lot more code.

Re: GL Gamma Correction

Posted: Sun May 12, 2013 5:46 am
by Baker
Burial ... Hardware gamma code: I can't imagine ever using it again and am removing it, but some of it I touched up sensibly.

Code: Select all

void VID_Local_Gamma_Reset (void)
{
	int i;
	HDC hdc = GetDC (NULL);
	WORD gammaramps[3][256];

	for (i = 0;i < 256;i++)
		gammaramps[0][i] = gammaramps[1][i] = gammaramps[2][i] = (i * 65535) / 255;

	i = SetDeviceGammaRamp(hdc, &gammaramps[0][0]);
	ReleaseDC (NULL, hdc);
}


/*
================
VID_Gamma_SetGamma -- apply gamma correction
================
*/
void VID_Local_Gamma_SetGamma (void)
{
	if (wplat.draw_context && vid.gammaworks)
	{
		if (SetDeviceGammaRamp(wplat.draw_context, vid.gammaramp) == false)
			Con_Printf ("VID_Gamma_SetGamma: failed on SetDeviceGammaRamp\n");
	}
}

/*
qboolean VID_Local_Validate_Gamma (void)
{
		static unsigned short checktable[768];
		Con_Printf ("Gamma guardian: ");
		if (GetDeviceGammaRamp (wplat.draw_context, checktable))
		{
			if (memcmp(&checktable, &vid.gammaramp, sizeof(checktable)) !=0 )
				Con_Printf ("Gamma is wrong!\n");
			else Con_Printf ("Gamma is correct!\n");
		} else Con_Printf ("Couldn't get gamma table\n");
} */

/*
================
VID_Gamma_Restore -- restore system gamma
================
*/
void VID_Local_Gamma_Restore (void)
{
	if (wplat.draw_context && vid.gammaworks)
	{
		if (SetDeviceGammaRamp(wplat.draw_context, vid.systemgammaramp) == false)
			Con_Printf ("VID_Gamma_Restore: failed on SetDeviceGammaRamp\n");
	}
}


/*
================
VID_Gamma_f -- callback when the cvar changes
================
*/
void VID_Local_Gamma_f (cvar_t *var)
{
	int i;

	if (vid_gamma.default_string == NULL || vid_gamma.default_string == NULL)
		return; // Presumed to be in initialization

 	for (i=0; i<256; i++)
	{
		float inf = (255 * pow ((i + 0.5) / 255.5, vid_gamma.value) + 0.5);

		inf -= 128;
		inf *= vid_contrast.value;
		inf += 128;
		vid.gammaramp[i +   0] =
		vid.gammaramp[i + 256] =
		vid.gammaramp[i + 512] = CLAMP (0, (int) inf, 255) << 8;
	}
	VID_Gamma_SetGamma ();
}

qboolean VID_Local_Gamma_Init (void)
{
	HDC hdc = GetDC (NULL);
	if (GetDeviceGammaRamp (hdc, vid.systemgammaramp))
		return true;
	return false;
}
And

Code: Select all

cvar_t		vid_gamma = {"gamma", "1", CVAR_ARCHIVE}; //johnfitz -- moved here from view.c
cvar_t		vid_contrast = {"contrast", "1", CVAR_ARCHIVE};

void VID_Gamma_Think (void)
{
	if (vid.ActiveApp && !vid.Minimized && vid.gammaworks /*&& wplat.draw_context*/)
	{
		if (vid.gamma_checktime && realtime > vid.gamma_checktime)
		{
			VID_Gamma_Restore ();
			VID_Gamma_SetGamma ();
			vid.gamma_checktime = 0;
			Con_DPrintf ("Gamma restore\n");
		}
	}
}

void VID_Gamma_Shutdown (void)
{
	VID_Local_Gamma_Restore ();
}

void VID_Gamma_Init (void)
{
	if ( (vid.gammaworks = VID_Local_Gamma_Init ()) == false)
		Con_Warning ("Hardware gamma not available.\n");

	Cvar_RegisterVariableWithCallback (&vid_contrast, VID_Local_Gamma_f);
	Cvar_RegisterVariableWithCallback (&vid_gamma, VID_Local_Gamma_f);
}

void VID_Gamma_SetGamma (void)
{
	VID_Local_Gamma_SetGamma ();
}

void VID_Gamma_Restore (void)
{
	VID_Local_Gamma_Restore ();
}

Re: GL Gamma Correction

Posted: Sun May 12, 2013 9:58 am
by Barnes
Kill'em, kill'em!!!!
Seriously I have already killed the hardware gamma ramps. A terrible thing has been :D

Re: GL Gamma Correction

Posted: Sun May 12, 2013 4:21 pm
by revelator
Definatly worth it sifting through mh's older OpenGL engine sources, lots of non standard but amazingly well working ideas :) His Q2 sources are also worth having a look at, many nice ideas in them.

Re: GL Gamma Correction

Posted: Sun May 12, 2013 11:03 pm
by revelator
Btw try replacing tenebraes old gamma code with the code posted :) i think your going to like it.