zoukankan      html  css  js  c++  java
  • Managed DirectX +C# 开发(入门篇)(七)

    第六章 Mesh对象
    一、什么是Mesh?
    前面已经接触过Mesh类,在这里则对它进行详细介绍
    Mesh可以用来储存任何类型的图形数据,但主要用来封装复杂的模型。Mesh类同样也有一些用来提高渲染物体性能的方法。使用Mesh可以从外部文件读入3D的模型文件,比如MaYa文件,这样就可以在3D Max或MaYa等软件中做好模型,然后读入程序。
    Mesh对象内部也包含了很多几何体的模型。
    Mesh对象包位于Direct3D扩展库(D3DX Direct3D Extensions library)中。注意添加对Direct3DX.dll程序集的引用。
    Mesh类有三个构造函数。Mesh类有几个静态方法用来创建或加载不同的模型。
    所有的Mesh对象都包含了一个顶点缓冲和一个索引缓存,除此之外,他还包含了一个属性缓冲(attribute buffer)。
    二、使用Mesh
    在前面,已经使用以下方法建立了Mesh对象:
    private Mesh mesh = null;
    mesh = Mesh.Box(device,2.0f,2.0f,2.0f);
    这样就建立了一个长宽高都为2的立方体。
    如果创建一个圆柱或园台或园锥则是这样的:
    mesh = Mesh.Cylinder(device,2.0f,2.0f,2.0f,36,36);
    第二和第三个参数Radius1,Radius2 表示圆柱体的下底面和上底面半径,必须为非负;第四个参数Length 表示圆柱体在Z方向的高度;第五个参数Slices 表示沿中心轴的片段数量,第六个参数Stacks 表示沿主轴的“堆数量。(类似于由经、纬线分成的水平和垂直方向上的块数;
    创建一个多边形方法是:
    mesh = Mesh.Polygon(device,2.0f,8);
    第二个参数Length 表示多边形每一边的长度,第三个参数Sides表示有多少条边
    mesh = Mesh.Sphere(device,2.0f,36,36);
    第二个参数Radius表示球体的半径,第三个参数Slices和第四个参数Stacks的含义与Cylinder的相同。
    mesh = Mesh.Torus(device,0.5f,2.0f,36,18)
    第二个参数InnerRadius 圆环的内径,第三个参数OutterRadius 圆环的外径,第四个Sides横截面上的面数,第五个参数Rings横截面上的环数,前两个值必须为非负数,后两个必须大于等于三。
    如果创建一个茶壶,则代码为:
           mesh1=Mesh.Teapot(device);
    执行结果:
    现在看看Render()函数:
    private void Render()
             {
                  if (device == null)
                       return;
                  device.Clear(ClearFlags.Target, System.Drawing.Color.Black , 1.0f, 0);
                  SetupCamera();
                  device.BeginScene();
                      
                  Material boxMaterial = new Material();
                  boxMaterial.Ambient = Color.Pink;
                  boxMaterial.Diffuse = Color.White;
                  device.Material = boxMaterial;
                 
                  device.Transform.World=Matrix.Translation(0,50,0);
                  device.Transform.World=Matrix.Identity;
                  mesh1.DrawSubset(0);
                  device.EndScene();
                  device.Present();
                 
             }
    此次和前面不同的是,给场景设置了一个材质,所谓材质是指可以指定物体如何反射环境光以及散射光,及镜面高光,还可以指定物体是否完全反射光线。 设置完成后,把材质赋予了device的Material属性,这样Direct3D就知道渲染时使用哪种材质。
    代码mesh1.DrawSubset(0);代码里传递了一个参数0;这是什么意思呢?
    Mesh会被分为一系列的子集(subsets),同时使用DrawSubset()方法来渲染。使用Mesh类创建的普通图元总是只有一个基于0的子集。所以使用了mesh.DrawSubset(0)
    三、读入外部文件
    使用Mesh.FormFile()和Mesh.FromStream()这两个方法可以读入外部的.X文件,但3Dmax建立的模型默认并不是.X文件,因此,你需要导出为.X文件,或使用专门工具进行转化。stream方法有更多的重载以适应不同大小的流。Mesh.FormFile()这个方法有很多重载的版本,下面则是其中的一个:
    public static Mesh FromFile(
        string filename, //文件名
        MeshFlags options,//如何加载数据
        Device device,// 渲染mesh的device
        out GraphicsStream adjacency,//保存每个面相邻的3个面
        out ExtendedMaterial materials,// 保存了普通的Direct3D材质和一个加载为纹理的字符串,常是使用的纹理或资源文件名
        out EffectInstance effects //用于mesh的HLSL材质文件和值。
    );
    adjacency参数是一个“out”参数,表示在这个方法结束后adjacency会被分配并且传递出去,它将返回相邻信息。ExtendedMaterial类保存了普通的Direct3D材质和一个加载为纹理的字符串。这个字符串通常是使用的纹理或资源文件名,因为加载纹理是由程序来进行的,也可以是任何用户提供的字符串。EffectInstance参数描述了用于mesh的HLSL材质文件和值。可以根据需要选择具有不同参数的方法重载。
    在程序中,如果读入的这个.X文件有材质或者纹理,就需要根据材质和纹理的大小建立数组以保存这些纹理和材质。因为mesh中可能有许多不同的子集,所以需要分别创建一个材质和纹理的数组以针对于每一个子集。Mesh会自动地把每一个子集和这些子集的材质纹理一一对座。
    使用循环可以把ExtenedMaterial中的数据拷贝到meshMaterials中。如果子集中还包含纹理信息的话,可以使用TextureLoader.FromFile方法来创建纹理。这个方法接受两个参数,device以及作为纹理的文件名,这个方法可要比以前使用的System.Drawing.Bitmap快许多。
    以下为读入一外部文件的一段代码:
    private void LoadMesh(string file)
            {
                ExtendedMaterial[] mtrl;
                // 载入mesh
                mesh = Mesh.FromFile(file, MeshFlags.Managed, device, out mtrl);
                 // 如果有材质,则保存它们;
                if ((mtrl != null) && (mtrl.Length > 0))
               {
                    meshMaterials = new Material[mtrl.Length];
                    meshTextures = new Texture[mtrl.Length];
                    // 存储每一个材质和纹理;
                    for (int i = 0; i < mtrl.Length; i++)
                    {
                        meshMaterials[i] = mtrl[i].Material3D;
                        if ((mtrl[i].TextureFilename != null) && (mtrl[i].TextureFilename != string.Empty))
                        {
                            //如果有纹理,则载入;
                            meshTextures[i] = TextureLoader.FromFile(device, @"..\..\" + mtrl[i].TextureFilename);
                        }
                    }
                }
            }
  • 相关阅读:
    leetcode231 2的幂 leetcode342 4的幂 leetcode326 3的幂
    leetcode300. Longest Increasing Subsequence 最长递增子序列 、674. Longest Continuous Increasing Subsequence
    leetcode64. Minimum Path Sum
    leetcode 20 括号匹配
    算法题待做
    leetcode 121. Best Time to Buy and Sell Stock 、122.Best Time to Buy and Sell Stock II 、309. Best Time to Buy and Sell Stock with Cooldown 、714. Best Time to Buy and Sell Stock with Transaction Fee
    rand7生成rand10,rand1生成rand6,rand2生成rand5(包含了rand2生成rand3)
    依图
    leetcode 1.Two Sum 、167. Two Sum II
    从分类,排序,top-k多个方面对推荐算法稳定性的评价
  • 原文地址:https://www.cnblogs.com/lcxu2/p/2004034.html
Copyright © 2011-2022 走看看