DirectX11 C++ 着色器缓冲区在多边形布局描述中变为空
Posted
技术标签:
【中文标题】DirectX11 C++ 着色器缓冲区在多边形布局描述中变为空【英文标题】:DirectX11 C++ Shader Buffer becomes null on polygon layout description 【发布时间】:2017-11-26 11:24:23 【问题描述】:我正在使用 DX11 开发游戏引擎。我的问题是我遇到了读取访问冲突,因为 vertexShaderBuffer
是 nullptr
。
bool TerrainShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, LPCSTR vsFileName, LPCSTR psFileName)
HRESULT result;
ID3D10Blob* errorMessage = nullptr;
ID3D10Blob* vertexShaderBuffer = nullptr;
ID3D10Blob* pixelShaderBuffer = nullptr;
D3D11_INPUT_ELEMENT_DESC polygonLayout[3];
unsigned int numElements;
D3D11_SAMPLER_DESC samplerDesc;
D3D11_BUFFER_DESC matrixBufferDesc;
D3D11_BUFFER_DESC lightBufferDesc;
result = D3DX11CompileFromFile(vsFileName, NULL, NULL, "TerrainVertexShader", "vs_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL,
&vertexShaderBuffer, &errorMessage, NULL);
if (FAILED(result))
if (errorMessage)
OutputShaderErrorMessage(errorMessage, hwnd, vsFileName);
else
MessageBox(hwnd, vsFileName, "Missing Shader File", MB_OK);
return false;
result = D3DX11CompileFromFile(psFileName, NULL, NULL, "TerrainPixelShader", "ps_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL,
&pixelShaderBuffer, &errorMessage, NULL);
if (FAILED(result))
if (errorMessage)
OutputShaderErrorMessage(errorMessage, hwnd, psFileName);
else
MessageBox(hwnd, psFileName, "Missing Shader File", MB_OK);
return false;
result = device->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL,
&m_vertexShader);
if (FAILED(result))
return false;
result = device->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL,
&m_pixelShader);
if (FAILED(result))
return false;
// This setup needs to match the VertexType stucture in the ModelClass and in the shader.
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_R32G32_FLOAT;
polygonLayout[1].InputSlot = 0;
polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
polygonLayout[1].InstanceDataStepRate = 0;
polygonLayout[2].SemanticName = "NORMAL";
polygonLayout[2].SemanticIndex = 0;
polygonLayout[2].Format = DXGI_FORMAT_R32G32B32_FLOAT;
polygonLayout[2].InputSlot = 0;
polygonLayout[2].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
polygonLayout[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
polygonLayout[2].InstanceDataStepRate = 0;
polygonLayout[3].SemanticName = "COLOR";
polygonLayout[3].SemanticIndex = 0;
polygonLayout[3].Format = DXGI_FORMAT_R32G32B32_FLOAT;
polygonLayout[3].InputSlot = 0;
polygonLayout[3].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
polygonLayout[3].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
polygonLayout[3].InstanceDataStepRate = 0;
numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]);
result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(),
vertexShaderBuffer->GetBufferSize(), &m_layout);
if (FAILED(result))
return false;
vertexShaderBuffer->Release();
vertexShaderBuffer = nullptr;
pixelShaderBuffer->Release();
pixelShaderBuffer = nullptr;
//Continues
当代码到达polygonLayout[3].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
时,缓冲区设置为正常。但在那一行 (polygonLayout[3].InstanceDataStepRate = 0;
) 之后,值变为null
,没有明显的原因,带有
result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(),
vertexShaderBuffer->GetBufferSize(), &m_layout);
抛出异常的行。
我尝试在线搜索但没有结果。任何帮助深表感谢。提前致谢。
【问题讨论】:
【参考方案1】:polygonLayout
数组仅包含 3 个项目,因此当您填充 polygonLayout[3]
时,您将产生缓冲区溢出并面临未定义行为(可能会破坏存储在堆栈中的其他变量)。 1) 让它包含 4 个项目是个好主意; 2) 使用带有(调试)索引检查的数组包装器:
::std::array<D3D11_INPUT_ELEMENT_DESC, 4> polygonLayout;
【讨论】:
以上是关于DirectX11 C++ 着色器缓冲区在多边形布局描述中变为空的主要内容,如果未能解决你的问题,请参考以下文章
DirectX11--深入理解Effects11使用着色器反射机制(Shader Reflection)实现一个复杂Effects框架
DirectX11 With Windows SDK--17 利用几何着色器实现公告板效果