Thanks, that looks clear.
What I don't understand is why your 'Begin' function has only one parameter, I can use a 2nd using flags, like D3DXFX_DONOTSAVESTATE.
What do you mean with pass specific passing of uniforms? (is this setting the vars in the shader)
Like to take this opportunity to improve my frame rendering using shaders.
I know do the following each frame (pseudo code):
// rendering the meshes
- loop through all effects/shaders
- setup vars for effect: SetTechnique, SetMatrix(viewproj)
- effect->Begin
- loop through all materials
- select the material: SetFloatArrays for effect (MatAmb, MatDiff)
- loop through all meshes
- set the streamsource (vertex and indexbuffer)
- and then:
for(unsigned int i=0;i<pD3dscene->mEffectNumPasses[ec];++i)
{
pD3dscene->mEffect[ec]->BeginPass(i);
pD3dscene->mD3dMeshes[oc].RenderAttr(mD3ddev, att, LIST);
++mAttrRendered;
pD3dscene->mEffect[ec]->EndPass();
}
Is there anything wrong in this order/ should I set the effect vars after the 'BeginPass'? (functionally it all works)
Here the 'cleaned up' code of my renderframe function:
bool CD3d::RenderFrameV2(CD3dscene *pD3dscene, CD3dcam *pCam)
{
if(!CheckDevice()) { mDeviceLost = true; return true; }
mObjRendered = 0; mAttrRendered = 0;
pCam->Update();
mD3ddev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
mD3ddev->BeginScene();
// WORLD MESHES; SHADER RENDERING
for(ec=0;ec<pD3dscene->mNrEffects;++ec)
{
if(!SetVertexShader(pD3dscene, ec, "BasicShader", pCam)) return false; // Sets Technique and Vieproj matrix
pD3dscene->mEffect[ec]->Begin(&pD3dscene->mEffectNumPasses[ec], D3DXFX_DONOTSAVESTATE);
for(mc=0;mc<pD3dscene->mNrMaterials;++mc)
{
if(!pD3dscene->PreSelectMaterial(mc, ec)) return false; // Sets 'MatAmb' and 'MatDiff' in the current 'effect/shader'
for(oc=0;oc<pD3dscene->mNrD3dMeshes;++oc)
{
if(pD3dscene->mD3dMeshes[oc].mEffectIndex == ec)
{
if(pCam->SphereInFrustum(&pD3dscene->mD3dMeshes[oc].mWorldPos,
pD3dscene->mD3dMeshes[oc].mBoundingRadius))
{
if(!pD3dscene->PreSelectMesh(oc, mD3ddev)) return false; // Sets the streamsource, vtx/ index buffers
for(DWORD att=0;att<pD3dscene->mD3dMeshes[oc].mAttrSize;++att)
{
if(pD3dscene->mD3dMeshes[oc].mMatIdPerAttr[att] == mc)
{
if(pCam->SphereInFrustum(&pD3dscene->mD3dMeshes[oc].mAttrWorldPos[att],
pD3dscene->mD3dMeshes[oc].mAttrBoundingRadius[att]))
{
for(unsigned int i=0;i<pD3dscene->mEffectNumPasses[ec];++i)
{
pD3dscene->mEffect[ec]->BeginPass(i);
pD3dscene->mD3dMeshes[oc].RenderAttr(mD3ddev, att, LIST);
pD3dscene->mEffect[ec]->EndPass();
}
}
}
}
}
}
}
}
pD3dscene->mEffect[ec]->End();
}
// SKY BOX; SHADER RENDERING
if(pD3dscene->mSkyBoxInScene)
if(!pD3dscene->mSkyBox.Render(pCam->mPosition, pCam, mD3ddev)) return false;
// FFP rendering
if(!SetDefaultRenderStates()) return false;
mD3ddev->EndScene();
HRESULT hr = mD3ddev->Present(NULL, NULL, NULL, NULL);
return true;
}