纹理就是3D模型外表面上的图案。在3D场景中纹理极大地增加了物体的真实性。纹理的本质是把平面图形贴到3D物体表面。在Direct3D中纹理的x和y坐标一般称为Tu和Tv坐标,纹理坐标范围都是0.0-1.0。如果知道一个面的顶点坐标,使面的顶点坐标和句型图片纹理坐标相对应,就可以将这些二维图片贴到3D图形表面。在Direct 3D中Texture类定义纹理。
如果希望为墙壁贴上瓷砖,可以只绘制一个瓷砖的平面图形,然后把瓷砖图形自动平铺到墙壁上。这里运用了Direct 3D默认的寻址模式TextureAddress.Wrap,如果纹理的x坐标大于1,例如为n,表示图片沿X轴方向重复贴图n次。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; namespace 墙壁贴瓷砖 { public partial class Form1 : Form { private Device device = null; bool pause = false; VertexBuffer vertexBuffer1 = null; Texture texture = null; public Form1() { InitializeComponent(); } public bool InitializeGraphics() { try { PresentParameters presentParams = new PresentParameters(); presentParams.Windowed = true; //不是全屏显示,在一个窗口显示 presentParams.SwapEffect = SwapEffect.Discard; //后备缓存交换的方式 presentParams.EnableAutoDepthStencil = true; //允许使用自动深度模板测试 //深度缓冲区单元为16位二进制数 presentParams.AutoDepthStencilFormat = DepthFormat.D16; device = new Device(0, DeviceType.Hardware, this, //建立设备类对象 CreateFlags.SoftwareVertexProcessing, presentParams); //设置设备重置事件(device.DeviceReset)事件函数为this.OnResetDevice device.DeviceReset += new System.EventHandler(this.OnResetDevice); this.OnCreateDevice(device, null);//自定义方法,初始化Device的工作放到这个方法中 this.OnResetDevice(device, null);//调用设备重置事件(device.DeviceReset)事件函数 } //设备重置事件函数要设置Device参数,初始函数中必须调用该函数 catch (DirectXException) { return false; } return true; } public void OnCreateDevice(object sender, EventArgs e) { Device dev = (Device)sender; vertexBuffer1 = new VertexBuffer(typeof(CustomVertex.PositionTextured), 6, dev, 0, CustomVertex.PositionTextured.Format, Pool.Default); vertexBuffer1.Created += new EventHandler(vertexBuffer1_Created); this.vertexBuffer1_Created(vertexBuffer1, null); texture = TextureLoader.FromFile(dev, Application.StartupPath + @"\..\..\..\p2.bmp"); } public void OnResetDevice(object sender, EventArgs e) { Device dev = (Device)sender; dev.RenderState.CullMode = Cull.None; //取消背面剔除 dev.RenderState.Lighting = false; //取消灯光 SetupMatrices(); //在程序运行期间,Device的3个变换不改变,因此放在此处 } public void Render() //渲染方法,本方法没有任何渲染代码,可认为是渲染方法的框架 { if (device == null) //如果未建立设备对象,退出 return; if (pause) return; device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.LightCoral, 1.0f, 0); device.BeginScene();//开始渲染 SetupMatrices(); device.SetTexture(0, texture); //为Device类对象device增加使用的第0个纹理 device.SetStreamSource(0, vertexBuffer1, 0); device.VertexFormat = CustomVertex.PositionTextured.Format; device.DrawPrimitives(PrimitiveType.TriangleList, 0, 2); device.EndScene(); //渲染结束 device.Present(); //更新显示区域,把后备缓存的D图形送到图形卡的显存中显示 } private void Form1_Paint(object sender, PaintEventArgs e) { this.Render(); } private void Form1_Resize(object sender, EventArgs e) { pause = ((this.WindowState == FormWindowState.Minimized) || !this.Visible); } void vertexBuffer1_Created(object sender, EventArgs e) { CustomVertex.PositionTextured[] verts = (CustomVertex.PositionTextured[])vertexBuffer1.Lock(0, 0);//墙壁 verts[0].Position = new Vector3(-2.0f, -2.0f, 2.0f); //顶点0位置 verts[0].Tu = 0.0f; //顶点0纹理坐标Tu verts[0].Tv = 10.0f; verts[1].Position = new Vector3(-2.0f, 2.0f, 2.0f); //顶点1位置 verts[1].Tu = 0.0f; //顶点1纹理坐标Tu verts[1].Tv = 0.0f; verts[2].Position = new Vector3(2.0f, 2.0f, 2.0f); //顶点2位置 verts[2].Tu = 10.0f; //顶点2纹理坐标Tu verts[2].Tv = 0.0f; verts[3].Position = new Vector3(-2.0f, -2.0f, 2.0f); //顶点3位置 verts[3].Tu = 0.0f; //顶点3纹理坐标Tu verts[3].Tv = 10.0f; verts[4].Position = new Vector3(2.0f, 2.0f, 2.0f); //顶点4位置 verts[4].Tu = 10.0f; //顶点4纹理坐标Tu verts[4].Tv = 0.0f; verts[5].Position = new Vector3(2.0f, -2.0f, 2.0f); //顶点5位置 verts[5].Tu = 10.0f; //顶点5纹理坐标Tu verts[5].Tv = 10.0f; vertexBuffer1.Unlock(); } private void SetupMatrices() //修改Device的3个变换 { device.Transform.World = Matrix.RotationY(0); //世界变换矩阵 device.Transform.View = Matrix.LookAtLH(new Vector3(0.0f, 0.0f, -4.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f)); device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, 1.0f, 1.0f, 100.0f); //投影变换矩阵 } private void Form1_Load(object sender, EventArgs e) { InitializeGraphics(); this.Show(); Render(); } } }
为有光照的空心圆柱增加纹理,此时还需要考虑光照的影响。Device类对象的TextureState数组记录了每一个纹理的状态,允许多层纹理,数组的索引值为0~7,其属性ColorOperation记录了该元素所代表的纹理图片颜色和其他参数(e.g.光照颜色)的混合方法;属性ColorArgument1和ColorArgument2用来指定属性ColorOperation使用的参数
实现如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; namespace 为空心圆柱增加纹理 { public partial class Form1 : Form { private Device device = null; bool pause = false; VertexBuffer vertexBuffer = null; Material mtrl; Texture texture = null; public Form1() { InitializeComponent(); } public bool InitializeGraphics() { try { PresentParameters presentParams = new PresentParameters(); presentParams.Windowed = true; //不是全屏显示,在一个窗口显示 presentParams.SwapEffect = SwapEffect.Discard; //后备缓存交换的方式 presentParams.EnableAutoDepthStencil = true; //允许使用自动深度模板测试 //深度缓冲区单元为16位二进制数 presentParams.AutoDepthStencilFormat = DepthFormat.D16; device = new Device(0, DeviceType.Hardware, this, //建立设备类对象 CreateFlags.SoftwareVertexProcessing, presentParams); //设置设备重置事件(device.DeviceReset)事件函数为this.OnResetDevice device.DeviceReset += new System.EventHandler(this.OnResetDevice); this.OnCreateDevice(device, null);//自定义方法,初始化Device的工作放到这个方法中 this.OnResetDevice(device, null);//调用设备重置事件(device.DeviceReset)事件函数 } //设备重置事件函数要设置Device参数,初始函数中必须调用该函数 catch (DirectXException) { return false; } return true; } public void OnCreateDevice(object sender, EventArgs e) { Device dev = (Device)sender; //注意阴影部分 vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionNormalTextured), 100, dev, Usage.WriteOnly, CustomVertex.PositionNormalTextured.Format, Pool.Default); vertexBuffer.Created += new System.EventHandler(this.OnCreateVertexBuffer); this.OnCreateVertexBuffer(vertexBuffer, null); mtrl = new Material(); mtrl.Diffuse = System.Drawing.Color.Yellow; //物体的颜色 mtrl.Ambient = System.Drawing.Color.Red; //反射环境光的颜色 texture = TextureLoader.FromFile(dev, Application.StartupPath + @"\..\..\..\p1.JPG"); } public void OnResetDevice(object sender, EventArgs e) { Device dev = (Device)sender; dev.RenderState.CullMode = Cull.None; //取消背面剔除 device.RenderState.ZBufferEnable = true; //打开Z缓冲 device.RenderState.Lighting = true; //打开灯光 SetupLights(); //设置灯光 } public void Render() //渲染方法,本方法没有任何渲染代码,可认为是渲染方法的框架 { if (device == null) //如果未建立设备对象,退出 return; if (pause) return; device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.WhiteSmoke, 1.0f, 0); SetupMatrices(); device.BeginScene(); //开始渲染 device.SetTexture(0, texture); device.TextureState[0].ColorOperation = TextureOperation.Modulate; device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;//纹理颜色 device.TextureState[0].ColorArgument2 = TextureArgument.Diffuse;//光照颜色 device.TextureState[0].AlphaOperation = TextureOperation.Disable; device.SetStreamSource(0, vertexBuffer, 0); device.VertexFormat = CustomVertex.PositionNormalTextured.Format; device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, (4 * 25) - 2); device.EndScene();//渲染结束 device.Present();//更新显示区域,把后备缓存的D图形送到图形卡的显存中显示 } private void Form1_Paint(object sender, PaintEventArgs e) { this.Render(); } private void Form1_Resize(object sender, EventArgs e) { pause = ((this.WindowState == FormWindowState.Minimized) || !this.Visible); } public void OnCreateVertexBuffer(object sender, EventArgs e) { CustomVertex.PositionNormalTextured[] verts = (CustomVertex.PositionNormalTextured[])vertexBuffer.Lock(0, 0); for (int i = 0; i < 50; i++) { float theta = (float)(2 * Math.PI * i) / 49; verts[2 * i].Position = new Vector3((float)Math.Sin(theta), -1, (float)Math.Cos(theta)); verts[2 * i].Normal = new Vector3((float)Math.Sin(theta), 0, (float)Math.Cos(theta)); verts[2 * i].Tu = ((float)i) / (50 - 1); verts[2 * i].Tv = 1.0f; verts[2 * i + 1].Position = new Vector3((float)Math.Sin(theta), 1, (float)Math.Cos(theta)); verts[2 * i + 1].Normal = new Vector3((float)Math.Sin(theta), 0, (float)Math.Cos(theta)); verts[2 * i + 1].Tu = ((float)i) / (50 - 1); verts[2 * i + 1].Tv = 0.0f; } vertexBuffer.Unlock(); } private void SetupMatrices() { device.Transform.World = Matrix.RotationAxis(new Vector3((float)Math.Cos(Environment.TickCount / 250.0f), 1, (float)Math.Sin(Environment.TickCount / 250.0f)), Environment.TickCount / 3000.0f); device.Transform.View = Matrix.LookAtLH(new Vector3(0.0f, 3.0f, -5.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f)); device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, 1.0f, 1.0f, 100.0f); } private void SetupLights() { device.Material = mtrl; device.Lights[0].Type = LightType.Directional; device.Lights[0].Diffuse = System.Drawing.Color.White; device.Lights[0].Direction = new Vector3((float)Math.Cos(Environment.TickCount / 250.0f), 1.0f, (float)Math.Sin(Environment.TickCount / 250.0f)); device.Lights[0].Enabled = true; device.RenderState.Ambient = System.Drawing.Color.FromArgb(0x404040); } private void Form1_load(object sender, EventArgs e) { InitializeGraphics(); this.Show(); Render(); } } }
可以为上面的空心圆柱添加背景,所谓的背景就是固定不动的图像,也就是在进行三个变换时,背景位置不变。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; namespace 空心圆柱添加背景 { public partial class Form1 : Form { private Device device = null; bool pause = false; VertexBuffer vertexBuffer = null; Material mtrl; Texture texture = null; VertexBuffer vertexBuffer1 = null; Texture texture1 = null; public Form1() { InitializeComponent(); } public bool InitializeGraphics() { try { PresentParameters presentParams = new PresentParameters(); presentParams.Windowed = true; //不是全屏显示,在一个窗口显示 presentParams.SwapEffect = SwapEffect.Discard; //后备缓存交换的方式 presentParams.EnableAutoDepthStencil = true; //允许使用自动深度模板测试 //深度缓冲区单元为16位二进制数 presentParams.AutoDepthStencilFormat = DepthFormat.D16; device = new Device(0, DeviceType.Hardware, this, //建立设备类对象 CreateFlags.SoftwareVertexProcessing, presentParams); //设置设备重置事件(device.DeviceReset)事件函数为this.OnResetDevice device.DeviceReset += new System.EventHandler(this.OnResetDevice); this.OnCreateDevice(device, null);//自定义方法,初始化Device的工作放到这个方法中 this.OnResetDevice(device, null);//调用设备重置事件(device.DeviceReset)事件函数 } //设备重置事件函数要设置Device参数,初始函数中必须调用该函数 catch (DirectXException) { return false; } return true; } public void OnCreateDevice(object sender, EventArgs e) { Device dev = (Device)sender; //阴影部分是所作的修改 vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionNormalTextured), 100, dev, Usage.WriteOnly, CustomVertex.PositionNormalTextured.Format, Pool.Default); vertexBuffer.Created += new System.EventHandler(this.OnCreateVertexBuffer); this.OnCreateVertexBuffer(vertexBuffer, null); mtrl = new Material(); mtrl.Diffuse = System.Drawing.Color.Yellow; //物体的颜色 mtrl.Ambient = System.Drawing.Color.Red; //反射环境光的颜色 texture = TextureLoader.FromFile(dev, Application.StartupPath + @"\..\..\..\p1.JPG"); vertexBuffer1 = new VertexBuffer(typeof(CustomVertex.TransformedTextured), 4, dev, 0, CustomVertex.TransformedTextured.Format, Pool.Default); vertexBuffer1.Created += new EventHandler(vertexBuffer1_Created); this.vertexBuffer1_Created(vertexBuffer1, null); texture1 = TextureLoader.FromFile(dev, Application.StartupPath + @"\..\..\..\p2.jpg"); } public void OnResetDevice(object sender, EventArgs e) { Device dev = (Device)sender; dev.RenderState.CullMode = Cull.None; //取消背面剔除 device.RenderState.ZBufferEnable = true; //打开Z缓冲 device.RenderState.Lighting = true; //打开灯光 SetupLights(); } public void Render() //渲染方法,本方法没有任何渲染代码,可认为是渲染方法的框架 { if (device == null) //如果未建立设备对象,退出 return; if (pause) return; device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.WhiteSmoke, 1.0f, 0); SetupMatrices(); device.BeginScene(); //开始渲染 device.SetTexture(0, texture1); //这段代码必须放在渲染圆柱体代码之前 device.RenderState.ZBufferEnable = false; device.SetStreamSource(0, vertexBuffer1, 0); device.VertexFormat = CustomVertex.TransformedTextured.Format; device.DrawPrimitives(PrimitiveType.TriangleFan, 0, 2); device.RenderState.ZBufferEnable = true; device.SetTexture(0, texture); device.TextureState[0].ColorOperation = TextureOperation.Modulate; device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor; device.TextureState[0].ColorArgument2 = TextureArgument.Diffuse; device.TextureState[0].AlphaOperation = TextureOperation.Disable; device.SetStreamSource(0, vertexBuffer, 0); device.VertexFormat = CustomVertex.PositionNormalTextured.Format; device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, (4 * 25) - 2); device.EndScene(); //渲染结束 device.Present(); //更新显示区域,把后备缓存的D图形送到图形卡的显存中显示 } private void Form1_Paint(object sender, PaintEventArgs e) { this.Render(); } private void Form1_Resize(object sender, EventArgs e) { pause = ((this.WindowState == FormWindowState.Minimized) || !this.Visible); } public void OnCreateVertexBuffer(object sender, EventArgs e) { CustomVertex.PositionNormalTextured[] verts = (CustomVertex.PositionNormalTextured[])vertexBuffer.Lock(0, 0); for (int i = 0; i < 50; i++) { float theta = (float)(2 * Math.PI * i) / 49; verts[2 * i].Position = new Vector3((float)Math.Sin(theta), -1, (float)Math.Cos(theta)); verts[2 * i].Normal = new Vector3((float)Math.Sin(theta), 0, (float)Math.Cos(theta)); verts[2 * i].Tu = ((float)i) / (50 - 1); verts[2 * i].Tv = 1.0f; verts[2 * i + 1].Position = new Vector3((float)Math.Sin(theta), 1, (float)Math.Cos(theta)); verts[2 * i + 1].Normal = new Vector3((float)Math.Sin(theta), 0, (float)Math.Cos(theta)); verts[2 * i + 1].Tu = ((float)i) / (50 - 1); verts[2 * i + 1].Tv = 0.0f; } vertexBuffer.Unlock(); } private void SetupMatrices() { device.Transform.World = Matrix.RotationAxis(new Vector3((float)Math.Cos(Environment.TickCount / 250.0f), 1, (float)Math.Sin(Environment.TickCount / 250.0f)), Environment.TickCount / 3000.0f); device.Transform.View = Matrix.LookAtLH(new Vector3(0.0f, 3.0f, -5.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f)); device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, 1.0f, 1.0f, 100.0f); } private void SetupLights() { device.Material = mtrl; device.Lights[0].Type = LightType.Directional; device.Lights[0].Diffuse = System.Drawing.Color.White; device.Lights[0].Direction = new Vector3((float)Math.Cos(Environment.TickCount / 250.0f), 1.0f, (float)Math.Sin(Environment.TickCount / 250.0f)); device.Lights[0].Enabled = true; device.RenderState.Ambient = System.Drawing.Color.FromArgb(0x404040); } void vertexBuffer1_Created(object sender, EventArgs e) { CustomVertex.TransformedTextured[] verts = (CustomVertex.TransformedTextured[])vertexBuffer1.Lock(0, 0); verts[0].Position = new Vector4(0, 0, 0, 1); verts[0].Tu = 0.0f; verts[0].Tv = 0.0f; verts[1].Position = new Vector4(this.Width, 0, 0, 1); verts[1].Tu = 1.0f; verts[1].Tv = 0.0f; verts[2].Position = new Vector4(this.Width, this.Height, 0, 1); verts[2].Tu = 1.0f; verts[2].Tv = 1.0f; verts[3].Position = new Vector4(0, this.Height, 0, 1); verts[3].Tu = 0.0f; verts[3].Tv = 1.0f; vertexBuffer1.Unlock(); } private void Form1_Load(object sender, EventArgs e) { InitializeGraphics(); this.Show(); Render(); } } }
为正方形增加纹理,如果正方形尺寸较大,而纹理的分辨率较低,这时纹理图像可能要出现马赛克,如果正方形尺寸较大,而纹理图片分辨率较高时,此时要缩小图形以适应正方形尺寸。为了解决这个问题,可以使用纹理滤波器,纹理滤波器的本质是数学差值。3D图形的表面可以贴多个图片,称为多层纹理。为正方形增加两个纹理,一个是一面不规则的墙的图案,另一个是一个光影。多纹理的混合需要一个是半透明的,两个混合后才有效果,通过设置纹理0的混合方法,再设置纹理1的混合方法,然后再把纹理0图案的颜色设置为半透明的即可。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; namespace 正方形添加多纹理 { public partial class Form1 : Form { private Device device = null; bool pause = false; VertexBuffer vertexBuffer1 = null; Texture texture = null; Texture texture1 = null; public Form1() { InitializeComponent(); } public bool InitializeGraphics() { try { PresentParameters presentParams = new PresentParameters(); presentParams.Windowed = true; //不是全屏显示,在一个窗口显示 presentParams.SwapEffect = SwapEffect.Discard; //后备缓存交换的方式 presentParams.EnableAutoDepthStencil = true; //允许使用自动深度模板测试 //深度缓冲区单元为16位二进制数 presentParams.AutoDepthStencilFormat = DepthFormat.D16; device = new Device(0, DeviceType.Hardware, this, //建立设备类对象 CreateFlags.SoftwareVertexProcessing, presentParams); //设置设备重置事件(device.DeviceReset)事件函数为this.OnResetDevice device.DeviceReset += new System.EventHandler(this.OnResetDevice); this.OnCreateDevice(device, null);//自定义方法,初始化Device的工作放到这个方法中 this.OnResetDevice(device, null);//调用设备重置事件(device.DeviceReset)事件函数 } //设备重置事件函数要设置Device参数,初始函数中必须调用该函数 catch (DirectXException) { return false; } return true; } public void OnCreateDevice(object sender, EventArgs e) { Device dev = (Device)sender; //注意有阴影部分 vertexBuffer1 = new VertexBuffer(typeof(CustomVertex.PositionTextured), 6, dev, 0, CustomVertex.PositionTextured.Format, Pool.Default); vertexBuffer1.Created += new EventHandler(vertexBuffer1_Created); this.vertexBuffer1_Created(vertexBuffer1, null); texture = TextureLoader.FromFile(dev, Application.StartupPath + @"\..\..\..\p1.bmp"); texture1 = TextureLoader.FromFile(dev, Application.StartupPath + @"\..\..\..\p2.bmp"); } public void OnResetDevice(object sender, EventArgs e) { Device dev = (Device)sender; dev.RenderState.CullMode = Cull.None; //取消背面剔除 dev.RenderState.Lighting = false; //取消灯光 SetupMatrices(); //在程序运行期间,Device的3个变换不改变,因此放在此处 device.SamplerState[0].MagFilter = TextureFilter.Linear; //使用线性滤波器 } public void Render() //渲染方法,本方法没有任何渲染代码,可认为是渲染方法的框架 { if (device == null) //如果未建立设备对象,退出 return; if (pause) return; device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Blue, 1.0f, 0); device.BeginScene(); //开始渲染 device.SetTexture(0, texture); //索引号为0的纹理是墙壁图案 device.SetTexture(1, texture1); //索引号为1的纹理是光影图案 device.TextureState[0].TextureCoordinateIndex = 0; //纹理坐标Tu和Tv初始值 device.TextureState[1].TextureCoordinateIndex = 0; device.SamplerState[0].MagFilter = TextureFilter.Linear; //放大图形使用线形滤波器 device.SamplerState[1].MagFilter = TextureFilter.Linear; //缩小图形使用线形滤波器 device.TextureState[0].ColorOperation = TextureOperation.SelectArg1; device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor; //以下两句设置纹理0为半透明的,和纹理1混合后能看到混合效果,透明效果见10.2节 device.TextureState[0].AlphaOperation = TextureOperation.SelectArg1; device.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor; device.TextureState[1].ColorOperation = TextureOperation.Modulate; device.TextureState[1].ColorArgument1 = TextureArgument.TextureColor; device.TextureState[1].ColorArgument2 = TextureArgument.Current; //device.TextureState[1].AlphaOperation = TextureOperation.Disable; //device.TextureState[2].ColorOperation = TextureOperation.Disable; //device.TextureState[2].AlphaOperation = TextureOperation.Disable; device.SetStreamSource(0, vertexBuffer1, 0); device.VertexFormat = CustomVertex.PositionTextured.Format; device.DrawPrimitives(PrimitiveType.TriangleList, 0, 2); device.EndScene(); //渲染结束 device.Present(); //更新显示区域,把后备缓存的图形送到图形卡的显存中显示 } private void Form1_Paint(object sender, PaintEventArgs e) { this.Render(); } private void Form1_Resize(object sender, EventArgs e) { pause = ((this.WindowState == FormWindowState.Minimized) || !this.Visible); } void vertexBuffer1_Created(object sender, EventArgs e) { CustomVertex.PositionTextured[] verts = (CustomVertex.PositionTextured[])vertexBuffer1.Lock(0, 0); //墙壁 verts[0].Position = new Vector3(-2.0f, -2.0f, 2.0f); //顶点0位置 verts[0].Tu = 0.0f; //顶点0纹理坐标Tu verts[0].Tv = 1.0f; verts[1].Position = new Vector3(-2.0f, 2.0f, 2.0f); //顶点1位置 verts[1].Tu = 0.0f; //顶点1纹理坐标Tu verts[1].Tv = 0.0f; verts[2].Position = new Vector3(2.0f, 2.0f, 2.0f); //顶点2位置 verts[2].Tu = 1.0f; //顶点2纹理坐标Tu verts[2].Tv = 0.0f; verts[3].Position = new Vector3(-2.0f, -2.0f, 2.0f); //顶点3位置 verts[3].Tu = 0.0f; //顶点3纹理坐标Tu verts[3].Tv = 1.0f; verts[4].Position = new Vector3(2.0f, 2.0f, 2.0f); //顶点4位置 verts[4].Tu = 1.0f; //顶点4纹理坐标Tu verts[4].Tv = 0.0f; verts[5].Position = new Vector3(2.0f, -2.0f, 2.0f); //顶点5位置 verts[5].Tu = 1.0f; //顶点5纹理坐标Tu verts[5].Tv = 1.0f; vertexBuffer1.Unlock(); } private void SetupMatrices() //修改Device的3个变换 { device.Transform.World = Matrix.RotationY(0); //世界变换矩阵 device.Transform.View = Matrix.LookAtLH(new Vector3(0.0f, 0.0f, -4.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f)); device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, 1.0f, 1.0f, 100.0f); //投影变换矩阵 } private void Form1_Load(object sender, EventArgs e) { InitializeGraphics(); this.Show(); Render(); } } }
在程序运行时有时需要多个不同分辨率的同一张图片,以适合大小不同的物体表面贴图用,当物体离观察者近的适合使用高质量的纹理,而物体离观察者远的时候使用低分辨率的纹理。这时就需要使用多级渐进纹理来控制渲染时纹理的质量,但是这样做的代价是会吃掉更多的内存。