1

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

11_two_light_with_structs示例 (OpenGL) 中,着色器中有一个 struct Material:

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");

看起来很乏味,你不能做吗

myCgVertexParam_materialALL = cgGetNamedParameter( myCgVertexProgram, "material" ) ;

然后是这样的:

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

在这里,我试图将结构视为一个数组,但是最后一个命令不起作用,错误“参数不是数字类型”。

4

1 回答 1

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 );

就是这样!

于 2011-10-14T23:36:28.617 回答