Inside3D!
     

Gamma/Constrast

 
Post new topic   Reply to topic    Inside3d Forums Forum Index -> Engine Programming
View previous topic :: View next topic  
Author Message
Baker



Joined: 14 Mar 2006
Posts: 1538

PostPosted: Wed Jul 14, 2010 6:52 pm    Post subject: Gamma/Constrast Reply with quote

Just a look at the different methods of doing gamma, contrast and view blends. I'm having a minor but annoying issue so if I document the process I can also fix it Very Happy But if I don't, I'll continue missing something that is eluding me.

My builds have 5 gamma/contrast methods:

1. WinQuake apply the gamma/contrast to the global palette method
2. GLQuake apply the gamma/contrast to the texture before upload method
3. D3DQuake's d3dSetGammaRamp method
4. The hardware gamma method
5. The render a brightness poly over everything method

Gamma

Building the gamma table from WinQuake. It later gets applied to the palette.

Code:
void BuildGammaTable (float g) // g = gamma
{
   int      i, inf;
   
   if (g == 1.0)
   {
      for (i=0 ; i<256 ; i++)
         gammatable[i] = i;
      return;
   }
   
   for (i=0 ; i<256 ; i++)
   {
      inf = 255 * pow ( (i+0.5)/255.5 , g ) + 0.5;
      if (inf < 0)
         inf = 0;
      if (inf > 255)
         inf = 255;
      gammatable[i] = inf;
   }
}


Enter Contrast

The gamma/contrast table from JoeQuake:

Code:
static void BuildGammaTable2 (float g, float c)
{
   int   i, inf;

   g = bound(0.3, g, 3);
   c = bound(1, c, 3);

   if (g == 1 && c == 1)
   {
      for (i=0 ; i<256 ; i++)
         gammatable[i] = i;
      return;
   }

   for (i=0 ; i<256 ; i++)
   {
      inf = 255 * pow((i + 0.5) / 255.5 * c, g) + 0.5;
      gammatable[i] = bound(0, inf, 255);
   }
}


I'll be stepping through where each of these are done and why as far as the application of the gamma and contrast.
_________________
Tomorrow Never Dies. I feel this Tomorrow knocking on the door ...
Back to top
View user's profile Send private message
metlslime



Joined: 05 Feb 2008
Posts: 177

PostPosted: Wed Jul 14, 2010 8:17 pm    Post subject: Reply with quote

don't forget idgamma, which causes people to complain that overbright lighting is bad Smile

Note: I think these two are the same:

3. D3DQuake's d3dSetGammaRamp method
4. The hardware gamma method

The only difference being which API you use; d3d or wgl. But they both affect the video card the same way (lookup table in the DAC i believe.)
Back to top
View user's profile Send private message
Spike



Joined: 05 Nov 2004
Posts: 944
Location: UK

PostPosted: Wed Jul 14, 2010 8:22 pm    Post subject: Reply with quote

yeah, setgammaramp is hardware gamma, but the d3d one has less down sides
_________________
What's a signature?
Back to top
View user's profile Send private message Visit poster's website
Baker



Joined: 14 Mar 2006
Posts: 1538

PostPosted: Wed Jul 14, 2010 8:29 pm    Post subject: Reply with quote

View Blends

Combined with the gamma [and contrast] the view blends also affect the palette flashes in WinQuake directly:

Code:
typedef struct
{
   int      destcolor[3];
   int      percent;      // 0-256
} cshift_t;

#define   CSHIFT_CONTENTS   0
#define   CSHIFT_DAMAGE   1
#define   CSHIFT_BONUS   2
#define   CSHIFT_POWERUP   3
#define   NUM_CSHIFTS      4


There are 4 chsifts -- I'm guessing the C stands for contrast but it could stand for client. Or maybe contents? Maybe something else (?)

Contents: Empty, Water, Lava, Slime, "Void". Void = no clipping outside the map
Damage: Obvious.
Bonus: Item pickups. "bf"
PowerUP: Quad, Pent, Ring, Suit

The cshift constants ... red, green, blue, intensity percent.

Code:
cshift_t   cshift_empty = { {130,80,50}, 0 };
cshift_t   cshift_water = { {130,80,50}, 128 };
cshift_t   cshift_slime = { {0,25,5}, 150 };
cshift_t   cshift_lava = { {255,80,0}, 150 };


Note: Kurok added an extra one for blue when you go underwater.

Code:
cshift_t   cshift_kwater = { {64,64,128}, 128 }; // Blue water for Kurok


The lifecycle of the CSHIFT begins in R_Render_View_ right after drawing particles.

Code:
void V_SetContentsColor (int contents)
{
   switch (contents)
   {
   case CONTENTS_EMPTY:
   case CONTENTS_SOLID:
      cl.cshifts[CSHIFT_CONTENTS] = cshift_empty;
      break;
   case CONTENTS_LAVA:
      cl.cshifts[CSHIFT_CONTENTS] = cshift_lava;
      break;
   case CONTENTS_SLIME:
      cl.cshifts[CSHIFT_CONTENTS] = cshift_slime;
      break;
   default:
      cl.cshifts[CSHIFT_CONTENTS] = cshift_water;
   }
}


Bonus Flash is actually a command sent over the server ...

Code:
void V_BonusFlash_f (void)
{
   cl.cshifts[CSHIFT_BONUS].destcolor[0] = 215;
   cl.cshifts[CSHIFT_BONUS].destcolor[1] = 186;
   cl.cshifts[CSHIFT_BONUS].destcolor[2] = 69;
   cl.cshifts[CSHIFT_BONUS].percent = 50;
}


It is received in CL_ReadFromServer --> CL_ParseServerMessage and added to the command buffer. So it is probably actually processed 1 frame later.

The damage flash is processed the moment it is received from CL_ParseServerMessage

Code:
      case svc_damage:
         V_ParseDamage ();
         break;


Power up shift is calculated in V_CalcPowerupCShift, which is called by V_UpdatePalette

Code:
/*
=============
V_CalcPowerupCshift
=============
*/
void V_CalcPowerupCshift (void)
{
   if (cl.items & IT_QUAD)
   {
      cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0;
      cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 0;
      cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 255;
      cl.cshifts[CSHIFT_POWERUP].percent = 30;
   }
   else if (cl.items & IT_SUIT)
   {
      cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0;
      cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255;
      cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0;
      cl.cshifts[CSHIFT_POWERUP].percent = 20;
   }
   else if (cl.items & IT_INVISIBILITY)
   {
      cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 100;
      cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 100;
      cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 100;
      cl.cshifts[CSHIFT_POWERUP].percent = 100;
   }
   else if (cl.items & IT_INVULNERABILITY)
   {
      cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 255;
      cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255;
      cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0;
      cl.cshifts[CSHIFT_POWERUP].percent = 30;
   }
   else
      cl.cshifts[CSHIFT_POWERUP].percent = 0;
}


Funny note, apparently the content blend was meant to be cleared in WinQuake if you pulled up the console ...

Code:
/*
===============
SCR_BringDownConsole

Brings the console down and fades the palettes back to normal
================
*/
void SCR_BringDownConsole (void)
{
   int      i;
   
   scr_centertime_off = 0;
   
   for (i=0 ; i<20 && scr_conlines != scr_con_current ; i++)
      SCR_UpdateScreen ();

   cl.cshifts[0].percent = 0;      // no area contents palette on next frame
   VID_SetPalette (host_basepal);
}


It doesn't work.

Probably because SCR_BringDownConsole is never called anywhere in the source and is commented out in cl_main.c Very Happy
_________________
Tomorrow Never Dies. I feel this Tomorrow knocking on the door ...
Back to top
View user's profile Send private message
mh



Joined: 12 Jan 2008
Posts: 909

PostPosted: Wed Jul 14, 2010 8:55 pm    Post subject: Reply with quote

"Colour" (or "Color" for those who didn't flunk math and married the prom queen) I would guess.

I don't bother with the D3D gamma ramp and just use the GDI functions instead. My guess is that the D3D version is just a wrapper around the GDI functions anyway (which may or may not work in windowed modes depending on which page of the documentation you read). It does have the ability to do calibration but I've never felt the need for it.
_________________
DirectQ Engine - New release 1.8.666a, 9th August 2010
MHQuake Blog (General)
Direct3D 8 Quake Engines
Back to top
View user's profile Send private message Visit poster's website
Baker



Joined: 14 Mar 2006
Posts: 1538

PostPosted: Wed Jul 14, 2010 9:03 pm    Post subject: Reply with quote

metlslime wrote:
3. D3DQuake's d3dSetGammaRamp method
4. The hardware gamma method


d3dquake's D3DSetGamma only affects the window itself and not the desktop. I noticed that FTEQW 2770 using the D3D render actually uses hardware and contrast, which looks much better.

mh wrote:
"Colour"


Baker -1
_________________
Tomorrow Never Dies. I feel this Tomorrow knocking on the door ...
Back to top
View user's profile Send private message
Spike



Joined: 05 Nov 2004
Posts: 944
Location: UK

PostPosted: Wed Jul 14, 2010 9:29 pm    Post subject: Reply with quote

why d3d's setgammaramps function is better than the windows api:
D3DSGR_NO_CALIBRATION
no stall, no bounds checks, what you send actually goes.

d3d8 only works if its fullscreen. d3d9 works even windowed (affecting the whole screen).

its probably worth creating a d3d9 context just to get ramps working without stalls, even if all rendering is done with opengl.
_________________
What's a signature?
Back to top
View user's profile Send private message Visit poster's website
mh



Joined: 12 Jan 2008
Posts: 909

PostPosted: Wed Jul 14, 2010 9:35 pm    Post subject: Reply with quote

Spike wrote:
why d3d's setgammaramps function is better than the windows api:
D3DSGR_NO_CALIBRATION
no stall, no bounds checks, what you send actually goes.

d3d8 only works if its fullscreen. d3d9 works even windowed (affecting the whole screen).

its probably worth creating a d3d9 context just to get ramps working without stalls, even if all rendering is done with opengl.

I think I now have the need to use D3D's SGR. Very Happy

(Although if my theory is correct there should be an API call to disable the crap too).
_________________
DirectQ Engine - New release 1.8.666a, 9th August 2010
MHQuake Blog (General)
Direct3D 8 Quake Engines
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Inside3d Forums Forum Index -> Engine Programming All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2004 phpBB Group