• 热门专题

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

作者:迈克老狼2012  发布日期:2012-03-21 20:39:43
Tag标签:Directx11  三角形  
  • 在本篇教程中,我们将通过D3D11画一个简单的三角形。在D3D11中,GPU的渲染主要通过shader来操作(当然还有一些操作是由GPU固定管线完成,比如光栅化操作),最常用的shader操作是顶点shader(vs)和像素shader(ps)。其实shader就是在GPU中执行的代码,这些代码被driver编译成硬件依赖的机器码,最终被GPU中SP(shader pipe)执行,从而完成3D渲染。D3D11中shader是用一种类C的语言HLSL编写的。首先我们来了解一下三维物体的模型,通常3D对象都是通过mesh(三角形)来表示的。比如我们看到的一个渲染后的球体,实际上它是有许许多多的小的mesh组成。
     

    顶点缓冲就是一个buffer,用来存放3D物体的顶点数据。

    索引缓冲,就是对顶点缓冲的索引,可以用来减少渲染物体时候传入显存的顶点数量。比如一个正方体有8个顶点,同时也是由12个三角形组成(每个面2个三角形),我们渲染3D物体,在硬件层次都是通过三角形来渲染的,所以渲染这12个三角形,就需要36个顶点数据,但是通过索引缓冲,我们只需传入8个顶点,通过索引不同顺序的3个顶点,来实现12个三角形的渲染。

    [GPU和系统内存之间,通过PCIE总线连接,传入数据受总线宽度的影响,所以我们要尽可能减少传输数据的数量]

     程序的框架现在如下图所示:

     
     

    我们增加了3个类:

    ModelClass主要用来建立顶点缓冲、索引缓冲,即准备渲染数据。

    CamerClass主要用来得到view矩阵,就是得到摄像机在三维空间的位置和方位。

    ColorShaderClass主要用来处理shader相关的代码。


    下面我们将贴出所有的程序代码:

    color.vs的代码如下:

     

    ///////////// 
    // GLOBALS // 
    //shader中使用的全局变量都在定义在const buffer中 
    //这样shader编译后,这些变量放在gpu的const buffer中 
    ///////////// 
    cbuffer MatrixBuffer 
    { 
        matrix worldMatrix; 
        matrix viewMatrix; 
        matrix projectionMatrix; 
    };
    
    ////////////// 
    // TYPEDEFS // 
    //注意:POSITION, COLOR等是我们在定义顶点布局中定义名字。 
    ////////////// 
    struct VertexInputType 
    { 
        float4 position : POSITION; 
        float4 color : COLOR; 
    };
    
    struct PixelInputType 
    { 
        float4 position : SV_POSITION; //SV表示系统自动定义的格式。 
        float4 color : COLOR; 
    };
    
    //////////////////////////////////////////////////////////////////////////////// 
    // Vertex Shader 
    //////////////////////////////////////////////////////////////////////////////// 
    PixelInputType ColorVertexShader(VertexInputType input) 
    { 
        PixelInputType output; 
        
    
        //顶点坐标扩展成四个分量,并设置为1,以便矩阵运算 
        input.position.w = 1.0f;
    
        // 乘以3个矩阵,得到clip空间的坐标。 
        output.position = mul(input.position, worldMatrix); 
        output.position = mul(output.position, viewMatrix); 
        output.position = mul(output.position, projectionMatrix); 
        
        //直接输出顶点的颜色(.顶点之间的颜色,会采用插值的方式计算) 
        output.color = input.color; 
        
        return output; 
    }
    
    

    color.ps的代码如下:


    ////////////// 
    // TYPEDEFS // 
    //像素输入格式 
    ////////////// 
    struct PixelInputType 
    { 
        float4 position : SV_POSITION; 
        float4 color : COLOR; 
    };
    
    
    //////////////////////////////////////////////////////////////////////////////// 
    // Pixel Shader 
    //////////////////////////////////////////////////////////////////////////////// 
    float4 ColorPixelShader(PixelInputType input) : SV_TARGET 
    { 
        return input.color; 
    } 
    
    
    

    main.cpp的代码如下:

     

    #include "SystemClass.h"
    
    //应用程序入口main函数 
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pScmdline, int iCmdshow) 
        { 
        SystemClass* System; 
        bool result;
    
    
        // 创建一个system对象. 
        System = new SystemClass; 
        if(!System) 
            { 
            return 0; 
            }
    
        // 初始化以及运行system对象. 
        result = System->Initialize(); 
        if(result) 
            { 
            System->Run(); 
            }
    
        // 关闭以及释放system对象. 
        System->Shutdown(); 
        delete System; 
        System = 0; 
        return 0; 
        }
    
    

    SystemClass.h的代码如下:

     

    #pragma once 
    //定义该宏能够减少windows头文件的大小,使编译器不编译一些不必要的文件,加快编译时间 
    #define WIN32_LEAN_AND_MEAN
    
    #include <windows.h>
    
    #include "InputClass.h" 
    #include "GraphicsClass.h"
    
    class SystemClass 
        { 
        public: 
            SystemClass(void); 
            SystemClass(const SystemClass &); 
            ~SystemClass(void);
    
            bool Initialize(); 
            void Shutdown(); 
            void Run();
    
            LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM); 
        private: 
            bool Frame(); 
            void InitializeWindows(int&, int&); 
            void ShutdownWindows();
    
            LPCWSTR m_applicationName; 
            HINSTANCE m_hinstance; 
            HWND m_hwnd;
    
            //InputClass和GraphicsClass是SystemClass的两个成员变量 
            InputClass* m_Input; 
            GraphicsClass* m_Graphics; 
        };
    
    //定义静态的回调函数以及应用程序句柄 
    //因为定义窗口类时候,必须指定窗口回调函数,所以我们用静态的回调函数WndProc 
    static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    static SystemClass* ApplicationHandle = 0;
    
    

    SystemClass.cpp代码如下:

     

    #include "SystemClass.h"
    
    
    SystemClass::SystemClass(void) 
        { 
        m_Input = 0; 
        m_Graphics = 0; 
        }
    
    SystemClass::SystemClass(const SystemClass &) 
        {
    
        }
    
    SystemClass::~SystemClass(void) 
        { 
        }
    
    //调用窗口初始化函数和其它一些类的初始化函数 
    bool SystemClass::Initialize() 
        { 
        bool result; 
        int screenWidth = 0, screenHeight = 0;
    
       // 初始化窗口 
        InitializeWindows(screenWidth, screenHeight);
    
        //创建input对象处理键盘输入 
        m_Input = new InputClass; 
        if(!m_Input) 
            { 
            return false; 
            }
    
        // 初始化输入对象. 
        m_Input->Initialize();
    
       // 创建图形对象,这个对象将渲染应用程序中的所有物体 
        m_Graphics = new GraphicsClass; 
        if(!m_Graphics) 
            { 
            return false; 
            } 
        // 初始化图形对象 
        result = m_Graphics->Initialize(screenWidth, screenHeight, m_hwnd); 
        if(!result) 
            { 
            return false; 
            }
    
    
        return true; 
        }
    
    void SystemClass::Shutdown() 
        { 
       //其它类的一些销毁工作 
        if(m_Graphics) 
            { 
            m_Graphics->Shutdown(); 
            delete m_Graphics; 
            m_Graphics = 0; 
            }
    
        if(m_Input) 
            { 
            delete m_Input; 
            m_Input = 0; 
            } 
        // 执行一些销毁工作. 
        ShutdownWindows();
    
        }
    
    //处理消息 
    void  SystemClass::Run() 
        { 
        MSG msg; 
        bool done, result ;
    
    
        // 初始化消息结构. 
        ZeroMemory(&msg, sizeof(MSG));
    
        // 循环进行消息处理,如果接收到WM_QUIT. 
        done = false; 
        while(!done) 
            { 
           // 处理windows消息. 
            if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
                { 
                TranslateMessage(&msg); 
                DispatchMessage(&msg); 
                }
    
           // 接收到WM_QUIT消息,退出程序. 
            if(msg.message == WM_QUIT) 
                { 
                done = true; 
                } 
            else 
                {
    
                //我们的渲染或者其它处理,可以放在这儿 
                //.... 
                //..... 
                result = Frame(); 
                if(!result) 
                    { 
                    done = true; 
                    } 
                }
    
            }
    
        return; 
        }
    
    bool SystemClass::Frame() 
        { 
        bool result;
    
    
       //检测用户是否按下ESC键,如果按下,退出程序. 
        if(m_Input->IsKeyDown(VK_ESCAPE)) 
            { 
            return false; 
            }
    
        // 执行帧渲染函数. 
        result = m_Graphics->Frame(); 
        if(!result) 
            { 
            return false; 
            } 
        return true; 
        }
    
    //初始化窗口类,创建应用程序窗口 
    void SystemClass::InitializeWindows(int& screenWidth, int& screenHeight) 
        { 
        WNDCLASSEX wc; 
        DEVMODE dmScreenSettings; 
        int posX, posY;
    
        //得到应用程序对象指针 
        ApplicationHandle = this;
    
        // 得到应用程序实例句柄 
        m_hinstance = GetModuleHandle(NULL);
    
        // 应用程序名字 
        m_applicationName = L"Engine";
    
        // 设置窗口类参数. 
        wc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; 
        wc.lpfnWndProc   = WndProc; //指定回调函数 
        wc.cbClsExtra    = 0; 
        wc.cbWndExtra    = 0; 
        wc.hInstance     = m_hinstance; 
        wc.hIcon         = LoadIcon(NULL, IDI_WINLOGO); 
        wc.hIconSm       = wc.hIcon; 
        wc.hCursor       = LoadCursor(NULL, IDC_ARROW); 
        wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); //默认黑色窗口黑色背景 
        wc.lpszMenuName  = NULL; 
        wc.lpszClassName = m_applicationName; 
        wc.cbSize        = sizeof(WNDCLASSEX);
    
        // 注册窗口类 
        RegisterClassEx(&wc);
    
       // 得到windows桌面分辨率 
        screenWidth  = GetSystemMetrics(SM_CXSCREEN); 
        screenHeight = GetSystemMetrics(SM_CYSCREEN);
    
        // 根据是否全屏设置不同的分辨率. 
        if(FULL_SCREEN) 
            { 
            //全屏模式下,设置窗口大小为windows桌面分辨率. 
            memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); 
            dmScreenSettings.dmSize       = sizeof(dmScreenSettings); 
            dmScreenSettings.dmPelsWidth  = (unsigned long)screenWidth; 
            dmScreenSettings.dmPelsHeight = (unsigned long)screenHeight; 
            dmScreenSettings.dmBitsPerPel = 32;            
            dmScreenSettings.dmFields     = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
    
            // 临时设置显示设备为全屏模式,注意:应用程序退出时候,将恢复系统默认设置。 
            ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
    
           // 设置窗口的默认位置为(0,0). 
            posX = posY = 0; 
            } 
        else 
            { 
           // 窗口模式:800*600. 
            screenWidth  = 800; 
            screenHeight = 600;
    
            // 窗口位置,posX, posY窗口左上角坐标 
            posX = (GetSystemMetrics(SM_CXSCREEN) - screenWidth)  / 2; 
            posY = (GetSystemMetrics(SM_CYSCREEN) - screenHeight) / 2; 
            }
    
       // 全屏和窗口使用不同的参数. 
        if( FULL_SCREEN) 
            { 
            m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_applicationName, m_applicationName, 
                WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP, 
                posX, posY, screenWidth, screenHeight, NULL, NULL, m_hinstance, NULL); 
            } 
        else 
            { 
            m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_applicationName, m_applicationName, 
                WS_OVERLAPPEDWINDOW, 
                posX, posY, screenWidth, screenHeight, NULL, NULL, m_hinstance, NULL); 
            }
    
       // 显示窗口并设置其为焦点. 
        ShowWindow(m_hwnd, SW_SHOW); 
        SetForegroundWindow(m_hwnd); 
        SetFocus(m_hwnd);
    
        // 隐藏鼠标. 
        //ShowCursor(false);
    
    
        }
    
    void SystemClass::ShutdownWindows() 
        { 
        //显示光标. 
        //ShowCursor(true);
    
        // 恢复默认显示设置. 
        if(FULL_SCREEN) 
            { 
            ChangeDisplaySettings(NULL, 0); 
            }
    
        // 销毁窗口 
        DestroyWindow(m_hwnd); 
        m_hwnd = NULL;
    
       // 销毁应用程序实例. 
        UnregisterClass(m_applicationName, m_hinstance); 
        m_hinstance = NULL; 
        ApplicationHandle = NULL;
    
        return;
    
        }
    
    LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) 
        {
    
        switch(umsg) 
            { 
            // 检测按键消息. 
        case WM_KEYDOWN: 
            { 
            m_Input->KeyDown((unsigned int)wparam); 
            return 0; 
            }
    
        case WM_KEYUP: 
            { 
            m_Input->KeyUp((unsigned int)wparam); 
            return 0; 
            } 
           //任何其它消息发送到windows缺省处理. 
        default: 
            { 
            return DefWindowProc(hwnd, umsg, wparam, lparam); 
            } 
            } 
        }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam) 
        { 
        switch(umessage) 
            {
    
            // 窗口销毁消息. 
        case WM_DESTROY: 
            { 
            PostQuitMessage(0); 
            return 0; 
            }
    
           // 窗口关闭消息. 
        case WM_CLOSE: 
            { 
            PostQuitMessage(0);        
            return 0; 
            }
    
            //MessageHandle过程处理其它所有消息. 
        default: 
            { 
            return ApplicationHandle->MessageHandler(hwnd, umessage, wparam, lparam); 
            } 
            } 
        }
    
    

    InputClass.h代码如下


    #pragma once 
    class InputClass 
        { 
        public: 
            InputClass(void); 
            InputClass(const InputClass&); 
            ~InputClass(void);
    
            void Initialize();
    
            void KeyDown(unsigned int); 
            void KeyUp(unsigned int);
    
            bool IsKeyDown(unsigned int);
    
        private: 
            bool m_keys[256]; //用来存放256个虚拟键是否被按下 
        };
    
    

    InputClass.cpp代码如下:


    #include "InputClass.h"
    
    
    InputClass::InputClass(void) 
        { 
        }
    
    InputClass::InputClass(const InputClass&) 
        {
    
        }
    
    InputClass::~InputClass(void) 
        { 
        }
    
    void InputClass::Initialize() 
        { 
        int i;
    
       // 初始所有的键都是非按下状态. 
        for(i=0; i<256; i++) 
            { 
            m_keys[i] = false; 
            }
    
        return; 
        }
    
    
    void InputClass::KeyDown(unsigned int input) 
        { 
        //键被按下. 
        m_keys[input] = true; 
        return; 
        }
    
    
    void InputClass::KeyUp(unsigned int input) 
        { 
        //释放按键. 
        m_keys[input] = false; 
        return; 
        }
    
    
    bool InputClass::IsKeyDown(unsigned int key) 
        { 
       // 判断键是否被按下? 
        return m_keys[key]; 
        }
    
    
    GraphicsClass.h代码如下:
    #pragma once
    
    #include <windows.h> 
    #include "d3dclass.h" 
    #include "cameraclass.h" 
    #include "modelclass.h" 
    #include "colorshaderclass.h"
    
    ///////////// 
    // GLOBALS // 
    ///////////// 
    const bool FULL_SCREEN = false; //是否全屏 
    const bool VSYNC_ENABLED = true; //是否垂直同步 
    const float SCREEN_DEPTH = 1000.0f; //深度,远点 
    const float SCREEN_NEAR = 0.1f; //深度,近点
    
    class GraphicsClass 
        { 
        public: 
            GraphicsClass(void); 
            GraphicsClass(const GraphicsClass&); 
            ~GraphicsClass(void); 
            bool Initialize(int, int, HWND); 
            void Shutdown(); 
            bool Frame();
    
        private: 
            bool Render();
    
           //定义一个D3DClass类成员变量 
            D3DClass* m_D3D; 
            CameraClass* m_Camera; 
            ModelClass* m_Model; 
            ColorShaderClass* m_ColorShader;
    
        };
    
    

    GraphicsClass.cpp代码如下:

     

    #include "GraphicsClass.h"
    
    
    GraphicsClass::GraphicsClass(void) 
        { 
        m_D3D = 0; 
        m_Camera = 0; 
        m_Model = 0; 
        m_ColorShader = 0;
    
        }
    
    GraphicsClass::GraphicsClass(const GraphicsClass&) 
        {
    
        } 
    GraphicsClass::~GraphicsClass(void) 
        { 
        }
    
    bool GraphicsClass:: Initialize(int screenWidth, int screenHeight, HWND hwnd) 
        { 
        bool result;
    
    
       // 创建一个D3DClass对象. 
        m_D3D = new D3DClass; 
        if(!m_D3D) 
            { 
            return false; 
            }
    
       // 调用D3DClass初始化函数 
        result = m_D3D->Initialize(screenWidth, screenHeight, VSYNC_ENABLED, hwnd, FULL_SCREEN, SCREEN_DEPTH, SCREEN_NEAR); 
        if(!result) 
            { 
            MessageBox(hwnd, L"Could not initialize Direct3D", L"Error", MB_OK); 
            return false; 
            }
    
       //创建摄像机对象 
        m_Camera = new CameraClass; 
        if(!m_Camera) 
            { 
            return false; 
            }
    
        // 设置摄像机位置. 
        m_Camera->SetPosition(0.0f, 0.0f, -10.0f);
    
        // 创建模型对象. 
        m_Model = new ModelClass; 
        if(!m_Model) 
            { 
            return false; 
            }
    
       // 初始化模型对象. 
        result = m_Model->Initialize(m_D3D->GetDevice()); 
        if(!result) 
            { 
            MessageBox(hwnd, L"Could not initialize the model object.", L"Error", MB_OK); 
            return false; 
            }
    
       // 创建shader对象 
        m_ColorShader = new ColorShaderClass; 
        if(!m_ColorShader) 
            { 
            return false; 
            }
    
       // 初始化shader对象 
        result = m_ColorShader->Initialize(m_D3D->GetDevice(), hwnd); 
        if(!result) 
            { 
            MessageBox(hwnd, L"Could not initialize the color shader object.", L"Error", MB_OK); 
            return false; 
            }
    
        return true; 
        }
    
    void GraphicsClass::Shutdown() 
        { 
        // 释放shader对象. 
        if(m_ColorShader) 
            { 
            m_ColorShader->Shutdown(); 
            delete m_ColorShader; 
            m_ColorShader = 0; 
            }
    
        // 释放模型对象. 
        if(m_Model) 
            { 
            m_Model->Shutdown(); 
            delete m_Model; 
            m_Model = 0; 
            }
    
        // 释放摄像机对象 
        if(m_Camera) 
            { 
            delete m_Camera; 
            m_Camera = 0; 
            }
    
       //销毁m_D3D对象 
        if(m_D3D) 
            { 
            m_D3D->Shutdown(); 
            delete m_D3D; 
            m_D3D = 0; 
            }
    
        return; 
        }
    
    
    bool GraphicsClass::Frame() 
        { 
        bool result;
    
    
        // 调用Render函数,渲染3D场景 
        // Render是GraphicsClass的私有函数. 
        result = Render(); 
        if(!result) 
            { 
            return false; 
            }
    
        return true; 
        }
    
    
    bool GraphicsClass::Render() 
        {
    
        D3DXMATRIX viewMatrix, projectionMatrix, worldMatrix; 
        bool result;
    
    
        // 设置framebuffer.为浅蓝色 
        m_D3D->BeginScene(0.0f, 0.0f, 0.5f, 1.0f);
    
        // 得到view矩阵. 
       m_Camera->Render();
    
        // 得到3个矩阵. 
        m_Camera->GetViewMatrix(viewMatrix); 
        m_D3D->GetWorldMatrix(worldMatrix); 
        m_D3D->GetProjectionMatrix(projectionMatrix);
    
        // 把模型顶点和索引缓冲放入管线,准备渲染. 
        m_Model->Render(m_D3D->GetDeviceContext());
    
        // 用shader渲染. 
        result = m_ColorShader->Render(m_D3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix); 
        if(!result) 
            { 
            return false; 
            } 
        
        //把framebuffer中的图像present到屏幕上. 
        m_D3D->EndScene();
    
        return true; 
        }
    
    

    D3DClass.h代码如下:

     

    #pragma once
    
    //链接程序使用的一些D3D库 
    #pragma comment(lib, "dxgi.lib") 
    #pragma comment(lib, "d3d11.lib") 
    #pragma comment(lib, "d3dx11.lib") 
    #pragma comment(lib, "d3dx10.lib")
    
    //D3D的一些头文件 
    #include <dxgi.h> 
    #include <d3dcommon.h> 
    #include <d3d11.h> 
    #include <d3dx10math.h>
    
    
    class D3DClass 
        { 
        public: 
            D3DClass(void); 
            D3DClass(const D3DClass&); 
            ~D3DClass(void);
    
            bool Initialize(int, int, bool, HWND, bool, float, float); 
            void Shutdown();
    
            void BeginScene(float, float, float, float); 
            void EndScene();
    
            ID3D11Device* GetDevice(); 
            ID3D11DeviceContext* GetDeviceContext();
    
            void GetProjectionMatrix(D3DXMATRIX&); 
            void GetWorldMatrix(D3DXMATRIX&); 
            void GetOrthoMatrix(D3DXMATRIX&);
    
            void GetVideoCardInfo(char*, int&);
    
        private: 
            bool m_vsync_enabled; //是否启用垂直同步 
            int m_videoCardMemory; //显存大小 
            char m_videoCardDescription[128]; //显卡名字 
            IDXGISwapChain* m_swapChain; //交换链对象 
            ID3D11Device* m_device;  //设备对象 
            ID3D11DeviceContext* m_deviceContext; //设备上下文对象 
            ID3D11RenderTargetView* m_renderTargetView; //渲染目标视图 
            ID3D11Texture2D* m_depthStencilBuffer; 
            ID3D11DepthStencilState* m_depthStencilState; 
            ID3D11DepthStencilView* m_depthStencilView; //深度目标视图 
            ID3D11RasterizerState* m_rasterState; //渲染状态 
            D3DXMATRIX m_projectionMatrix; //投影矩阵 
            D3DXMATRIX m_worldMatrix; //世界坐标系矩阵 
            D3DXMATRIX m_orthoMatrix; //正交投影矩阵
    
    
        };
    
    

    D3DClass.cpp代码如下:

     

    #include "D3DClass.h"
    
    D3DClass::D3DClass(void) 
        { 
        m_swapChain = 0; 
        m_device = 0; 
        m_deviceContext = 0; 
        m_renderTargetView = 0; 
        m_depthStencilBuffer = 0; 
        m_depthStencilState = 0; 
        m_depthStencilView = 0; 
        m_rasterState = 0;
    
        }
    
    D3DClass::D3DClass(const D3DClass& other) 
        { 
        }
    
    
    D3DClass::~D3DClass(void) 
        { 
        }
    
    //Initialize函数包含完成D3D设置的所有代码。 
    bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, 
        float screenDepth, float screenNear) 
        { 
        HRESULT result; 
        IDXGIFactory* factory; 
        IDXGIAdapter* adapter; 
        IDXGIOutput* adapterOutput; 
        unsigned int numModes, i, numerator, denominator, stringLength; 
        DXGI_MODE_DESC* displayModeList; 
        DXGI_ADAPTER_DESC adapterDesc; 
        int error; 
        DXGI_SWAP_CHAIN_DESC swapChainDesc; 
        D3D_FEATURE_LEVEL featureLevel; 
        ID3D11Texture2D* backBufferPtr; 
        D3D11_TEXTURE2D_DESC depthBufferDesc; 
        D3D11_DEPTH_STENCIL_DESC depthStencilDesc; 
        D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; 
        D3D11_RASTERIZER_DESC rasterDesc; 
        D3D11_VIEWPORT viewport; 
        float fieldOfView, screenAspect;
    
    
        // 保存垂直同步设置 
        m_vsync_enabled = vsync;
    
        // 创建一个DirectX graphics interface factory. 
        result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
        // 用接口工厂创建一个主显卡的适配 
        result = factory->EnumAdapters(0, &adapter); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
        // 得到主适配器的输出. 
        result = adapter->EnumOutputs(0, &adapterOutput); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
       //得到适合 DXGI_FORMAT_R8G8B8A8_UNORM 的显示模式. 
        result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
        displayModeList = new DXGI_MODE_DESC[numModes]; 
        if(!displayModeList) 
            { 
            return false; 
            }
    
       // 保存显示模式到displayModeList中 
        result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
       //遍历所有显示模式,得到刷新率两个参数值numerator 和 denominato 
        for(i=0; i<numModes; i++) 
            { 
            if(displayModeList[i].Width == (unsigned int)screenWidth) 
                { 
                if(displayModeList[i].Height == (unsigned int)screenHeight) 
                    { 
                    numerator = displayModeList[i].RefreshRate.Numerator; 
                    denominator = displayModeList[i].RefreshRate.Denominator; 
                    } 
                } 
            } 
       // 得到显卡描述 
        result = adapter->GetDesc(&adapterDesc); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
        // 保存显存大小. 
        m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024);
    
        //保存显卡描述串 
        //wcstombs_s, wide char转化为char 
        error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); 
        if(error != 0) 
            { 
            return false; 
            } 
        // 释放显示模式列表 
        delete [] displayModeList; 
        displayModeList = 0;
    
        //释放适配器输出. 
        adapterOutput->Release(); 
        adapterOutput = 0;
    
       //释放适配器 
        adapter->Release(); 
        adapter = 0;
    
       // 释放接口工厂. 
        factory->Release(); 
        factory = 0;
    
        // 初始化交换链描述 
        ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
    
        // 用1个后缓冲 
        swapChainDesc.BufferCount = 1;
    
        //帧缓冲的大小和应用程序窗口大小相等. 
        swapChainDesc.BufferDesc.Width = screenWidth; 
        swapChainDesc.BufferDesc.Height = screenHeight;
    
        // 后缓冲的surface的格式为DXGI_FORMAT_R8G8B8A8_UNORM. 
        // surface的每个像素用4个无符号的8bit[映射到0-1]来表示。NORM表示归一化。 
        swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    
        // 如果使用垂直同步,设置后缓冲的刷新率。. 
        //刷新率就是一秒钟把后缓冲内容在屏幕上画出的次数。 
        //如果开启垂直同步,则锁定刷新率,则fps是固定的 
        if(m_vsync_enabled) 
            { 
            swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; 
            swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; 
            } 
        else 
            { 
            swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; 
            swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; 
            }
    
        // 设置后缓冲的用途 
        // 我们的渲染目标缓冲为后缓冲。 
        swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    
       // 后缓冲输出的窗口句柄. 
        swapChainDesc.OutputWindow = hwnd;
    
        // 不使用多重采样 
        swapChainDesc.SampleDesc.Count = 1; 
        swapChainDesc.SampleDesc.Quality = 0;
    
        // 设置全屏或者窗口模式. 
        if(fullscreen) 
            { 
            swapChainDesc.Windowed = false; 
            } 
        else 
            { 
            swapChainDesc.Windowed = true; 
            }
    
        // 设定扫描线ordering以及缩放为unspecified. 
        swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; 
        swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
    
        // 后缓冲内容呈现到屏幕后,放弃其内容 
        swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    
        //不设置标志 
        swapChainDesc.Flags = 0;
    
        // 设置feature level为D3D11 
        // 如果显卡不支持D3D11,我们能够通过设置这个参数,使用D3D10,或者9. 
        featureLevel = D3D_FEATURE_LEVEL_11_0;
    
        // 创建交换链,设备以及设备上下文. 
        result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, 
            D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
        // 得到交换链中的后缓冲指针. 
        result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
       // 用后缓冲创建渲染目标视图. 
        result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
       //释放后缓冲.(引用计数减1) 
        backBufferPtr->Release(); 
        backBufferPtr = 0;
    
        // 初始化深度缓冲描述. 
        ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));
    
       //设置深度缓冲描述 
        depthBufferDesc.Width = screenWidth; 
        depthBufferDesc.Height = screenHeight; 
        depthBufferDesc.MipLevels = 1; //对于深度缓冲为1 
        depthBufferDesc.ArraySize = 1; //对于深度缓冲为1,对于纹理,这2个参数有更多用途 
        depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; 
        depthBufferDesc.SampleDesc.Count = 1; 
        depthBufferDesc.SampleDesc.Quality = 0; 
        depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; 
        depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; 
        depthBufferDesc.CPUAccessFlags = 0; 
        depthBufferDesc.MiscFlags = 0;
    
        // 创建深度缓冲. 
        result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); 
        if(FAILED(result)) 
            { 
            return false;
    
            }
    
       // 初始化深度模版状态描述. 
        ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));
    
        // 设置深度模版状态描述. 
        depthStencilDesc.DepthEnable = true; 
        depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;//D3D11_DEPTH_WRITE_MASK_ZERO禁止写深度缓冲 
        depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
    
        depthStencilDesc.StencilEnable = true; 
        depthStencilDesc.StencilReadMask = 0xFF; 
        depthStencilDesc.StencilWriteMask = 0xFF;
    
        // 对于front face 像素使用的模版操作操作. 
        depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; 
        depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; 
        depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; 
        depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
    
        // 对于back face像素使用的模版操作模式. 
        depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; 
        depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; 
        depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; 
        depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
    
       // 创建深度模版状态,使其生效 
        result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); 
        if(FAILED(result)) 
            { 
            return false;
    
            }
    
        // 设置深度模版状态. 
        m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1);
    
        // 初始化深度模版视图. 
        ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));
    
        // 设置深度模版视图描述. 
        depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; 
        depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; 
        depthStencilViewDesc.Texture2D.MipSlice = 0;
    
        // 创建深度模版视图. 
        result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
        // 绑定渲染目标视图和深度缓冲到渲染管线. 
        m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);
    
    
        // 设置光栅化描述,指定多边形如何被渲染. 
        rasterDesc.AntialiasedLineEnable = false; 
        rasterDesc.CullMode = D3D11_CULL_BACK; 
        rasterDesc.DepthBias = 0; 
        rasterDesc.DepthBiasClamp = 0.0f; 
        rasterDesc.DepthClipEnable = true; 
        rasterDesc.FillMode = D3D11_FILL_SOLID; 
        rasterDesc.FrontCounterClockwise = false; 
        rasterDesc.MultisampleEnable = false; 
        rasterDesc.ScissorEnable = false; 
        rasterDesc.SlopeScaledDepthBias = 0.0f;
    
       // 创建光栅化状态 
        result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
       //设置光栅化状态,使其生效 
        m_deviceContext->RSSetState(m_rasterState);
    
    
        // 设置视口,显示全部后缓冲内容 
        viewport.Width = (float)screenWidth; 
        viewport.Height = (float)screenHeight; 
        viewport.MinDepth = 0.0f; 
        viewport.MaxDepth = 1.0f; 
        viewport.TopLeftX = 0.0f; 
        viewport.TopLeftY = 0.0f;
    
       // 创建视口 
        m_deviceContext->RSSetViewports(1, &viewport);
    
        // 设置透视投影矩阵 
        fieldOfView = (float)D3DX_PI / 4.0f; 
        screenAspect = (float)screenWidth / (float)screenHeight;
    
        // 创建透视投影矩阵. 
        D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, screenNear, screenDepth);
    
        //初始化world矩阵为单位矩阵. 
        //该矩阵实现局部坐标到世界坐标的转换 
        D3DXMatrixIdentity(&m_worldMatrix);
    
    
       // 创建正交投影矩阵,主要用来实施2D渲染. 
        D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, screenNear, screenDepth);
    
        return true;
    
    
        }
    
        void D3DClass::Shutdown() 
            { 
           // 释放交换链资源前,先设置为窗口模式,否则可能会产生异常. 
            if(m_swapChain) 
                { 
                m_swapChain->SetFullscreenState(false, NULL); 
                }
    
            if(m_rasterState) 
                { 
                m_rasterState->Release(); 
                m_rasterState = 0; 
                }
    
            if(m_depthStencilView) 
                { 
                m_depthStencilView->Release(); 
                m_depthStencilView = 0; 
                }
    
            if(m_depthStencilState) 
                { 
                m_depthStencilState->Release(); 
                m_depthStencilState = 0; 
                }
    
            if(m_depthStencilBuffer) 
                { 
                m_depthStencilBuffer->Release(); 
                m_depthStencilBuffer = 0; 
                }
    
            if(m_renderTargetView) 
                { 
                m_renderTargetView->Release(); 
                m_renderTargetView = 0; 
                }
    
            if(m_deviceContext) 
                { 
                m_deviceContext->Release(); 
                m_deviceContext = 0; 
                }
    
            if(m_device) 
                { 
                m_device->Release(); 
                m_device = 0; 
                }
    
            if(m_swapChain) 
                { 
                m_swapChain->Release(); 
                m_swapChain = 0; 
                }
    
            return; 
            }
    
        void D3DClass::BeginScene(float red, float green, float blue, float alpha) 
            { 
            float color[4];
    
    
           // 设置清除后缓冲颜色. 
            color[0] = red; 
            color[1] = green; 
            color[2] = blue; 
            color[3] = alpha;
    
            //清除后缓冲. 
            m_deviceContext->ClearRenderTargetView(m_renderTargetView, color);
    
            //清除深度缓冲. 
            m_deviceContext->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
    
            return; 
            }
    
    
        void D3DClass::EndScene() 
            { 
            //渲染完成后,把后缓冲内容present到前缓冲 
            if(m_vsync_enabled) 
                { 
               // 锁定屏幕刷新率. 
                m_swapChain->Present(1, 0); 
                } 
            else 
                { 
               // 尽可能快的present后缓冲. 
                m_swapChain->Present(0, 0); 
                }
    
            return; 
            }
    
        ID3D11Device* D3DClass::GetDevice() 
            { 
            return m_device; 
            }
    
    
        ID3D11DeviceContext* D3DClass::GetDeviceContext() 
            { 
            return m_deviceContext; 
            }
    
        void D3DClass::GetProjectionMatrix(D3DXMATRIX& projectionMatrix) 
            { 
            projectionMatrix = m_projectionMatrix; 
            return; 
            }
    
    
        void D3DClass::GetWorldMatrix(D3DXMATRIX& worldMatrix) 
            { 
            worldMatrix = m_worldMatrix; 
            return; 
            }
    
    
        void D3DClass::GetOrthoMatrix(D3DXMATRIX& orthoMatrix) 
            { 
            orthoMatrix = m_orthoMatrix; 
            return; 
            }
    
        void D3DClass::GetVideoCardInfo(char* cardName, int& memory) 
            { 
            strcpy_s(cardName, 128, m_videoCardDescription); 
            memory = m_videoCardMemory; 
            return; 
            }
    
    

    ModelClass.h代码如下:

     

    #pragma once
    
    #include <d3d11.h> 
    #include <d3dx10math.h>
    
    
    class ModelClass 
        { 
        private: 
            struct VertexType 
                { 
                D3DXVECTOR3 position; 
                D3DXVECTOR4 color; 
                };
    
        public: 
            ModelClass(void); 
            ModelClass(const ModelClass &);
    
            ~ModelClass(void); 
            bool Initialize(ID3D11Device*); 
            void Shutdown(); 
            void Render(ID3D11DeviceContext*);
    
            int GetIndexCount();
    
        private: 
            bool InitializeBuffers(ID3D11Device*); 
            void ShutdownBuffers(); 
            void RenderBuffers(ID3D11DeviceContext*); 
           //顶点缓冲和顶点索引缓冲 
            ID3D11Buffer *m_vertexBuffer, *m_indexBuffer; 
            int m_vertexCount, m_indexCount;
    
        };
    
    

    ModelClass.cpp代码如下:

     

    #include "ModelClass.h"
    
    
    ModelClass::ModelClass(void) 
        { 
        m_vertexBuffer = 0; 
        m_indexBuffer = 0;
    
        }
    
    ModelClass::ModelClass(const ModelClass & others) 
        {
    
        }
    
    ModelClass::~ModelClass(void) 
        { 
        }
    
    bool ModelClass::Initialize(ID3D11Device* device) 
        { 
        bool result;
    
    
        // 初始化顶点缓冲和顶点索引缓冲. 
        result = InitializeBuffers(device); 
        if(!result) 
            { 
            return false; 
            }
    
        return true; 
        }
    
    void ModelClass::Shutdown() 
        { 
       // 释放顶点和索引缓冲. 
        ShutdownBuffers();
    
        return; 
        }
    
    void ModelClass::Render(ID3D11DeviceContext* deviceContext) 
        { 
        // 把顶点和索引缓冲放入图形管线,准备渲染. 
        RenderBuffers(deviceContext);
    
        return; 
        }
    
    int ModelClass::GetIndexCount() 
        { 
        //返回索引顶点计数 
        return m_indexCount; 
        }
    
    bool ModelClass::InitializeBuffers(ID3D11Device* device) 
        { 
        VertexType* vertices; 
        unsigned long* indices; 
        D3D11_BUFFER_DESC vertexBufferDesc, indexBufferDesc; 
        D3D11_SUBRESOURCE_DATA vertexData, indexData; 
        HRESULT result;
    
        //首先,我们创建2个临时缓冲存放顶点和索引数据,以便后面使用。. 
    
        // 设置顶点缓冲大小为3,一个三角形. 
        m_vertexCount = 3;
    
        // 设置索引缓冲大小. 
        m_indexCount = 3;
    
        // 创建顶点临时缓冲. 
        vertices = new VertexType[m_vertexCount]; 
        if(!vertices) 
            { 
            return false; 
            }
    
        // 创建索引缓冲. 
        indices = new unsigned long[m_indexCount]; 
        if(!indices) 
            { 
            return false; 
            } 
        //创建顺时针方向的三角形,左手规则 
        // 设置顶点数据. 
        vertices[0].position = D3DXVECTOR3(-1.0f, -1.0f, 0.0f);  // 左下 
        vertices[0].color = D3DXVECTOR4(1.0f, 1.0f, 0.0f, 1.0f);
    
        vertices[1].position = D3DXVECTOR3(0.0f, 1.0f, 0.0f);  // 中上. 
        vertices[1].color = D3DXVECTOR4(0.0f, 1.0f, 0.0f, 1.0f);
    
        vertices[2].position = D3DXVECTOR3(1.0f, -1.0f, 0.0f);  // 底右 
        vertices[2].color = D3DXVECTOR4(0.0f, 1.0f, 1.0f, 1.0f);
    
       // 设置索引缓冲数据. 
        indices[0] = 0;  // Bottom left. 
        indices[1] = 1;  // Top middle. 
        indices[2] = 2;  // Bottom right.
    
        // 设置顶点缓冲描述 
        vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT; 
        vertexBufferDesc.ByteWidth = sizeof(VertexType) * m_vertexCount; 
        vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; 
        vertexBufferDesc.CPUAccessFlags = 0; 
        vertexBufferDesc.MiscFlags = 0; 
        vertexBufferDesc.StructureByteStride = 0;
    
       // 指向保存顶点数据的临时缓冲. 
        vertexData.pSysMem = vertices; 
        vertexData.SysMemPitch = 0; 
        vertexData.SysMemSlicePitch = 0;
    
        // 创建顶点缓冲. 
        result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &m_vertexBuffer); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
        // 设置索引缓冲描述. 
        indexBufferDesc.Usage = D3D11_USAGE_DEFAULT; 
        indexBufferDesc.ByteWidth = sizeof(unsigned long) * m_indexCount; 
        indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; 
        indexBufferDesc.CPUAccessFlags = 0; 
        indexBufferDesc.MiscFlags = 0; 
        indexBufferDesc.StructureByteStride = 0;
    
        // 指向存临时索引缓冲. 
        indexData.pSysMem = indices; 
        indexData.SysMemPitch = 0; 
        indexData.SysMemSlicePitch = 0;
    
       // 创建索引缓冲. 
        result = device->CreateBuffer(&indexBufferDesc, &indexData, &m_indexBuffer); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
       // 释放临时缓冲. 
        delete [] vertices; 
        vertices = 0;
    
        delete [] indices; 
        indices = 0;
    
        return true; 
        }
    
    void ModelClass::ShutdownBuffers() 
        { 
        // 释放顶点缓冲. 
        if(m_indexBuffer) 
            { 
            m_indexBuffer->Release(); 
            m_indexBuffer = 0; 
            }
    
       // 释放索引缓冲 
        if(m_vertexBuffer) 
            { 
            m_vertexBuffer->Release(); 
            m_vertexBuffer = 0; 
            }
    
        return; 
        }
    
    void ModelClass::RenderBuffers(ID3D11DeviceContext* deviceContext) 
        { 
        unsigned int stride; 
        unsigned int offset;
    
    
       // 设置顶点缓冲跨度和偏移. 
        stride = sizeof(VertexType); 
        offset = 0;
    
        //在input assemberl阶段绑定顶点缓冲,以便能够被渲染 
        deviceContext->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &offset);
    
        //在input assemberl阶段绑定索引缓冲,以便能够被渲染 
        deviceContext->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R32_UINT, 0);
    
       // 设置体元语义,渲染三角形列表. 
        deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    
        return; 
        }
    
    

    CameraClass.h代码如下:

     

    #pragma once
    
    #include <d3dx10math.h>
    
    class CameraClass 
        { 
        public: 
            CameraClass(void); 
            CameraClass(const CameraClass&); 
            ~CameraClass(void); 
            void SetPosition(float, float, float); 
            void SetRotation(float, float, float);
    
            D3DXVECTOR3 GetPosition(); 
            D3DXVECTOR3 GetRotation();
    
            void Render(); 
            void GetViewMatrix(D3DXMATRIX&); 
        private: 
            float m_positionX, m_positionY, m_positionZ; //摄像机在世界坐标系中的位置 
            float m_rotationX, m_rotationY, m_rotationZ; //摄像机的欧拉旋转角度 
            D3DXMATRIX m_viewMatrix;
    
    
        };
    
    

    CameraClass.cpp的代码如下:

     

    #include "CameraClass.h"
    
    
    CameraClass::CameraClass(void) 
        { 
        m_positionX = 0.0f; 
        m_positionY = 0.0f; 
        m_positionZ = 0.0f;
    
        m_rotationX = 0.0f; 
        m_rotationY = 0.0f; 
        m_rotationZ = 0.0f; 
        }
    
    CameraClass::CameraClass(const CameraClass& other) 
        { 
        }
    
    CameraClass::~CameraClass(void) 
        { 
        }
    
    void CameraClass::SetPosition(float x, float y, float z) 
        { 
        m_positionX = x; 
        m_positionY = y; 
        m_positionZ = z; 
        return; 
        }
    
    
    void CameraClass::SetRotation(float x, float y, float z) 
        { 
        m_rotationX = x; 
        m_rotationY = y; 
        m_rotationZ = z; 
        return; 
        }
    
    D3DXVECTOR3 CameraClass::GetPosition() 
        { 
        return D3DXVECTOR3(m_positionX, m_positionY, m_positionZ); 
        }
    
    
    D3DXVECTOR3 CameraClass::GetRotation() 
        { 
        return D3DXVECTOR3(m_rotationX, m_rotationY, m_rotationZ); 
        }
    
    void CameraClass::Render() 
        { 
        D3DXVECTOR3 up, position, lookAt; 
        float yaw, pitch, roll; 
        D3DXMATRIX rotationMatrix;
    
    
        // 设置up向量为(0,1,0). 
        up.x = 0.0f; 
        up.y = 1.0f; 
        up.z = 0.0f;
    
        // 设置摄像机的位置. 
        position.x = m_positionX; 
        position.y = m_positionY; 
        position.z = m_positionZ;
    
        // 设置摄像机lookat的方向. 
        lookAt.x = 0.0f; 
        lookAt.y = 0.0f; 
        lookAt.z = 1.0f;
    
        // 得到弧度单位的欧拉旋转 yaw (Y axis), pitch (X axis), 以及 roll (Z axis) . 
        pitch = m_rotationX * 0.0174532925f; 
        yaw   = m_rotationY * 0.0174532925f; 
        roll  = m_rotationZ * 0.0174532925f;
    
        // 得到旋转矩阵. 
        D3DXMatrixRotationYawPitchRoll(&rotationMatrix, yaw, pitch, roll);
    
        // 变换lookat和up向量,一般view能够在原点被正确旋转. 
        D3DXVec3TransformCoord(&lookAt, &lookAt, &rotationMatrix); 
        D3DXVec3TransformCoord(&up, &up, &rotationMatrix);
    
        // 平移旋转后的摄像机位置. 
        lookAt = position + lookAt;
    
       // 创建view矩阵. 
        D3DXMatrixLookAtLH(&m_viewMatrix, &position, &lookAt, &up);
    
        return; 
        }
    
        void CameraClass::GetViewMatrix(D3DXMATRIX& viewMatrix) 
        { 
        viewMatrix = m_viewMatrix; 
        return; 
        }
    
    

    ColorShaderClass.h代码如下:

     

    #pragma once 
    #include <d3d11.h> 
    #include <d3dx10math.h> 
    #include <d3dx11async.h> 
    #include <fstream> 
    using namespace std;
    
    class ColorShaderClass 
        { 
        private: 
            //和shader中const buffer结构一致,主要用来给这些shader参数赋值。 
            struct MatrixBufferType 
                { 
                D3DXMATRIX world; 
                D3DXMATRIX view; 
                D3DXMATRIX projection; 
                };
    
        public: 
            ColorShaderClass(void); 
            ColorShaderClass(const ColorShaderClass&); 
            ~ColorShaderClass(void); 
            bool Initialize(ID3D11Device*, HWND); 
            void Shutdown(); 
            bool Render(ID3D11DeviceContext*, int, D3DXMATRIX, D3DXMATRIX, D3DXMATRIX); 
        private: 
            bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*); 
            void ShutdownShader(); 
            void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*);
    
            bool SetShaderParameters(ID3D11DeviceContext*, D3DXMATRIX, D3DXMATRIX, D3DXMATRIX); 
            void RenderShader(ID3D11DeviceContext*, int);
    
            ID3D11VertexShader* m_vertexShader; 
            ID3D11PixelShader* m_pixelShader; 
            ID3D11InputLayout* m_layout; 
            ID3D11Buffer* m_matrixBuffer; 
        };

    ColorShaderClass.cpp代码如下:

     

    #include "ColorShaderClass.h"
    
    
    ColorShaderClass::ColorShaderClass(void) 
        { 
        m_vertexShader = 0; 
        m_pixelShader = 0; 
        m_layout = 0; 
        m_matrixBuffer = 0;
    
        }
    
    ColorShaderClass::ColorShaderClass(const ColorShaderClass& other) 
        { 
        }
    
    
    ColorShaderClass::~ColorShaderClass(void) 
        { 
        }
    
    bool ColorShaderClass::Initialize(ID3D11Device* device, HWND hwnd) 
        { 
        bool result;
    
    
        // 初始化vs 和ps. 
        result = InitializeShader(device, hwnd, L"color.vs", L"color.ps"); 
        if(!result) 
            { 
            return false; 
            }
    
        return true; 
        } 
    void ColorShaderClass::Shutdown() 
        { 
        // 释放shader资源. 
        ShutdownShader();
    
        return; 
        } 
    bool ColorShaderClass::Render(ID3D11DeviceContext* deviceContext, int indexCount, D3DXMATRIX worldMatrix, 
        D3DXMATRIX viewMatrix, D3DXMATRIX projectionMatrix) 
        { 
        bool result;
    
    
        // 设置shader参数. 
        result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix); 
        if(!result) 
            { 
            return false; 
            }
    
        // 用shader渲染指定缓冲顶点 
        RenderShader(deviceContext, indexCount);
    
        return true; 
        }
    
    bool ColorShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR* vsFilename, WCHAR* psFilename) 
        { 
        HRESULT result; 
        ID3D10Blob* errorMessage; 
        ID3D10Blob* vertexShaderBuffer; 
        ID3D10Blob* pixelShaderBuffer; 
        D3D11_INPUT_ELEMENT_DESC polygonLayout[2]; 
        unsigned int numElements; 
        D3D11_BUFFER_DESC matrixBufferDesc;
    
    
       // 初始化指针为空. 
        errorMessage = 0; 
        vertexShaderBuffer = 0; 
        pixelShaderBuffer = 0;
    
       // 编译vs代码. 
        result = D3DX11CompileFromFile(vsFilename, NULL, NULL, "ColorVertexShader", "vs_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL, 
            &vertexShaderBuffer, &errorMessage, NULL); 
        if(FAILED(result)) 
            { 
            // 如果vs编译失败,输出错误消息. 
            if(errorMessage) 
                { 
                OutputShaderErrorMessage(errorMessage, hwnd, vsFilename); 
                } 
            // 如果没有任何错误消息,可能是shader文件丢失. 
            else 
                { 
                MessageBox(hwnd, vsFilename, L"Missing Shader File", MB_OK); 
                }
    
            return false; 
            }
    
        // 编译ps. 
        result = D3DX11CompileFromFile(psFilename, NULL, NULL, "ColorPixelShader", "ps_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL, 
            &pixelShaderBuffer, &errorMessage, NULL); 
        if(FAILED(result)) 
            { 
            // 如果ps编译失败,输出错误信息. 
            if(errorMessage) 
                { 
                OutputShaderErrorMessage(errorMessage, hwnd, psFilename); 
                } 
            // 如果没有任何错误消息,可能是shader文件丢失. 
            else 
                { 
                MessageBox(hwnd, psFilename, L"Missing Shader File", MB_OK); 
                }
    
            return false; 
            }
    
    
       // 从缓冲创建vs shader. 
        result = device->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &m_vertexShader); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
        // 从缓冲创建ps shader. 
        result = device->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, &m_pixelShader); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
        // 设置数据布局,以便在shader中使用. 
        // 定义要和ModelClass中的顶点结构一致. 
        polygonLayout[0].SemanticName = "POSITION";//vs中的输入参数 
        polygonLayout[0].SemanticIndex = 0; 
        polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT; 
        polygonLayout[0].InputSlot = 0; 
        polygonLayout[0].AlignedByteOffset = 0; 
        polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; 
        polygonLayout[0].InstanceDataStepRate = 0;
    
        polygonLayout[1].SemanticName = "COLOR"; 
        polygonLayout[1].SemanticIndex = 0; 
        polygonLayout[1].Format = DXGI_FORMAT_R32G32B32A32_FLOAT; 
        polygonLayout[1].InputSlot = 0; 
        polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; 
        polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; 
        polygonLayout[1].InstanceDataStepRate = 0;
    
       // 得到layout中的元素数量 
        numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]);
    
        // 创建顶点输入布局. 
        result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(), 
            vertexShaderBuffer->GetBufferSize(), &m_layout); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
        //释放顶点和像素缓冲. 
        vertexShaderBuffer->Release(); 
        vertexShaderBuffer = 0;
    
        pixelShaderBuffer->Release(); 
        pixelShaderBuffer = 0;
    
        // 设置动态矩阵描述. 
        matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC; 
        matrixBufferDesc.ByteWidth = sizeof(MatrixBufferType); 
        matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; 
        matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 
        matrixBufferDesc.MiscFlags = 0; 
        matrixBufferDesc.StructureByteStride = 0;
    
        // 创建const buffer指针,以便访问shader常量. 
        result = device->CreateBuffer(&matrixBufferDesc, NULL, &m_matrixBuffer); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
        return true; 
        }
    
    void ColorShaderClass::ShutdownShader() 
        { 
        // 释放常量缓冲 
        if(m_matrixBuffer) 
            { 
            m_matrixBuffer->Release(); 
            m_matrixBuffer = 0; 
            }
    
        //释放顶点布局 
        if(m_layout) 
            { 
            m_layout->Release(); 
            m_layout = 0; 
            }
    
        // 释放ps . 
        if(m_pixelShader) 
            { 
            m_pixelShader->Release(); 
            m_pixelShader = 0; 
            }
    
        // 释放vs 
        if(m_vertexShader) 
            { 
            m_vertexShader->Release(); 
            m_vertexShader = 0; 
            }
    
        return; 
        }
    
    void ColorShaderClass::OutputShaderErrorMessage(ID3D10Blob* errorMessage, HWND hwnd, WCHAR* shaderFilename) 
        { 
        char* compileErrors; 
        unsigned long bufferSize, i; 
        ofstream fout;
    
    
        // 得到错误信息buffer指针. 
        compileErrors = (char*)(errorMessage->GetBufferPointer());
    
        // 得到buffer的长度. 
        bufferSize = errorMessage->GetBufferSize();
    
        // 打开一个文件写错误信息. 
        fout.open("shader-error.txt");
    
       // 输出错误信心. 
        for(i=0; i<bufferSize; i++) 
            { 
            fout << compileErrors[i]; 
            }
    
        // 关闭文件 
        fout.close();
    
       // 释放错误消息. 
        errorMessage->Release(); 
        errorMessage = 0;
    
        //弹出错误提示. 
        MessageBox(hwnd, L"Error compiling shader.  Check shader-error.txt for message.", shaderFilename, MB_OK);
    
        return; 
        }
    
    bool ColorShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, D3DXMATRIX worldMatrix, 
        D3DXMATRIX viewMatrix, D3DXMATRIX projectionMatrix) 
        { 
        HRESULT result; 
        D3D11_MAPPED_SUBRESOURCE mappedResource; 
        MatrixBufferType* dataPtr; 
        unsigned int bufferNumber;
    
        // 传入shader前,确保矩阵转置,这是D3D11的要求. 
        D3DXMatrixTranspose(&worldMatrix, &worldMatrix); 
        D3DXMatrixTranspose(&viewMatrix, &viewMatrix); 
        D3DXMatrixTranspose(&projectionMatrix, &projectionMatrix);
    
        //  锁定常量缓冲,以便能够写入. 
        result = deviceContext->Map(m_matrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
        // 得到const buffer指针. 
        dataPtr = (MatrixBufferType*)mappedResource.pData;
    
        // 设置world,view以及projection矩阵. 
        dataPtr->world = worldMatrix; 
        dataPtr->view = viewMatrix; 
        dataPtr->projection = projectionMatrix;
    
        // 解锁常量缓冲. 
        deviceContext->Unmap(m_matrixBuffer, 0);
    
        // 设置常量缓冲位置. 
        bufferNumber = 0;
    
        // 用更新后的值设置常量缓冲. 
        deviceContext->VSSetConstantBuffers(bufferNumber, 1, &m_matrixBuffer);
    
        return true; 
        }
    
    void ColorShaderClass::RenderShader(ID3D11DeviceContext* deviceContext, int indexCount) 
        { 
        // 绑定顶点布局. 
        deviceContext->IASetInputLayout(m_layout);
    
        // 设置渲染使用vs和ps. 
        deviceContext->VSSetShader(m_vertexShader, NULL, 0); 
        deviceContext->PSSetShader(m_pixelShader, NULL, 0);
    
       // 渲染三角形 
        deviceContext->DrawIndexed(indexCount, 0, 0);
    
        return; 
        } 

    程序运行后如下图所示:

     

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规