DirectX 11 访问冲突

Posted

技术标签:

【中文标题】DirectX 11 访问冲突【英文标题】:DirectX 11 Access Violation 【发布时间】:2014-02-07 15:21:38 【问题描述】:

我从使用 Visual Studio 2010 构建的旧 DirectX 11.0 项目中获取了一个可用的 CSprite 类。我只是对其进行了一些修改,我提取了一些变量、getter 和 setter 并将其放入名为 CObject 的新类中.现在我想用 Visual Studio 2012 构建。

但是现在我每次尝试从 Visual Studio 创建一个 CSprite 对象时都会出现“访问冲突”错误:

Engine.exe 中 0x010A74A8 处未处理的异常:0xC0000005:访问冲突读取位置 0x00000000。

似乎我无法创建任何 DirectX 11 接口对象,如果我想读出对象 Visual Studio 只需说“无法读取内存”。

源码:

对象.h

#ifndef __OBJECT_H__
#define __OBJECT_H__

#include "../DX11Core/DX11Util.h"

class CObject

public:
    CObject();
    ~CObject()

    void SetStatus( STRING _status )     m_status = _status; 
    void SetTag( STRING _tag )           m_tag = _tag; 
    void SetPosition( float _x, float _y, float _z )  SetPosition( XMFLOAT3( _x, _y, _z ) ); 
    void SetPosition( XMFLOAT3 _pos )    m_position = _pos; 
    void SetRotation( float _rot )       m_fRotation = _rot; 
    void SetScale( float _x, float _y )  SetScale( XMFLOAT3( _x, _y, 1 ) ); 
    void SetScale( XMFLOAT3 _scale )     m_scale = _scale; 
    void SetAlpha( float _alpha )        m_fAlpha = Clamp( _alpha, 0.0f, 1.0f ); 
    void SetActive( bool _active )       m_bActive = _active; 

    XMFLOAT3&   GetPosition()            return m_position; 
    STRING      GetStatus()              return m_status; 
    STRING      GetTag()                 return m_tag; 
    float       GetXPosition()           return m_position.x; 
    float       GetYPosition()           return m_position.y; 
    float       GetZPosition()           return m_position.z; 
    float       GetRotation()            return m_fRotation; 
    XMFLOAT3&   GetScale()               return m_scale; 
    float       GetXScale()              return m_scale.x; 
    float       GetYScale()              return m_scale.y; 
    bool        IsActive()               return m_bActive; 

protected:
    XMFLOAT3    m_position;
    STRING      m_tag;
    STRING      m_status;
    float       m_fRotation;
    XMFLOAT3    m_scale;
    float       m_fAlpha;
    bool        m_bActive;
;

#endif // __OBJECT_H__

Sprite.h

#ifndef __SPRITE_H__
#define __SPRITE_H__

#include "Object.h"
#include "../DX11Core/DX11Core.h"
#include "../DX11Core/GraphicHelper.h"

struct Vertex

    XMFLOAT3 Pos;
    XMFLOAT2 Tex;
;

class CSprite : public CObject

public:
    CSprite( STRING _filename );
    ~CSprite()
    
        RELEASE_COM( m_pVertices );
        RELEASE_COM( m_pTextureSampler );
        RELEASE_COM( m_pTextureSRV );
    

    int Initialize();
    int Update( const float _dt );
    void Render();

#pragma region Getter & Setter

    void SetTexture( STRING _filename );
    void SetFrameCount( int _framecount )  m_nFrameCount = _framecount; 
    void SetFrame( int _frameidx )
    
        if( _frameidx >= 0 && _frameidx < m_nFrameCount )
        
            m_nActualFrame = _frameidx;
        
        BuildVertices();
    
    void SetPosition( XMFLOAT3& _pos )
    
        m_position = _pos;
        m_position.x -= ( theDXCore->GetClientWidth() / 2 );
        m_position.y *= -1.0f;
        m_position.y += ( theDXCore->GetClientHeight() / 2 );
    

    float       GetLeftBounding() const  return ( m_position.x + m_fBoundingLeft ); 
    float       GetRightBounding() const     return ( m_position.x + m_fBoundingRight ); 
    float       GetTopBounding() const   return ( m_position.y + m_fBoundingTop ); 
    float       GetBottomBounding() const  return ( m_position.y + m_fBoundingBottom ); 
    int         GetFrameIdx() const  return m_nActualFrame; 
    XMMATRIX    GetWorldMatrix() const;
    Vertex      GetVertex( int _i) const  return tempVertex[_i]; 

#pragma endregion

private:
    void BuildVertices();

    int         m_nFrameCount;
    int         m_nActualFrame;
    float       m_fFrameDT;
    float       m_fActualFrameDT;

    float       m_fBoundingLeft;
    float       m_fBoundingRight;
    float       m_fBoundingTop;
    float       m_fBoundingBottom;

    Vertex tempVertex[6];

    ID3D11Buffer*                           m_pVertices;
    ID3D11ShaderResourceView*               m_pTextureSRV;
    ID3D11SamplerState*                     m_pTextureSampler;
    ID3DX11EffectMatrixVariable*            m_pFXWorld;
    ID3DX11EffectShaderResourceVariable*    m_pFXTexture;
    ID3DX11EffectSamplerVariable*           m_pFXTextureSampler;
;

#endif //__SPRITE_H__

Sprite.cpp |我在问题开始的地方插入了两个 cmets

#include "Sprite.h"
#include "SpriteManager.h"

CSprite::CSprite( STRING _filename )
    : m_nFrameCount( 1 )
    , m_nActualFrame( 0 )
    , m_pTextureSRV( 00 )
    , m_pTextureSampler( 00 )
    , m_pVertices( 00 )
    , m_pFXWorld( 00 )
    , m_pFXTexture( 00 )
    , m_pFXTextureSampler( 00 )
    , m_fFrameDT( 1000.0f )
    , m_fActualFrameDT( 0.0f )

    GraphicHelper::CreateSRV( m_pTextureSRV, _filename ); // can't create ID3D11ShaderResourceView

    this->Initialize();


int CSprite::Initialize()

    D3D11_SAMPLER_DESC samplerDesc = ;
    samplerDesc.AddressU = samplerDesc.AddressV = samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
    samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
    samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
    //  samplerDesc.Filter = D3D11_FILTER_ANISOTROPIC;
    //  samplerDesc.MaxAnisotropy = 4;
    samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
    HR( theDevice->CreateSamplerState( &samplerDesc, &m_pTextureSampler ) );

    BuildVertices( );

    D3D11_SAMPLER_DESC colorMapDesc = ;
    colorMapDesc.AddressU = colorMapDesc.AddressV = colorMapDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
    colorMapDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
    colorMapDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
    //  colorMapDesc.Filter = D3D11_FILTER_ANISOTROPIC;
    //  colorMapDesc.MaxAnisotropy = 4;
    colorMapDesc.MaxLOD = D3D11_FLOAT32_MAX;
    HR( theDevice->CreateSamplerState( &colorMapDesc, &m_pTextureSampler ) );

    m_pFXWorld          = theSpriteManager->GetFX()->GetVariableByName( "gWorld" )->AsMatrix();
    m_pFXTexture        = theSpriteManager->GetFX()->GetVariableByName( "gTexture" )->AsShaderResource();
    m_pFXTextureSampler = theSpriteManager->GetFX()->GetVariableByName( "gTextureSampler" )->AsSampler();

    return 0;


void CSprite::SetTexture( STRING _filename )

    GraphicHelper::CreateSRV( m_pTextureSRV, _filename );


XMMATRIX CSprite::GetWorldMatrix() const

    XMMATRIX translation = XMMatrixTranslation( m_position.x, m_position.y, m_position.z );
    XMMATRIX rotationZ = XMMatrixRotationZ( m_fRotation );
    XMMATRIX scale = XMMatrixScaling( m_scale.x, m_scale.y, 1.0f );

    return scale * rotationZ * translation;


void CSprite::BuildVertices()

    RELEASE_COM( m_pVertices );

    ID3D11Resource* pcolorTex = 00;
    m_pTextureSRV->GetResource( &pcolorTex ); //throw access violation

    D3D11_TEXTURE2D_DESC colorTexDesc = ;
    ( reinterpret_cast<ID3D11Texture2D*>( pcolorTex ) )->GetDesc( &colorTexDesc );
    pcolorTex->Release();

    colorTexDesc.Width /= m_nFrameCount;
    // Calculate corners for uneven boundings
    float left = -(float)(int)( colorTexDesc.Width * 0.5f );
    float right = (float)((int)( colorTexDesc.Width * 0.5f ) );
    if( colorTexDesc.Width % 2 == 1 ) right += 1.0f;
    m_fBoundingLeft = left;
    m_fBoundingRight = right;

    float top = (float)(int)( colorTexDesc.Height * 0.5f );
    float bottom = -(float)(int)( colorTexDesc.Height * 0.5f );
    if( colorTexDesc.Height % 2 == 1 ) bottom -= 1.0f;
    m_fBoundingTop = top;
    m_fBoundingBottom = bottom;

    float FrameWidth = 1.0f / m_nFrameCount;
    // Create Vertexbuffer

    Vertex vertices[] =
    
         XMFLOAT3( right, top, 1.0f ),    XMFLOAT2( FrameWidth * ( m_nActualFrame + 1 ), 0.0f ) ,
         XMFLOAT3( right, bottom, 1.0f ), XMFLOAT2( FrameWidth * ( m_nActualFrame + 1 ), 1.0f ) ,
         XMFLOAT3( left, bottom, 1.0f ),  XMFLOAT2( FrameWidth * ( m_nActualFrame     ), 1.0f ) ,

         XMFLOAT3( left, bottom, 1.0f ),  XMFLOAT2( FrameWidth * ( m_nActualFrame     ), 1.0f ) ,
         XMFLOAT3( left, top, 1.0f ),     XMFLOAT2( FrameWidth * ( m_nActualFrame     ), 0.0f ) ,
         XMFLOAT3( right, top, 1.0f ),    XMFLOAT2( FrameWidth * ( m_nActualFrame + 1 ), 0.0f ) ,
    ;

    D3D11_BUFFER_DESC vdesc = ;
    vdesc.Usage = D3D11_USAGE_IMMUTABLE;
    vdesc.ByteWidth = sizeof( Vertex ) * ARRAYSIZE( vertices );
    vdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    D3D11_SUBRESOURCE_DATA vdata = ;
    vdata.pSysMem = vertices;
    HR( theDevice->CreateBuffer( &vdesc, &vdata, &m_pVertices ) );

    memcpy( &tempVertex, vertices, sizeof( vertices ) );


int CSprite::Update( const float _dt )

    m_fActualFrameDT -= _dt;
    if( m_fActualFrameDT < 0.0f )
    
        m_fActualFrameDT = m_fFrameDT;

        int i = m_nActualFrame + 1;
        if( i >= m_nFrameCount ) i = 0;

        SetFrame( i );
    

    return ERROR_SUCCESS;


void CSprite::Render()

    UINT stride = sizeof( Vertex );
    UINT offset = 0;
    theContext->IASetVertexBuffers( 0, 1, &m_pVertices, &stride, &offset );
    XMMATRIX world = GetWorldMatrix();
    m_pFXWorld->SetMatrix( reinterpret_cast<float*>( &world ) );
    m_pFXTexture->SetResource( m_pTextureSRV );
    m_pFXTextureSampler->SetSampler( 0, m_pTextureSampler );

    D3DX11_TECHNIQUE_DESC techDesc = ;
    theSpriteManager->GetFXTech()->GetDesc( &techDesc );

    for( UINT p = 0; p < techDesc.Passes; ++p )
    
        theSpriteManager->GetFXTech()->GetPassByIndex( p )->Apply( 0, theContext );

        theContext->Draw( 6, 0 );
    

【问题讨论】:

你试过调试它吗?您应该能够使用 VS 找到该行 我现在行在哪里,但我无法创建任何 DX 接口对象... 你没有碰巧修改其他东西吗?与您使用的任何版本控制系统中的工作版本进行比较。如果您不使用它,那么任何时候开始都不会太晚。 好的,我尝试了早期版本的课程,但我认为不会有任何改变...... 不,即使我的旧代码也不起作用,我几乎什么也没做,只是外包了。唯一真正改变的是 IDE 从 Visual Studio 2010 到 Visual Studio 2012。我还用 VS2012 重建了 Effects11.lib 和 Effects11d.lib 【参考方案1】:

可能你得到这个异常是因为你的 m_pTextureSRV 是 NULL,试试这个:

if (m_pTextureSRV != NULL)

    ID3D11Resource* pcolorTex = 00;
    m_pTextureSRV->GetResource( &pcolorTex ); // put a break point here

在运行时,如果断点会停止执行将意味着我错了,但如果不是,则意味着我是对的并且你没有正确初始化 m_pTexture!

【讨论】:

以上是关于DirectX 11 访问冲突的主要内容,如果未能解决你的问题,请参考以下文章

简单的 DirectX 11 程序运行时错误

WPF 应用程序和 DirectX 光栅器中的访问冲突异常

DirectX11 C++ 着色器缓冲区在多边形布局描述中变为空

Directx 11 前缓冲器

DirectX 12和DirectX 11选哪个,有什么区别

DirectX - BackBuffer 概念