生成.X文件的一些方法&&DirectX获取及处理.X文件(初级版)

       近期一直在研究关于DirectX处理.X文件方面的知识,走了很多的弯路,也感觉浪费了很多时间。记得之前看过一篇大神写的博客,说是不管某一方面的知识多么简单,但总会有“外行“,总还是会有一些人不太了解,所以写下这篇博客分享下,也许你会用到。

如何获取.X文件

       网上或者很多书里边介绍的大都是3DSMAX或者MAYA如何生成.X文件,我也尝试了运用3DSMAX来生成.X文件,然后还自己发现了使用CATIA这个软件做的模型如何去获取.X文件。接下来先介绍3DSMAX是如何生成.X文件的。

3DSMAX生成.X文件

         由于网上有很多方法,这里只简单的说下我使用的方法。安装完3dsmax这个软件之后,需要下载一个插件: panda插件。这个插件就是3DS MAX 导出 directx .X 文件的插件,解压后把文件拷贝到3DS max安装目录的stdplugs文件夹即可,重新启动3ds max,导出时就可以看到选项中有direct .X格式了。
    虽然用这种方式生成了.X文件,刚开始时用在DirectX程序中居然根本读不出网格对象(mesh为空),后来尝试修改过各种参数,最终也只是可以读进程序中,但是什么也看不到。现在还是不懂为什么,不知道是3dsmax不熟悉的问题还是程序的问题,留作以后的研究。(问题一!)
CATIA软件做的模型生成.X文件
    CATIA软件制作的模型格式为.CATPart,一般别的软件没有打开这种文件格式的能力,但是CATIA还是很强大,你可以将你的模型另存为.stl或者.wrl格式的,使用一个软件叫做3d exploration,它可以读取这两种格式的文件并且可以生成.X文件(另存为.X即可).3d exploration这款软件很小但是真的很强大,强烈推荐!(我用的是3D Exploration 汉化版 1.5)当然还有另外一款类似的软件,Deep Exploration(3D文件转换工具),很强大,比 3d exploration功能强大,只是我用它生成的.X文件在程序中居然也无法显示或根本无法读出mesh,不知为何。(问题二!).stl或者.wrl这两种格式的用3dsmax也可以导入。
这是我用CATIA模型采用另存为.wrl格式文件,然后使用3d exploration所生成的.X文件打开后的情况:
生成.X文件的一些方法&&DirectX获取及处理.X文件(初级版)_第1张图片
    

                                         如何在DirectX程序中获取及使用.X文件

贴出部分主要代码:
        private Device device = null;//定义绘图设备
        private Mesh meshObj = null;//定义网格对象
        private Material[] meshMaterials;//定义网格材质对象
        private Texture[] meshTextures;//定义网格贴图对象
        ExtendedMaterial[] materials;//用于保存材质信息
        private void MeshFromFile(string xFilePath, string xFileName)//从文件导入网格
        {
            //从X文件导入网格
            meshObj = Mesh.FromFile(xFilePath + "\\" + xFileName,MeshFlags.SystemMemory,device,out materials);
            if (meshTextures == null)
            {
                meshTextures = new Texture[materials.Length];
                meshMaterials = new Material[materials.Length];
                for (int i = 0; i < materials.Length; i++)
                {
                    meshMaterials[i] = materials[i].Material3D;
                    meshMaterials[i].Ambient = meshMaterials[i].Diffuse;
                    //导入贴图
                    //meshTextures[i] = TextureLoader.FromFile(device,xFilePath + "\\" + materials[i].TextureFilename);
                }
            }
        }

        public bool InitializeDirect3D()
        {
            try
            {
                PresentParameters presentParams = new PresentParameters();
                presentParams.Windowed = true; //指定以Windows窗体形式显示
                presentParams.SwapEffect = SwapEffect.Discard; //当前屏幕绘制后它将自动从内存中删除
                device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams); //实例化device对象
                MeshFromFile(@"C:\Users\Administrator\Desktop", "jian8.x");
                return true;
            }
            catch (DirectXException e)
            {
                MessageBox.Show(e.ToString(), "Error"); //处理异常
                return false;
            }
        }

        /// 
        /// 定义渲染函数
        /// 
        public void Render()
        {
            if (device == null) //如果device为空则不渲染
            {
                return;
            }
            device.Clear(ClearFlags.Target, Color.LightSkyBlue, 1.0f, 0); //清除windows界面为深蓝色
            device.BeginScene();


            // 1.设备基本绘制参数设置  
            device.RenderState.ZBufferEnable = true;
            device.RenderState.CullMode = Cull.None;
            device.RenderState.Lighting = true;
            device.RenderState.AmbientColor = 0x808080;
            device.RenderState.NormalizeNormals = true; 
            //加灯光
            device.Lights[0].Diffuse = Color.FromArgb(255, 255, 255);
            device.Lights[0].Type = LightType.Directional;
            device.Lights[0].Direction = new Vector3(1f, 1f, 1f);
            device.Lights[0].Enabled = true;
            // 纹理采样的uv设置  
            device.SamplerState[0].AddressU = TextureAddress.Wrap;
            device.SamplerState[0].AddressV = TextureAddress.Wrap;
            // 透明通道的开启  
            device.RenderState.AlphaBlendEnable = true;
            device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;
            device.TextureState[0].ColorOperation = TextureOperation.SelectArg1;


            //在此添加渲染图形代码
            for (int i = 0; i < meshMaterials.Length; i++)
            {
                //设置网格子集的材质和贴图
                device.Material = meshMaterials[i];
                //device.SetTexture(0, meshTextures[i]);
                //绘制网格子集
                meshObj.DrawSubset(i);
            }
            device.EndScene();
            device.Present();
        }

        static void Main()
        {
            BasicForm basicForm = new BasicForm(); //创建窗体对象
            if (basicForm.InitializeDirect3D() == false) //检查Direct3D是否启动
            {
                MessageBox.Show("无法启动Direct3D!", "错误!");
                return;
            }
            basicForm.Show(); //如果一切都初始化成功,则显示窗体
            while (basicForm.Created) //设置一个循环用于实时更新渲染状态
            {
                basicForm.Render(); //保持device渲染,直到程序结束
                basicForm.SetUpCamera();
                Application.DoEvents(); //处理键盘鼠标等输入事件
            }
        }

程序中meshObj = Mesh.FromFile(xFilePath + "\\" + xFileName,MeshFlags.SystemMemory,device,out materials);这句代码就是用来读取.X文件的。渲染函数Render()很重要,设置灯光、漫反射等有利于模型的显示。一开始没有加入渲染时显示的模型不完整,加入一些灯光及漫反射就一切OK了。
这是在DirectX中的结果:
生成.X文件的一些方法&&DirectX获取及处理.X文件(初级版)_第2张图片

关于博客中的问题,如果有网友了解的话望帮忙解答,不胜感激!

你可能感兴趣的:(技术博客,directx,direct3d,3dsmax,.X,3d)