Skip to content

Commit

Permalink
Re-add gamma/brightness/contrast options
Browse files Browse the repository at this point in the history
Some people really need this feature, so we should work on adding it
back, maybe even before we manage to get the render ready for PP.

Reverts commit 3ad44dc

This is not meant as a final version, as it has all the problems those
settings had before we removed them. These include:
 * Doesn't work under Linux at all (at least for me)
 * From the IRC logs it looks like this changed the gamma for the whole
   desktop when in windowed mode.
More tests are needed on these problems.

We may want to use those settings like they are used now, but only when
in fullscreen mode.

Either way, we should make sure that the defaults provide a 1:1 mapping.
  • Loading branch information
dscharrer committed Jun 15, 2012
1 parent d4d41bf commit 4fe8a4a
Show file tree
Hide file tree
Showing 14 changed files with 166 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/core/ArxGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2331,6 +2331,8 @@ void ArxGame::onRendererInit(RenderWindow & window) {
return;
}

window.setGamma(config.video.luminosity, config.video.contrast, config.video.gamma);

InitDeviceObjects();

// The app is ready to go
Expand Down
12 changes: 12 additions & 0 deletions src/core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ const int
bpp = 16,
levelOfDetail = 2,
fogDistance = 10,
gamma = 5,
luminosity = 4,
contrast = 5,
volume = 10,
sfxVolume = 10,
speechVolume = 10,
Expand Down Expand Up @@ -155,6 +158,9 @@ const string
fullscreen = "full_screen",
levelOfDetail = "others_details",
fogDistance = "fog",
gamma = "gamma",
luminosity = "luminosity",
contrast = "contrast",
showCrosshair = "show_crosshair",
antialiasing = "antialiasing",
vsync = "vsync";
Expand Down Expand Up @@ -379,6 +385,9 @@ bool Config::save() {
writer.writeKey(Key::fullscreen, video.fullscreen);
writer.writeKey(Key::levelOfDetail, video.levelOfDetail);
writer.writeKey(Key::fogDistance, video.fogDistance);
writer.writeKey(Key::gamma, video.gamma);
writer.writeKey(Key::luminosity, video.luminosity);
writer.writeKey(Key::contrast, video.contrast);
writer.writeKey(Key::showCrosshair, video.showCrosshair);
writer.writeKey(Key::antialiasing, video.antialiasing);
writer.writeKey(Key::vsync, video.vsync);
Expand Down Expand Up @@ -468,6 +477,9 @@ bool Config::init(const fs::path & file) {
video.fullscreen = reader.getKey(Section::Video, Key::fullscreen, Default::fullscreen);
video.levelOfDetail = reader.getKey(Section::Video, Key::levelOfDetail, Default::levelOfDetail);
video.fogDistance = reader.getKey(Section::Video, Key::fogDistance, Default::fogDistance);
video.gamma = reader.getKey(Section::Video, Key::gamma, Default::gamma);
video.luminosity = reader.getKey(Section::Video, Key::luminosity, Default::luminosity);
video.contrast = reader.getKey(Section::Video, Key::contrast, Default::contrast);
video.showCrosshair = reader.getKey(Section::Video, Key::showCrosshair, Default::showCrosshair);
video.antialiasing = reader.getKey(Section::Video, Key::antialiasing, Default::antialiasing);
video.vsync = reader.getKey(Section::Video, Key::vsync, Default::vsync);
Expand Down
3 changes: 3 additions & 0 deletions src/core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ class Config {
bool fullscreen;
int levelOfDetail;
float fogDistance;
float gamma;
float luminosity;
float contrast;
bool showCrosshair;
bool antialiasing;
bool vsync;
Expand Down
1 change: 1 addition & 0 deletions src/core/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,7 @@ void runGame() {
ARX_SetAntiAliasing();
ARXMenu_Options_Video_SetFogDistance(config.video.fogDistance);
ARXMenu_Options_Video_SetDetailsQuality(config.video.levelOfDetail);
ARXMenu_Options_Video_SetGamma(config.video.gamma);
ARXMenu_Options_Audio_SetMasterVolume(config.audio.volume);
ARXMenu_Options_Audio_SetSfxVolume(config.audio.sfxVolume);
ARXMenu_Options_Audio_SetSpeechVolume(config.audio.speechVolume);
Expand Down
23 changes: 23 additions & 0 deletions src/gui/MenuPublic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,21 @@ void ARXMenu_Options_Video_SetFogDistance(int _iFog) {
config.video.fogDistance = clamp(_iFog, 0, 10);
}

void ARXMenu_Options_Video_SetGamma(int _iGamma) {
config.video.gamma = _iGamma;
mainApp->GetWindow()->setGamma(config.video.luminosity, config.video.contrast, config.video.gamma);
}

void ARXMenu_Options_Video_SetLuminosity(int _iLuminosity) {
config.video.luminosity = _iLuminosity;
mainApp->GetWindow()->setGamma(config.video.luminosity, config.video.contrast, config.video.gamma);
}

void ARXMenu_Options_Video_SetContrast(int _iContrast) {
config.video.contrast = _iContrast;
mainApp->GetWindow()->setGamma(config.video.luminosity, config.video.contrast, config.video.gamma);
}

extern long MAX_FRAME_COUNT;
extern long USEINTERNORM;
extern long DYNAMIC_NORMALS;
Expand Down Expand Up @@ -219,6 +234,9 @@ void ARXMenu_Options_Audio_ApplyGameVolumes() {

bool ARXMenu_Options_Audio_SetEAX(bool _bEnable) {

int iOldGamma = config.video.gamma;
ARXMenu_Options_Video_SetGamma((iOldGamma - 1) < 0 ? 0 : (iOldGamma - 1));

config.audio.eax = _bEnable;

ARX_SOUND_PushAnimSamples();
Expand All @@ -243,6 +261,8 @@ bool ARXMenu_Options_Audio_SetEAX(bool _bEnable) {

ARX_SOUND_PopAnimSamples();

ARXMenu_Options_Video_SetGamma(iOldGamma);

return config.audio.eax;
}

Expand Down Expand Up @@ -321,9 +341,12 @@ void ARXMenu_LoadQuest(size_t num) {
void ARXMenu_SaveQuest(const std::string & name, size_t num) {

ARX_SOUND_MixerPause(ARX_SOUND_MixerMenu);
int iOldGamma = config.video.gamma;
ARXMenu_Options_Video_SetGamma((iOldGamma - 1) < 0 ? 0 : (iOldGamma - 1));

savegames.save(name, num, savegame_thumbnail);

ARXMenu_Options_Video_SetGamma(iOldGamma);
ARX_SOUND_MixerResume(ARX_SOUND_MixerMenu);
}

Expand Down
6 changes: 6 additions & 0 deletions src/gui/MenuPublic.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
// Video options

void ARXMenu_Options_Video_SetFogDistance(int fogDistance);
void ARXMenu_Options_Video_GetTextureQuality(int & quality);
void ARXMenu_Options_Video_SetTextureQuality(int quality);
void ARXMenu_Options_Video_SetGamma(int gamma);
void ARXMenu_Options_Video_SetLuminosity(int luminosity);
void ARXMenu_Options_Video_SetContrast(int contrast);

void ARXMenu_Options_Video_SetDetailsQuality(int lod);

// Audio options
Expand Down
43 changes: 43 additions & 0 deletions src/gui/MenuWidgets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,14 @@ void ARX_QuickSave() {
return;
}

int iOldGamma = config.video.gamma;
ARXMenu_Options_Video_SetGamma((iOldGamma - 1) < 0 ? 0 : (iOldGamma - 1));

ARX_SOUND_MixerPause(ARX_SOUND_MixerGame);

savegames.quicksave(savegame_thumbnail);

ARXMenu_Options_Video_SetGamma(iOldGamma);
ARX_SOUND_MixerResume(ARX_SOUND_MixerGame);
}

Expand Down Expand Up @@ -1081,6 +1085,36 @@ bool Menu2_Render() {

pWindowMenuConsole->AddMenuCenterY(pc);

pc = new CMenuPanel();
szMenuText = getLocalised("system_menus_options_video_gamma");
me = new CMenuElementText(-1, hFontMenu, szMenuText, fPosX1, 0.f, lColor, 1.f, NOP);
me->SetCheckOff();
pc->AddElement(me);
me = new CMenuSlider(BUTTON_MENUOPTIONSVIDEO_GAMMA, iPosX2, 0);
((CMenuSlider*)me)->setValue(config.video.gamma);
pc->AddElement(me);
pWindowMenuConsole->AddMenuCenterY(pc);

pc = new CMenuPanel();
szMenuText = getLocalised("system_menus_options_video_luminosity", "luminosity");
me = new CMenuElementText(-1, hFontMenu, szMenuText, fPosX1, 0.f, lColor, 1.f, NOP);
me->SetCheckOff();
pc->AddElement(me);
me = new CMenuSlider(BUTTON_MENUOPTIONSVIDEO_LUMINOSITY, iPosX2, 0);
((CMenuSlider*)me)->setValue(config.video.luminosity);
pc->AddElement(me);
pWindowMenuConsole->AddMenuCenterY(pc);

pc = new CMenuPanel();
szMenuText = getLocalised("system_menus_options_video_contrast", "contrast");
me = new CMenuElementText(-1, hFontMenu, szMenuText, fPosX1, 0.f, lColor, 1.f, NOP);
me->SetCheckOff();
pc->AddElement(me);
me = new CMenuSlider(BUTTON_MENUOPTIONSVIDEO_CONTRAST, iPosX2, 0);
((CMenuSlider*)me)->setValue(config.video.contrast);
pc->AddElement(me);
pWindowMenuConsole->AddMenuCenterY(pc);

szMenuText = getLocalised("system_menus_options_video_crosshair", "Show Crosshair");
szMenuText += " ";
metemp = new CMenuElementText(-1, hFontMenu, szMenuText, fPosX1, 0.f, lColor, 1.f, NOP);
Expand Down Expand Up @@ -4779,6 +4813,15 @@ bool CMenuSlider::OnMouseClick(int)
case BUTTON_MENUOPTIONSVIDEO_FOG:
ARXMenu_Options_Video_SetFogDistance(iPos);
break;
case BUTTON_MENUOPTIONSVIDEO_GAMMA:
ARXMenu_Options_Video_SetGamma(iPos);
break;
case BUTTON_MENUOPTIONSVIDEO_LUMINOSITY:
ARXMenu_Options_Video_SetLuminosity(iPos);
break;
case BUTTON_MENUOPTIONSVIDEO_CONTRAST:
ARXMenu_Options_Video_SetContrast(iPos);
break;
// MENUOPTIONS_AUDIO
case BUTTON_MENUOPTIONSAUDIO_MASTER:
ARXMenu_Options_Audio_SetMasterVolume(iPos);
Expand Down
3 changes: 3 additions & 0 deletions src/gui/MenuWidgets.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ enum MenuButton {
BUTTON_MENUOPTIONSVIDEO_FULLSCREEN,
BUTTON_MENUOPTIONSVIDEO_APPLY,
BUTTON_MENUOPTIONSVIDEO_FOG,
BUTTON_MENUOPTIONSVIDEO_GAMMA,
BUTTON_MENUOPTIONSVIDEO_LUMINOSITY,
BUTTON_MENUOPTIONSVIDEO_CONTRAST,
BUTTON_MENUOPTIONSVIDEO_CROSSHAIR,
BUTTON_MENUOPTIONSVIDEO_ANTIALIASING,
BUTTON_MENUOPTIONSVIDEO_VSYNC,
Expand Down
27 changes: 27 additions & 0 deletions src/window/D3D9Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ D3D9Window::~D3D9Window() {
// Do a safe check for releasing the D3DDEVICE. RefCount must be zero.
if(GD3D9Device) {

// Restore initial gamma ramp - Needed for wine
GD3D9Device->SetGammaRamp(0, D3DSGR_NO_CALIBRATION, &initialGammaRamp);

if(0 < GD3D9Device->Release()) {
LogWarning << "D3DDevice object is still referenced";
}
Expand Down Expand Up @@ -293,6 +296,10 @@ bool D3D9Window::initialize() {
// Finally, set the viewport for the newly created device
renderer->SetViewport(Rect(GetSize().x, GetSize().y));

// Store initial gamma settings to restore them later - Needed for wine
GD3D9Device->GetGammaRamp(0, &initialGammaRamp);
GD3D9Device->GetGammaRamp(0, &currentGammaRamp);

onRendererInit();

return true;
Expand Down Expand Up @@ -336,6 +343,9 @@ void D3D9Window::restoreObjects() {
// Reload all textures
onRendererInit();

// Restore gamma settings
GD3D9Device->SetGammaRamp(0, D3DSGR_NO_CALIBRATION, &currentGammaRamp);

// Set the multisampling render state
renderer->SetAntialiasing(d3dpp.MultiSampleType != D3DMULTISAMPLE_NONE);

Expand All @@ -349,3 +359,20 @@ void D3D9Window::destroyObjects() {

onRendererShutdown();
}

void D3D9Window::setGammaRamp(const u16 * red, const u16 * green, const u16 * blue) {

if(red) {
std::copy(red, red + 256, currentGammaRamp.red);
}

if(green) {
std::copy(green, green + 256, currentGammaRamp.green);
}

if(blue) {
std::copy(blue, blue + 256, currentGammaRamp.blue);
}

GD3D9Device->SetGammaRamp(0, D3DSGR_NO_CALIBRATION, &currentGammaRamp);
}
4 changes: 4 additions & 0 deletions src/window/D3D9Window.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class D3D9Window : public Win32Window {
void setWindowSize(Vec2i size);
void restoreObjects();

void setGammaRamp(const u16 * red, const u16 * green, const u16 * blue);

private:

// Internal functions for the framework class
Expand All @@ -67,6 +69,8 @@ class D3D9Window : public Win32Window {
class D3D9Renderer* d3d9Renderer;

LPDIRECT3D9 d3d; // The Direct3D object
D3DGAMMARAMP initialGammaRamp; // Gamma ramp to restore
D3DGAMMARAMP currentGammaRamp; // Current gamma ramp
D3DPRESENT_PARAMETERS d3dpp; // Present params
};

Expand Down
33 changes: 33 additions & 0 deletions src/window/RenderWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,36 @@ void RenderWindow::onRendererShutdown() {
(*i)->onRendererShutdown(*this);
}
}

void RenderWindow::setGamma(float brightness, float contrast, float gamma) {

u16 ramp[256];

float fGammaMax = (1.f / 6.f);
float fGammaMin = 2.f;
float fGamma = ((fGammaMax - fGammaMin) / 11.f) * (gamma + 1.f) + fGammaMin;

float fLuminosityMin = -.2f;
float fLuminosityMax = .2f;
float fLuminosity = ((fLuminosityMax - fLuminosityMin) / 11.f) * (brightness + 1.f) + fLuminosityMin;

float fContrastMax = -.3f;
float fContrastMin = .3f;
float fContrast = ((fContrastMax - fContrastMin) / 11.f) * (contrast + 1.f) + fContrastMin;

float fRangeMin = 0.f + fContrast;
float fRangeMax = 1.f - fContrast;
float fdVal = (fRangeMax - fRangeMin) / 256.f;
float fVal = 0.f;

for(size_t i = 0; i < 256; i++) {

int iColor = clamp(int(65536.f * (fLuminosity + pow(fVal, fGamma))), 0, 65535);

ramp[i] = static_cast<u16>(iColor);

fVal += fdVal;
}

setGammaRamp(ramp, ramp, ramp);
}
3 changes: 3 additions & 0 deletions src/window/RenderWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ class RenderWindow : public Window {

virtual void showFrame() = 0;

virtual void setGammaRamp(const u16 * red, const u16 * green, const u16 * blue) = 0;
void setGamma(float brightness, float contrast, float gamma);

protected:

Renderer * renderer;
Expand Down
4 changes: 4 additions & 0 deletions src/window/SDLWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,10 @@ void SDLWindow::showFrame() {
SDL_GL_SwapBuffers();
}

void SDLWindow::setGammaRamp(const u16 * red, const u16 * green, const u16 * blue) {
SDL_SetGammaRamp(red, green, blue);
}

void SDLWindow::hide() {
SDL_WM_IconifyWindow();
OnShow(false);
Expand Down
2 changes: 2 additions & 0 deletions src/window/SDLWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class SDLWindow : public RenderWindow {

void showFrame();

void setGammaRamp(const u16 * red, const u16 * green, const u16 * blue);

void hide();

private:
Expand Down

2 comments on commit 4fe8a4a

@clort81
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this commit. I was wondering how to re-enable this.

However the fullscreen xgamma is a 'meh' way to do this in windowed mode. The same effect can be had with xgamma -xamma 1.1 etc.

All openGL windows should have per-window gamma. Does SDL2 not expose this for their GL windows?

@dscharrer
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not aware of any per-window gamma correction with X11 (or Wayland for that matter).

You can do your own gamma correction in shaders, but AL does not have the infrastructure set up for that yet - the renderer is still mostly OpenGL 1.5 even if it uses more modern extensions for some things if available.

Please sign in to comment.