Mash
Mash

Reputation: 43

XNA Framework: Manipulating screen brightness

I am working on a project for Game with XNA Framework.

I am using a OptionsMenuScreen class to display different game options/settings to the user.

I have added two UP and DOWN buttons (Texture2D) on the screen that would increase or decrease the screen's brightness.

I am not able to find the logic I would need to use to manipulate the brightness of the screen.

I would really appreciate if you can please point me into the right direction.

Here is the relevant code:


class OptionsMenuScreen : MenuScreen
{
    SpriteBatch spriteBatch;

    MenuEntry brightness;
    Texture2D brightnessUp;
    Texture2D brightnessDown;

    ContentManager contentManager;

    public OptionsMenuScreen() : base("Options")
    {
        brightness = new MenuEntry("Brightness");
        MenuEntries.Add(brightness);
    }

    public override void LoadContent()
    {
        if (contentManager == null)
        {
            contentManager = new ContentManager(ScreenManager.Game.Services, "Content");
        }

        brightnessUp = contentManager.Load<Texture2D>("handup");
        brightnessDown = contentManager.Load<Texture2D>("handdown");
    }

    public override void Draw(GameTime gameTime)
    {
        spriteBatch = ScreenManager.SpriteBatch;

        var brightnessDownPosition =
            new Vector2(brightness.Position.X - 50, brightness.Position.Y - 12);

        var brightnessUpPosition =
            new Vector2(brightness.Position.X 
                + brightness.GetWidth(this) + 8, brightness.Position.Y - 12);

        spriteBatch.Begin();

        spriteBatch.Draw(brightnessDown,
            new Rectangle((int)brightnessDownPosition.X, (int)brightnessDownPosition.Y,
                30, 30), Color.White);

        spriteBatch.Draw(brightnessUp,
            new Rectangle((int)brightnessUpPosition.X, (int)brightnessUpPosition.Y,
                30, 30), Color.White);

        spriteBatch.End();

        base.Draw(gameTime);
    }

    public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
    {
        base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);

        foreach (TouchLocation t in TouchPanel.GetState())
        {
            if (t.Position.X >= brightnessDown.Bounds.Left
                && t.Position.X <= brightnessDown.Bounds.Right
                && t.Position.Y >= brightnessDown.Bounds.Top
                && t.Position.X <= brightnessDown.Bounds.Bottom)
            {
                // What should I do here?
            }
            else if (t.Position.X >= brightnessUp.Bounds.Left
                && t.Position.X <= brightnessUp.Bounds.Right
                && t.Position.Y >= brightnessUp.Bounds.Top
                && t.Position.X <= brightnessUp.Bounds.Bottom)
            {
                // What should I do here?
            }
        }
    }
}

Thanks a lot for looking into this :)

Upvotes: 3

Views: 2022

Answers (1)

Merlyn Morgan-Graham
Merlyn Morgan-Graham

Reputation: 59151

According to this thread, there are several ways you can go about it:

  • Use GraphicsDevice.SetGammaRamp(...)
  • Use a black texture and alpha transparency
  • Adjust materials and/or lights on textures for all objects in the scene
  • Per-pixel color recalculation using a pixel shader

The first option is the easiest, but has some drawbacks (ugly graphical effects while you're setting it up - mostly effects just the options menu), and isn't always supported.

You could use SupportsFullScreenGamma and CanCalibrateGamma to determine if it is supported, and fall back to another method if it isn't.

Edit

On Windows Phone 7, some of these options might not be available to you.

That site (currently broken, but if you google it you can find a cached copy) suggests you use the full-screen quad with alpha blending approach, with these specific blending modes:

Brightness: source = ZERO, dest = SOURCECOLOR
Contrast: source = DESTCOLOR, dest = SOURCECOLOR

Here's some code (stolen from that article):

// In your game class:

Texture2D whiteTexture;

// In LoadContent:

whiteTexture = new Texture2D(GraphicsDevice, 1, 1);
whiteTexture.SetData<Color>(new Color[] { Color.White });

// In the appropriate class (the game class? not sure...):

int brightness;
int contrast;

BlendState brightnessBlend;
BlendState contrastBlend;

// In Initialize:

brightness = 255;
contrast = 128;

brightnessBlend = new BlendState();
brightnessBlend.ColorSourceBlend = brightnessBlend.AlphaSourceBlend =  Blend.Zero;
brightnessBlend.ColorDestinationBlend = brightnessBlend.AlphaDestinationBlend = Blend.SourceColor;

contrastBlend = new BlendState();
contrastBlend.ColorSourceBlend = contrastBlend.AlphaSourceBlend = Blend.DestinationColor;
contrastBlend.ColorDestinationBlend = contrastBlend.AlphaDestinationBlend = Blend.SourceColor;

// In Draw:

spriteBatch.Begin(SpriteSortMode.Immediate, brightnessBlend);
spriteBatch.Draw(whiteTexture, new Rectangle(0, 0, 480, 800), new Color (brightness, brightness, brightness, 255));
spriteBatch.End();

spriteBatch.Begin(SpriteSortMode.Immediate, contrastBlend);
spriteBatch.Draw(whiteTexture, new Rectangle(0, 0, 480, 800), new Color(contrast, contrast, contrast, 255));
spriteBatch.End();

GraphicsDevice.BlendState = BlendState.Opaque;

Upvotes: 3

Related Questions