DirectX 11添加着色器后窗口崩溃问题排查求助
DirectX 11 程序创建着色器与输入布局后崩溃排查
我在学习Win32 DirectX 11绘制三角形的教程,原本程序能正常渲染蓝色背景,但添加着色器创建、设置及输入布局配置的代码后,窗口会在创建约1秒后崩溃。注释掉这段代码后程序恢复正常。
相关代码
InitPipeline 函数
void InitPipeline() { // load and compile the two shaders ID3D10Blob *VS, *PS; D3DX11CompileFromFile("shaders.shader", 0, 0, "VShader", "vs_4_0", 0, 0, 0, &VS, 0, 0); D3DX11CompileFromFile("shaders.shader", 0, 0, "PShader", "ps_4_0", 0, 0, 0, &PS, 0, 0); //-------------------------------------------STARTS FROM HERE--------------------- // encapsulate both shaders into shader objects dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS); dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS); // set the shader objects devcon->VSSetShader(pVS, 0, 0); devcon->PSSetShader(pPS, 0, 0); // create the input layout object D3D11_INPUT_ELEMENT_DESC ied[] = { {"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}, }; dev->CreateInputLayout(ied, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &pLayout); devcon->IASetInputLayout(pLayout); //-------------------------------------------ENDS HERE------------------------ }
着色器文件(shaders.shader)
struct VOut { float4 position : SV_POSITION; float4 color : COLOR; }; VOut VShader(float4 position : POSITION, float4 color : COLOR) { VOut output; output.position = position; output.color = color; return output; } float4 PShader(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET { return color; }
崩溃原因排查与解决
未检查着色器编译结果:当前代码没有验证
D3DX11CompileFromFile的返回值,也未获取编译错误信息。如果着色器编译失败,VS或PS会是NULL,后续调用VS->GetBufferPointer()会直接触发访问违规崩溃。
解决:添加编译错误检查,获取错误Blob并输出:ID3D10Blob* errorBlob = nullptr; HRESULT hr = D3DX11CompileFromFile("shaders.shader", 0, 0, "VShader", "vs_4_0", 0, 0, 0, &VS, &errorBlob, 0); if (FAILED(hr)) { if (errorBlob) { MessageBoxA(nullptr, (char*)errorBlob->GetBufferPointer(), "顶点着色器编译错误", MB_OK); errorBlob->Release(); } // 终止流程或处理错误 return; } // 像素着色器编译同理添加检查输入布局与着色器输入不匹配:输入布局中
POSITION的格式是DXGI_FORMAT_R32G32B32_FLOAT(3个浮点分量),但顶点着色器的POSITION参数是float4(4个分量),两者不匹配会导致CreateInputLayout失败,pLayout为NULL,后续渲染时触发崩溃。
解决:二选一修改:- 修改输入布局的
POSITION格式为DXGI_FORMAT_R32G32B32A32_FLOAT,并调整COLOR的偏移量为16:D3D11_INPUT_ELEMENT_DESC ied[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; - 修改顶点着色器的输入为
float3,并补充w分量为1.0:VOut VShader(float3 position : POSITION, float4 color : COLOR) { VOut output; output.position = float4(position, 1.0f); output.color = color; return output; }
- 修改输入布局的
COM对象未正确初始化与释放:
pVS、pPS、pLayout这些COM指针如果未初始化为nullptr,或者创建失败后仍被使用,会导致访问违规。另外程序退出时需调用Release()释放这些对象,避免内存泄漏或后续错误。
解决:声明指针时初始化为nullptr,创建失败时终止后续流程,程序退出时依次释放:// 声明时初始化 ID3D11VertexShader* pVS = nullptr; ID3D11PixelShader* pPS = nullptr; ID3D11InputLayout* pLayout = nullptr; // 退出时释放 if (pVS) pVS->Release(); if (pPS) pPS->Release(); if (pLayout) pLayout->Release();着色器文件路径错误:如果
shaders.shader不在程序运行目录下,编译函数会找不到文件,导致VS/PS为NULL,后续访问崩溃。
解决:使用绝对路径测试,或确保编译后的可执行文件与着色器文件在同一目录。
内容的提问来源于stack exchange,提问作者bugger
相关产品推荐
相关产品推荐

