ID3DX11EffectPass GetDesc 访问冲突

ID3DX11EffectPass GetDesc Access Violation

您好,我刚刚了解了使用 DirectX 11 进行 3D 游戏编程的简介,我正在尝试让 BoxDemo 代码正常工作,但是我在效果方面遇到了麻烦。 基本上编译的着色器部分可以工作,甚至效果的创建也可以,但是当涉及到从效果通道获取描述时,我收到访问冲突错误,我已经尝试并在线研究但找不到任何帮助这件事。 请注意我有最新版本的 effects11.

这是效果图:

//*****************************************************************************    **********
// color.fx by Frank Luna (C) 2011 All Rights Reserved.
//
// Transforms and colors geometry.
 //***************************************************************************************

cbuffer cbPerObject
{
    float4x4 gWorldViewProj;
};

struct VertexIn
{
    float3 PosL  : POSITION;
    float4 Color : COLOR;
};

struct VertexOut
{
    float4 PosH  : SV_POSITION;
    float4 Color : COLOR;
};

VertexOut VS(VertexIn vin)
{
    VertexOut vout;

    // Transform to homogeneous clip space.
    vout.PosH = mul(float4(vin.PosL, 1.0f), gWorldViewProj);

    // Just pass vertex color into the pixel shader.
    vout.Color = vin.Color;

    return vout;
}

float4 PS(VertexOut pin) : SV_Target
{
     return pin.Color;
} 

technique11 ColorTech
{
    pass P0
    {
        SetVertexShader(CompileShader(vs_5_0, VS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_5_0, PS()));
    }
}

这里是 cpp 文件:

#include "BoxApp.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
PSTR cmdLine, int showCmd)
{
    // Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif

    BoxApp theApp(hInstance);

    if (!theApp.Init())
        return 0;

    return theApp.Run();
}


BoxApp::BoxApp(HINSTANCE hInstance)
    : D3DApp(hInstance), mBoxVB(0), mBoxIB(0), mFX(0), mTech(0),
    mfxWorldViewProj(0), mInputLayout(0),
    mTheta(1.5f*MathHelper::Pi), mPhi(0.25f*MathHelper::Pi), mRadius(5.0f)
{
    mMainWndCaption = L"Box Demo";

    mLastMousePos.x = 0;
    mLastMousePos.y = 0;

    XMMATRIX I = XMMatrixIdentity();
    XMStoreFloat4x4(&mWorld, I);
    XMStoreFloat4x4(&mView, I);
    XMStoreFloat4x4(&mProj, I);
}

BoxApp::~BoxApp()
{
    ReleaseCOM(mBoxVB);
    ReleaseCOM(mBoxIB);
    ReleaseCOM(mFX);
    ReleaseCOM(mInputLayout);
}

bool BoxApp::Init()
{
    if (!D3DApp::Init())
        return false;

    BuildGeometryBuffers();
    BuildFX();
    BuildVertexLayout();

    return true;
}

void BoxApp::OnResize()
{
    D3DApp::OnResize();

    // The window resized, so update the aspect ratio and recompute the         projection matrix.
    XMMATRIX P = XMMatrixPerspectiveFovLH(0.25f*MathHelper::Pi,         AspectRatio(), 1.0f, 1000.0f);
    XMStoreFloat4x4(&mProj, P);
}

void BoxApp::UpdateScene(float dt)
{
    // Convert Spherical to Cartesian coordinates.
    float x = mRadius*sinf(mPhi)*cosf(mTheta);
    float z = mRadius*sinf(mPhi)*sinf(mTheta);
    float y = mRadius*cosf(mPhi);

    // Build the view matrix.
    XMVECTOR pos = XMVectorSet(x, y, z, 1.0f);
    XMVECTOR target = XMVectorZero();
    XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);

    XMMATRIX V = XMMatrixLookAtLH(pos, target, up);
    XMStoreFloat4x4(&mView, V);
}

void BoxApp::DrawScene()
{
    md3dImmediateContext->ClearRenderTargetView(mRenderTargetView,     reinterpret_cast<const float*>(&Colors::LightSteelBlue));
    md3dImmediateContext->ClearDepthStencilView(mDepthStencilView,     D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);

    md3dImmediateContext->IASetInputLayout(mInputLayout);
    md3dImmediateContext-    >IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    UINT stride = sizeof(Vertex);
    UINT offset = 0;
    md3dImmediateContext->IASetVertexBuffers(0, 1, &mBoxVB, &stride, &offset);
    md3dImmediateContext->IASetIndexBuffer(mBoxIB, DXGI_FORMAT_R32_UINT, 0);

     // Set constants
    XMMATRIX world = XMLoadFloat4x4(&mWorld);
    XMMATRIX view = XMLoadFloat4x4(&mView);
    XMMATRIX proj = XMLoadFloat4x4(&mProj);
    XMMATRIX worldViewProj = world*view*proj;

    mfxWorldViewProj->SetMatrix(reinterpret_cast<float*>(&worldViewProj));

    D3DX11_TECHNIQUE_DESC techDesc;
    mTech->GetDesc(&techDesc);
    for (UINT p = 0; p < techDesc.Passes; ++p)
    {
        mTech->GetPassByIndex(p)->Apply(0, md3dImmediateContext);

        // 36 indices for the box.
        md3dImmediateContext->DrawIndexed(36, 0, 0);
     }

    HRESULT hr = (mSwapChain->Present(0, 0));
 }

 void BoxApp::OnMouseDown(WPARAM btnState, int x, int y)
 {
    mLastMousePos.x = x;
    mLastMousePos.y = y;

    SetCapture(mhMainWnd);
 }

 void BoxApp::OnMouseUp(WPARAM btnState, int x, int y)
 {
    ReleaseCapture();
 }

 void BoxApp::OnMouseMove(WPARAM btnState, int x, int y)
 {
     if ((btnState & MK_LBUTTON) != 0)
     {
         // Make each pixel correspond to a quarter of a degree.
        float dx = XMConvertToRadians(0.25f*static_cast<float>(x - mLastMousePos.x));
        float dy = XMConvertToRadians(0.25f*static_cast<float>(y - mLastMousePos.y));

        // Update angles based on input to orbit camera around box.
        mTheta += dx;
        mPhi += dy;

        // Restrict the angle mPhi.
        mPhi = MathHelper::Clamp(mPhi, 0.1f, MathHelper::Pi - 0.1f);
     }
     else if ((btnState & MK_RBUTTON) != 0)
     {
        // Make each pixel correspond to 0.005 unit in the scene.
        float dx = 0.005f*static_cast<float>(x - mLastMousePos.x);
        float dy = 0.005f*static_cast<float>(y - mLastMousePos.y);

        // Update the camera radius based on input.
        mRadius += dx - dy;

        // Restrict the radius.
        mRadius = MathHelper::Clamp(mRadius, 3.0f, 15.0f);
     }

     mLastMousePos.x = x;
     mLastMousePos.y = y;
 }

 void BoxApp::BuildGeometryBuffers()
 {
     // Create vertex buffer
    Vertex vertices[] =
    {
         { XMFLOAT3(-1.0f, -1.0f, -1.0f), (const float*)&Colors::White },
        { XMFLOAT3(-1.0f, +1.0f, -1.0f), (const float*)&Colors::Black },
        { XMFLOAT3(+1.0f, +1.0f, -1.0f), (const float*)&Colors::Red },
        { XMFLOAT3(+1.0f, -1.0f, -1.0f), (const float*)&Colors::Green },
        { XMFLOAT3(-1.0f, -1.0f, +1.0f), (const float*)&Colors::Blue },
        { XMFLOAT3(-1.0f, +1.0f, +1.0f), (const float*)&Colors::Yellow },
        { XMFLOAT3(+1.0f, +1.0f, +1.0f), (const float*)&Colors::Cyan },
        { XMFLOAT3(+1.0f, -1.0f, +1.0f), (const float*)&Colors::Magenta }
    };

    D3D11_BUFFER_DESC vbd;
    vbd.Usage = D3D11_USAGE_IMMUTABLE;
    vbd.ByteWidth = sizeof(Vertex) * 8;
    vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vbd.CPUAccessFlags = 0;
    vbd.MiscFlags = 0;
    vbd.StructureByteStride = 0;
    D3D11_SUBRESOURCE_DATA vinitData;
    vinitData.pSysMem = vertices;
    HRESULT hr1 = (md3dDevice->CreateBuffer(&vbd, &vinitData, &mBoxVB));


     // Create the index buffer

    UINT indices[] = {
    // front face
    0, 1, 2,
    0, 2, 3,

    // back face
    4, 6, 5,
    4, 7, 6,

    // left face
    4, 5, 1,
    4, 1, 0,

    // right face
    3, 2, 6,
    3, 6, 7,

    // top face
    1, 5, 6,
    1, 6, 2,

    // bottom face
    4, 0, 3,
    4, 3, 7
};

    D3D11_BUFFER_DESC ibd;
    ibd.Usage = D3D11_USAGE_IMMUTABLE;
    ibd.ByteWidth = sizeof(UINT) * 36;
    ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
    ibd.CPUAccessFlags = 0;
    ibd.MiscFlags = 0;
    ibd.StructureByteStride = 0;
    D3D11_SUBRESOURCE_DATA iinitData;
    iinitData.pSysMem = indices;
    HRESULT hr2 = (md3dDevice->CreateBuffer(&ibd, &iinitData, &mBoxIB));
 }

 void BoxApp::BuildFX()
 {
    DWORD shaderFlags = 0;
    //#if defined( DEBUG ) || defined( _DEBUG )
    //  shaderFlags |= D3D10_SHADER_DEBUG;
    //  shaderFlags |= D3D10_SHADER_SKIP_OPTIMIZATION;
    //#endif

    ID3D10Blob* compiledShader = 0;
    ID3D10Blob* compilationMsgs = 0;
    HRESULT hr;
    hr = D3DX11CompileFromFile(L"color.fx", NULL, NULL, "ColorTech",       "fx_5_0"
    , shaderFlags, 0, 0, &compiledShader, &compilationMsgs, &hr);

    // compilationMsgs can store errors or warnings.
    if (compilationMsgs != 0)
    {
         MessageBoxA(0, (char*)compilationMsgs->GetBufferPointer(), 0, 0);
        ReleaseCOM(compilationMsgs);
    }

    // Even if there are no compilationMsgs, check to make sure there were no other errors.
    if (FAILED(hr))
    {
         //DXTrace(__FILE__, (DWORD)__LINE__, hr, L"D3DX11CompileFromFile",     true);
    }

    ID3D10Blob* pErrorBlob = 0;
    //ID3DInclude* include = D3D_COMPILE_STANDARD_FILE_INCLUDE;
    HRESULT hr3 = (D3DX11CreateEffectFromMemory(compiledShader->GetBufferPointer(), compiledShader->GetBufferSize(),
    0, md3dDevice, &mFX));
    //HRESULT hr3 = (D3DX11CreateEffectFromFile(L"color.fx", shaderFlags, md3dDevice, &mFX));

    // Done with compiled shader.
    ReleaseCOM(compiledShader);

    mTech = mFX->GetTechniqueByName("ColorTech");
    mfxWorldViewProj = mFX->GetVariableByName("gWorldViewProj")->AsMatrix();
}

void BoxApp::BuildVertexLayout()
{
    // Create the vertex input layout.
    D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "COLOR",    0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
   };

    // Create the input layout
    D3DX11_PASS_DESC passDesc;

    ID3DX11EffectPass* pass = mTech->GetPassByIndex(0);

    if (pass != nullptr)
    {
        HRESULT hr5 = pass->GetDesc(&passDesc);
        HRESULT hr4 = (md3dDevice->CreateInputLayout(vertexDesc, 2,     passDesc.pIAInputSignature,
            passDesc.IAInputSignatureSize, &mInputLayout));
    }
}

您已注释掉所有错误检查,因此 D3DX11CreateEffectFromMemory 可能返回失败。如果一个函数 returns 一个 HRESULT,你必须在运行时检查它,否则你会错过潜在的错误。这意味着使用 FAILED 宏、SUCCEEDED 宏或 ThrowIfFailed helper on every function that returns an HRESULT. See MSDN.

由于您正在使用 Effects for Direct3D 11 库,因此您应该从 GitHub. If you are using VS 2013 or VS 2015 for a Windows desktop app, you can also get it from NuGet 中获取最新版本。

您还应该阅读 this post which has some additional notes about the Introduction to 3D Game Programming with DirectX 11 book. It's a good book, but unfortunately it was published just before the DirectX development story was changed rather radically with the deprecation of the DirectX SDK. See MSDN

You should also take a look at the DirectX Tool Kit tutorials, particularly the material on ComPtr.

好的,最后是最终代码

BoxDemoApp.h:

#pragma once
//#pragma comment(lib, "Effects11.lib")
#pragma comment(lib, "d3d11.lib")
//#pragma comment(lib, "d3dx11.lib")
//#pragma comment(lib, "DxErr.lib")
//#pragma comment(lib, "D3DCompiler.lib")
//#pragma comment(lib, "dxguid.lib")
#include <windows.h>
#include <d3d11_1.h>
#include "d3dApp.h"

#include "d3dx11effect.h"
#include "MathHelper.h"
#include "StaticCamera.h"
#include "Conversion.h"
#include "DefinedModel.h"

#include <iostream>
using namespace std;

class BoxDemoApp : public D3DApp
{
public:
    BoxDemoApp(HINSTANCE hInstance);
    ~BoxDemoApp();

    bool Init();
    bool InitScene();
    void OnResize();
    void UpdateScene(float dt);
    void DrawScene();

private:
    DefinedModel* m_Model;
    bool m_bLoaded;
    bool m_bInitModel;
};

BoxDemoApp.cpp: #include "BoxDemoApp.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
    PSTR cmdLine, int showCmd)
{
    // Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif

    BoxDemoApp theApp(hInstance);

    if (!theApp.Init())
        return 0;

    return theApp.Run();
}

BoxDemoApp::BoxDemoApp(HINSTANCE hInstance)
    : D3DApp(hInstance)
{
    mMainWndCaption = L"Box Demo";  
    m_bLoaded = false;
    m_bInitModel = false;
    m_Model = NULL;
}

BoxDemoApp::~BoxDemoApp()
{
    m_Model->Destroy();
    SafeDelete(m_Model);
}

bool BoxDemoApp::Init()
{
    if (!D3DApp::Init())
        return false;

    InitScene();

    return true;
}

bool BoxDemoApp::InitScene()
{
    //Camera information
    m_Camera->setCamera(XMFLOAT4(0.0f, 3.0f, -8.0f, 0.0f),
        XMFLOAT4(0.0f, 0.0f, 0.0f, 0.0f),
        XMFLOAT4(0.0f, 1.0f, 0.0f, 0.0f));

    //Set the Projection matrix
    m_Camera->setFOV(0.4f*3.14f, (float)mClientWidth / mClientHeight, 1.0f, 1000.0f);
    ///////////////**************new**************////////////////////
    return true;
}

void BoxDemoApp::OnResize()
{
    D3DApp::OnResize();

    //Create the Viewport
    D3D11_VIEWPORT viewport;
    ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));

    viewport.TopLeftX = 0;
    viewport.TopLeftY = 0;
    viewport.Width = this->mClientWidth;
    viewport.Height = this->mClientHeight;

    //Set the Viewport
    md3dImmediateContext->RSSetViewports(1, &viewport);

    //Set the Projection matrix
    m_Camera->setFOV(0.4f*3.14f, (float)mClientWidth / mClientHeight, 1.0f, 1000.0f);
    ///////////////**************new**************////////////////////
}

void BoxDemoApp::UpdateScene(float dt)
{
    if (m_bLoaded && !m_bInitModel)
    {
        m_Model = new DefinedModel(this);       
        m_Model->create3DCube(4, 4, 4);     

        m_bInitModel = true;
    }
}

void BoxDemoApp::DrawScene()
{
    assert(md3dImmediateContext);
    assert(mSwapChain);

    md3dImmediateContext->ClearRenderTargetView(mRenderTargetView, reinterpret_cast<const float*>(&Colors::LightSteelBlue));
    md3dImmediateContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);

    if (m_bInitModel)
    {
        m_Model->Draw();
    }

    if (!m_bLoaded)
    {
        m_bLoaded = true;
    }

    HRESULT hr = (mSwapChain->Present(0, 0));
}

MathHelper.h:

//***************************************************************************************
// MathHelper.h by Frank Luna (C) 2011 All Rights Reserved.
//
// Helper math class.
//***************************************************************************************
#pragma once
#ifndef MATHHELPER_H
#define MATHHELPER_H

#include <Windows.h>
#include <xnamath.h>

class MathHelper
{
public:
    // Returns random float in [0, 1).
    static float RandF()
    {
        return (float)(rand()) / (float)RAND_MAX;
    }

    // Returns random float in [a, b).
    static float RandF(float a, float b)
    {
        return a + RandF()*(b - a);
    }

    template<typename T>
    static T Min(const T& a, const T& b)
    {
        return a < b ? a : b;
    }

    template<typename T>
    static T Max(const T& a, const T& b)
    {
        return a > b ? a : b;
    }

    template<typename T>
    static T Lerp(const T& a, const T& b, float t)
    {
        return a + (b - a)*t;
    }

    template<typename T>
    static T Clamp(const T& x, const T& low, const T& high)
    {
        return x < low ? low : (x > high ? high : x);
    }

    // Returns the polar angle of the point (x,y) in [0, 2*PI).
    static float AngleFromXY(float x, float y);

    static XMMATRIX InverseTranspose(CXMMATRIX M)
    {
        // Inverse-transpose is just applied to normals.  So zero out 
        // translation row so that it doesn't get into our inverse-transpose
        // calculation--we don't want the inverse-transpose of the translation.
        XMMATRIX A = M;
        A.r[3] = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);

        XMVECTOR det = XMMatrixDeterminant(A);
        return XMMatrixTranspose(XMMatrixInverse(&det, A));
    }

    static XMVECTOR RandUnitVec3();
    static XMVECTOR RandHemisphereUnitVec3(XMVECTOR n);

    static const float Infinity;
    static const float Pi;


};

#endif // MATHHELPER_H

MathHelper.cpp:

//***************************************************************************************
// MathHelper.cpp by Frank Luna (C) 2011 All Rights Reserved.
//***************************************************************************************

#include "MathHelper.h"
#include <float.h>
#include <cmath>

const float MathHelper::Infinity = FLT_MAX;
const float MathHelper::Pi = 3.1415926535f;

float MathHelper::AngleFromXY(float x, float y)
{
    float theta = 0.0f;

    // Quadrant I or IV
    if (x >= 0.0f)
    {
        // If x = 0, then atanf(y/x) = +pi/2 if y > 0
        //                atanf(y/x) = -pi/2 if y < 0
        theta = atanf(y / x); // in [-pi/2, +pi/2]

        if (theta < 0.0f)
            theta += 2.0f*Pi; // in [0, 2*pi).
    }

    // Quadrant II or III
    else
        theta = atanf(y / x) + Pi; // in [0, 2*pi).

    return theta;
}

XMVECTOR MathHelper::RandUnitVec3()
{
    XMVECTOR One = XMVectorSet(1.0f, 1.0f, 1.0f, 1.0f);
    XMVECTOR Zero = XMVectorZero();

    // Keep trying until we get a point on/in the hemisphere.
    while (true)
    {
        // Generate random point in the cube [-1,1]^3.
        XMVECTOR v = XMVectorSet(MathHelper::RandF(-1.0f, 1.0f), MathHelper::RandF(-1.0f, 1.0f), MathHelper::RandF(-1.0f, 1.0f), 0.0f);

        // Ignore points outside the unit sphere in order to get an even distribution 
        // over the unit sphere.  Otherwise points will clump more on the sphere near 
        // the corners of the cube.

        if (XMVector3Greater(XMVector3LengthSq(v), One))
            continue;

        return XMVector3Normalize(v);
    }
}

XMVECTOR MathHelper::RandHemisphereUnitVec3(XMVECTOR n)
{
    XMVECTOR One = XMVectorSet(1.0f, 1.0f, 1.0f, 1.0f);
    XMVECTOR Zero = XMVectorZero();

    // Keep trying until we get a point on/in the hemisphere.
    while (true)
    {
        // Generate random point in the cube [-1,1]^3.
        XMVECTOR v = XMVectorSet(MathHelper::RandF(-1.0f, 1.0f), MathHelper::RandF(-1.0f, 1.0f), MathHelper::RandF(-1.0f, 1.0f), 0.0f);

        // Ignore points outside the unit sphere in order to get an even distribution 
        // over the unit sphere.  Otherwise points will clump more on the sphere near 
        // the corners of the cube.

        if (XMVector3Greater(XMVector3LengthSq(v), One))
            continue;

        // Ignore points in the bottom hemisphere.
        if (XMVector3Less(XMVector3Dot(n, v), Zero))
            continue;

        return XMVector3Normalize(v);
    }
}

StaticCamera.h:

    #pragma once
    #include "MathHelper.h"
    #include "Conversion.h"

    class StaticCamera
    {
    public:
        StaticCamera();
        ~StaticCamera();

        XMMATRIX* WVP();    
        XMMATRIX* World();
        XMMATRIX* camView();
        XMMATRIX* camProjection();

        XMVECTOR* camPosition();
        XMVECTOR* camTarget();
        XMVECTOR* camUp();

        void WVP(XMMATRIX WVP);
        void World(XMMATRIX World);

        void setFOV(float FOV, float aspectRatio, float nearZ, float farZ);
        void setCamera(XMFLOAT4 position, XMFLOAT4 Target, XMFLOAT4 Up);
        void updateMatrix();

    private:
        ///////////////**************new**************////////////////////
        XMMATRIX m_WVP;
        XMMATRIX m_World;
        XMMATRIX m_camView;
        XMMATRIX m_camProjection;

        XMVECTOR m_camPosition;
        XMVECTOR m_camTarget;
        XMVECTOR m_camUp;
        ///////////////**************new**************////////////////////
    };

StaticCamera.cpp:
#include "StaticCamera.h"

StaticCamera::StaticCamera()
{   
}


StaticCamera::~StaticCamera()
{
}

XMMATRIX* StaticCamera::WVP()
{
    return &m_WVP;
}

XMMATRIX* StaticCamera::World()
{
    return &m_World;
}

XMMATRIX* StaticCamera::camView()
{
    return &m_camView;
}
XMMATRIX* StaticCamera::camProjection()
{
    return &m_camProjection;
}

XMVECTOR* StaticCamera::camPosition()
{
    return &m_camPosition;
}

XMVECTOR* StaticCamera::camTarget()
{
    return &m_camTarget;
}

XMVECTOR* StaticCamera::camUp()
{
    return &m_camUp;
}

void StaticCamera::WVP(XMMATRIX WVP)
{
    m_WVP = WVP;
}

void StaticCamera::World(XMMATRIX World)
{
    m_World = World;
}

void StaticCamera::setFOV(float FOV, float aspectRatio, float nearZ, float farZ)
{
    //Set the Projection matrix
    m_camProjection = XMMatrixPerspectiveFovLH(FOV, aspectRatio, nearZ, farZ);

    updateMatrix();
}

void StaticCamera::setCamera(XMFLOAT4 position, XMFLOAT4 Target, XMFLOAT4 Up)
{
    //Camera information
    m_camPosition = Conversion::XMFLOAT4TOXMVECTOR(position);
    m_camTarget = Conversion::XMFLOAT4TOXMVECTOR(Target);
    m_camUp = Conversion::XMFLOAT4TOXMVECTOR(Up);

    //Set the View matrix
    m_camView = XMMatrixLookAtLH(m_camPosition, m_camTarget, m_camUp);
    ///////////////**************new**************////////////////////

    updateMatrix();
}

void StaticCamera::updateMatrix()
{
    m_World = XMMatrixIdentity();
    m_WVP = (m_World * m_camView * m_camProjection);
}

Conversion.h:

#pragma once
#include "MathHelper.h"
#include <vector>
using namespace std;

static class Conversion
{
public:
    static XMFLOAT4 XMVECTORTOXMFLOAT4(XMVECTOR Xmvector);
    static XMFLOAT3 XMVECTORTOXMFLOAT3(XMVECTOR Xmvector);
    static XMVECTOR XMFLOAT4TOXMVECTOR(XMFLOAT4 Xmfloat);
    static void INTVECTORTOARRAY(std::vector<int> vector, int *arr);
    static LPCWSTR STRINGTOLPCWSTR(std::string stdstr);
};

Conversion.cpp:

#include "Conversion.h"

XMFLOAT4 Conversion::XMVECTORTOXMFLOAT4(XMVECTOR Xmvector)
{
    XMFLOAT4 pos;
    XMStoreFloat4(&pos, Xmvector);
    return pos;
}

XMFLOAT3 Conversion::XMVECTORTOXMFLOAT3(XMVECTOR Xmvector)
{
    XMFLOAT3 pos;
    XMStoreFloat3(&pos, Xmvector);
    return pos;
}

XMVECTOR Conversion::XMFLOAT4TOXMVECTOR(XMFLOAT4 Xmfloat)
{
    return XMLoadFloat4(&Xmfloat);
}

void Conversion::INTVECTORTOARRAY(std::vector<int> vector, int *arr)
{
    arr = &vector[0];
}

LPCWSTR Conversion::STRINGTOLPCWSTR(std::string stdstr)
{
    std::wstring stemp = std::wstring(stdstr.begin(), stdstr.end());
    LPCWSTR sw = stemp.c_str();
    return sw;
}

DefinedModel.h:

#pragma once
#include <windows.h>
#include <d3d11_1.h>
#include "ShaderHelper.h"
#include "d3dx11effect.h"
#include "Conversion.h"
#include "Vector3.h"
#include "d3dApp.h"



class DefinedModel
{

public:

    enum RastMode {
        Solid,
        Wireframe
    };

public:
    DefinedModel(D3DApp* parent);
    ~DefinedModel();

protected:
    D3DApp* m_pParent; 

    //Vertex Structure and Vertex Layout (Input Layout)//
    struct Vertex    //Overloaded Vertex Structure
    {
        Vertex() {}
        Vertex(float x, float y, float z,
            float cr, float cg, float cb, float ca)
            : pos(x, y, z), color(cr, cg, cb, ca) {}

        XMFLOAT3 pos;
        XMFLOAT4 color;
    };  

    std::vector<Vertex> m_VertexArray;
    std::vector<int> m_indices;

    struct cbPerObject
    {
        XMMATRIX  WVP;
    };

    cbPerObject cbPerObj;

    ID3D11Buffer* cbPerObjectBuffer;

    ID3D11Buffer* squareIndexBuffer;
    ID3D11Buffer* squareVertBuffer;

    ID3D11VertexShader* VS;
    ID3D11PixelShader* PS;
    ID3D10Blob* VS_Buffer;
    ID3D10Blob* PS_Buffer;
    ID3D11InputLayout* vertLayout;

    ///////////////**************new**************////////////////////
    Vector3 m_Rotation;
    Vector3 m_Scale;
    Vector3 m_Offset;

    XMMATRIX m_modelWorld;
    ///////////////**************new**************////////////////////

    RastMode m_RastMode;
    ID3D11RasterizerState* m_RastState;

public:
    virtual void create3DCube(float Width, float Height, float Depth);
    void Init();
    void Draw();
    void Rotation(float X, float Y, float Z);   
    void Scale(float X, float Y, float Z);
    void Offset(float X, float Y, float Z);
    void rastMode(RastMode rastmode);

    Vector3 Rotation();
    Vector3 Scale();
    Vector3 Offset();

    XMMATRIX worldMatrix();

    void Destroy();

private:
    virtual void InitBuffers();
    virtual void InitFX();
    virtual void InitInputLayout();
    virtual void InitCBBuffer();
};

DefinedModel.cpp:

#include "DefinedModel.h"


DefinedModel::DefinedModel(D3DApp* parent): m_pParent(parent)
{
    m_VertexArray = std::vector<Vertex>();
    m_indices = std::vector<int>();

    m_modelWorld = XMMatrixIdentity();

    Offset(0, 0, 0);
    Scale(1, 1, 1);
    Rotation(0, 0, 0);

    rastMode(RastMode::Solid);
}


DefinedModel::~DefinedModel()
{

}

void DefinedModel::create3DCube(float Width, float Height, float Depth)
{
    ///////////////**************new**************////////////////////
    //Create the vertex buffer
    m_VertexArray = {
    Vertex(-Width / 2, -Height / 2, -Depth / 2, 1.0f, 0.0f, 0.0f, 1.0f),
    Vertex(-Width / 2, +Height / 2, -Depth / 2, 0.0f, 1.0f, 0.0f, 1.0f),
    Vertex(+Width / 2, +Height / 2, -Depth / 2, 0.0f, 0.0f, 1.0f, 1.0f),
    Vertex(+Width / 2, -Height / 2, -Depth / 2, 1.0f, 1.0f, 0.0f, 1.0f),
    Vertex(-Width / 2, -Height / 2, +Depth / 2, 0.0f, 1.0f, 1.0f, 1.0f),
    Vertex(-Width / 2, +Height / 2, +Depth / 2, 1.0f, 1.0f, 1.0f, 1.0f),
    Vertex(+Width / 2, +Height / 2, +Depth / 2, 1.0f, 0.0f, 1.0f, 1.0f),
    Vertex(+Width / 2, -Height / 2, +Depth / 2, 1.0f, 0.0f, 0.0f, 1.0f),
    };
    ///////////////**************new**************////////////////////

    m_indices = {
        // front face
        0, 1, 2,
        0, 2, 3,

        // back face
        4, 6, 5,
        4, 7, 6,

        // left face
        4, 5, 1,
        4, 1, 0,

        // right face
        3, 2, 6,
        3, 6, 7,

        // top face
        1, 5, 6,
        1, 6, 2,

        // bottom face
        4, 0, 3,
        4, 3, 7
    };

    Init();
}

void DefinedModel::Init()
{
    InitBuffers();
    InitFX();
    InitInputLayout();
    InitCBBuffer();
}

void DefinedModel::InitBuffers()
{
    HRESULT hr;

    //index buffer creation
    D3D11_BUFFER_DESC indexBufferDesc;
    ZeroMemory(&indexBufferDesc, sizeof(indexBufferDesc));

    indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
    indexBufferDesc.ByteWidth = sizeof(DWORD) * 12 * 3;
    indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
    indexBufferDesc.CPUAccessFlags = 0;
    indexBufferDesc.MiscFlags = 0;

    D3D11_SUBRESOURCE_DATA iinitData;
    iinitData.pSysMem = &m_indices[0];

    hr = m_pParent->Device()->CreateBuffer(&indexBufferDesc, &iinitData, &squareIndexBuffer);

    //vertex buffer creation
    D3D11_BUFFER_DESC vertexBufferDesc;
    ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc));

    vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
    vertexBufferDesc.ByteWidth = sizeof(Vertex) * 8;
    vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vertexBufferDesc.CPUAccessFlags = 0;
    vertexBufferDesc.MiscFlags = 0;

    D3D11_SUBRESOURCE_DATA vertexBufferData;

    ZeroMemory(&vertexBufferData, sizeof(vertexBufferData));
    vertexBufferData.pSysMem = &m_VertexArray[0];
    hr = m_pParent->Device()->CreateBuffer(&vertexBufferDesc, &vertexBufferData, &squareVertBuffer);
}

void DefinedModel::InitFX()
{
    HRESULT hr;

    //Compile Shaders from shader file
    hr = D3DX11CompileFromFile(L"Trans.fx", 0, 0, "VS", "vs_4_0", 0, 0, 0, &VS_Buffer, 0, 0);
    hr = D3DX11CompileFromFile(L"Trans.fx", 0, 0, "PS", "ps_4_0", 0, 0, 0, &PS_Buffer, 0, 0);

    //Create the Shader Objects
    hr = m_pParent->Device()->CreateVertexShader(VS_Buffer->GetBufferPointer(), VS_Buffer->GetBufferSize(), NULL, &VS);
    hr = m_pParent->Device()->CreatePixelShader(PS_Buffer->GetBufferPointer(), PS_Buffer->GetBufferSize(), NULL, &PS);

    //Set Vertex and Pixel Shaders
    m_pParent->DeviceContext()->VSSetShader(VS, 0, 0);
    m_pParent->DeviceContext()->PSSetShader(PS, 0, 0);
}

void DefinedModel::InitInputLayout()
{
    HRESULT hr;

    D3D11_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };
    UINT numElements = ARRAYSIZE(layout);

    //Create the Input Layout
    hr = m_pParent->Device()->CreateInputLayout(layout, numElements, VS_Buffer->GetBufferPointer(),
        VS_Buffer->GetBufferSize(), &vertLayout);
}

void DefinedModel::InitCBBuffer()
{
    HRESULT hr;

    //Create the buffer to send to the cbuffer in effect file
    D3D11_BUFFER_DESC cbbd;
    ZeroMemory(&cbbd, sizeof(D3D11_BUFFER_DESC));

    cbbd.Usage = D3D11_USAGE_DEFAULT;
    cbbd.ByteWidth = sizeof(cbPerObject);
    cbbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    cbbd.CPUAccessFlags = 0;
    cbbd.MiscFlags = 0;

    hr = m_pParent->Device()->CreateBuffer(&cbbd, NULL, &cbPerObjectBuffer);
}

void DefinedModel::Draw()
{
    //set index buffer
    m_pParent->DeviceContext()->IASetIndexBuffer(squareIndexBuffer, DXGI_FORMAT_R32_UINT, 0);

    //Set the vertex buffer
    UINT stride = sizeof(Vertex);
    UINT offset = 0;
    m_pParent->DeviceContext()->IASetVertexBuffers(0, 1, &squareVertBuffer, &stride, &offset);

    //Set the Input Layout
    m_pParent->DeviceContext()->IASetInputLayout(vertLayout);

    //Set Primitive Topology
    m_pParent->DeviceContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    //set rasteriser state
    m_pParent->DeviceContext()->RSSetState(m_RastState);

    //Matrices
    ///////////////**************new**************////////////////////
    //Set the WVP matrix and send it to the constant buffer in effect file
    XMMATRIX WVP = (worldMatrix()) * (*m_pParent->Camera()->camView()) * (*m_pParent->Camera()->camProjection());
    cbPerObj.WVP = XMMatrixTranspose(WVP);
    m_pParent->DeviceContext()->UpdateSubresource(cbPerObjectBuffer, 0, NULL, &cbPerObj, 0, 0);
    m_pParent->DeviceContext()->VSSetConstantBuffers(0, 1, &cbPerObjectBuffer);

    //draw shape
    m_pParent->DeviceContext()->DrawIndexed(m_indices.size(), 0, 0);
}

void DefinedModel::Rotation(float X, float Y, float Z)
{
    m_Rotation = Vector3(X, Y, Z);
    //m_Rotation.X = X;
    //m_Rotation.Y = Y;
    //m_Rotation.Z = Z;
}

void DefinedModel::Scale(float X, float Y, float Z)
{
    m_Scale = Vector3(X, Y, Z);
    //m_Scale.X = X;
    //m_Scale.Y = Y;
    //m_Scale.Z = Z;
}

void DefinedModel::Offset(float X, float Y, float Z)
{
    m_Offset = Vector3(X, Y, Z);
    //m_Offset.X = X;
    //m_Offset.Y = Y;
    //m_Offset.Z = Z;
}

Vector3 DefinedModel::Rotation()
{
    return m_Rotation;
}

Vector3 DefinedModel::Scale()
{
    return m_Scale;
}

Vector3 DefinedModel::Offset()
{
    return m_Offset;
}

XMMATRIX DefinedModel::worldMatrix()
{
    XMMATRIX Scale = XMMatrixScaling(m_Scale.X(), m_Scale.Y(), m_Scale.Z());
    XMMATRIX Rot = (XMMatrixRotationX(m_Rotation.X())) * (XMMatrixRotationY(m_Rotation.Y())) * (XMMatrixRotationZ(m_Rotation.Z()));
    XMMATRIX Trans = XMMatrixTranslation(m_Offset.X(), m_Offset.Y(), m_Offset.Z());

    // orbital
    //m_modelWorld = Trans * Rot * Scale;

    //on spot
    m_modelWorld = Scale * Rot * Trans;

    return m_modelWorld;
}

void DefinedModel::Destroy()
{
    squareVertBuffer->Release();
    squareIndexBuffer->Release();
    VS->Release();
    PS->Release();
    VS_Buffer->Release();
    PS_Buffer->Release();
    vertLayout->Release();

    cbPerObjectBuffer->Release();

    m_VertexArray.clear();
    m_indices.clear();
}

void DefinedModel::rastMode(RastMode rastmode)
{
    HRESULT hr;
    m_RastMode = rastmode;

    switch (rastmode)
    {
        case RastMode::Solid:
        {
            ///////////////**************new**************////////////////////
            D3D11_RASTERIZER_DESC wfdesc;
            ZeroMemory(&wfdesc, sizeof(D3D11_RASTERIZER_DESC));
            wfdesc.FillMode = D3D11_FILL_SOLID;
            wfdesc.CullMode = D3D11_CULL_BACK;
            hr = m_pParent->Device()->CreateRasterizerState(&wfdesc, &m_RastState);
            ///////////////**************new**************////////////////////
            break;
        }
        case RastMode::Wireframe:
        {
            ///////////////**************new**************////////////////////
            D3D11_RASTERIZER_DESC wfdesc;
            ZeroMemory(&wfdesc, sizeof(D3D11_RASTERIZER_DESC));
            wfdesc.FillMode = D3D11_FILL_WIREFRAME;
            wfdesc.CullMode = D3D11_CULL_BACK;
            hr = m_pParent->Device()->CreateRasterizerState(&wfdesc, &m_RastState);         
            ///////////////**************new**************////////////////////
            break;
        }
    }
}

效果文件(trans.fx):

cbuffer cbPerObject
{
    float4x4 WVP;
};

struct VS_OUTPUT
{
    float4 Pos : SV_POSITION;
    float4 Color : COLOR;
};

VS_OUTPUT VS(float4 inPos : POSITION, float4 inColor : COLOR)
{
    VS_OUTPUT output;
    output.Pos = mul(inPos, WVP);
    output.Color = inColor;

    return output;
}

float4 PS(VS_OUTPUT input) : SV_TARGET
{
    return input.Color;
}