• 热门专题

Directx11教程(10) 画一个简易坐标轴

作者:迈克老狼2012  发布日期:2012-03-21 20:59:46
Tag标签:Directx11  简易坐标轴  
  • 本篇日志中,我们将在三维场景中,画一个简易的坐标轴,分别用红、绿、蓝三种颜色表示x,y,z轴的正向坐标轴。

    为此,我们要先建立一个AxisModelClass类,来表示坐标轴顶。

     


     

    AxisModelClass.h的代码如下:

     

    #pragma once
    
    #include <d3d11.h> 
    #include <d3dx10math.h> 
    #include "common.h"
    
    class AxisModelClass 
        { 
        private: 
            struct VertexType 
                { 
                D3DXVECTOR3 position; 
                D3DXVECTOR4 color; 
                };
    
        public: 
            AxisModelClass(void); 
            AxisModelClass(const AxisModelClass &); 
            ~AxisModelClass(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; 
        };
    

    AxisModelClass.cpp的代码如下:

     

    #include "AxisModelClass.h"
    
    
    AxisModelClass::AxisModelClass(void) 
        { 
        }
    
    AxisModelClass::AxisModelClass(const AxisModelClass & others) 
        {
    
        }
    
    AxisModelClass::~AxisModelClass(void) 
        { 
        }
    
    bool AxisModelClass::Initialize(ID3D11Device* device) 
        { 
        bool result;
    
    
        // 初始化顶点缓冲和顶点索引缓冲. 
        result = InitializeBuffers(device); 
        if(!result) 
            { 
            return false; 
            }
    
        return true; 
        }
    
    void AxisModelClass::Shutdown() 
        { 
        // 释放顶点和索引缓冲. 
        ShutdownBuffers();
    
        return; 
        }
    
    void AxisModelClass::Render(ID3D11DeviceContext* deviceContext) 
        { 
       // 把顶点和索引缓冲放入图形管线,准备渲染. 
        RenderBuffers(deviceContext);
    
        return; 
        }
    
    int AxisModelClass::GetIndexCount() 
        { 
       //返回索引顶点计数 
        return m_indexCount; 
        }
    
    bool AxisModelClass::InitializeBuffers(ID3D11Device* device) 
        { 
        VertexType* vertices; 
        unsigned long* indices; 
        D3D11_BUFFER_DESC vertexBufferDesc, indexBufferDesc; 
        D3D11_SUBRESOURCE_DATA vertexData, indexData; 
        HRESULT result;
    
        //首先,我们创建2个临时缓冲存放顶点和索引数据,以便后面使用。. 
    
        // 设置顶点缓冲大小为6 
        m_vertexCount = 6;
    
        // 设置索引缓冲大小. 
        m_indexCount = 6;
    
        // 创建顶点临时缓冲. 
        vertices = new VertexType[m_vertexCount]; 
        if(!vertices) 
            { 
            return false; 
            }
    
       // 创建索引缓冲. 
        indices = new unsigned long[m_indexCount]; 
        if(!indices) 
            { 
            return false; 
            }
    
        // 设置顶点数据. 
        //x轴,红色 
        vertices[0].position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);  
        vertices[0].color = RED;
    
        vertices[1].position = D3DXVECTOR3(10.0f, 0.0f, 0.0f);  
        vertices[1].color = RED;
    
        //y轴,绿色 
        vertices[2].position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);  
        vertices[2].color = GREEN;
    
        vertices[3].position = D3DXVECTOR3(0.0f, 10.0f, 0.0f);  
        vertices[3].color = GREEN;
    
       //z轴,蓝色 
        vertices[4].position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);  
        vertices[4].color = BLUE;
    
        vertices[5].position = D3DXVECTOR3(0.0f, 0.0f, 10.0f);  
        vertices[5].color = BLUE;
    
    
       // 设置索引缓冲数据. 
        indices[0] = 0;  
        indices[1] = 1; 
        indices[2] = 2;  
        indices[3] = 3; 
        indices[4] = 4; 
        indices[5] = 5;  
    
    
        // 设置顶点缓冲描述 
        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 AxisModelClass::ShutdownBuffers() 
        { 
        // 释放顶点缓冲. 
        if(m_indexBuffer) 
            { 
            m_indexBuffer->Release(); 
            m_indexBuffer = 0; 
            }
    
        // 释放索引缓冲 
        if(m_vertexBuffer) 
            { 
            m_vertexBuffer->Release(); 
            m_vertexBuffer = 0; 
            }
    
        return; 
        }
    
    void AxisModelClass::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_LINELIST);
    
        return; 
        }
    
    

    为了使用颜色宏定义,我么去掉了上篇文章在ModelClass.h 中定义的颜色,而新建一个common.h文件,

    ModelClass.h中将包含common.h

    ModelClass.h代码改变如下:

     

    #pragma once
    
    #include <d3d11.h> 
    #include <d3dx10math.h> 
    #include "common.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;
    
        };
    
    

    common.h的代码如下:

     

    //定义一些常用颜色 
    #include <d3d11.h> 
    #include <d3dx10math.h>
    
    const D3DXVECTOR4 WHITE(1.0f, 1.0f, 1.0f, 1.0f); 
    const D3DXVECTOR4 BLACK(0.0f, 0.0f, 0.0f, 1.0f); 
    const D3DXVECTOR4 RED(1.0f, 0.0f, 0.0f, 1.0f); 
    const D3DXVECTOR4 GREEN(0.0f, 1.0f, 0.0f, 1.0f); 
    const D3DXVECTOR4 BLUE(0.0f, 0.0f, 1.0f, 1.0f); 
    const D3DXVECTOR4 YELLOW(1.0f, 1.0f, 0.0f, 1.0f); 
    const D3DXVECTOR4 CYAN(0.0f, 1.0f, 1.0f, 1.0f); //蓝绿色 
    const D3DXVECTOR4 MAGENTA(1.0f, 0.0f, 1.0f, 1.0f); //洋红色
    
    const D3DXVECTOR4 BEACH_SAND(1.0f, 0.96f, 0.62f, 1.0f); 
    const D3DXVECTOR4 LIGHT_YELLOW_GREEN(0.48f, 0.77f, 0.46f, 1.0f); 
    const D3DXVECTOR4 DARK_YELLOW_GREEN(0.1f, 0.48f, 0.19f, 1.0f); 
    const D3DXVECTOR4 DARKBROWN(0.45f, 0.39f, 0.34f, 1.0f);
    
    GraphicsClass.h代码如下:
    
    #pragma once
    
    #include <windows.h> 
    #include "d3dclass.h" 
    #include "cameraclass.h" 
    #include "modelclass.h" 
    #include "AxisModelClass.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(); 
            CameraClass* m_Camera; //设为public,便于在SystemClass中控制 
        private: 
            bool Render();
    
           //定义一个D3DClass类成员变量 
            D3DClass* m_D3D; 
            
            ModelClass* m_Model; 
            AxisModelClass* m_AxisModel; 
            ColorShaderClass* m_ColorShader;
    
        };
    
    

    GraphicsClass.cpp代码如下:

     

    #include "GraphicsClass.h"
    
    
    GraphicsClass::GraphicsClass(void) 
        { 
        m_D3D = 0; 
        m_Camera = 0; 
        m_Model = 0; 
        m_AxisModel = 0; 
        m_ColorShader = 0; 
        
        }
    
    GraphicsClass::GraphicsClass(const GraphicsClass&) 
        {
    
        } 
    GraphicsClass::~GraphicsClass(void) 
        { 
        }
    
    bool GraphicsClass:: Initialize(int screenWidth, int screenHeight, HWND hwnd) 
        { 
        bool result;
    
       //如果对象已经存在,先释放掉它们 
        Shutdown();
    
        // 创建一个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; 
            }
    
       // 设置摄像机位置. 
        D3DXVECTOR3 campos = D3DXVECTOR3(8.0f, 3.0f, -20.0f); 
        m_Camera->setPosition(&campos);
    
        // 创建模型对象. 
        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; 
            }
    
       // 创轴建模型对象. 
        m_AxisModel = new AxisModelClass; 
        if(!m_AxisModel) 
            { 
            return false; 
            } 
        // 初始化坐标轴模型对象. 
        result = m_AxisModel->Initialize(m_D3D->GetDevice()); 
        if(!result) 
            { 
            MessageBox(hwnd, L"Could not initialize the axis 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_AxisModel) 
            { 
            m_AxisModel->Shutdown(); 
            delete m_AxisModel; 
            m_AxisModel = 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);
    
        // 得到3个矩阵. 
        m_Camera->getViewMatrix(&viewMatrix); 
        m_D3D->GetWorldMatrix(worldMatrix); 
        m_D3D->GetProjectionMatrix(projectionMatrix);
    
    
        m_AxisModel->Render(m_D3D->GetDeviceContext()); 
        // 用shader渲染. 
        result = m_ColorShader->Render(m_D3D->GetDeviceContext(), m_AxisModel->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix); 
        if(!result) 
            { 
            return false; 
            }    
        // 把模型顶点和索引缓冲放入管线,准备渲染. 
        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; 
        }
    
    

    程序执行后,如下图所示:

     

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