2011-07-27 5 views
2

슬라이딩 메뉴를 만들려고합니다 ... 원형 이미지에서 사용자가 아이콘을 터치하고 슬라이드하여 (예 : 현대 휴대 전화 또는 카지노 머신의 과일 등 ...)XNA 4.0 - 알파 및 다중 텍스처 ... 엉망진창

나는 투명한 원을 가지고 있으며, 3 개의 아이콘을 말할 수 있습니다 ... 어떻게 그런 식으로 그들을 혼합합니까?

항목 :

http://i52.tinypic.com/rcn67s.jpg

문제 :

http://i52.tinypic.com/i77nrk.jpg

내가 그들을 위해 함께 하나의 SpriteBatch 하나에 의해 그려진 얻을 수 있습니다하지만 어떻게 그런 식으로 그들을 혼합

?

내가 그 일이 쉽지하다는 것을 느낄 수 있습니다 미안하지만 난 붙어입니다 ..

감사합니다!

답변

4

내가 해냈어 ... 방법은 다음과 같습니다

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Audio; 
using Microsoft.Xna.Framework.Content; 
using Microsoft.Xna.Framework.GamerServices; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework.Input; 
using Microsoft.Xna.Framework.Media; 

namespace StencilTest 
{ 
    public class Game1 : Microsoft.Xna.Framework.Game 
    { 
     GraphicsDeviceManager graphics; 
     SpriteBatch spriteBatch; 

     Texture2D star, cloud, shape; 
     AlphaTestEffect alphaTestEffect; 
     DepthStencilState stencilAlways; 
     DepthStencilState stencilKeep; 
     RenderTarget2D rt; 

     public Game1() 
     { 
      graphics = new GraphicsDeviceManager(this); 
      Content.RootDirectory = "Content"; 

      graphics.PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8; 

      graphics.PreferredBackBufferWidth = 800; 
      graphics.PreferredBackBufferHeight = 600; 

      IsMouseVisible = true; 
     } 

     protected override void Initialize() 
     { 
      base.Initialize(); 
     } 

     Texture2D grass; 

     protected override void LoadContent() 
     { 
      // Create a new SpriteBatch, which can be used to draw textures. 
      spriteBatch = new SpriteBatch(GraphicsDevice); 
      star = Content.Load<Texture2D>("star1"); 
      cloud = Content.Load<Texture2D>("cloud1"); 
      shape = Content.Load<Texture2D>("shape"); 
      back = Content.Load<Texture2D>("back"); 
      grass = Content.Load<Texture2D>("grass1"); 

      Matrix projection = Matrix.CreateOrthographicOffCenter(0, shape.Width, shape.Height, 0, 0, 1); 
      Matrix halfPixelOffset = Matrix.CreateTranslation(-0.5f, -0.5f, 0); 

      alphaTestEffect = new AlphaTestEffect(GraphicsDevice); 
      alphaTestEffect.VertexColorEnabled = true; 
      alphaTestEffect.DiffuseColor = Color.White.ToVector3(); 
      alphaTestEffect.AlphaFunction = CompareFunction.Equal; 
      alphaTestEffect.ReferenceAlpha = 0; 
      alphaTestEffect.World = Matrix.Identity; 
      alphaTestEffect.View = Matrix.Identity; 
      alphaTestEffect.Projection = halfPixelOffset * projection; 

      // set up stencil state to always replace stencil buffer with 1 
      stencilAlways = new DepthStencilState(); 
      stencilAlways.StencilEnable = true; 
      stencilAlways.StencilFunction = CompareFunction.Always; 
      stencilAlways.StencilPass = StencilOperation.Replace; 
      stencilAlways.ReferenceStencil = 1; 
      stencilAlways.DepthBufferEnable = false; 

      // set up stencil state to pass if the stencil value is 1 
      stencilKeep = new DepthStencilState(); 
      stencilKeep.StencilEnable = true; 
      stencilKeep.StencilFunction = CompareFunction.Equal; 
      stencilKeep.StencilPass = StencilOperation.Keep; 
      stencilKeep.ReferenceStencil = 1; 
      stencilKeep.DepthBufferEnable = false; 

      rt = new RenderTarget2D(GraphicsDevice, shape.Width, shape.Height, 
            false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8, 
            0, RenderTargetUsage.DiscardContents); 
     } 

     protected override void UnloadContent() 
     { 

     } 

     protected override void Update(GameTime gameTime) 
     { 
      // Allows the game to exit 
      if (Keyboard.GetState().IsKeyDown(Keys.Escape)) 
       this.Exit(); 

      // TODO: Add your update logic here 

      base.Update(gameTime); 
     } 

     float angle = 0f; 
     private Texture2D back; 
     Vector2 pos = new Vector2(400, 300); 
     float cloudscale = 0.25f; 

     protected override void Draw(GameTime gameTime) 
     { 

      // set up rendering to the active render target 
      GraphicsDevice.SetRenderTarget(rt); 

      // clear the render target to opaque black, 
      // and initialize the stencil buffer with all zeroes 
      GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.Stencil, 
           new Color(0, 0, 0, 1), 0, 0); 

      spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, 
         null, stencilAlways, null, alphaTestEffect); 

      spriteBatch.Draw(shape, Vector2.Zero, null, Color.White, 0f, 
          Vector2.Zero, 1f, SpriteEffects.None, 0f); 

      spriteBatch.End(); 

      spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, 
        null, stencilKeep, null, null); 

      //for (int i = 0; i < Math.Ceiling(800/(cloud.Width * cloudscale)); i++) 
      // for (int j = 0; j < Math.Ceiling(600/(cloud.Height * cloudscale)); j++) 
      //  spriteBatch.Draw(cloud, Vector2.Zero + new Vector2(i * cloud.Width * cloudscale, j * cloud.Height * cloudscale), null, Color.White, 0f, 
      //   Vector2.Zero, cloudscale, SpriteEffects.None, 0f); 

      spriteBatch.Draw(grass, new Vector2(rt.Width/2, rt.Height/2) + new Vector2(0f, -100f), null, Color.White, 0f, 
     new Vector2(grass.Width/2, grass.Height/2), .85f, SpriteEffects.None, 0f); 

      spriteBatch.Draw(cloud, new Vector2(rt.Width/2, rt.Height/2), null, Color.White, 0f, 
        new Vector2(cloud.Width/2, cloud.Height/2), 1f, SpriteEffects.None, 0f); 

      spriteBatch.Draw(star, new Vector2(rt.Width/2, rt.Height/2) + new Vector2(0f, 100f), null, Color.White, 0f, 
     new Vector2(star.Width/2, star.Height/2), .85f, SpriteEffects.None, 0f); 

      spriteBatch.End(); 

      GraphicsDevice.SetRenderTarget(null); 

      spriteBatch.Begin(); 

      spriteBatch.Draw(back, Vector2.Zero, null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); 

      spriteBatch.Draw(rt, pos + new Vector2(50f * (float)Math.Cos(MathHelper.ToRadians(angle)), 50f * (float)Math.Sin(MathHelper.ToRadians(angle))), null, Color.White, 0f, new Vector2(rt.Width/2, rt.Height/2), 1f, SpriteEffects.None, 0f); 

      spriteBatch.End(); 

      // TODO: Add your drawing code here 

      angle +=0.5f; 

      base.Draw(gameTime); 
     } 
    } 
} 
0

원을 더 크게 만들어서 아래에 아무것도 표시하지 않고 위에 놓을 수 없습니까?

+1

이것은 가장 쉬운 솔루션입니다. 그리고 제가 추가 할 수 있다면 : 가위 사각형을 사용하여 (또는 뷰포트를 변경하여) 덮어 씌울 영역을 줄일 수 있습니다. 그러나 원래의 질문에 따라 임의의 컷 아웃을 수행 할 수있는 BlendState (또는, DepthStencilState) 시퀀스를 사용하는 솔루션도 존재합니다. –

+2

스텐실 버퍼를 사용하는 것이 가장 유연한 솔루션입니다. 숀 하그리브스 (Shawn Hargreaves)는 멋진 간단한 코드로 게시물을 가지고 있습니다 : [http://blogs.msdn.com/b/shawnhar/archive/2007/05/17/transitions-part-three-stencil-swipes.aspx](http:/) /blogs.msdn.com/b/shawnhar/archive/2007/05/17/transitions-part-three-stencil-swipes.aspx) – Aranda

+0

친애하는 Aranda/Andrew, 친절한 도움에 많은 감사를드립니다. 나는 지금 그 사람들에게 초점을 맞추고 가능한 한 빨리 여기에 해결책을 제시 할 것입니다. – JML