• Directx11教程(55) 建立球形和锥形物体


    本教程中,我们新建2个model class,SphereModelClass以及CylinderModelClass,分别用来表示球形和锥形物体。

    程序执行后的界面如下:

    image

    线框模式界面如下:

    image

    从线框模式可以看出,球形是由三个因素决定:半径、经度线、纬度线

           在SphereModelClass.cpp中,我们看到,初始化顶点缓冲和索引缓冲的函数为:InitializeBuffers(ID3D11Device* device,  float radius, int numSlices, int numStacks),它多了三个参数,分别表示半径、经度切片的数量、纬度切面的数量。具体构建球形顶点的操作在函数buildStacks(vertices, indices)中,主要就是把经纬度切片的数目转化成球坐标系中的角度,求出球坐标系中顶点,再转化到笛卡尔坐标系中。

    代码如下:

    void SphereModelClass::buildStacks(VertexList& vertices, IndexList& indices)
        {
        float phiStep = PI/m_NumStacks;

        int numRings = m_NumStacks-1;

        // 对于每个纬度环,计算顶点.
        for(int i = 1; i <= numRings; ++i)
            {
            float phi = i*phiStep;

            // 环上的顶点
            float thetaStep = 2.0f*PI/m_NumSlices;
            for(int j = 0; j <= m_NumSlices; ++j)
                {
                float theta = j*thetaStep;

                VertexType v;

                // 球坐标到笛卡尔坐标的转化
                v.position.x = m_Radius*sinf(phi)*cosf(theta);
                v.position.y = m_Radius*cosf(phi);
                v.position .z = m_Radius*sinf(phi)*sinf(theta);

                D3DXVec3Normalize(&v.normal, &v.position);

                //球的纹理坐标
                v.texture.x = theta / (2.0f*PI);
                v.texture.y = phi / PI;

                v.Kd    = D3DXVECTOR4(0.2, 0.2, 0.1,1.0);
                v.Ks = D3DXVECTOR4(0.2, 0.2, 0.2,1.0);
                vertices.push_back( v );
                }
            }

        // 球的极点: 会出现纹理坐标扭曲
         VertexType t1;
         t1.position = D3DXVECTOR3(0.0f, -m_Radius, 0.0f);
         t1.normal = D3DXVECTOR3(0.0f, -1.0f, 0.0f);
         t1.texture = D3DXVECTOR2(0.0f, 1.0f);
         t1.Kd = D3DXVECTOR4(0.2, 0.2, 0.1,1.0);
         t1.Ks = D3DXVECTOR4(0.2, 0.2, 0.2,1.0);
        
         vertices.push_back( t1 );

         t1.position = D3DXVECTOR3(0.0f, m_Radius, 0.0f);
         t1.normal = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
         t1.texture = D3DXVECTOR2(0.0f, 0.0f);

        vertices.push_back(t1 );

        int northPoleIndex = (int)vertices.size()-1;
        int southPoleIndex = (int)vertices.size()-2;

        int numRingVertices = m_NumSlices+1;

        // 计算索引(不考虑极点)
        for(int i = 0; i < m_NumStacks-2; ++i)
            {
            for(int j = 0; j < m_NumSlices; ++j)
                {
                indices.push_back(i*numRingVertices + j);
                indices.push_back(i*numRingVertices + j+1);
                indices.push_back((i+1)*numRingVertices + j);

                indices.push_back((i+1)*numRingVertices + j);
                indices.push_back(i*numRingVertices + j+1);
                indices.push_back((i+1)*numRingVertices + j+1);
                }
            }

    //北极点索引
        for(int i = 0; i < m_NumSlices; ++i)
            {
            indices.push_back(northPoleIndex);
            indices.push_back(i+1);
            indices.push_back(i);
            }

    //南极点索引
        int baseIndex = (numRings-1)*numRingVertices;
        for(int i = 0; i < m_NumSlices; ++i)
            {
            indices.push_back(southPoleIndex);
            indices.push_back(baseIndex+i);
            indices.push_back(baseIndex+i+1);
            }
        }

          在CylinderModelClass.cpp中,我们看到InitializeBuffers(ID3D11Device* device,  float topRadius, float bottomRadius,     float height, int numSlices, int numStacks),它多出了5个参数,分别表示锥体的顶部圆半径、底部圆半径,高度、经度切片的数量、纬度切片的数量。

    具体计算顶点缓冲和索引缓冲由个函数组成,这三个函数的具体代码请参考源文件:

    buildStacks(vertices, indices);
    buildTopCap(vertices, indices);
    buildBottomCap(vertices, indices);

        

    完整的代码请参考:

    工程文件myTutorialD3D11_50

    代码下载:

    https://files.cnblogs.com/mikewolf2002/d3d1150-58.zip

    https://files.cnblogs.com/mikewolf2002/pictures.zip

  • 相关阅读:
    scanf使用尿性
    System : Assembly Programming
    Biology 03: Cardiovascular
    remove the smallest element from a linkedlist
    Relativity 04: CH4CH5
    Relativity 03: Space and Time in Classical Mechanics
    146 __str__和__repr__
    145 __init__和__new__
    144 __call__
    143 __doc__
  • 原文地址:https://www.cnblogs.com/mikewolf2002/p/2629566.html
Copyright © 2020-2023  润新知