|
|
|
|
|
Up till now, the only way you’ve seen to add some color to your scene is to declare separate vertices for every different color. Of course, this is not the way today’s great games are being made. DirectX supports a very efficient way of adding images to the scene: you can simply put an image on a triangle. These kind of images are called textures.
As a first example, we’re going to draw 1 simple triangle, and paste a texture over it. You can find a sample texture here (link) (you can download the image as a file by right-clicking on the image, and selecting Save Image). So once again we’re going to define 3 vertices, which we’ll store in an array. This time, the vertex format will be PositionTextured, so declare this variable at the top of your code:
private CustomVertex.PositionTextured[] vertices;
Next we’ll be defining the 3 vertices of our triangle in our VertexDeclarartion method:
private void VertexDeclaration() { vertices = new CustomVertex.PositionTextured[3]; vertices[0].Position = new Vector3(10f, 10f, 0f); vertices[0].Tu = 0; vertices[0].Tv = 0; vertices[1].Position = new Vector3(-10f, -10f, 0f); vertices[1].Tu = 1; vertices[1].Tv = 1; vertices[2].Position = new Vector3(10f, -10f, 0f); vertices[2].Tu = 0; vertices[2].Tv = 1; }
As you see, for every vertex we first define its position. Notice again that we have defined our vertices in a clockwise way, so DirectX will not cull them. The next 2 settings define which point in our texture image we want to correspond with the vertex. These u and v coordinates are simply the 2 coordinates of the texture, with the (0,0) point being the top left point of the texture image. Don’t forget to call the VertexDeclaration method from your Main method:
our_directx_form.VertexDeclaration();
Now we have our vertex data, we can already try to display them by modifying the OnPaint method. So put these lines between your calls to BeginScene and EndScene:
device.VertexFormat = CustomVertex.PositionTextured.Format; device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, vertices);
You can find more info on these lines in Series 1. This code should already be runnable, although the only thing you’ll see on your screen is a solid white triangle. This is because we haven’t yet declared which texture image DirectX has to use!
First we’ll have to define 2 variables. One to hold the texture, the other one to store the material. With a material type you can set how the surface of your triangle should reflect light. Put these lines at the top of your code:
private Texture texture; private Material material;
Now we’ll be creating a new small method, LoadTexturesAndMaterials, that sets the active texture image on the device:
private void LoadTexturesAndMaterials() { material = new Material(); material.Diffuse = Color.White; material.Specular = Color.LightGray; material.SpecularSharpness = 15.0F; device.Material = material; texture = TextureLoader.FromFile(device, "riemerstexture.bmp"); }
First you create a material and set a few properties. These 2 setting in fact only matter when using lights, so we’ll get back to them in a later chapter where we combine textures and lights. Now we only have to set the material as the current active material of the device in our OnPaint method, before we draw our triangle:
device.SetTexture(0,texture);
Concerning the texture, we simply load the image from the file into the texture variable, and again set the texture as the active texture on the device. If these lines give an error like ‘The name 'TextureLoader' does not exist in the current context’, add a reference to Microsoft.Direct3DX to solve your problem!
Again, call this method from the main method:
our_directx_form.LoadTexturesAndMaterials();
Running this should give you a triangle, displaying half of the texture image! To display the whole image, we simply have to expand our VertexDeclaration method:
private void VertexDeclaration() { vertices = new CustomVertex.PositionTextured[6]; vertices[0].Position = new Vector3(10f,10f,0f); vertices[0].Tu = 0; vertices[0].Tv = 1; vertices[1].Position = new Vector3(-10f,-10f,0f); vertices[1].Tu = 1; vertices[1].Tv = 1; vertices[2].Position = new Vector3(10f,-10f,0f); vertices[2].Tu = 0; vertices[2].Tv = 0; vertices[3].Position = new Vector3(-10.1f,-9.9f,0f); vertices[3].Tu = 1; vertices[3].Tv = 1; vertices[4].Position = new Vector3(9.9f,10.1f,0f); vertices[4].Tu = 0; vertices[4].Tv = 0; vertices[5].Position = new Vector3(-10.1f,10.1f,0f); vertices[5].Tu = 1; vertices[5].Tv = 0; }
We simply added another set of 3 vertices for a second triangle, to complete the texture image. Don’t forget to adjust your OnPaint method so the 2 triangles will be drawn:
device.DrawUserPrimitives(PrimitiveType.TriangleList, 2, vertices);
Now run this code, and you should see the whole texture image, displayed by 2 triangles!

Click here to go to the forum on this chapter!
Or click on one of the topics on this chapter to go there: texture problem i placed the image.bmp in the debug file
but also...problem in texture i have headach problem in texture...Charge 2 image I need charge two image in the screen , how can i ...How to delete a texture Hi:
I want to know how I can delete or release ...Texturing a cube with indexed vertices Hi!
Can anyone help me with this problem? It se...Upside-Down Triangle has this happened to anyone else?
I followed the ...Materials Just a question that I was curious about..
The ot..."Join Line" using textures. Hi,
I've come across a bit of an annoying prob...Texturing a terrain? Hi!
How I can texturing or adding a terrain in tu...InvalidDataException??? HI!
The following message shows up, when I comp...texture doesnt fit How do I get a texture that is oddly shaped to fit...texture Where am i supposed to save the bitmap to? Is it s...Problem with TextureLoader When I try to compile the program, it gives me the...textureloader problem when I try to run texture program in season 2. I g...Display An Image File Faster Hi.
I've tried to use a Sprite to draw images on...Display Image File on Screen Now I use two TransformedTextured triangles to dis...TransformedTextured Hi, I want to use TransformedTextured vertices to ...
You’ll notice the small gap between both triangles.. This is of course because I defined the vertices that way, so you can actually see the image is made out of two separate triangles. Try to remove the gap between the triangles yourself. Also, try playing with the U and V coordinates, it’s worth it!! You can choose any value between 0 and 1.
The code for displaying this texture:
using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; using D3D = Microsoft.DirectX.Direct3D; namespace DirectX_Tutorial { public class WinForm : System.Windows.Forms.Form { private System.ComponentModel.Container components = null; private D3D.Device device;
private CustomVertex.PositionTextured[] vertices; private Texture texture; private Material material;
public WinForm() { InitializeComponent(); this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true); } public void InitializeDevice() { PresentParameters presentParams = new PresentParameters(); presentParams.Windowed = true; presentParams.SwapEffect = SwapEffect.Discard; presentParams.AutoDepthStencilFormat = DepthFormat.D16; presentParams.EnableAutoDepthStencil = true; device = new D3D.Device(0, D3D.DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams); device.RenderState.Lighting = false; } protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) { device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.DarkSlateBlue, 1.0f, 0); device.BeginScene();
device.VertexFormat = CustomVertex.PositionTextured.Format; device.SetTexture(0, texture); device.DrawUserPrimitives(PrimitiveType.TriangleList, 2, vertices);
device.EndScene(); device.Present(); this.Invalidate(); } private void SetUpCamera() { device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 0.3f, 500f); device.Transform.View = Matrix.LookAtLH(new Vector3(0, 0, 30), new Vector3(0, 0, 0), new Vector3(0, 1, 0)); }
private void VertexDeclaration() { vertices = new CustomVertex.PositionTextured[6]; vertices[0].Position = new Vector3(10f, 10f, 0f); vertices[0].Tu = 0; vertices[0].Tv = 0; vertices[1].Position = new Vector3(-10f, -10f, 0f); vertices[1].Tu = 1; vertices[1].Tv = 1; vertices[2].Position = new Vector3(10f, -10f, 0f); vertices[2].Tu = 0; vertices[2].Tv = 1; vertices[3].Position = new Vector3(-10.1f, -9.9f, 0f); vertices[3].Tu = 1; vertices[3].Tv = 1; vertices[4].Position = new Vector3(9.9f, 10.1f, 0f); vertices[4].Tu = 0; vertices[4].Tv = 0; vertices[5].Position = new Vector3(-10.1f, 10.1f, 0f); vertices[5].Tu = 1; vertices[5].Tv = 0; } private void LoadTexturesAndMaterials() { material = new Material(); material.Diffuse = Color.White; material.Specular = Color.LightGray; material.SpecularSharpness = 15.0F; device.Material = material; texture = TextureLoader.FromFile(device, "riemerstexture.bmp"); }
protected override void Dispose(bool disposing) { if (disposing) { if (components != null) { components.Dispose(); } } base.Dispose(disposing); } private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.Size = new System.Drawing.Size(500, 500); this.Text = "Riemer's DirectX Tutorial using C# -- Season 2"; } static void Main() { using (WinForm our_directx_form = new WinForm()) { our_directx_form.InitializeDevice(); our_directx_form.SetUpCamera();
our_directx_form.VertexDeclaration(); our_directx_form.LoadTexturesAndMaterials();
Application.Run(our_directx_form); } } } }
- Website design & XNA + DirectX code : Riemer Grootjans - ©2003 - 2008 Riemer Grootjans
|
|
|
|
|