Kagula
2010-04-23
学习环境:
[1]NVIDIA Cg 2.2 October 2009
[2]DirectX SDK 2009 Aug
这里主要是通过DX9目录中cgfx_bumpdemo例程来学习CgFX的调用流程。
具体参考main函数定义
myCgContext = cgCreateContext();//CGcontext myCgContext;
一开始调用cgD3D9SetDevice(pDev);//IDirect3DDevice9* pDev
然后Initialization CG(参考initCG函数定义)
Step2-1:注册CgFX状态,从固定管线接管纹理状态,根据cgfx文件名创建Effect对象。
cgD3D9RegisterStates(myCgContext);//CGcontext myCgContext
cgD3D9SetManageTextureParameters(myCgContext, CG_TRUE)
myCgEffect = cgCreateEffectFromFile(myCgContext, "bumpdemo.cgfx", NULL);
// CGeffect myCgEffect
Step2-2:取CGtechnique实例,检查CGtechnique实例的有效性
取CGtechnique实例的代码段:
myCgTechnique = cgGetFirstTechnique(myCgEffect);//CGtechnique myCgTechnique
myCgTechnique = cgGetNextTechnique(myCgTechnique);
//返回bumpdemo.cgfx(由myCgEffect对应)中名为“bumpdemo_hlsl”的CGtechnique实例
myCgTechniqueHLSL = cgGetNamedTechnique(myCgEffect, "bumpdemo_hlsl");
检查CGtechnique实例,当前硬件是否支持
(cgValidateTechnique(myCgTechnique) == CG_FALSE) // #define CG_FALSE ((CGbool)0)
辅助功能:
const char * cgGetTechniqueName(myCgTechnique); //返回bumpdemo.cgfx中,指定Technique的名称
Step3-3:根据CgFX文件对应的Effect创建CGparameter实例。
Bumpdemo.cgfx文件的代码片段
float4x4 ModelViewProj : ModelViewProjection;
float OuterRadius = 6;
float InnerRadius = 2;
float3 LightPosition = { -8, 0, 15 };
float3 EyePosition = { 0, 0, 18 };
下面是cgfx_bumpdemo.cpp文件中的代码片段
myCgModelViewProjParam =
cgGetEffectParameterBySemantic(myCgEffect, "ModelViewProjection");
//CGparameter myCgModelViewProjParam
myCgEyePositionParam =
cgGetNamedEffectParameter(myCgEffect, "EyePosition");
//CGparameter myCgEyePositionParam
通常情况下Cg函数失败,会返回零
Step3-4:设置bumpdemo.cfgx运行时(纹理)参数
Bumpdemo.cgfx文件中的相关代码
sampler2D normalMap = sampler_state {
minFilter = LinearMipMapLinear;
magFilter = Linear;
wrapS = Repeat;
wrapT = Repeat;
};
samplerCUBE normalizeCube = sampler_state {
minFilter = Linear;
magFilter = Linear;
wrapS = ClampToEdge;
wrapT = ClampToEdge;
};
Cgfx_bumpdemo.cpp文件中的代码
useSamplerParameter(myCgEffect, "normalMap",
myBrickNormalMap);
// PDIRECT3DTEXTURE9 myBrickNormalMap;
useSamplerParameter(myCgEffect, "normalizeCube",
myNormalizeVectorCubeMap);
// PDIRECT3DCUBETEXTURE9 myNormalizeVectorCubeMap;
下面是useSamplerParameter函数的定义
static void useSamplerParameter(CGeffect effect,
const char *paramName, IDirect3DBaseTexture9 *tex)
{
CGparameter param = cgGetNamedEffectParameter(effect, paramName);
if (!param) {
fprintf(stderr, "%s: expected effect parameter named %s/n",
myProgramName, paramName);
exit(1);
}
cgD3D9SetTextureParameter(param, tex);
cgSetSamplerState(param);
}
Step3-1:设置CGFX程序运行时参数
cgSetMatrixParameterfr(myCgModelViewProjParam, modelViewProjMatrix );
// float modelViewMatrix[16];
cgSetParameter3fv(myCgEyePositionParam, eyePosition);
// float eyePosition[3];
Step3-2: Render
/* Iterate through rendering passes for technique (even
though bumpdemo.cgfx has just one pass). */
pass = cgGetFirstPass(myCurrentCgTechninque);
while (pass) {
cgSetPassState(pass);
…调用DrawPrimitive函数,绘制Primitive图元…
cgResetPassState(pass);
pass = cgGetNextPass(pass);
}
//myCurrentCgTechninque=>建立联系=>myCgEffect=>建立联系=>bumpdemo.cgfx
cgD3D9SetDevice(NULL);//对应OnResetDevice事件cgD3D9SetDevice的调用
cgDestroyEffect(myCgEffect);
cgDestroyContext(myCgContext);
cgD3D9SetDevice(NULL);
一个进程中只有一个myCgContext,但是可以有多个myCgEffect(即多个cgfx格式程序文件)。
希望以后有能力,买台带ATI5870显卡的新机器,研究下DirectX11的新特性,娱乐下。当然,算法才是最重要的。