Thanks, I think I get it.
The ->End() is Always called when begin was called, because the destructor will be called at the end of function.
- can I do exactly the same with the passes that begin/end?
Meanwhile I've been playing around a bit, and the function is now as below (without the EFFECT_RAII).
(by the way, what does RAII stand for?)
/***************** TO DO : ERROR HANDLING WHEN DOING BINDINGS !!!!! ******************/
bool CD3d::RenderScene(const char *pTechnique, const CD3dcam &pCam, std::vector<Q_RENDERABLE>& pRenderBucket)
{
// retrieve the 1st element from bucket and do all bindings
Q_RENDERABLE *last = NULL; //&pRenderBucket[0];
size_t bucketSize = pRenderBucket.size();
for(size_t renderable = 0;renderable<bucketSize;++renderable)
{
auto next = &pRenderBucket[renderable];
if(next->Effect != last->Effect)
{
if(!last) mD3dscene->mShaders[last->Effect].End();
mD3dscene->mShaders[next->Effect].SetTechnique(pTechnique);
mD3dscene->mShaders[next->Effect].Begin();
}
for(unsigned int p=0;p<mD3dscene->mShaders[next->Effect].GetNumPasses();++p)
{
mD3dscene->mShaders[next->Effect].BeginPass(p);
if(next->Material != last->Material) mD3dscene->ShaderSelectMaterial(next->Material, last->Effect);
if(next->Mesh != last->Mesh) mD3dscene->mMeshes[next->Mesh].SetBuffers();
mD3dscene->ShaderSetWorld(next.Instance, next.Id);
mD3dscene->mShaders[next->Effect].Commit();
mD3dscene->mMeshes[next->Mesh].RenderSubMesh(next->Id, LIST); // does the draw call
mD3dscene->mShaders[next->Effect].EndPass();
}
last = &pRenderBucket[renderable];
}
mD3dscene->mShaders[bucketSize-1].End();
return true;
}
I tried to modify this version using RAII, but I got stuck because I have no initial bindings anymore.
Meaning that when I create the erEffect in the scope of the whole function, I have to create it for last->effect, which is a null pointer at that moment.
Also then I try this:
EFFECT_RAII erEffect(&mD3dscene->mShaders[last->Effect].mEffect);
I get an error "no instance of constructor ... matches the argument" list.
mEffect is a CComPtr<ID3DXEffect>. When I remove the reference (&), the error is gone, probably because it already is a pointer.
Note; I will also add the number of passes to the constructor/ & operator, because this is needed for the 'begin' call.