zoukankan      html  css  js  c++  java
  • DirectX基础学习系列8 渐进网格以及外接体

    1 IUnknown--> ID3DXBUFFER D3D泛型接口:

    GetBufferPointer

    Retrieves a pointer to the data in the buffer.

    GetBufferSize

    Retrieves the total size of the data in the buffer.

    使用完之后需要进行释放:Release()

    2XFILE

    //从文件中加载xfile文件

     HRESULT  D3DXLoadMeshFromX(
      __in   LPCTSTR pFilename,    //xfile文件名
      __in   DWORD Options,        //加载可选项
      __in   LPDIRECT3DDEVICE9 pD3DDevice, //设备
      __out  LPD3DXBUFFER *ppAdjacency,  //临街信息,DWORD数组
      __out  LPD3DXBUFFER *ppMaterials,  //材质信息
      __out  LPD3DXBUFFER *ppEffectInstances, //
      __out  DWORD *pNumMaterials,   //材质数目
      __out  LPD3DXMESH *ppMesh
    );
    //材质结构:ppMaterials结构中第I项 对应第I个子集
    typedef struct D3DXMATERIAL {
      D3DMATERIAL9 MatD3D;
      LPSTR        pTextureFilename;
    } D3DXMATERIAL, *LPD3DXMATERIAL;
    加载时,首先加载XFILE文件,然后遍历纹理数据,将纹理数据加载,在渲染的时候,先设置纹理和纹理
    3生成顶点法线
    方便使用光照,网格的法向量计算方法
     HRESULT  D3DXComputeNormals(
      __inout  LPD3DXBASEMESH pMesh,     //输出的网格数据
      __in     const DWORD *pAdjacency   //临街数据
    );
    pMesh参数中顶点格式必须包含D3DFVF_NORMAL,所以需要从原先的mesh数据copy一份过来
    4.渐进网格
    类似于渐进纹理数据,通过边折叠技术对网格进行简化,并且这种操作时可逆转的
    渐进网格从已有的网格数据中产生:
        D3DXGeneratePMesh(
            LPD3DXMESH pMesh, 
            CONST DWORD* pAdjacency, //邻接信息dword数组
            CONST D3DXATTRIBUTEWEIGHTS *pVertexAttributeWeights, //指定相应顶点属性权值 涉及被移除的概率
            CONST FLOAT *pVertexWeights,  //指定顶点权值,涉及被移除的概率
            DWORD MinValue,        //面片简化的最少值,如果设置为1 表示尽可能的少
            DWORD Options,         //决定上面的参数为定点数或者面片数
            LPD3DXPMESH* ppPMesh); 
    D3DXATTRIBUTEWEIGHTS 顶点属相权值结构,暂且使用默认值
    D3DXPMesh提供的操作接口:
    GetMaxFaces() //最多的面片数目上限
    GetMinFaces() //最少的面片数目下限
    GetMaxVertexs() //最多的顶点数目上限
    GetMinVertexs() //最少的顶点数目下限
    SetNumFaces() // 设置面片数目,
    SetNumVertexs() //设置顶点数目
    trimByFaces(newfacemin , newfacemax, --- ., --)  // 重新设置顶点的最大,最小限制
    trimByVetex(newfacemin , newfacemax, --- ., --)  // 重新设置顶点的最大,最小限制
    5外接体:可以用于检测碰撞以及可见性
    //外接球
        D3DXComputeBoundingSphere(
            CONST D3DXVECTOR3 *pFirstPosition,  // pointer to first position  指向顶点的第一个位置
    DWORD NumVertices, 数组中顶点数目 DWORD dwStride, // count in bytes to subsequent position vectors 每个顶点字节数 D3DXVECTOR3 *pCenter, 外界球中心 FLOAT *pRadius); 外接球半径
    // 外界体
        D3DXComputeBoundingBox(
            CONST D3DXVECTOR3 *pFirstPosition,  // pointer to first position,指向顶点的第一个位置
            DWORD NumVertices,                      //顶点数组中的顶点数目
            DWORD dwStride,                     // count in bytes to subsequent position vectors 每个顶点的字节数
            D3DXVECTOR3 *pMin,     //返回的
            D3DXVECTOR3 *pMax);
    //////////////////////////////////////////////////////////////////////////////////////////////////
    // 
    // File: boundingvolumes.cpp
    // 
    // Author: Frank Luna (C) All Rights Reserved
    //
    // System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 
    //
    // Desc: Demonstrates how to use D3DXComputeBoundingSphere and D3DXComputeBoundingBox.
    //
    //      -The spacebar key switches between rendering the mesh's bounding sphere and box.
    //          
    //////////////////////////////////////////////////////////////////////////////////////////////////
    
    #include "d3dUtility.h"
    #include <vector>
    
    //
    // Globals
    //
    
    IDirect3DDevice9* Device = 0; 
    
    const int Width  = 640;
    const int Height = 480;
    
    ID3DXMesh*                      Mesh = 0;
    ID3DXPMesh*                     pMesh = 0;
    std::vector<D3DMATERIAL9>       Mtrls(0);
    std::vector<IDirect3DTexture9*> Textures(0);
    
    ID3DXMesh* SphereMesh = 0;
    ID3DXMesh* BoxMesh    = 0;
    
    bool RenderBoundingSphere = true;
    
    //
    // Prototypes
    //
    
    bool ComputeBoundingSphere(ID3DXMesh* mesh, d3d::BoundingSphere* sphere);
    bool    ComputeBoundingBox(ID3DXMesh* mesh, d3d::BoundingBox*    box);
    
    //
    // Framework functions
    //
    bool Setup()
    {
        HRESULT hr = 0;
    
        //
        // Load the XFile data.
        //
        ID3DXBuffer* adjBuffer  = 0;
        ID3DXBuffer* mtrlBuffer = 0;
        DWORD        numMtrls   = 0;
    
        hr = D3DXLoadMeshFromX(  
            "bigship1.x",
            D3DXMESH_MANAGED,
            Device,
            &adjBuffer,
            &mtrlBuffer,
            0,
            &numMtrls,
            &Mesh);
    
        if(FAILED(hr))
        {
            ::MessageBox(0, "D3DXLoadMeshFromX() - FAILED", 0, 0);
            return false;
        }
    
        //
        // Extract the materials, load textures.
        //
    
        if( mtrlBuffer != 0 && numMtrls != 0 )
        {
            D3DXMATERIAL* mtrls = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer();
    
            for(int i = 0; i < numMtrls; i++)
            {
                // the MatD3D property doesn't have an ambient value set
                // when its loaded, so set it now:
                mtrls[i].MatD3D.Ambient = mtrls[i].MatD3D.Diffuse;
    
                // save the ith material
                Mtrls.push_back( mtrls[i].MatD3D );
    
                // check if the ith material has an associative texture
                if( mtrls[i].pTextureFilename != 0 )
                {
                    // yes, load the texture for the ith subset
                    IDirect3DTexture9* tex = 0;
                    D3DXCreateTextureFromFile(
                        Device,
                        mtrls[i].pTextureFilename,
                        &tex);
    
                    // save the loaded texture
                    Textures.push_back( tex );
                }
                else
                {
                    // no texture for the ith subset
                    Textures.push_back( 0 );
                }
            }
        }
        d3d::Release<ID3DXBuffer*>(mtrlBuffer); // done w/ buffer
    
        //
        // Optimize the mesh.
        //
    
        hr = Mesh->OptimizeInplace(        
            D3DXMESHOPT_ATTRSORT |
            D3DXMESHOPT_COMPACT  |
            D3DXMESHOPT_VERTEXCACHE,
            (DWORD*)adjBuffer->GetBufferPointer(),
            0, 0, 0);
    
        d3d::Release<ID3DXBuffer*>(adjBuffer); // done w/ buffer
    
        if(FAILED(hr))
        {
            ::MessageBox(0, "OptimizeInplace() - FAILED", 0, 0);
            return false;
        }
    
        //
        // Compute Bounding Sphere and Bounding Box.
        //
        
        d3d::BoundingSphere boundingSphere;
        d3d::BoundingBox    boundingBox;
    
        ComputeBoundingSphere(Mesh, &boundingSphere);
        ComputeBoundingBox(Mesh, &boundingBox);
    
        D3DXCreateSphere(
            Device,
            boundingSphere._radius,
            20,
            20,
            &SphereMesh,
            0);
    
        D3DXCreateBox(
            Device,
            boundingBox._max.x - boundingBox._min.x,
            boundingBox._max.y - boundingBox._min.y,
            boundingBox._max.z - boundingBox._min.z,
            &BoxMesh,
            0);
    
        //
        // Set texture filters.
        //
    
        Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
        Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
        Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
    
        // 
        // Set Lights.
        //
    
        D3DXVECTOR3 dir(1.0f, -1.0f, 1.0f);
        D3DXCOLOR col(1.0f, 1.0f, 1.0f, 1.0f);
        D3DLIGHT9 light = d3d::InitDirectionalLight(&dir, &col);
    
        Device->SetLight(0, &light);
        Device->LightEnable(0, true);
        Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
        Device->SetRenderState(D3DRS_SPECULARENABLE, true);
    
        //
        // Set camera.
        //
    
        D3DXVECTOR3 pos(4.0f, 12.0f, -20.0f);
        D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
        D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
    
        D3DXMATRIX V;
        D3DXMatrixLookAtLH(
            &V,
            &pos,
            &target,
            &up);
    
        Device->SetTransform(D3DTS_VIEW, &V);
    
        //
        // Set projection matrix.
        //
    
        D3DXMATRIX proj;
        D3DXMatrixPerspectiveFovLH(
                &proj,
                D3DX_PI * 0.5f, // 90 - degree
                (float)Width / (float)Height,
                1.0f,
                1000.0f);
        Device->SetTransform(D3DTS_PROJECTION, &proj);
    
        return true;
    }
    
    void Cleanup()
    {
        d3d::Release<ID3DXMesh*>(Mesh);
    
        for(int i = 0; i < Textures.size(); i++)
            d3d::Release<IDirect3DTexture9*>( Textures[i] );
    
        d3d::Release<ID3DXMesh*>(SphereMesh);
        d3d::Release<ID3DXMesh*>(BoxMesh);
    }
    
    bool Display(float timeDelta)
    {
        if( Device )
        {
            //
            // Update: Rotate the mesh.
            //
    
            static float y = 0.0f;
            D3DXMATRIX yRot;
            D3DXMatrixRotationY(&yRot, y);
            y += timeDelta;
    
            if( y >= 6.28f )
                y = 0.0f;
    
            D3DXMATRIX World = yRot;
    
            Device->SetTransform(D3DTS_WORLD, &World);
    
            //
            // Render
            //
    
            Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
            Device->BeginScene();
    
            // draw the mesh
            for(int i = 0; i < Mtrls.size(); i++)
            {
                Device->SetMaterial( &Mtrls[i] );
                Device->SetTexture(0, Textures[i]);
                Mesh->DrawSubset(i);
            }    
    
            //
            // Draw bounding volume in blue and at 10% opacity
            D3DMATERIAL9 blue = d3d::BLUE_MTRL;
            blue.Diffuse.a = 0.10f; // 10% opacity
    
            Device->SetMaterial(&blue);
            Device->SetTexture(0, 0); // disable texture
    
            Device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
            Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
            Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    
            if( RenderBoundingSphere )
                SphereMesh->DrawSubset(0);
            else
                BoxMesh->DrawSubset(0);
    
            Device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
    
            Device->EndScene();
            Device->Present(0, 0, 0, 0);
        }
        return true;
    }
    
    //
    // WndProc
    //
    LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch( msg )
        {
        case WM_DESTROY:
            ::PostQuitMessage(0);
            break;
            
        case WM_KEYDOWN:
            if( wParam == VK_ESCAPE )
                ::DestroyWindow(hwnd);
    
            if( wParam == VK_SPACE )
                RenderBoundingSphere = !RenderBoundingSphere;
    
            break;
        }
        return ::DefWindowProc(hwnd, msg, wParam, lParam);
    }
    
    //
    // WinMain
    //
    int WINAPI WinMain(HINSTANCE hinstance,
                       HINSTANCE prevInstance, 
                       PSTR cmdLine,
                       int showCmd)
    {
        if(!d3d::InitD3D(hinstance,
            Width, Height, true, D3DDEVTYPE_HAL, &Device))
        {
            ::MessageBox(0, "InitD3D() - FAILED", 0, 0);
            return 0;
        }
            
        if(!Setup())
        {
            ::MessageBox(0, "Setup() - FAILED", 0, 0);
            return 0;
        }
    
        d3d::EnterMsgLoop( Display );
    
        Cleanup();
    
        Device->Release();
    
        return 0;
    }
    
    bool ComputeBoundingSphere(ID3DXMesh* mesh, d3d::BoundingSphere* sphere)
    {
        HRESULT hr = 0;
    
        BYTE* v = 0;
        mesh->LockVertexBuffer(0, (void**)&v);
    
        hr = D3DXComputeBoundingSphere(
                (D3DXVECTOR3*)v,
                mesh->GetNumVertices(),
                D3DXGetFVFVertexSize(mesh->GetFVF()),
                &sphere->_center,
                &sphere->_radius);
    
        mesh->UnlockVertexBuffer();
    
        if( FAILED(hr) )
            return false;
    
        return true;
    }
    
    bool ComputeBoundingBox(ID3DXMesh* mesh, d3d::BoundingBox* box)
    {
        HRESULT hr = 0;
    
        BYTE* v = 0;
        mesh->LockVertexBuffer(0, (void**)&v);
    
        hr = D3DXComputeBoundingBox(
                (D3DXVECTOR3*)v,
                mesh->GetNumVertices(),
                D3DXGetFVFVertexSize(mesh->GetFVF()),
                &box->_min,
                &box->_max);
    
        mesh->UnlockVertexBuffer();
    
        if( FAILED(hr) )
            return false;
    
        return true;
    }
    View Code
  • 相关阅读:
    numpy.random.seed()方法
    TensorFlow问题“The TensorFlow library wasn't compiled to use SSE instructions, but these are available on your machine and could speed up CPU computations.”
    TensorFlow实现Softmax Regression识别手写数字中"TimeoutError: [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败”问题
    关于from nltk.book import * 报错解决方法
    LeetCode---Container With Most Water(11)
    如何解决python中使用flask时遇到的markupsafe._compat包缺失的问题
    解决python中flask_sqlalchemy包安装失败的问题
    高级软件工程第二次作业(四则运算生成器)
    Truncate有外键约束的表
    OSharp DbContent初始化分析
  • 原文地址:https://www.cnblogs.com/zsb517/p/3394063.html
Copyright © 2011-2022 走看看