zoukankan      html  css  js  c++  java
  • Direct3D中的绘制

    1.顶点缓存和索引缓存

    一个顶点缓存是一个包含顶点数据的连续内存空间;一个索引缓存是一个包含索引数据的连续内存空间。

    顶点缓存用接口IDirect3DVertexBuffer9表示;索引缓存用接口IDirect3DIndexBuffer9表示。

    1.1创建顶点缓存和索引缓存

    HRESULT IDirect3DDevice9::CreateVertexBuffer(
      UINT Length,  //为缓存分配的字节数
      DWORD Usage, //指定如何使用缓存的附加属性,0表明无需附加属性
      DWORD FVF,   //存储在顶点缓存中的灵活顶点格式
      D3DPOOL Pool,  //容纳缓存的内存池
      IDirect3DVertexBuffer9** ppVertexBuffer,  //顶点缓存的指针
      HANDLE* pSharedHandle   //不使用,为0。
    );
    HRESULT IDirect3DDevice9::CreateIndexBuffer(
      UINT Length,  //为缓存分配的字节数
      DWORD Usage,  //指定如何使用缓存的附加属性,0表明无需附加属性
      D3DFORMAT Format, //索引的大小.D3DFMT_INDEX16(16位索引),D3DFMT_INDEX32 (32位索引)
      D3DPOOL Pool,  //容纳缓存的内存池
      IDirect3DIndexBuffer9** ppIndexBuffer,  //索引缓存的指针
      HANDLE* pSharedHandle   //不使用,为0。
    );
    下面例子,创建一个容纳8个Vertex类型顶点的静态顶点缓存:
    IDirect3DVertexBuffer9* vb;
    Device-> CreateVertexBuffer(8*sizeof(Vertex),
    0,
    D3DFVF_XYZ,
    D3DPOOL_MANAGED,
    &vb,
    0);
    下面是创建动态缓存的例子,可容纳36个16位索引:
    IDirect3DIndexBuffer9* ib;
    Device-> CreateIndexBuffer(36*sizeof(WORD),
    D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
    D3DFMT_INDEX16,
    D3DPOOL_MANAGED,
    & ib,
    0);
    1.2访问缓存内容
    借助方法Lock来获取指向缓存内容的指针。对缓存访问完毕后,要进行Unlock。
    HRESULT IDirect3DVertexBuffer9::Lock(
      UINT OffsetToLock,
      UINT SizeToLock,
      VOID ** ppbData,
      DWORD Flags
    );
    HRESULT IDirect3DIndexBuffer9::Lock (
      UINT OffsetToLock, //自缓存的起始点到开始锁定位置的偏移量,单位为字节。
      UINT SizeToLock,  //所要锁定的字节数
      VOID ** ppbData,  //指向被锁定的存储区,起始位置的指针
      DWORD Flags  //锁定的方式,可以为0.
    );
    注:Flags,可以是0,也可以是下列选项之一或组合。
    D3DLOCK_DISCARD 仅用于动态缓存。它指示硬件将缓存丢弃,并返回一个新的缓存指针。
    D3DLOCK_NOOVERWRITE仅用于动态缓存。数据以追加方式写入缓存。
    D3DLOCK_NO_DIRTY_UPDATE 
    D3DLOCK_NOSYSLOCK 
    D3DLOCK_READONLY  对锁定的缓存只读,不能写
    D3DLOCK_DONOTWAIT
    下面例子说明了Lock的一般使用方式:
    Vertex * v;
    vb->Lock(0,0,(void **)&v,0);
    v[0]=Vertex(-1.0f,0.0f,2.0f);
    v[1]=Vertex(0.0f,1.0f,2.0f);
    v[2]=Vertex(1.0f,0.0f,2.0f);
    vb->Unlock();
    1.3获取顶点缓存和索引缓存的信息
    D3DVERTEXBUFFER_DESC vbDescription;
    vb->GetDesc(&vbDescription);
    D3DINDEXBUFFER_DESC ibDescription;
    Ib->GetDesc(&ibDescription);
    2.绘制状态
    Direct3D封装了多种绘制状态,这些绘制状态影响了几何体的绘制方式。如果要更改默认值,用方法:
    HRESULT  IDirect3DDevice9::SetRenderState
    {
    D3DRENDERSTATETYPE State,
     DWORD Value
    }
    3.绘制的准备工作
    一旦我们创建了顶点缓存和索引缓存(可选),我们基本上可以对其存储内容进行绘制。在绘制前有3个步骤需完成:
    3.1指定数据流输入源.实质是将几何体的信息传输的绘制流水线中。
    HRESULT IDirect3DDevice9::SetStreamSource(
      UINT StreamNumber, //标示与顶点缓存建立连接的数据流
      IDirect3DVertexBuffer9 * pStreamData, //顶点缓存的指针
      UINT OffsetInBytes, //指定了将被传输至绘制流水线的顶点数据的起始位置
      UINT Stride  //顶点缓存中每个元素的大小
    );
    Device->SetStreamSource(0,vb,0,sizeof(Vertex));
    3.2设置顶点格式
    Device->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE);
    3.3设置索引缓存
    Device->SetIndices(ib);
    4.使用顶点缓存和索引缓存进行绘制
    HRESULT IDirect3DDevice9::DrawPrimitive
    (D3DPRIMITIVETYPE PrimitiveType,  //所要绘制的图元类型,
      UINT StartVertex,   //读取起点元素的索引
      UINT PrimitiveCount //图元数量
    )
    HRESULT IDirect3DDevice9::DrawIndexedPrimitive(
      D3DPRIMITIVETYPE Type,
      INT BaseVertexIndex,
      UINT MinIndex, //允许引用的最小索引值
      UINT NumVertices,//将引用的顶点总数
      UINT StartIndex, //
      UINT PrimitiveCount
    );
    以上的绘制函数必须位于BeginScene() 和EndScene()函数对之间。
    #include "d3dUtility.h"
    
    IDirect3DDevice9* Device = 0; 
    
    const int Width  = 640;
    const int Height = 480;
    
    IDirect3DVertexBuffer9* Triangle = 0; 
    
    struct Vertex
    {
        Vertex(){}
    
        Vertex(float x, float y, float z)
        {
            _x = x;     _y = y;  _z = z;
        }
    
        float _x, _y, _z;
    
        static const DWORD FVF;
    };
    const DWORD Vertex::FVF = D3DFVF_XYZ;
    
    //
    // Framework Functions
    //
    bool Setup()
    {
        Device->CreateVertexBuffer(
            3 * sizeof(Vertex), // size in bytes
            D3DUSAGE_WRITEONLY, // flags
            Vertex::FVF,        // vertex format
            D3DPOOL_MANAGED,    // managed memory pool
            &Triangle,          // return create vertex buffer
            0);                 // not used - set to 0
    
        //
        // Fill the buffers with the triangle data.
        //
    
        Vertex* vertices;
        Triangle->Lock(0, 0, (void**)&vertices, 0);
    
        vertices[0] = Vertex(-1.0f, 0.0f, 2.0f);
        vertices[1] = Vertex( 0.0f, 1.0f, 2.0f);
        vertices[2] = Vertex( 1.0f, 0.0f, 2.0f);
    
        Triangle->Unlock();
    
        //
        // Set the projection matrix.
        //
    
        D3DXMATRIX proj;
        D3DXMatrixPerspectiveFovLH(
                &proj,                        // result
                D3DX_PI * 0.5f,               // 90 - degrees
                (float)Width / (float)Height, // aspect ratio
                1.0f,                         // near plane
                1000.0f);                     // far plane
        Device->SetTransform(D3DTS_PROJECTION, &proj);
    
        //
        // Set wireframe mode render state.
        //
    
        Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
    
        return true;
    }
    void Cleanup()
    {
        d3d::Release<IDirect3DVertexBuffer9*>(Triangle);
    }
    
    bool Display(float timeDelta)
    {
        if( Device )
        {
            Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
            Device->BeginScene();
    
            Device->SetStreamSource(0, Triangle, 0, sizeof(Vertex));
            Device->SetFVF(Vertex::FVF);
    
            // Draw one triangle.
            Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
    
            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);
            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;
    }
    main.cpp
  • 相关阅读:
    pc 端支付宝支付流程
    crontab
    Java集合之HashSet
    Java内存与垃圾收集知识总结
    Volley设计思想和流程分析
    java内部类
    HandlerThread源码分析
    IntentService源码分析
    Android消息机制:Looper,MessageQueue,Message与handler
    LeetCode340 Longest Substring with At Most K Distinct Characters
  • 原文地址:https://www.cnblogs.com/hometown/p/3652307.html
Copyright © 2011-2022 走看看