XNA框架:操纵屏幕亮度

本文关键字:屏幕 亮度 操纵 框架 XNA | 更新日期: 2023-09-27 18:16:31

我正在做一个使用XNA框架的游戏项目。

我使用OptionsMenuScreen类向用户显示不同的游戏选项/设置。

我在屏幕上添加了两个UPDOWN按钮(Texture2D),可以增加或减少屏幕的亮度。

我无法找到我需要用来操纵屏幕亮度的逻辑。

如果您能给我指一下正确的方向,我将非常感激。

相关代码如下:


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?
            }
        }
    }
}

非常感谢你的调查:)

XNA框架:操纵屏幕亮度

根据这个帖子,有几种方法可以做到:

  • 使用GraphicsDevice.SetGammaRamp(...)
  • 使用黑色纹理和alpha透明度
  • 调整场景中所有对象的材质和/或纹理上的灯光
  • 使用像素着色器重新计算逐像素颜色

第一个选项是最简单的,但有一些缺点(设置时的图形效果很难看——主要是选项菜单的效果),并且并不总是支持。

您可以使用SupportsFullScreenGammaCanCalibrateGamma来确定是否支持,如果不支持,则退回到另一个方法。

编辑

在Windows Phone 7上,你可能无法使用这些选项。

该网站(目前坏了,但如果你谷歌它,你可以找到一个缓存的副本)建议你使用全屏四边形与alpha混合方法,与这些特定的混合模式:

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

下面是一些代码(从那篇文章中偷来的):

// 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;