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

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

程序执行后的界面如下:

线框模式界面如下:

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

       在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

代码下载:

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

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

时间: 2024-09-20 12:36:35

Directx11教程(55) 建立球形和锥形物体的相关文章

Directx11教程(56) 建立一个skydome

      本章建立一个skydome(天空穹),主要学习如何使用cube mapping.      cube map就是把六张纹理当作一个cube的六个面,而cube的中心,则是坐标轴,而六个面则是垂直于坐标轴某个轴,如下图所示,在cube mapping中,我们不在使用二维纹理坐标,而是用(u,v,w)三维纹理坐标,用这个坐标产生一个查询向量,这个向量和cube 纹理的交点,即为该顶点对应的纹理texel.             可以通过微软的Directx Texture tool制作

Directx11教程(5) 画一个简单的三角形(1)

      在本篇教程中,我们将通过D3D11画一个简单的三角形.在D3D11中,GPU的渲染主要通过shader来操作(当然还有一些操作是由GPU固定管线完成,比如光栅化操作),最常用的shader操作是顶点shader(vertex shader)和像素shader(pixel shader).其实shader就是在GPU中执行的代码,这些代码被driver编译成硬件依赖的机器码,最终被GPU中shader pipe执行,从而完成3D渲染.D3D11中shader是用一种类C的语言HLSL编

教程/dreamweaver/入门 Dreamweaver 4 简明教程9(建立超级链接)

dreamweaver|教程|链接 超级链接(Link),简称链接,是页面与页面之间一个单向的关联关系.通过点击链接,我们可以从一个页面跳到另一个页面.我们可以在文字.图片建立链接. 1.文字链接 在页面中选取需要建立链接的文字,如下图: 在属性面板的Link一项,填写链接地址,当浏览者点击该链接的时候,浏览器就回跳转到该页面,例如这里填写的是:http://www.goeway.com 如果你希望该页面是在一个新窗口打开,可以在Target中选择"_balnk". 如果要链接到网站内

Dreamweaver MX 2004视频宝典教程(55)

dreamweaver|教程 第 55 集:按钮和图像域 课程目标:学习Dreamweaver在按钮和图像域中的插入与设置 课程要点:按钮包括submit, botton和reset.图像域可以添加按钮图片,它具有按钮的提交功能.本节将介绍Dreamweaver在按钮和图像域中的插入与设置. [全屏观看] | [下载视频] 本教程尺寸为 800 * 600 建议全屏在线观看或下载观看,以达到最佳观看效果

FrontPage 2003基础教程(十三) 建立网站链接

这个功能和共享边框一起使用. 1.在编辑区下方有一个选项"链接"点击它. 进入建立链接面页 2.修改"新建网页"为"主页" 3.添加"新建网页"--新建一个网页--或"已有的网页"--已存在的网页,点击找到被链接的网页. 还可修改新建网页为你想要的中文名. 查看全套FrontPage 2003基础教程

Django 博客开发教程 2 - 建立 Django 博客应用

建立博客应用 我们已经建立了 Django 博客的项目工程,并且成功地运行了它.不过到目前为止这一切都还只是 Django 为我们创建的项目初始内容,Django 不可能为我们初始化生成博客代码,这些功能性代码都得由我们自己编写. Django 鼓励我们把自己编写的代码组织到应用(Application)里,并且最好是一个应用只提供一种功能.例如我们要开发的 Django 博客,相关的代码都放在 blog 这个应用里.其实应用也没什么复杂的,不过是把功能相关的代码组织到一个文件夹里,这个文件夹就

Directx11教程(3) 一个最基本D3D应用程序(1)

      在前一篇教程程序代码的基础上,这次我们将增加2个类: InputClass,键盘处理的代码将放在这个类里面,GraphicsClass类,D3D渲染的代码放在这个类里,这两个类都是SystemClass类的成员变量,SystemClass类中会调用这2个类实例的初始化.渲染以及shutdown函数.    增加这个两个类后,应用的程序的框架如下:     System Class类有点小变动,增加了两个成员变量m_Input,m_Graphics,分别处理输入和渲染的操作. Syst

Directx11教程(31) 纹理映射(1)

        在前面的例子中,我们要么是直接给顶点赋颜色值,要么是在顶点属性中设置Diffuse和Specular系数,从而根据光照参数计算得到物体表面颜色,但这样得到的颜色真实感要差很多.如果我们直接把一副图像映射到三角形面上,从而得到物体表面颜色值,效果会好很多,比如下面的两幅图,右边的图是把一副图片映射到2个三角形上.         甚至,我们还可以直接使用图像的颜色值做为顶点(或者pixel)的diffuse值,融合光照计算公式,得到最终的表面颜色值,这样会有更好的效果.     

Directx11 教程(1) 基本的windows应用程序框架(1)

       在vs2010中,建立一个新的win32工程,名字是: myTutorialD3D11, 注意:同时勾选Create directory for solution,我们同时建立一个solution,后面教程的所有的工程文件,我们都建立在这个solution中.   勾选 Emtpy project 增加source files->add new item->main.cpp   创建一个windows应用程序需要以下步骤: 1.在入口Main函数中注册窗口类 2.调用Create