着色器构造
2026-02-01
11
0
d3d11.dll对外着色器提供的结构体分别为:
- gs_vertex_shader(device_vertexshader_create)
- gs_pixel_shader (device_pixelshader_create)
gs_shader_t *device_vertexshader_create(gs_device_t *device,
const char *shader_string,
const char *file, char **error_string)
{
return new gs_vertex_shader(device, file, shader_string);
}
gs_shader_t *device_pixelshader_create(gs_device_t *device,
const char *shader_string,
const char *file, char **error_string)
{
return new gs_pixel_shader(device, file, shader_string);
}
无论是gs_vertex_shader还是gs_pixel_shader,其核心是通过ShaderProcessor类处理着色器。
struct ShaderParser : shader_parser {
inline ShaderParser() { shader_parser_init(this); }
inline ~ShaderParser() { shader_parser_free(this); }
};
struct ShaderProcessor {
gs_device_t *device;
ShaderParser parser;
void BuildInputLayout(vector<D3D11_INPUT_ELEMENT_DESC> &inputs);
void BuildParams(vector<gs_shader_param> ¶ms);
void BuildSamplers(vector<unique_ptr<ShaderSampler>> &samplers);
void BuildString(string &outputString);
void Process(const char *shader_string, const char *file);
inline ShaderProcessor(gs_device_t *device) : device(device) {}
};
过程如下:
gs_vertex_shader::gs_vertex_shader(gs_device_t *device, const char *file,
const char *shaderString)
: gs_shader(device, gs_type::gs_vertex_shader, GS_SHADER_VERTEX),
hasNormals(false),
hasColors(false),
hasTangents(false),
nTexUnits(0)
{
ShaderProcessor processor(device);
ComPtr<ID3D10Blob> shaderBlob;
string outputString;
HRESULT hr;
//词法分析
processor.Process(shaderString, file);
//生成最终的HLSL脚本
processor.BuildString(outputString);
processor.BuildParams(params); //参数
processor.BuildInputLayout(layoutData);//布局
GetBuffersExpected(layoutData);
BuildConstantBuffer(); //常量参数
//编译
Compile(outputString.c_str(), file, "vs_4_0", shaderBlob.Assign());
data.resize(shaderBlob->GetBufferSize());
memcpy(&data[0], shaderBlob->GetBufferPointer(), data.size());
hr = device->device->CreateVertexShader(data.data(), data.size(), NULL,shader.Assign());
const UINT layoutSize = (UINT)layoutData.size();
if (layoutSize > 0) {
hr = device->device->CreateInputLayout(layoutData.data(),
(UINT)layoutSize,
data.data(), data.size(),
layout.Assign());
}
viewProj = gs_shader_get_param_by_name(this, "ViewProj");
world = gs_shader_get_param_by_name(this, "World");
}
OBS-D3D11渲染梳理





