• WP7XNA 3D开发 基本贴图控制


    如果一个3DMAX场景中有多个模型,但是只想控制其中一个模型的颜色,并对其进行模型进行变色(替换贴图)。

    补充一下:导入的一个model中,3DMAX建模时的每个小的模型作为这个model的mesh。(囧 大概就这么回事,不好描述啊,多理解理解吧)

    image

    这个情况再实际项目中可以用来实现一个播放中的电视机模型(知识设想,回头可以试着实现一个玩一玩),可以将屏幕单独做成一个面,然后只轮换修改其贴图,做出电视播放的效果。

    好了 大概就是这么个东西。然后谈谈如何实现。

    还是,新建个项目,叫TextureControl吧(由于要对模型的内部结构进行控制,所以显示的时候不能简单的用model.Draw方法,要用之前那个一堆foreach循环那个)

       1: protected override void Draw(GameTime gameTime)
       2: {
       3:     GraphicsDevice.Clear(Color.CornflowerBlue);
       4:  
       5:     // TODO: Add your drawing code here
       6:     Matrix world = Matrix.Identity; 
       7:     Matrix view = Matrix.CreateLookAt(new Vector3(0,100,20), Vector3.Zero, Vector3.Up);
       8:     Matrix projection = Matrix.CreatePerspectiveFieldOfView(
       9:                                                MathHelper.ToRadians(45),            //视角
      10:                                                GraphicsDevice.Viewport.AspectRatio,  //屏幕长宽比
      11:                                                0.1f, //最近拍摄范围
      12:                                                1000f  //最远拍摄范围
      13:                                                );
      14:     Matrix[] transforms = new Matrix[model.Bones.Count];
      15:     model.CopyAbsoluteBoneTransformsTo(transforms);
      16:  
      17:     foreach (ModelMesh mesh in model.Meshes)
      18:     {
      19:         foreach (BasicEffect effect in mesh.Effects)
      20:         {
      21:             //光照设置
      22:             effect.LightingEnabled = true;
      23:             effect.AmbientLightColor = new Vector3(0.9f, 0.9f, 0.9f);
      24:  
      25:             effect.View = view;
      26:             effect.Projection = projection;
      27:             effect.World = transforms[mesh.ParentBone.Index] * world;
      28:         }
      29:         mesh.Draw();
      30:     }
      31:     base.Draw(gameTime);
      32: }

    image

    然后构造一个纯色的贴图

    新建一个类变量用来保存贴图

       1: Texture2D texture;

    然后在LoadContent方法中添加构造贴图的代码(这里构造一个纯红色贴图)

       1: protected override void LoadContent()
       2: {
       3:     // Create a new SpriteBatch, which can be used to draw textures.
       4:     spriteBatch = new SpriteBatch(GraphicsDevice);
       5:  
       6:     // TODO: use this.Content to load your game content here
       7:     model = Content.Load<Model>(@"boxes");
       8:  
       9:     texture = new Texture2D(GraphicsDevice, 1, 1);//创建一个2D图片对象
      10:     texture.SetData(new Color[] { new Color(255, 0, 0, 255) });//改变图像属性(上色)
      11: }

    贴上试试

    image

    好了 接下来就是重头戏了。。

    观察显示模型的foreach循环之前的准备动作那两句

       1: Matrix[] transforms = new Matrix[model.Bones.Count];
       2: model.CopyAbsoluteBoneTransformsTo(transforms);

    这两句的作用就是将模型中每个Mesh相对于模型基准坐标的平移变量缓存出来

    然后观察缓存出来的那个矩阵数据再循环中的应用,也可以证明,这个矩阵数据即使用来分别设置每个Mesh的位置并分别进行显示

       1: foreach (ModelMesh mesh in model.Meshes)//循环模型的每个Mesh
       2: {
       3:     foreach (BasicEffect effect in mesh.Effects)//对Mesh的每个Effect进行设置
       4:     {
       5:         //光照设置
       6:         effect.LightingEnabled = true;
       7:         effect.AmbientLightColor = new Vector3(0.9f, 0.9f, 0.9f);
       8:  
       9:         //设置贴图
      10:         effect.TextureEnabled = true;
      11:         effect.Texture = texture;
      12:  
      13:         //设置观察矩阵
      14:         effect.View = view;
      15:         //设置投影矩阵
      16:         effect.Projection = projection;
      17:         //设置位置(相对于基准点)矩阵
      18:         effect.World = transforms[mesh.ParentBone.Index] * world;
      19:     }
      20:     mesh.Draw();//显示Mesh
      21: }

    重点观察 设置为是矩阵那一句

       1: effect.World = transforms[mesh.ParentBone.Index] * world;

    这里用到了之前缓存回来的矩阵数组。所以数组的游标可以用来控制前正在处理的Mesh。

    然后debug观察下mesh.ParentBone.Index值的变化发现这个值再1--9之间变化,结合我之前再Max中给场景创建了9个方块,可知游标从1开始。

    所以改变单独一个Mesh的贴图就是在循环中控制只有在需要改变时采取设置贴图,代码如下

       1: protected override void Draw(GameTime gameTime)
       2: {
       3:     GraphicsDevice.Clear(Color.CornflowerBlue);
       4:  
       5:     // TODO: Add your drawing code here
       6:     Matrix world = Matrix.Identity; 
       7:     Matrix view = Matrix.CreateLookAt(new Vector3(0,100,20), Vector3.Zero, Vector3.Up);
       8:     Matrix projection = Matrix.CreatePerspectiveFieldOfView(
       9:                                                MathHelper.ToRadians(45),            //视角
      10:                                                GraphicsDevice.Viewport.AspectRatio,  //屏幕长宽比
      11:                                                0.1f, //最近拍摄范围
      12:                                                1000f  //最远拍摄范围
      13:                                                );
      14:     Matrix[] transforms = new Matrix[model.Bones.Count];
      15:     model.CopyAbsoluteBoneTransformsTo(transforms);
      16:  
      17:     foreach (ModelMesh mesh in model.Meshes)
      18:     {
      19:         foreach (BasicEffect effect in mesh.Effects)
      20:         {
      21:             effect.LightingEnabled = true;
      22:             effect.AmbientLightColor = new Vector3(0.9f, 0.9f, 0.9f);
      23:  
      24:             if (mesh.ParentBone.Index == 1) //如果当前Mesh游标为1 则修改其贴图
      25:             {
      26:                 //设置贴图
      27:                 effect.TextureEnabled = true;
      28:                 effect.Texture = texture;
      29:             }
      30:             else
      31:             {
      32:                 effect.TextureEnabled = false;
      33:             }
      34:  
      35:  
      36:             effect.View = view;
      37:             effect.Projection = projection;
      38:             //设置位置(相对于基准点)矩阵
      39:             effect.World = transforms[mesh.ParentBone.Index] * world;
      40:         }
      41:         mesh.Draw();//显示Mesh
      42:     }
      43:     base.Draw(gameTime);
      44: }

    显示效果如下

    image

    补充一点,经过测试,对于每个Mash的游标编号和Mash 对应的模型再3DMAX中创建顺序相关,第几个创建的编号就是几。

    代码下载:http://vdisk.weibo.com/s/1a7y8

    作者:Lighting Cui

    出处:http://tugeler.cnblogs.com/

    本文版权归作者所,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    产品经理之职责篇
    Scrum实践
    通用泛型存储接口的设计
    Jquery ajax执行顺序 返回自定义错误信息
    Js参数值中含有单引号或双引号解决办法
    Winform下的HTMLEditor引用Microsoft.mshtml的注意事项
    引用类型传参不加 ref 的注意事项
    List<T> 排序(Sort)查找(Find)功能的多种实现
    多线程三种传值方式
    SQL 存储过程传入多个ID
  • 原文地址:https://www.cnblogs.com/tugeler/p/2253370.html
Copyright © 2020-2023  润新知