• 两天学会DirectX 3D之入门


    环境配置以及背景知识

    环境
    Windows 8.1 64bit
    VS2013
    Microsoft DirectX SDK (June 2010)
    NVDIA Geforce GT755

    环境的配置參考 VS2008整合DirectX9.0开发环境


    一些背景知识 


    DirectX的和应用层与硬件层的关系例如以下


    DirectX的和应用层与硬件层的关系

    REF设备同意开发者測试那些Direct3D提供了但未被图形设备所实现的功能。

    COM(Component Object Model)是一项可使DirectX独立于编程语言,并具备向下兼容的技术。基本思想是将大而复杂的应用软件分为一系列的可现行实现,易于开发,理解复用和调整的软件单元。

    COM组件是遵循COM规范编写,以Win32动态链接库(dll)或者可执行文件形式公布的可执行二进制代码(exe)。

    COM的长处:

    • 与开发语言无关
    • 通过接口有效保证了组件的复用性
    • 组件执行效率高。便于使用和管理

    以下能够正式開始今天的学习了。

    绘制一个三角形

    用到的DxUtility类在 VS2008整合DirectX9.0开发环境已经实现了。能够直接去看。主要改动一下渲染的几个函数。

    #include "dxutility.h"
    #include <windows.h>
    #include <iostream>
    
    //
    // Globals
    //
    
    IDirect3DDevice9* Device = 0;
    D3DXMATRIX World;
    IDirect3DVertexBuffer9 * VB = 0;
    
    const int Width = 800;
    const int Height = 600;
    
    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),
            D3DUSAGE_WRITEONLY,
            Vertex::FVF,
            D3DPOOL_MANAGED,
            &VB,
            0);
    
        Vertex* vertices;
        VB->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);
    
    
        VB->Unlock();
    
        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);
    
        Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
    
        return true;
    }
    
    void Cleanup()
    {
        Dx::Release<IDirect3DVertexBuffer9*>(VB);
    }
    
    bool Display(float timeDelta)
    {
        if (Device) // Only use Device methods if we have a valid device.
        {
            Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
            Device->BeginScene();
    
            Device->SetStreamSource(0, VB, 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 Dx::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 (!Dx::InitDx(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;
        }
        Dx::EnterMsgLoop(Display);
    
        Cleanup();
    
        Device->Release();
    
        return 0;
    }
    


    终于效果 


    终于效果



    给三角形加上颜色
    数据结构定义

    struct ColorVertex{
        ColorVertex(float _x, float _y, float _z, D3DCOLOR c)
        {
            x = _x;
            y = _y;
            z = _z;
            color = c;
        }
        float x, y, z;
        D3DCOLOR color;
        static const DWORD FVF;
    };
    const DWORD ColorVertex::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;

    创建Buffer

        Device->CreateVertexBuffer(
            3 * sizeof(ColorVertex),
            D3DUSAGE_WRITEONLY,
            ColorVertex::FVF,
            D3DPOOL_MANAGED,
            &VB,
            0);
    
        ColorVertex *v;
        VB->Lock(0, 0, (void**)&v, 0);
        v[0] = ColorVertex(-1.0f, 0.0f, 2.0f, D3DCOLOR_XRGB(255, 0, 0));
        v[1] = ColorVertex(0.0f, 1.0f, 2.0f, D3DCOLOR_XRGB(0, 255, 0));
        v[2] = ColorVertex(1.0f, 0.0f, 2.0f, D3DCOLOR_XRGB(0, 0, 255));
    
        VB->Unlock();

    在绘制函数中设置使用Ground插值进行三角形绘制

    bool Display(float timeDelta)
    {
        if (Device) // Only use Device methods if we have a valid device.
        {
            std::cout << "Display" << std::endl;
            Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
            Device->BeginScene();
    
            Device->SetStreamSource(0, VB, 0, sizeof(ColorVertex));
            Device->SetFVF(ColorVertex::FVF);
    
            Device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
            Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
    
            Device->EndScene();
            Device->Present(0, 0, 0, 0);
        }
    
        return true;
    }
    


    渲染结果


    渲染结果


    绘制一个旋转的正方体

    生成Vertex Buffer和Index Buffer

       Device->CreateVertexBuffer(
            8 * sizeof(ColorVertex),
            D3DUSAGE_WRITEONLY,
            ColorVertex::FVF,
            D3DPOOL_MANAGED,
            &VB,
            0);
        Device->CreateIndexBuffer(
            36 * sizeof(WORD),
            D3DUSAGE_WRITEONLY,
            D3DFMT_INDEX16,
            D3DPOOL_MANAGED,
            &IB,
            0);
    
        ColorVertex *v;
        VB->Lock(0, 0, (void**)&v, 0);
        v[0] = ColorVertex(-1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB(255, 0, 0));
        v[1] = ColorVertex(-1.0f, 1.0f, -1.0f, D3DCOLOR_XRGB(0, 255, 0));
        v[2] = ColorVertex(1.0f, 1.0f, -1.0f, D3DCOLOR_XRGB(0, 0, 255));
        v[3] = ColorVertex(1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB(255, 255, 0));
        v[4] = ColorVertex(-1.0f, -1.0f, 1.0f, D3DCOLOR_XRGB(0, 255, 0));
        v[5] = ColorVertex(-1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 255));
        v[6] = ColorVertex(1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 255));
        v[7] = ColorVertex(1.0f, -1.0f, 1.0f, D3DCOLOR_XRGB(0, 255, 0));
    
        VB->Unlock();
    
        WORD* indices = 0;
        IB->Lock(0, 0, (void**)&indices, 0);
        // front side
        indices[0] = 0; indices[1] = 1; indices[2] = 2;
        indices[3] = 0; indices[4] = 2; indices[5] = 3;
    
        // back side
        indices[6] = 4; indices[7] = 6; indices[8] = 5;
        indices[9] = 4; indices[10] = 7; indices[11] = 6;
    
        // left side
        indices[12] = 4; indices[13] = 5; indices[14] = 1;
        indices[15] = 4; indices[16] = 1; indices[17] = 0;
    
        // right side
        indices[18] = 3; indices[19] = 2; indices[20] = 6;
        indices[21] = 3; indices[22] = 6; indices[23] = 7;
    
        // top
        indices[24] = 1; indices[25] = 5; indices[26] = 6;
        indices[27] = 1; indices[28] = 6; indices[29] = 2;
    
        // bottom
        indices[30] = 4; indices[31] = 0; indices[32] = 3;
        indices[33] = 4; indices[34] = 3; indices[35] = 7;
    
        IB->Unlock();



    绘制函数。让正方体旋转起来

           // spin the cube:
            //
            D3DXMATRIX Rx, Ry;
    
            // rotate 45 degrees on x-axis
            D3DXMatrixRotationX(&Rx, 3.14f / 4.0f);
    
            // incremement y-rotation angle each frame
            static float y = 0.0f;
            D3DXMatrixRotationY(&Ry, y);
            y += timeDelta;
    
            // reset angle to zero when angle reaches 2*PI
            if (y >= 6.28f)
                y = 0.0f;
    
            // combine x- and y-axis rotation transformations.
            D3DXMATRIX p = Rx * Ry;
    
            Device->SetTransform(D3DTS_WORLD, &p);
    
            Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
            Device->BeginScene();
    
            Device->SetStreamSource(0, VB, 0, sizeof(ColorVertex));
            Device->SetIndices(IB);
            Device->SetFVF(ColorVertex::FVF);
    
    
            Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);
    
            Device->EndScene();
            Device->Present(0, 0, 0, 0);
    



    在屏幕上显示FPS信息
    首先初始化文字

        D3DXFONT_DESC d3dFont;
    
        memset(&d3dFont, 0, sizeof(d3dFont));
        d3dFont.Height = 25; // in logical units
        d3dFont.Width = 12; // in logical units
        d3dFont.Weight = 500;// boldness, range 0(light) - 1000(bold)
        d3dFont.Italic = FALSE;
        d3dFont.CharSet = DEFAULT_CHARSET;
        strcpy_s(d3dFont.FaceName, "Times New Roman");
        if (FAILED(D3DXCreateFontIndirect(Device, &d3dFont, &font)))
        {
            ::MessageBox(0, "D3DXCreateFontIndirect() - FAILED", 0, 0);
            ::PostQuitMessage(0);
        }
    



    声明几个变量

    ID3DXFont* font = 0;
    DWORD FrameCnt = 0;
    float TimeElapsed = 0;
    float FPS = 0;
    char FPSString[16];
    


    FPS的计算 

    FrameCnt++;
    TimeElapsed += timeDelta;
    if (TimeElapsed >= 1.0f)
    {
        FPS = (float)FrameCnt / TimeElapsed;
        sprintf_s(FPSString, "FPS:%f", FPS);
        FPSString[15] = ''; // mark end of string
        TimeElapsed = 0.0f;
        FrameCnt = 0;
    }



    文字的渲染

    Device->BeginScene();
    RECT rect = { 0, 0, Width, Height };
    font->DrawText(
        m_pSprite,
        FPSString,
        -1, // size of string or -1 indicates null terminating string
        &rect, // rectangle text is to be formatted to in windows coords
        DT_TOP | DT_LEFT, // draw in the top left corner of the viewport
        0xff000000);      // black text
    
    Device->EndScene();


    记住最后要Clear掉COM对象

    void Cleanup()
    {
        Dx::Release<IDirect3DVertexBuffer9*>(VB);
        Dx::Release<IDirect3DIndexBuffer9*>(IB);
        Dx::Release<ID3DXFont*>(font);
    }
    


    执行结果

    执行结果


    參考

    Introduction to 3D Game Programming with DirectX® 9.0

  • 相关阅读:
    存储过程的优缺点?
    springboot注解
    springboot处理事务
    索引面试问题
    剑指Offer编程题(Java实现)——替换空格
    剑指Offer编程题(Java实现)——二维数组中的查找
    Java集合概括总结及集合选用
    Java中获取大小:length、length()、size()
    解决MarkDown打开出现:awesomium web-brower framework This view has crashed
    Java集合:Collection、List、Set、Map、泛型
  • 原文地址:https://www.cnblogs.com/llguanli/p/8417473.html
Copyright © 2020-2023  润新知