Home > TutorialsComputer Graphics Essentials
2.8. Rotating textures over a mesh
In this tutorial you will apply a new effect that rotates a texture over a mesh. The code is almost the same as 2.7.



Click here to go to the forum discussion of this tutorial


 

2.8.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
   
 

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

 

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

using BetaCell.Util.GlobalInfo;
using BetaCell.Debug;
using BetaCell.Environment.Camera;
using BetaCell.Environment.Texture.Feeder;
using BetaCell.Environment.Mesh;
using BetaCell.Environment;
using BetaCell.Environment.Mesh.Visitors;
using BetaCell.Util.Procedural;
using BetaCell.Common.Vertex;
using BetaCell.Environment.Texture;
using BetaCell.Effects;
using BetaCell.Effects.Composer
;

 

2.8.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:

BCTimedTextureFeeder timedTexFeeder;
BCMesh cube
;

 

Advertisement
 

2.8.5. The Initialize method 
The initialize method of this tutorial is almost the same as the one in 2.7 because the names of the textures are the same. The function obtained from the timed texture feeder to compose the effect is the main difference:

BCFunction centricRoll =
            timedTexFeeder.getFunction("Shader.Texture.Motion.CentricRoll");


default.jpg
This function represents an effect that combines two textures, the first is rotating counterclock wise, the second clockwise. The combination is very simple, where texture 2 is white, the final color is is texture 1, where texture 2 is black, the final color is black, any value between is texture1 darkened by how black is texture 2.



 

 2.8.6. The Update method
Here we update the time in the timed texture feeder to update the texture position.

timedTexFeeder.gTime = (float)gameTime.TotalGameTime.TotalSeconds;

 

2.8.7. The Draw method
Nothing new, just draw the cube:

cube.Draw(gameTime);

 

2.8.8. Conclusion
This tutorial was a reinforcement of the texture concepts introduced in previous tutorials.

Click here to go to the forum discussion of this tutorial

 

Advertisement
 

2.8.9. 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.Environment.Texture.Feeder;
using BetaCell.Environment.Mesh;
using BetaCell.Environment;
using BetaCell.Environment.Mesh.Visitors;
using BetaCell.Util.Procedural;
using BetaCell.Common.Vertex;
using BetaCell.Environment.Texture;
using BetaCell.Effects;
using BetaCell.Effects.Composer;

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
        BCTimedTextureFeeder timedTexFeeder;
        BCMesh cube;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            graphics.PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8;
            content = new ContentManager(Services);
#if(XBOX360)
            graphics.PreferredBackBufferWidth = 1280;
            graphics.PreferredBackBufferHeight = 720;
#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);

            recreateScene();

            base.Initialize();
        }

        private void recreateScene()
        {
            BCColorSet colorSet = new BCColorSet(Color.White);
            BCDynamicEffectVisitor colorSetter =
                new BCDynamicEffectVisitor(colorSet.getFunction("Shader.ColorSet"), colorSet, 0);

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

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

            //Seating texture
            BCTextureVisitor diffuseSetter = new BCTextureVisitor(
                "tex",
                new BCMemoryTextureStrategy(content.Load<Texture2D>("Content/gameAssets/flare"))
            );

            BCTextureVisitor alphaSetter = new BCTextureVisitor(
                "tex1",
                new BCMemoryTextureStrategy(content.Load<Texture2D>("Content/gameAssets/flarealpha"))
            );

            timedTexFeeder = new BCTimedTextureFeeder();
            timedTexFeeder.addSampler(
                "tex",
                new BCSampler(
                    "LINEAR", "LINEAR", "LINEAR", "4",
                    "WRAP", "WRAP", "0xffffffff"
                )
            );
            timedTexFeeder.addSampler(
                "tex1",
                new BCSampler(
                    "LINEAR", "LINEAR", "LINEAR", "4",
                    "WRAP", "WRAP", "0xffffffff"
                )
            );

            BCFunction centricRoll = timedTexFeeder.getFunction("Shader.Texture.Motion.CentricRoll");
            BCDynamicEffectVisitor textureEffectSetter =
                new BCDynamicEffectVisitor(centricRoll, timedTexFeeder, BCDynamicEffect.MAX_FUNCTIONS);

            cube.visit(diffuseSetter);
            cube.visit(alphaSetter);
            cube.visit(colorSetter);
            cube.visit(textureEffectSetter);
        }

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

        void buildViewMatrix()
        {
            Vector3 pos = new Vector3(15, 15, 15);
            Vector3 look = new Vector3(-1, -1, -1);
            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)
        {
            timedTexFeeder.gTime = (float)gameTime.TotalGameTime.TotalSeconds;
        }

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

            cube.Draw(gameTime);

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