Thursday, May 19, 2016

c++ - Loading and using an HLSL shader?


I've been looking everywhere and all I can find are tutorials on writing the shaders. None of them showed me how to incorporate them into my scene.


So essentially:


Given an hlsl shader, if I were to have a function called drawTexturedQuad() and I wanted the shader to be applied to the result, how exactly could I do this?


Thanks



Answer



There are three steps:




  1. Load effect and set the technique

  2. Provide data to the effect

  3. Render


1) Load effect and set the technique


  // Declaration of your effect variable
LPD3DXEFFECT mDSEGeometryStage;
...
initEffects()
{

//With this method you load your effect file
HR(**D3DXCreateEffectFromFile**( d3ddev, "./DeferredEffect_MaterialsStage.fx", 0, 0, D3DXSHADER_DEBUG, 0, &mDSEGeometryStage, &errors);)
// Some Error checking
if( errors )
{
MessageBoxA(0, (char *)errors->GetBufferPointer(), 0, 0);
errors->Release();
}
// Retrieve a Technique from your effects handler
D3DXHANDLE mhTech = mDSEGeometryStage->**GetTechniqueByName**("MaterialsTech");

// Set the technique to be used
HR(mDSEGeometryStage->SetTechnique(mhTech));
}

2) Provide data to the effect:


renderGeometryStage()
{
// Effect values handlers (String parameter is the name of a variable in your .fx file)
D3DXHANDLE mhView = mDSEGeometryStage->GetParameterByName(0, "gView");
D3DXHANDLE mhProjection = mDSEGeometryStage->GetParameterByName(0, "gProjection");

D3DXHANDLE mhNearClip = mDSEGeometryStage->GetParameterByName(0, "gNearClip");
D3DXHANDLE mhFarClip = mDSEGeometryStage->GetParameterByName(0, "gFarClip");

// Set effect values indicating the handler and the data as paramters
HR(mDSEGeometryStage->SetMatrix(mhProjection, &(camera->getProjectionMatrix())));
HR(mDSEGeometryStage->SetMatrix(mhView, &(camera->getViewMatrix())));
HR(mDSEGeometryStage->SetFloat(mhFarClip, camera->getFarClip()));

...


3) Render: As said in a previous answer



ID3DXEffect provides Begin() and BeginPass() methods.



So, in the same rendering method you can start to render by calling the device BeginScene() method and inside call the Begin or BeginPass methods of your effect.


    ...

// Begin Scene
HR(d3ddev->BeginScene());
{

...

// Clear targets surface
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER,
D3DCOLOR_ARGB(0, 0,0,0), 1.0f, 0);

// Begin Effect passes.
UINT numPasses = 0;
HR(mDSEGeometryStage->Begin(&numPasses, 0))
{

// PLACE HERE YOUR RENDERING STUFF
// like: drawTexturedQuad();
}
// End Effect passes
HR(mDSEGeometryStage->End());
}
// End scene rendering
HR(d3ddev->EndScene());
}// End of renderGeometryStage method


Hope it helps, but your question is not about a chunk of code that you can copy/paste, its more about "basic" concepts. So for this kind of things I really recommend you to follow some tutorial because you will understand all the underlying concepts better. Cheers!


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...