【发布时间】:2019-07-03 14:10:42
【问题描述】:
这里是着色器代码文件名:Shader.shader
struct VOut
{
float4 position : SV_POSITION;
float4 color : COLOR;
};
VOut VMain(float4 position : POSITION, float4 color : COLOR)
{
VOut output;
output.position = position;
output.color = color;
return output;
}
float4 PMain(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
{
return color;
}
这是我编译着色器的方法
RasterShader::RasterShader(ID3D11Device* device,LPCWSTR vFile,LPCSTR vEntry,LPCSTR vVersion,LPCWSTR pFile,LPCSTR pEntry,LPCSTR pVersion)
{
ID3DBlob* compiledCode=nullptr;
vShader = nullptr;
pShader = nullptr;
errors = 0;
if (FAILED(Compile(vFile,vEntry,vVersion,&compiledCode)))
{
errors = 1;
return;
}
if (FAILED(device->CreateVertexShader(compiledCode->GetBufferPointer(), compiledCode->GetBufferSize(),nullptr, &vShader)))
{
compiledCode->Release();
MessageBox(NULL, L"Failed To Create Vertex Shader", L"Failed Vertex Shader", MB_OK);
errors = 1;
return;
}
D3D11_INPUT_ELEMENT_DESC desc[] =
{
{"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0}
,{"COLOR",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0}
};
if (FAILED(device->CreateInputLayout(desc, 2,compiledCode->GetBufferPointer(),compiledCode->GetBufferSize(),&inputLayout)))
{
compiledCode->Release();
MessageBox(NULL, L"Failed To Create Input Layout", L"Failed Input Layout", MB_OK);
errors = 1;
return;
}
compiledCode->Release();
if (FAILED(Compile(pFile,pEntry,pVersion,&compiledCode)))
{
errors = 1;
return;
}
if (FAILED(device->CreatePixelShader(compiledCode->GetBufferPointer(), compiledCode->GetBufferSize(), nullptr, &pShader)))
{
compiledCode->Release();
MessageBox(NULL, L"Failed To Create Pixel Shader", L"Failed Pixel Shader", MB_OK);
errors = 1;
return;
}
compiledCode->Release();
}
HRESULT RasterShader::Compile(LPCWSTR fileName,LPCSTR entry,LPCSTR version,ID3DBlob** code)
{
ID3DBlob* errors=nullptr;
HRESULT hr = D3DCompileFromFile(fileName,nullptr,nullptr
,entry,version
,0,0,code,&errors);
if (FAILED(hr))
{
if (errors!=nullptr)
{
CString data((char*)errors->GetBufferPointer());
MessageBox(NULL, data.GetBuffer(), L"Shader Compile Errors", MB_OK);
data.ReleaseBuffer();
errors->Release();
}
if (code) { (*code)->Release(); }
}
return hr;
}
RasterShader * RasterShader::Create(ID3D11Device* device,LPCWSTR vFile,LPCSTR vMain,LPCSTR vVersion,LPCWSTR pFile,LPCSTR pMain,LPCSTR pVersion)
{
RasterShader* shader = new RasterShader(device,vFile,vMain,vVersion,pFile,pMain,pVersion);
if (shader->errors == 1)
{
delete shader;
shader = nullptr;
}
return shader;
}
这是我创建着色器的方法
shader = RasterShader::Create(directx->getDevice(), L"Shader.shader","VMain","vs_4_0",L"Shader.shader","PMain","ps_4_0");
if (shader == nullptr)
{
errors = 1;
return;
}
这是我创建设备的方式
D3D_FEATURE_LEVEL levels[] = {
D3D_FEATURE_LEVEL_9_1,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_11_1
};
//CREATE DEVICE AND CONTEXT
HRESULT hr = D3D11CreateDevice(nullptr,D3D_DRIVER_TYPE_HARDWARE,0,D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D10_CREATE_DEVICE_DEBUG
,levels,ARRAYSIZE(levels),D3D11_SDK_VERSION
,&device,&level,&context);
返回/支持的功能级别是 9_1
程序在我使用消息"FAILED TO CREATE VERTEX SHADER" 创建顶点着色器时中断
当我分析 device->CreateVertexShader() 返回的 HRESULT 时,我得到错误代码
E_INVALIDARG
启用调试层后出现此错误
CreateVertexShader:编码的顶点着色器大小与指定大小不匹配。 [状态创建错误#166:CREATEVERTEXSHADER_INVALIDSHADERBYTECODE]
我厌倦了询问缓冲区的大小。不确定是否有帮助,或者我是否做得对。
wchar_t buffer[256];
wsprintf(buffer, L"%d",sizeof((*code)->GetBufferPointer()));
MessageBox(NULL, buffer, L"A", MB_OK);
It prints 4
wchar_t buffer[256];
wsprintf(buffer, L"%d",sizeof((*code)->GetBufferSize()));
MessageBox(NULL, buffer, L"A", MB_OK);
It prints 164
任何帮助将不胜感激。谢谢你
【问题讨论】:
-
着色器模型 4 似乎适用于 DX10+。改用着色器模型 3:docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/….
-
另外,请尝试启用 directx 调试标志并在输出窗口中查找错误消息。
-
我将着色器版本更改为 3 无效。我也启用了调试,我得到了这个错误 CreateVertexShader: Encoded Vertex Shader size doesn't match specified size。 [状态创建错误#166:CREATEVERTEXSHADER_INVALIDSHADERBYTECODE]
-
几件事,您还可以将 10 和 11 添加到您的功能集以用于调试目的,以确保确实有支持。但我实际上会检查你编译的字节码传递了什么。我不相信它完全编译,检查你没有一个长度为 0 的缓冲区作为断言。
-
我如何创建我的设备以及我如何检查我的缓冲区大小在新编辑的问题中