1 Texture Chapter 6. 2 What is Texture? Texture is a D3D interface that can map a partial of a...
-
Upload
primrose-bond -
Category
Documents
-
view
216 -
download
0
Transcript of 1 Texture Chapter 6. 2 What is Texture? Texture is a D3D interface that can map a partial of a...
1
Texture
Chapter 6
2
What is Texture?Texture is a D3D interface that can map a partial of a picture to a 3D space by using Texture coordinates. The following code loads a picture file data to a Texture object
Texture texture;private bool InitTexture(){
try {texture =TextureLoader.FromFile(device,"number.bmp"); return true;}catch(Exception){ MessageBox.Show("Cannot find the file"); }return false;
}which supports types bmp, dds, dib, jpg, png, and tga. Type gif is not supported.
3
Texture Coordinates Tu & TvAny image loaded to a Texture object will automatically get texture coordinates (Tu, Tv) from(0.0, 0.0) to (1.0, 1.0) as the picture shows.
Tu
Tv
(0.0, 0.0) (1.0, 0.0)
(0.0, 1.0) (1.0, 1.0)
4
CustomVertex.PositionTextured
We need to use CustomVertex.PositionTextured, to set cube vertices, which has Texture coordinates Tu & Tv.
private void SetVertex()
{
Vertices = new CustomVertex.PositionTextured[24];
CustomVertex.PositionTextured[] cube = new CustomVertex.PositionTextured[8];
cube[0].Position = new Vector3(-4.0f, 4.0f, -4.0f);cube[1].Position = new Vector3(4.0f,4.0f,-4.0f);cube[2].Position = new Vector3(-4.0f, 4.0f,4.0f);cube[3].Position = new Vector3(4.0f,4.0f, 4.0f);
5
cube[4].Position = new Vector3(-4.0f, -4.0f, -4.0f);cube[5].Position = new Vector3(4.0f, -4.0f,-4.0f);cube[6].Position = new Vector3(-4.0f, -4.0f,4.0f);cube[7].Position = new Vector3( 4.0f, -4.0f, 4.0f);
// top face, copy position, then set Tu &TvVertices[0] = cube[0]; Vertices[1] = cube[2];Vertices[2] = cube[1]; Vertices[3] = cube[3];
Vertices[0].Tu = 0.0f; Vertices[0].Tv = 0.0f;Vertices[1].Tu = 1.0f; Vertices[1].Tv = 0.0f;Vertices[2].Tu= 0.0f; Vertices[2].Tv =1.0f;Vertices[3].Tu = 1.0f; Vertices[3].Tv = 1.0f
// bottom face, notice the texture orderVertices[4] = cube[4]; Vertices[5] = cube[5];Vertices[6] = cube[6]; Vertices[7] = cube[7];
Vertices[4].Tu =0.0f; Vertices[4].Tv = 0.0f;Vertices[5].Tu= 1.0f; Vertices[5].Tv = 0.0f;Vertices[6].Tu = 0.0f; Vertices[6].Tv = 1.0f;Vertices[7].Tu = 1.0f; Vertices[7].Tv = 1.0f;
6
// front faceVertices[8] = cube[0]; Vertices[9] = cube[1];Vertices[10] = cube[4]; Vertices[11] = cube[5];
Vertices[8].Tu = 0.0f; Vertices[8].Tv = 0.0f;Vertices[9].Tu = 1.0f; Vertices[9].Tv = 0.0f;Vertices[10].Tu= 0.0f; Vertices[10].Tv =1.0f;Vertices[11].Tu = 1.0f; Vertices[11].Tv = 1.0f;
// right face
Vertices[12] = cube[1]; Vertices[13] = cube[3];Vertices[14] = cube[5]; Vertices[15] = cube[7];
Vertices[12].Tu = 0.0f; Vertices[12].Tv = 0.0f;Vertices[13].Tu = 1.0f; Vertices[13].Tv = 0.0f;Vertices[14].Tu= 0.0f; Vertices[14].Tv =1.0f;Vertices[15].Tu = 1.0f; Vertices[15].Tv = 1.0f;
7
// back faceVertices[16] = cube[3]; Vertices[17] = cube[2];Vertices[18] = cube[7]; Vertices[19] = cube[6];
Vertices[16].Tu = 0.0f; Vertices[16].Tv = 0.0f;Vertices[17].Tu = 1.0f; Vertices[17].Tv = 0.0f;Vertices[18].Tu= 0.0f; Vertices[18].Tv =1.0f;Vertices[19].Tu = 1.0f; Vertices[19].Tv = 1.0f;
// left faceVertices[20] = cube[2]; Vertices[21] = cube[0];Vertices[22] = cube[6]; Vertices[23] = cube[4];
Vertices[20].Tu = 0.0f; Vertices[20].Tv = 0.0f;Vertices[21].Tu = 1.0f; Vertices[21].Tv = 0.0f;Vertices[22].Tu= 0.0f; Vertices[22].Tv =1.0f;Vertices[23].Tu = 1.0f; Vertices[23].Tv = 1.0f;
}
8
Set Texture before drawingvoid Render(){
m_device.BeginScene();m_device.VertexFormat=CustomVertex.PositionTextured.Formatm_device.SetStreamSource( 0, VB, 0);SetRotation();m_device.SetTexture(0,texture); // set texture m_device.DrawPrimitives(PrimitiveType.TriangleStrip, 0,2);m_device.DrawPrimitives(PrimitiveType.TriangleStrip, 4,2);m_device.DrawPrimitives(PrimitiveType.TriangleStrip, 8,2);m_device.DrawPrimitives(PrimitiveType.TriangleStrip, 12,2);m_device.DrawPrimitives(PrimitiveType.TriangleStrip, 16,2);m_device.DrawPrimitives(PrimitiveType.TriangleStrip, 20,2);m_device.EndScene();m_device.Present();
}
9
Out put
10
Set different face imagesMethod 1: One picture, set 6 different textures coordinates.
Tu
Tv
0.25 0.5 0.75 1.0
0.5
1.0
0.0
11
. . . . . . .. . . . .
// top faceVertices[0].Tu = 0.0f; Vertices[0].Tv = 0.0f;Vertices[1].Tu = 0.25f; Vertices[1].Tv = 0.0f;Vertices[2].Tu= 0.0f; Vertices[2].Tv =0.5f;Vertices[3].Tu = 0.25f; Vertices[3].Tv = 0.5f
// bottom faceVertices[4].Tu =0.25f; Vertices[4].Tv = 0.0f;Vertices[5].Tu= 0.5f; Vertices[5].Tv = 0.0f;Vertices[6].Tu = 0.25f; Vertices[6].Tv = 0.5f;Vertices[7].Tu = 0.5f; Vertices[7].Tv = 0.5f;
// front faceVertices[8].Tu = 0.5f; Vertices[8].Tv = 0.0f;Vertices[9].Tu = 0.75f; Vertices[9].Tv = 0.0f;Vertices[10].Tu= 0.5f; Vertices[10].Tv =0.5f;Vertices[11].Tu = 0.75f; Vertices[11].Tv = 0.5f;
12
// right face
Vertices[12].Tu = 0.75f; Vertices[12].Tv = 0.0f;Vertices[13].Tu = 1.0f; Vertices[13].Tv = 0.0f;Vertices[14].Tu= 0.75f; Vertices[14].Tv = 0.5f;Vertices[15].Tu = 1.0f; Vertices[15].Tv = 0.5f;
// back faceVertices[16].Tu = 0.25f; Vertices[16].Tv = 0.5f;Vertices[17].Tu = 0.5f; Vertices[17].Tv = 0.5f;Vertices[18].Tu= 0.25f; Vertices[18].Tv = 1.0f;Vertices[19].Tu = 0.5f; Vertices[19].Tv = 1.0f;
// left face
Vertices[20].Tu = 0.5f; Vertices[20].Tv = 0.5f;Vertices[21].Tu = 0.75f; Vertices[21].Tv = 0.5f;Vertices[22].Tu= 0.5f; Vertices[22].Tv =1.0f;Vertices[23].Tu = 0.75f; Vertices[23].Tv = 1.0f;
13
Out put
14
Method 2: make six different textures from six pictures.All texture coordinates are the same as before.
number1.bmp
number2.bmp
number3.bmp
number4.bmp
number5.bmp
number6.bmp
15
Load 6 TexturesTexture[] textures;
private bool InitTexture()
{
textures = new Texture[6];
for(int k=0; k<6; k++)
{
textures[k] =TextureLoader.FromFile(m_device, "number"+
(k+1)+".bmp"); if(textures[k]==null) return false;
} return true;
}
16
Set 6 Textures before Drawingvoid Render(){ . . . . . . . ..
m_device.SetTexture(0,textures[0]); // set texture 1 m_device.DrawPrimitives(PrimitiveType.TriangleStrip, 0,2);m_device.SetTexture(0,textures[1]); // set texture 2 m_device.DrawPrimitives(PrimitiveType.TriangleStrip, 4,2);m_device.SetTexture(0,textures[2]); // set texture 3 m_device.DrawPrimitives(PrimitiveType.TriangleStrip, 8,2);m_device.SetTexture(0,textures[3]); // set texture 4 m_device.DrawPrimitives(PrimitiveType.TriangleStrip, 12,2);m_device.SetTexture(0,textures[4]); // set texture 5m_device.DrawPrimitives(PrimitiveType.TriangleStrip, 16,2);m_device.SetTexture(0,textures[5]); // set texture 6m_device.DrawPrimitives(PrimitiveType.TriangleStrip, 20,2);. . . . . . .
}
17
Out put is the same
18
Two sides of one card
We have picture
We want to draw it in the two sides of a card
Tu
Tv
0.5 1.0
1.0
Card.bmp
19
private void SetVertex()
{ Vertices = new CustomVertex.PositionTextured[8];
Vertices[0].Position = new Vector3(-0.7f, -1.0f, 1.0f );
Vertices[1].Position = new Vector3( 0.7f, -1.0f, 1.0f );
Vertices[2].Position = new Vector3(-0.7f, -1.0f, -1.0f );
Vertices[3].Position = new Vector3( 0.7f, -1.0f, -1.0f );
// two faces have different directions
Vertices[4].Position = new Vector3( 0.7f, -1.0f, 1.0f );
Vertices[5].Position = new Vector3(-0.7f, -1.0f, 1.0f );
Vertices[6].Position = new Vector3( 0.7f, -1.0f, -1.0f );
Vertices[7].Position = new Vector3(-0.7f, -1.0f, -1.0f );
20
Vertices[0].Tu = 0.0f; Vertices[0].Tv = 0.0f;
Vertices[1].Tu = 0.5f; Vertices[1].Tv = 0.0f;
Vertices[2].Tu= 0.0f; Vertices[2].Tv = 1.0f;
Vertices[3].Tu = 0.5f; Vertices[3].Tv = 1.0f;
Vertices[4].Tu = 0.5f; Vertices[4].Tv = 0.0f;
Vertices[5].Tu = 1.0f; Vertices[5].Tv = 0.0f;
Vertices[6].Tu = 0.5f; Vertices[6].Tv = 1.0f;
Vertices[7].Tu = 1.0f; Vertices[7].Tv = 1.0f;
}
21
void Render()
{
. . . . . . . .
m_device.RenderState.CullMode = Cull.CounterClockwise;
// control direction
m_device.SetTexture(0,texture);
m_device.DrawPrimitives(PrimitiveType.TriangleStrip, 0,2);
m_device.DrawPrimitives(PrimitiveType.TriangleStrip, 4,2)
. . . . . . . . .
}
22
Out put
23
If the area is not Rectangle
How to map a square picture to the inside of a trapezoid ?
X
Y
(1, 0)(1, 0)
(0.5, 1.7)(0.5, 1.7)
Tv
Tu
24
If pick 2 triangles and set their texture coordinates (u, v) as(0,0), (0,1), (1,0) and (1,1)
25
If we make 2 triangles by code
device.DrawPrimitives(PrimitiveType.TriangleStrip , 0, 2);
{v_axis = new CustomVertex.PositionTextured[4];
v_axis[0].Position = new Vector3 (-1.0f, 0.0f, 0.0f); v_axis[0].Tu = 0.0f; v_axis[0].Tv = 1.0f;v_axis[1].Position = new Vector3 (-0.5f, 1.7f, 0.0f); v_axis[1].Tu = 0.0f; v_axis[1].Tv = 0.0f;v_axis[2].Position = new Vector3 (1.0f, 0.0f, 0.0f); v_axis[2].Tu = 1.0f; v_axis[2].Tv = 1.0f;v_axis[3].Position = new Vector3 (0.5f, 1.7f, 0.0f); v_axis[3].Tu = 1.0f; v_axis[3].Tv = 0.0f;
}}
private void SetVertex()0
1
2
3
26
We only get
This is because that the Microsoft 3D texture mapping only can be done though triangles. Within one triangle the mapping is linear. However any two consecutive triangles’ mapping may not be adjoin linearly very well
27
(1, 1)(0, 1)
(1, 0)
(0, 0)
To overcome this problem, we have to partition the trapezoid in to many triangles as the following:
In this time, texture mapping of two consecutive triangles is still not adjoin linearly. However, the disjoin error can be reduced so small that our eye cannot see them.More triangles can result better out put.
28
If we partition trapezoid to 20 triangles by code
device.DrawPrimitives(PrimitiveType.TriangleStrip , 0, 20);
{v_axis = new CustomVertex.PositionTextured[22];for(int k=0; k<11; k++){
v_axis[2*k].Position = new Vector3 (-1.0f + k*0.2f, 0.0f, 0.0f); v_axis[2*k].Tu = 0.0f +k*0.1f;v_axis[2*k].Tv = 1.0f;v_axis[2*k+1].Position = new Vector3 (-0.5f+ k*0.1f , 1.7f, 0.0f); v_axis[2*k+1].Tu = 0.0f +k*0.1f;v_axis[2*k+1].Tv = 0.0f;
}}
private void SetVertex()
29
Then we can get pretty good output
30
If the area is a triangle
How to map a square picture to the inside of a triangle
X
Y
(1, 0)(1, 0)
(0, 1.7)
Tv
Tu
31
(1, 1)(0, 1)
Similarly we partition it into many triangles
However, the texture coordinate of the vertex is different for different triangle
?
32
If we partition trapezoid to 10 triangles by code
device.DrawPrimitives(PrimitiveType.TriangleList , 0, 10);
{v_axis = new CustomVertex.PositionTextured[30];for(int k=0; k<10; k++){
v_axis[3*k].Position = new Vector3 (-1.0f + k*0.2f, 0.0f, 0.0f); v_axis[3*k].Tu = 0.0f +k*0.1f;v_axis[3*k].Tv = 1.0f;v_axis[3*k+1].Position = new Vector3 (-0.8f+ k*0.2f , 0.0f, 0.0f); v_axis[3*k+1].Tu = 0.1f +k*0.1f;v_axis[3*k+1].Tv = 0.0f;v_axis[3*k+2].Position = new Vector3 (0.0f , 1.7f, 0.0f); v_axis[3*k+2].Tu = 0.05f +k*0.1f;v_axis[3*k+2].Tv = 0.0f;
}}
private void SetVertex()
33
Then we can get output
It is obviously that this mapping loses some image data. However, the lost image information concentrate on top vertex.
34
If the area is a circle
X
Y
(0, 0)
Tv
Tu
How to map a square picture to the inside of a circle such that the bottom side is mapped to the circle perimeter and the top side is mapped to the center?
35
This time, we partition circle into many triangles by radius
However, the texture coordinate of the center is different for different triangle
36
private void SetVertex()
{
v_axis = new CustomVertex.PositionTextured[180];float d = 1.0f/60.0f; float a = (float)Math.PI*2.0f/60.0f; for(int k=0; k<60; k++){
v_axis[3*k].Position = new Vector3 ( (float)Math.Cos(k*a),(float)Math.Sin(k*a),0.0f);
v_axis[3*k].Tu = 0.0f+k*d;v_axis[3*k].Tv = 1.0f;v_axis[3*k+1].Position = new
Vector3( (float)Math.Cos(k*a+a),(float)Math.Sin(k*a+a),0.0f); v_axis[3*k+1].Tu = d +k*d;
v_axis[3*k+1].Tv = 0.0f;v_axis[3*k+2].Position = new Vector3 (0.0f ,
0.0f, 0.0f); v_axis[3*k+2].Tu = d/2.0f +k*d;v_axis[3*k+2].Tv = 0.0f}
}}
37
Then we can get output
38
How to paste a map to a sphere?
Tv
Tu
39
2
m intervals
n in
terv
als
2π
m
π
n
Use grid map picture to set Texture coordinate
40
Set Texture Coordinatesprivate void SetVertex(){
v_sphere = new CustomVertex.PositionColored[(m+1)*(n+1)];float alpha = 2.0f*(float)Math.PI /(float)m;float theta = (float)Math.PI /(float)n;for(int i=0; i<m+1; i++) for(int k=0; k<n+1; k++){
v_sphere[k*(m+1)+i].Y =r*(float)Math.Cos(k*theta); v_sphere[k*(m+1)+i].X =
r*(float)Math.Sin(k*theta)*(float)Math.Cos(i*alpha); v_sphere[k*(m+1)+i].Z =
r*(float)Math.Sin(k*theta)*(float)Math.Sin(i*alpha); v_sphere[k*(m+1)+i].Tu= i/ (float)m;v_sphere[k*(m+1)+i].Tu= k/ (float)n;
}}
41
Output
42
Embedding picture to Resource1. Right click on the selected project in Solution Explorer and select AddAdd Existing Item.
43
2. Search sphere.bmp in your computer hard disk, click Open
44
3. Right click on the added resource file in solution explorer and click properties.
45
4. In the Properties tab of selected file, go to 'Build Action'
and change it from 'Content' to 'Embedded Resource'.
46
Data name in the Resource Each file data in the resource has a name, which is project name
dot file name. For example sphere.bmp will get name
MyProjectName.sphere.bmpIf we put file sphere.bmp in subfolder named images then it
will get name:
MyProjectName.images.sphere.bmpThe data formation of each file in the resource is stream.
All resource data will be a part of an Assembly (similar to
DLL) in the compiled executable file.
Therefore we need to get this Assembly, search data name and
get data back in stream formation
47
Get stream data from the Resource using System.Reflection; public Stream GetFromResource(string name){
Assembly asm = Assembly.GetExecutingAssembly();Stream stream=null;foreach(string srcName in asm.GetManifestResourceNames()) {
if( srcName.IndexOf("name")>0);{
stream =asm.GetManifestResourceStream(srcName); break;
}}return stream;
}
48
Load image data from Resource
Texture texture;private bool InitTexture(){
try {Stream stream = GetFromResource("sphera.bmp");
texture =TextureLoader.FromStream(device, stream); return true;}catch(Exception){ MessageBox.Show("Cannot find the file"); }return false;
}.Then we will not need image file during the executing time.