Абстрактный базовый класс, который определяет чисто виртуальную функцию с параметром void *. Производный класс, соответствующий параметру, является указателем на некоторый тип

Пересмотренный, актуальный базовый и производный класс, с которым я работаю, плюс функция, которая его создает и использует вызов не виртуальной функции

ShaderClass.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

ShaderClass.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

0

Решение

Ваш doSomethingNotPureVirtual() имеет различную подпись в базовом классе и производном классе

в базовом классе

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

в производном классе

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

Я вижу, что вы используете C ++ 11, как вы используете nullptr. попробуйте добавить переопределение в классе Drived, компилятор скажет вам что-то

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

Другие решения

В вашем коде psuedo ваш производный класс объявил новые версии settingFunctionPureVirtual и usingSomethingPureVirtual вместо того, чтобы предоставлять специфические для класса реализации виртуальных функций, которые соответствуют объявлениям в базовом классе.

Объявления в вашем производном классе оба отсутствуют виртуальные и являются частными, а не защищенными.

0