2011-07-27 49 views
1

我觉得这很讨厌,但是有没有更好的方法从Cg着色器中检索结构参数?从Cg着色器检索结构参数

11_two_light_with_structs例子(OpenGL的),还有在着色器结构材料:

CG着色器:

// From page 128 
struct Material { 
    float3 Ke; 
    float3 Ka; 
    float3 Kd; 
    float3 Ks; 
    float shininess; 
}; 

然后在代码中,他们做到这一点:

C代码:

myCgVertexParam_material_Ke = cgGetNamedParameter(myCgVertexProgram, "material.Ke"); 
myCgVertexParam_material_Ka = cgGetNamedParameter(myCgVertexProgram, "material.Ka"); 
myCgVertexParam_material_Kd = cgGetNamedParameter(myCgVertexProgram, "material.Kd"); 
myCgVertexParam_material_Ks = cgGetNamedParameter(myCgVertexProgram, "material.Ks"); 

请参阅MS乏味,你不能只是做

myCgVertexParam_materialALL = cgGetNamedParameter(myCgVertexProgram, "material") ; 

然后是这样的:

cgSetParameterValuefr(myCgVertexParam_materialALL, 13, brassMat) ;//! no. 

在这里,我想对待结构作为一个数组,但最后一个命令不工作,虽然,出现错误“参数不是数字类型”。

回答

0

Cg就是这样做的,它就是这样。

HLSL/D3D11通过CBUFFERS的概念改善了这一点。你最终可以做的是在你的C++代码中创建一个C风格的结构,以反映你着色器中的所有参数,并且一次冲洗到GPU,而不必通过愚蠢的变量名来完成:

C++代码:

struct GPUCDATA 
{ 
    // the concatenated modelview-projection matrix 
    float modelViewProj[16] ; // column major 
    float diffuseLightPos[4] ; 
    float diffuseLightColor[4] ; 
    float specularLightPos[4] ; 
    float specularLightColor[4] ; 
    float eyePos[4] ; 
} ; 

hlslShader.vsh
cbuffer Globals : register(b0) 
{ 
    // the concatenated modelview-projection matrix 
    float4x4 modelViewProj ; 
    float4 diffuseLightPos ; 
    float4 diffuseLightColor ; 
    float4 specularLightPos ; 
    float4 specularLightColor ; 
    float4 eyePos ; 
} ; 

然后从C++:

// gpu is the ID3D11DeviceContext 
D3D11_MAPPED_SUBRESOURCE mappedRes ; 
CHECK_HRESULT(gpu->Map(gpuCDataBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedRes), "Map gpucdatabuffer"); 
GPUCDATA* gpuMems = (GPUCDATA*)mappedRes.pData ; 
memcpy(gpuMems, &gpuCData, sizeof(GPUCDATA)) ; // write to the gpu mems. 
gpu->Unmap(gpuCDataBuffer, 0) ; 
gpu->VSSetConstantBuffers(0, 1, &gpuCDataBuffer); 
gpu->PSSetConstantBuffers(0, 1, &gpuCDataBuffer); 

就是这样!