Home > TutorialsComputer Graphics Essentials
2.10. Transparency with the alpha test 
In this tutorial you will create a cage by setting the alpha channel at a finer level with a texture.



Click here to go to the forum discussion of this tutorial


 

2.10.1. Prerequisites
default.jpg
Before you start this tutorial make sure that you have:
  • Installed XNA Game Studio 3.1
  • Downloaded the starter project from the downloads section
  • Successfully run the starter project
  • For a better understanding, is preferred to have finished the previous tutorials.
 

2.10.2. Game Assets 
Game assets [2.3.2] for this tutorial:

 

2.10.3. The using statements
Besides the using statements from the starter project, this tutorial needs the following using statements:

using BetaCell.Util.RenderStates;
using BetaCell.Environment.Mesh.Visitors;
using BetaCell.Environment;
using BetaCell.Environment.Light;
using BetaCell.Effects;
using BetaCell.Util.Procedural;
using BetaCell.Common.Vertex;
using BetaCell.Environment.Texture.Feeder;
using BetaCell.Environment.Texture
;
using BetaCell.Environment.Mesh;

 

2.10.4. Game Attributes 
The attributes that come with the starter project are explained in tutorial section 1.1.4.

For this tutorial we are going to be needing the following attributes:

BCMesh plane;
BCMesh cube;

BCAlphaGreaterRenderStrategy alphaBlock
;

 

Advertisement
 

2.10.5. The Initialize method 

default.jpg
In this tutorial we will apply the alpha channel at a finer level. Instead of setting the alpha channel in the whole material; we are going to set it with the texture in the figure; in it, white=255 and black=0 for the alpha channel.

Now, what we are going to do is create a cage; first we'll create a cube, then we'll set it's texture to the one in the figure and finally we'll draw the cube with the BCAlphaGreaterRenderStrategy strategy.

The BCAlphaGreaterRenderStrategy tells XNA to draw objects where the alpha channel is greater than a certain value; by default this value is 128 but you can set this value as you need.


The main difference between this tutorial and the 2.9 is the render strategy.

 

2.10.6. The Draw method
Now we draw the plane

plane.Draw(gameTime);

Then the cube is drawn between a push and pop calls of the alpha greater render state set strategy.

alphaBlock.push(device);
cube.Draw(gameTime);
alphaBlock.pop(device);

 

2.10.7. Conclusion
The only relevant difference between this tutorial and the last one is the render set strategy and the texture. The texture has an alpha channel; to look at it, use the texture tool that comes with the DirectX SDK.

Click here to go to the forum discussion of this tutorial

 

Advertisement
 

2.10.8. Complete source code
using System;
using System.Collections.Generic;
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.Net;
using Microsoft.Xna.Framework.Storage;

using BetaCell.Debug;
using BetaCell.Util.GlobalInfo.Content;
using BetaCell.Environment.Camera;
using BetaCell.Util.GlobalInfo;

using BetaCell.Util.RenderStates;
using BetaCell.Environment.Mesh.Visitors;
using BetaCell.Environment;
using BetaCell.Environment.Light;
using BetaCell.Effects;
using BetaCell.Util.Procedural;
using BetaCell.Common.Vertex;
using BetaCell.Environment.Texture.Feeder;
using BetaCell.Environment.Texture;
using BetaCell.Environment.Mesh;

namespace Starter
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        //Game attributes
        GraphicsDeviceManager graphics;
        GraphicsDevice device;
        ContentManager content;

        BCFirstPersonHumanCamera camera;
        //end game attributes

        //This tutorial's attributes
        BCMesh plane;
        BCMesh cube;

        BCAlphaGreaterRenderStrategy alphaBlock;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            graphics.PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8;
            content = new ContentManager(Services);
#if(XBOX360)
            graphics.PreferredBackBufferWidth = 1280;
            graphics.PreferredBackBufferHeight = 768;
#else
            graphics.PreferredBackBufferWidth = 852;
            graphics.PreferredBackBufferHeight = 480;
#endif
        }

        protected override void Initialize()
        {
            //base initialization
            device = graphics.GraphicsDevice;

            BCLogger.instance.init(device, content);
            BCInitializationManager.initialize(content);

            OnActivated(null, null);

            alphaBlock = new BCAlphaGreaterRenderStrategy();
            recreateScene();

            base.Initialize();
        }

        private void recreateScene()
        {
            BCMaterialBase material = new BCMaterialBase();
            material.specRange = 0.8f;
            material.diff = new Color(255, 255, 255, 128);
            material.spec = Color.White;
            material.amb = Color.LightGray;

            BCMaterialVisitor materialSetter = new BCMaterialVisitor(material);

            BCColorSet colorSet = new BCColorSet(Color.Black);
            BCDynamicEffectVisitor colorSetter =
                new BCDynamicEffectVisitor(colorSet.getFunction("Shader.ColorSet"), colorSet, 0);

            BCBasicLight light = new BCBasicLight();
            light.range = 2000;
            light.transform = Matrix.CreateTranslation(10, 10, 0);
            light.constAtten = 1;
            light.linAtten = 0;
            light.cubAtten = 0;
            light.spotRange = 0.9f;
            light.useShadows = false;

            BCDynamicEffectVisitor lightSetter = new BCDynamicEffectVisitor(
                light.getFunction("Shader.Light.Classic.PixelPointLight"),
                light,
                BCDynamicEffect.MAX_FUNCTIONS
            );

            //-------------
            //cube
            //-------------

            cube = ProceduralModelers.CUBE_MODELER.createCube(10, 10, 10, new BCVertexPosNorTexContainer());
            BCMeshGraphicUtil.init(cube, device);

            //Setting texture
            BCTextureVisitor textureSetter = new BCTextureVisitor(
                "tex",
                new BCMemoryTextureStrategy(content.Load<Texture2D>("Content/gameAssets/gatea"))
            );

            BCTextureFeeder texFeeder = new BCTextureFeeder();
            texFeeder.addSampler(
                "tex",
                new BCSampler(
                    "LINEAR", "LINEAR", "LINEAR", "4",
                    "WRAP", "WRAP", "0xffffffff"
                )
            );
            BCDynamicEffectVisitor textureEffectSetter = new BCDynamicEffectVisitor(
                texFeeder.getFunction("Shader.Texture.Texture"),
                texFeeder,
                BCDynamicEffect.MAX_FUNCTIONS
            );

            cube.transform = Matrix.CreateTranslation(0, 5, 0);
            cube.visit(materialSetter);
            cube.visit(textureSetter);
            cube.visit(colorSetter);
            cube.visit(lightSetter);
            cube.visit(textureEffectSetter);

            //-----
            //plane
            //-----

            textureSetter.strategy = new BCMemoryTextureStrategy("Content/gameAssets/ground0", content);

            plane = ProceduralModelers.PLANE_MODELER.createPlane(
                10, 10, 10, 10, new Vector3(0, 0, 0),
                new BCVertexPosNorTexContainer(),
                4);
            BCMeshGraphicUtil.init(plane, device);

            plane.visit(materialSetter);
            plane.visit(textureSetter);
            plane.visit(colorSetter);
            plane.visit(lightSetter);
            plane.visit(textureEffectSetter);
        }

        protected override void OnActivated(object sender, EventArgs args)
        {
            buildViewMatrix();
            base.OnActivated(sender, args);
        }

        void buildViewMatrix()
        {
            Vector3 pos = new Vector3(20, 20, 20);
            Vector3 look = new Vector3(-2, -2, -2);
            look.Normalize();

            camera = new BCFirstPersonHumanCamera(look, pos,
                MathHelper.PiOver4,
                (float)this.Window.ClientBounds.Width / (float)this.Window.ClientBounds.Height,
                1f, 200);

            BCGlobalInfo.instance.setMatrix(
                BCGlobalInfo.VIEW_INDEX,
                camera.getViewMatrix(-1)
            );

            BCGlobalInfo.instance.setMatrix(
                BCGlobalInfo.PROJECTION_INDEX,
                camera.getProjectionMatrix(-1)
            );
        }

        protected override void Update(GameTime gameTime)
        {
        }

        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.White, 1.0f, 0);

            plane.Draw(gameTime);

            alphaBlock.push(device);
            cube.Draw(gameTime);
            alphaBlock.pop(device);

            BCLogger.instance.printFPS(gameTime);
            BCLogger.instance.flush();
            base.Draw(gameTime);
        }
    }
}