Logo
programming4us
programming4us
programming4us
programming4us
Home
programming4us
XP
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server
programming4us
Windows Phone
 
Windows Phone

Developing for Windows Phone and Xbox Live : Using BasicEffect (part 2) - Textures, Vertex Colors, and Fog

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
6/5/2011 4:58:21 PM

Textures, Vertex Colors, and Fog

The basic effect also handles rendering a texture. If the model you are loading from the content pipeline includes textures, they are included as part of your model and rendered automatically. If they aren’t included, you can control that directly through the effect. To do this, add a new texture variable:

Texture2D texture;

To include a texture to load, add the file cat.jpg from your content project. Next, in your LoadContent method, switch the model you’re loading back to the box you used earlier. Remove the lighting code you used for the emissive color example, and create the texture and set it to the effect, as follows:

texture = Content.Load<Texture2D>("cat");
effect.TextureEnabled = true;
effect.Texture = texture;

Running the application shows you the box again, except this time you see each face of the box covered in the cat (see Figure 6).

Figure 6. A textured box

Notice that each face of the box looks the same. Because you’re using BasicEffect, you can use the other features as well. Add the standard lighting rig in your LoadContent method:

effect.EnableDefaultLighting();

The top of box is now slightly lighter than the other two faces due to the lighting. If you had a different model, you would see the specular highlights on it. You don’t see them because you rendered a cube, which has only a small number of vertices.

You’re almost done with the BasicEffect class. You can also use this effect for rendering vertex colors that are baked into the model. First, delete the code in your LoadContent method after the view and projection matrices are set, and add the following line:

effect.VertexColorEnabled = true;

This turns on the mode to render with vertex colors enabled. If you run the application, you see a black square-like blob. This is because the box model has no vertex colors in it. Let’s modify the model to add vertex colors. Add a new vertex buffer variable that will hold the updated data:

VertexBuffer vb;

Before you create the vertex buffer to hold the updated data, define the structure for what kind of data it will hold. The structure does not exist, so you need to create it. Add the following lines to your project:

struct VertexColor : IVertexType
{
public Vector3 Position;
public Vector3 Normal;
public Vector2 UV;
public Color Color;
public static readonly VertexDeclaration _decl = new VertexDeclaration(
new VertexElement(0, VertexElementFormat.Vector3,
VertexElementUsage.Position, 0),
new VertexElement(12, VertexElementFormat.Vector3,
VertexElementUsage.Normal, 0),
new VertexElement(24, VertexElementFormat.Vector2,
VertexElementUsage.TextureCoordinate, 0),
new VertexElement(32, VertexElementFormat.Color,
VertexElementUsage.Color, 0));
public VertexColor(VertexPositionNormalTexture data)
{
Position = data.Position;
Normal = data.Normal;
UV = data.TextureCoordinate;
Color = Color.White;
}
public VertexDeclaration VertexDeclaration
{
get { return _decl; }
}
}


Whew, that’s a lot of information, so let’s break it down. First, notice that the structure expects to implement IVertexType. This is used to describe the data to the graphics device, and has only one method to get the VertexDeclaration. Next, you have the actual data you want to store. The current box has three pieces of data it stores: the position of each vertex, the normal of each vertex, and the texture coordinates of each vertex. You keep these three, but you also add the color.

Next, you create a static VertexDeclaration (so you don’t create a new one every time you use the property that the interface implementation requires). This is done by describing the data this structure has in a language the graphics device understands. This is done through an array of VertexElement, with each of the members in the array describing a piece of the data that will be held. Let’s look at the VertexElement constructor that’s used here.

The first parameter of the constructor is the offset of the data (in bytes) from the beginning of the vertex. For the first member, use zero; for the second member, use 12. This is because the first piece of data is a Vector3, which contains three floats that are each four bytes large, and three times four is 12. The others are calculated in the same manner. The second parameter in the constructor is the format of the data. In your first two members, your data is in the Vector3 format. Your third member is a Vector2, and the last is a Color. This parameter tells the graphics device how much data is required for each member.

The third parameter of the constructor is how the effects will use this data. In the first member, it is a Position, the second is a Normal, the third is a TextureCoordinate, and the last is a Color. You can ignore the last parameter for now—just use zero.

There is then a constructor on the structure itself taking in the data type of vertices in the model, VertexPositionNormalTexture, which uses the old data. This constructor simply sets the default color to white, and then uses the data from the passed in structure to fill out the current structure.

This describes the new data, so let’s take a look at creating the vertex buffer and filling it up with good data. Add the following lines to the end of your LoadContent method:

int numberVertices = model.Meshes[0].MeshParts[0].NumVertices;
vb = new VertexBuffer(GraphicsDevice, typeof(VertexColor),
numberVertices, BufferUsage.None);
VertexPositionNormalTexture[] data =
new VertexPositionNormalTexture[numberVertices];
VertexColor[] newData = new VertexColor[numberVertices];
model.Meshes[0].MeshParts[0].VertexBuffer.GetData <VertexPositionNormalTexture>(data);
// Copy the data
for (int i = 0; i < numberVertices; i++)
{
newData[i] = new VertexColor(data[i]);
newData[i].Color = Color.Red;
}
vb.SetData<VertexColor>(newData);


The box model you used has exactly one mesh with one mesh part in it, so getting the total number of vertices here is easy. You have to do a bit more work to make this more generic, which is beyond the scope of this example. You can then create your new vertex buffer using the type of structure you previously defined that dictates what type of data you’re using.

Now you need to get the old data from the model. First, create two new arrays of vertices: one of the type VertexPositionNormalTexture, which is the type of data currently in the model, and the other of type VertexColor, the new data you use. Then, you can simply call the GetData method passing in the first array to have the model’s data push into that array. You then can use the for loop to go through each of pieces of old data, filling up the new data and setting the vertex color to red. Finally, call SetData on your vertex buffer to fill it with the newly created data including the vertex color.

You’re not quite ready to render yet because your current DrawModel call uses the model’s vertex buffer, not the one you just created. Add the following method to draw with a specific vertex buffer:

private void DrawModelWithVertexBuffer(Model m, VertexBuffer v,
Matrix world, BasicEffect be)
{
foreach (ModelMesh mm in model.Meshes)
{
foreach (ModelMeshPart mmp in mm.MeshParts)
{
be.World = GetParentTransform(m, mm.ParentBone) * world;
GraphicsDevice.SetVertexBuffer(v, 0);
GraphicsDevice.Indices = mmp.IndexBuffer;
be.CurrentTechnique.Passes[0].Apply();
GraphicsDevice.DrawIndexedPrimitives(
PrimitiveType.TriangleList, 0, 0,
mmp.NumVertices, mmp.StartIndex, mmp.PrimitiveCount);
}
}
}

This is almost identical to the previous DrawModel call; it uses the passed in vertex buffer instead. Update your Draw method to call this instead of DrawModel, and notice the black box is now a red box. However, just like everything else, this effect can be combined with all the other effects. For example, to see the box shaded by the standard lighting rig, add the following line after your SetData call in LoadContent:

effect.EnableDefaultLighting();

You can texture this as well by adding the following code:

texture = Content.Load<Texture2D>("cat");
effect.Texture = texture;
effect.TextureEnabled = true;

Now, the box with the cat picture has everything shaded red. If you change the previous vertex color to blue, everything is shaded blue.

The last thing to talk about is the fog effect. Your project is a bit crowded, so to show this, replace your LoadContent method with the following lines:

protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
model = Content.Load<Model>("sphere");
effect = new BasicEffect(GraphicsDevice);
effect.Projection = Matrix.CreatePerspectiveFieldOfView(
MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 1.0f, 100.0f);
effect.View = Matrix.CreateLookAt(
new Vector3(0, 8, 22), Vector3.Zero, Vector3.Up);
effect.EnableDefaultLighting();
effect.SpecularColor = Vector3.Zero;
effect.PreferPerPixelLighting = true;
effect.FogColor = Color.Red.ToVector3();
effect.FogEnabled = true;
effect.FogStart = 10.0f;
effect.FogEnd = 40.0f;
}


The majority of the previous code should be old hat by now. You switched back to the sphere to see the effect slightly better. You modified the view matrix to be a little bit higher and quite a bit farther away, and then turned on the standard lighting rig. Setting the specular color back to black isn’t necessary, but it’s easier to see the effect without the specular highlights.

Next, let’s set the four fog parameters. Enabling the fog is pretty straightforward, as is setting the color. The start and end parameters determine where the fog effect starts and where it ends, although “end” is a bit of a misnomer. These numbers are distances from the camera, where everything closer than the start value has no fog effect, everything beyond the end value has the full fog effect, and everything in between those values scale linearly between no effect and full effect.

It is easier to visualize this by seeing it in action, so let’s update the Draw method to render some spheres. Delete everything from this method except the Clear call and add the following lines:

const int NumberSpheres = 55;
for (int i = 0; i < NumberSpheres; i++)
{
Matrix world =Matrix.CreateTranslation(
((i % 5) - 2) * 4, 0, (i/5-3) * -4);
DrawModel(model, world, effect);
}

This renders a set of fifty-five spheres across the screen (you can change the constant to lower/raise the amount you are rendering). The spheres start close to the screen, and every set of five moves the next set a bit farther from the camera. Eventually, as you get ten units away, the spheres start having a red tint. The farther way they get from the camera, the moreof the tint they get until they’re completely red (see Figure 7).

Figure 7. A first look at fog

Fog adds another way to set the final color of objects in the world. By using fog, you can make objects appear to “disappear” the farther away they are. Using red doesn’t make that apparent, but go back and change the FogColor in your LoadContent method to CornflowerBlue. Much like you see in Figure 8, the farthest spheres simply disappear, while the ones in the fog range appear to be faded.

Figure 8. Spheres disappearing in fog

As before, all of these effects that BasicEffect uses can be combined with each other. To show this, switch your model back to the box, and add the following to the end of the LoadContent method:

texture = Content.Load<Texture2D>("cat");
effect.TextureEnabled = true;
effect.Texture = texture;

Notice your spheres are replaced with boxes that have pictures of cats on them, and they slowly fade out into the distance (see Figure 9).

Figure 9. Textured boxes disappearing in fog

As you can see, BasicEffect does quite a bit. Before moving on to the other built-in effects, let’s take a few minutes to see the interfaces it uses.

Other -----------------
- Developing for Windows Phone and Xbox Live : Camera Types & Models
- Developing for Windows Phone and Xbox Live : Projection Matrix
- Developing for Windows Phone and Xbox Live : View Matrix
- Programming Windows Phone 7 : Pivot and Panorama - The XNA Music Classes: MediaPlayer
- Programming Windows Phone 7 : Pivot and Panorama - Displaying the Albums
- Programming Windows Phone 7 : Pivot and Panorama - The XNA Music Classes: MediaLibrary
- Programming Windows Phone 7 : Pivot and Panorama - The XNA Connection
- Programming Windows Phone 7 : Pivot and Panorama - Music by Composer
- Programming Windows Phone 7 : Pivot and Panorama - Compare and Contrast
- Programming Windows Phone 7 : Elements and Properties - Modes of Opacity
 
 
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
 
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server