0

我正在使用的修订后的实际基类和派生类加上实例化它的函数并使用非虚函数调用

着色器类.h

    #ifndef SHADERCLASS_H
    #define SHADERCLASS_H

    #include <D3D11.h>
    #include <D3DX10math.h>
    #include <D3DX11async.h>
    #include <fstream>
    using namespace std;

    class ShaderClass {
    protected:
        struct MatrixBufferType {
            D3DXMATRIX world;
            D3DXMATRIX view;
            D3DXMATRIX projection;
        };

        ID3D11Device*           m_pDevice;
        ID3D11DeviceContext*    m_pDeviceContext;
        HWND m_hWnd;

        ID3D11VertexShader* m_pVertexShader;
        ID3D11PixelShader*  m_pPixelShader;
        ID3D11InputLayout*  m_pLayout;
        ID3D11Buffer*       m_pMatrixBuffer;
        ID3D11SamplerState* m_pSampleState;

        WCHAR*    m_vsFilename;
        WCHAR*    m_psFilename;

    public:
        ShaderClass();
        //ShaderClass( const ShaderClass& other );
        virtual ~ShaderClass();

        bool initialize( ID3D11Device* pDevice, ID3D11DeviceContext* pDeviceContext, HWND hWnd, WCHAR* vsFilename, WCHAR* psFilename );
        void shutdown();
        bool render( int index, D3DXMATRIX view, D3DXMATRIX world, D3DXMATRIX projection, void* pData );

    protected:
        virtual bool initializeShader() = 0;
        virtual void shutdownShader() = 0;
        virtual bool setShaderParameters( D3DXMATRIX world, D3DXMATRIX view, D3DXMATRIX projection, void* pData ) = 0;
        virtual void renderShader( int index ) = 0;

        void outputShaderErrorMessage( ID3D10Blob* pErrorMessage, WCHAR* shaderFilename );

    }; // ShaderClass

    #endif // SHADERCLASS_H

着色器类.cpp

    #include "ShaderClass.h"

    // ------------------------------------------------------------------------------------------
    ShaderClass::ShaderClass() :
      m_pVertexShader( nullptr ),
      m_pPixelShader( nullptr ),
      m_pLayout( nullptr ),
      m_pMatrixBuffer( nullptr ),
      m_pSampleState( nullptr ) {
    } // ShaderClass

    // ----------------------------------------------------------------------------
    // ShaderClass::ShaderClass( const ShaderClass& other ) {
    //} // ShaderClass

    // ----------------------------------------------------------------------------
    ShaderClass::~ShaderClass() {
    } // ~ShaderClass

    // ----------------------------------------------------------------------------
    bool ShaderClass::initialize( ID3D11Device* pDevice, ID3D11DeviceContext* pDeviceContext, HWND hWnd, WCHAR* vsFilename, WCHAR* psFilename ) {
        bool bResult;

        if ( !pDevice ) {
            return false;
        }
        m_pDevice = pDevice;

        if ( !pDeviceContext ) {
            return false;
        }
        m_pDeviceContext = pDeviceContext;

        m_hWnd = hWnd;

        m_vsFilename = vsFilename;
        m_psFilename = psFilename;

        // Initialize The Vertex And Pixel Shaders
        bResult = initializeShader();
        if ( !bResult ) {
            return false;
        }
        return true;
    } // initialize

    // ----------------------------------------------------------------------------
    void ShaderClass::shutdown() {
        // Shutdown Individual Shader Contents
        shutdownShader();
    } // shutdown

    // -----------------------------------------------------------------------------
    bool ShaderClass::render( int indexCount, D3DXMATRIX world, D3DXMATRIX view, D3DXMATRIX projection, void* pData  ) {
        bool bResult;

        bResult = setShaderParameters( world, view, projection, pData );
        if ( !bResult ) {
            return false;
        }

        renderShader( indexCount );

        return true;
    } // render

    // ----------------------------------------------------------------------------
    void ShaderClass::outputShaderErrorMessage( ID3D10Blob* pErrorMessage, WCHAR*   shaderFilename ) {
        char* compileErrors;
        unsigned long bufferSize, i;
        ofstream fout;

        // Get A Pointer To The Error Message Text Buffer
        compileErrors = (char*)(pErrorMessage->GetBufferPointer());

        // Get The Length Of The Message
        bufferSize = pErrorMessage->GetBufferSize();

        // Open A File To Write The Error Message
        fout.open( "shader-error.txt" );

        // Write Out The Error Message
        for ( i = 0; i < bufferSize; i++ ) {
            fout << compileErrors[i];
        }

        // Close The File
        fout.close();

        // Release The Error Message
        pErrorMessage->Release();
        pErrorMessage = nullptr;

        // Pop A Message To Notify The User
        MessageBox( m_hWnd, L"Error compiling shader. Check shader-error.txt for message", shaderFilename, MB_OK );

        return;
    } // outputShaderErrorMessage

LightMapShaderClass.h

    #ifndef LIGHTMAPSHADERCLASS_H
    #define LIGHTMAPSHADERCLASS_H

    #include "ShaderClass.h"

    class LightMapShaderClass : public ShaderClass {    
    public:
        LightMapShaderClass();
        //LightMapShaderClass( const LightMapShaderClass& other );
        ~LightMapShaderClass();

    protected:
        bool    initializeShader();
        void    shutdownShader();
        bool    setShaderParameters( D3DXMATRIX world, D3DXMATRIX view, D3DXMATRIX projection, ID3D11ShaderResourceView** pTextures );
        void    renderShader( int index );

    }; // LightMapShaderCLASS

    #endif // LIGHTMAPSHADERCLASS_H

LightMapShaderClass.cpp

    #include "LightMapShaderClass.h"

    // ----------------------------------------------------------------------------
    LightMapShaderClass::LightMapShaderClass() : ShaderClass() {    
    } // LightMapShaderClass

    // ----------------------------------------------------------------------------
    //LightMapShaderClass::LightMapShaderClass( const LightMapShaderClass& other ) : ShaderClass( other ) {
    //} // LightMapShaderClass

    // ----------------------------------------------------------------------------
    LightMapShaderClass::~LightMapShaderClass() {
    } // ~LightMapShaderClass

    // ----------------------------------------------------------------------------
    bool LightMapShaderClass::initializeShader() {
        HRESULT hr;
        ID3D10Blob* pErrorMessage;
        ID3D10Blob* pVertexShaderBuffer;
        ID3D10Blob* pPixelShaderBuffer;
        D3D11_INPUT_ELEMENT_DESC polygonLayout[2];
        unsigned int uiNumElements;
        D3D11_BUFFER_DESC matrixBufferDesc;
        D3D11_SAMPLER_DESC samplerDesc;

        // Initialize The Pointers
        pErrorMessage = nullptr;
        pVertexShaderBuffer = nullptr;
        pPixelShaderBuffer = nullptr;

        // Compile The Vertex Shader Code
        hr = D3DX11CompileFromFile( m_vsFilename, NULL, NULL, "LightMapVertexShader", "vs_4_1", D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL, &pVertexShaderBuffer, &pErrorMessage, NULL );
        if ( FAILED( hr ) ) {
            // If The Shader Failed To Compile It Should Have Written Something To The Error Message
            if ( pErrorMessage ) {
                outputShaderErrorMessage( pErrorMessage, m_vsFilename );
            }
            // If There Was Nothing In The Error Message It Could Not Find The Shader File
            else {
                MessageBox( m_hWnd, m_vsFilename, L"Missing Shader File", MB_OK );
            }
            return false;
        }

        // Compile The Pixel Shader Code
        hr = D3DX11CompileFromFile( m_psFilename, NULL, NULL, "LightMapPixelShader", "ps_4_1", D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL, &pPixelShaderBuffer, &pErrorMessage, NULL );
        if ( FAILED( hr ) ) {
            // If The Shader Failed To Compile It Should Have Written Something To The Error Message
            if ( pErrorMessage ) {
                outputShaderErrorMessage( pErrorMessage, m_psFilename );
            }
            // If There Was Nothing In The Error Message It Could Not Find The Shader File
            else {
                MessageBox( m_hWnd, m_psFilename, L"Missing Shader File", MB_OK );
            }
            return false;
        }

        // Create The Vertex Shader From The Buffer
        hr = m_pDevice->CreateVertexShader( pVertexShaderBuffer->GetBufferPointer(), pVertexShaderBuffer->GetBufferSize(), NULL, &m_pVertexShader );
        if ( FAILED( hr ) ) {
            return false;
        }

        // Create The Pixel Shader From The Buffer
        hr = m_pDevice->CreatePixelShader( pPixelShaderBuffer->GetBufferPointer(), pPixelShaderBuffer->GetBufferSize(), NULL, &m_pPixelShader );
        if ( FAILED( hr ) ) {
            return false;
        }

        // Create The Vertex Input Layout Description
        // This Setup Needs To Match The VertexType Structure In The ModelClass And In The Shader Buffer
        polygonLayout[0].SemanticName = "POSITION";
        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 = "TEXCOORD";
        polygonLayout[1].SemanticIndex = 0;
        polygonLayout[1].Format = DXGI_FORMAT_R32G32B32_FLOAT;
        polygonLayout[1].InputSlot = 0;
        polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
        polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
        polygonLayout[1].InstanceDataStepRate = 0;

        // Get A Count Of The Elements In The Layout
        uiNumElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]);

        // Create The Vertex Input Layout
        hr = m_pDevice->CreateInputLayout( polygonLayout, uiNumElements, pVertexShaderBuffer->GetBufferPointer(), pVertexShaderBuffer->GetBufferSize(), &m_pLayout );
        if ( FAILED( hr ) ) {
            return false;
        }

        // Release The Vertex Shader Buffer And Pixel Shader Buffer Since They Are No Longer Needed
        pVertexShaderBuffer->Release();
        pVertexShaderBuffer = nullptr;

        pPixelShaderBuffer->Release();
        pPixelShaderBuffer = nullptr;

        // Setup The Description Of The Matrix Dynamic Constant Buffer That Is In The Vertex Shader
        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;

        // Create The Matrix Constant Buffer Pointer So We Can Access The Vertex Shader Constant Buffer From Within This Class
        hr = m_pDevice->CreateBuffer( &matrixBufferDesc, NULL, &m_pMatrixBuffer );
        if ( FAILED( hr ) ) {
            return false;
        }

        // Create A Texture Sampler State Description
        samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
        samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
        samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
        samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
        samplerDesc.MipLODBias = 0.0f;
        samplerDesc.MaxAnisotropy = 1;
        samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
        samplerDesc.BorderColor[0] = 0;
        samplerDesc.BorderColor[1] = 0;
        samplerDesc.BorderColor[2] = 0;
        samplerDesc.BorderColor[3] = 0;
        samplerDesc.MinLOD = 0;
        samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;

        // Create The Texture Sampler State
        hr = m_pDevice->CreateSamplerState( &samplerDesc, &m_pSampleState );
        if ( FAILED( hr ) ) {
            return false;
        }

        return true;
    } // initializeShader

    // ----------------------------------------------------------------------------
    void LightMapShaderClass::shutdownShader() {
        // Release The Sampler State
        if ( m_pSampleState ) {
            m_pSampleState->Release();
            m_pSampleState = nullptr;
        }

        // Release The Matrix Constant Buffer
        if ( m_pMatrixBuffer ) {
            m_pMatrixBuffer->Release();
            m_pMatrixBuffer = nullptr;
        }

        // Release The Layout
        if ( m_pLayout ) {
            m_pLayout->Release();
            m_pLayout = nullptr;
        }

        // Release The Pixel Shader
        if ( m_pPixelShader ) {
            m_pPixelShader->Release();
            m_pPixelShader = nullptr;
        }

        // Release The Vertex Shader
        if ( m_pVertexShader ) {
            m_pVertexShader->Release();
            m_pVertexShader = nullptr;
        }

        return;
    } // shutdownShader

    // ----------------------------------------------------------------------------
    bool LightMapShaderClass::setShaderParameters( D3DXMATRIX world, D3DXMATRIX view, D3DXMATRIX projection, ID3D11ShaderResourceView** pTextures ) {
        HRESULT hr;
        D3D11_MAPPED_SUBRESOURCE mappedResource;
        MatrixBufferType* pData;
        unsigned int uiBufferNumber;

        // Transpose The Matrices To Prepare Them For The Shader
        D3DXMatrixTranspose( &world, &world );
        D3DXMatrixTranspose( &view, &view );
        D3DXMatrixTranspose( &projection, &projection );

        // Lock The Matrix Constant Buffer So It Can Be Written To
        hr = m_pDeviceContext->Map( m_pMatrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource );
        if ( FAILED( hr ) )  {
            return false;
        }

        // Get A Pointer To The Data In The Constant Buffer
        pData = (MatrixBufferType*)mappedResource.pData;

        // Copy The Matrices Into The Constant Buffer
        pData->world = world;
        pData->view  = view;
        pData->projection = projection;

        // Unlock The Matrix Constant Buffer
        m_pDeviceContext->Unmap( m_pMatrixBuffer, 0 );

        // Set The Position Of The Matrix Constant Buffer In The Vertex Shader
        uiBufferNumber = 0;

        // Now Set The Matrix Constant Buffer In The Vertex Shader With The Updated Values
        m_pDeviceContext->VSSetConstantBuffers( uiBufferNumber, 1, &m_pMatrixBuffer );

        // Set Shader Texture Array Resource In The Pixel Shader
        m_pDeviceContext->PSSetShaderResources( 0, 2, pTextures );

        return true;
    } // setShaderParameters

    // ----------------------------------------------------------------------------
    void LightMapShaderClass::renderShader( int indexCount ) {
        // Set The Vertex Input Layout
        m_pDeviceContext->IASetInputLayout( m_pLayout );

        // Set The Vertex And Pixel Shaders That Will Be Used To Render This Triangle
        m_pDeviceContext->VSSetShader( m_pVertexShader, NULL, 0 );
        m_pDeviceContext->PSSetShader( m_pPixelShader, NULL, 0 );

        // Set The Sampler State In The Pixel Shader
        m_pDeviceContext->PSSetSamplers( 0, 1, &m_pSampleState );

        // Render The Triangles
        m_pDeviceContext->DrawIndexed( indexCount, 0, 0 );

        return;
    } // renderShader

使用基类的函数

    // ----------------------------------------------------------------------------
    bool GraphicsClass::initialize( int iScreenWidth, int iScreenHeight, HWND hWnd ) {
        bool bResult;
        D3DXMATRIX baseViewMatrix;

        // Create The Direct3D Object
        m_pD3D = new D3DClass;
        if ( !m_pD3D ) {
            return false;
        }
        // Initialize The Direct3D Object
        bResult = m_pD3D->initialize( iScreenWidth, iScreenHeight, VSYNC_ENABLED, hWnd, FULL_SCREEN, SCREEN_DEPTH, SCREEN_NEAR );
        if ( !bResult ) {
            MessageBox( hWnd, L"Could not initialize Direct3D", L"Error", MB_OK );
            return false;
        }

        // Create The Camera Object
        m_pCamera = new Camera;
        if ( !m_pCamera ) {
            return false;
        }
        // Initialize The Base View Matrix With The Camera For 2D User Interface Rendering
        m_pCamera->setPosition( 0.0f, 0.0f, -1.0f );
        m_pCamera->render();
        m_pCamera->getViewMatrix( baseViewMatrix );

        // Create The Model Object
        m_pModel = new ModelClass;
        if ( !m_pModel ) {
            return false;
        }
        // Initialize The Model Object
        bResult = m_pModel->initialize( m_pD3D->getDevice(), "../DX11Engine/data/square.txt", L"../DX11Engine/data/stone01.dds", L"../DX11Engine/data/light01.dds" );
        if ( !bResult ) {
            MessageBox( hWnd, L"Could not initialize the model object.", L"Error", MB_OK );
            return false;
        }

        // Create The LightMapTextureShader Object
        m_pShader = new LightMapShaderClass;
        if ( !_pShader ) {
            return false;
        }
        // Initialize The LightMapTextureShader Object
        bResult = _pShader->initialize( _pD3D->getDevice(), _pD3D->getDeviceContext(), hWnd, L"../DX11Engine/lightmap.vs", L"../DX11Engine/lightmap.ps" );
        if ( !bResult ) {
            MessageBox( hWnd, L"Could not initialize the light map shader object.", L"Error", MB_OK );
            return false;
        }
        return true;
    } // initialize
4

2 回答 2

1

doSomethingNotPureVirtual()在基类和派生类中有不同的签名

在基类

bool doSomethingNotPureVirtual( param1, param2, param3, param4, void* pData ); 

在派生类

bool settingFunctionPureVirtual( param1, param2, param3, DataType** pMyTypes );

我看到您在使用 nullptr 时使用的是 C++11。尝试在 Drived 类中添加覆盖,编译器会告诉你一些事情

bool settingFunctionPureVirtual( param1, param2, param3, DataType** pMyTypes ) override;
于 2012-11-14T05:35:42.817 回答
0

在您的伪代码中,您的派生类声明了新版本的settingFunctionPureVirtual 和doingSomethingPureVirtual,而不是提供与基类中的声明匹配的虚拟函数的类特定实现。

派生类中的声明都缺少 virtual 并且它们是私有的而不是受保护的。

于 2012-11-14T05:35:14.230 回答