void Renderer::RenderXModel(const XModel& model, const Effect& effect, const D3DXMATRIX& model_matrix)
{
  assert(model.IsCorrect());
  assert(effect.IsCorrect());

  D3DXMATRIX full_matrix = model_matrix * view_ * projection_;

  const auto& effect_data = effect.d3d9_effect();
  effect_data->SetMatrix
    ("matrix_world_view_proj", &full_matrix);

  UINT passes;
  D3DXHANDLE tech;
  effect_data->FindNextValidTechnique(0, &tech);
  effect_data->SetTechnique(tech);
  effect_data->Begin(&passes, 0);
  for (UINT pass = 0; pass < passes; ++pass)
  {
    effect_data->BeginPass(pass);

    const auto& materials = model.textures();
    for (UINT i = 0; i < model.subset_number(); ++i) {
      if (i < materials.size())
        effect_data->SetTexture("tex0", materials[i]->d3d9_texture());
      effect_data->CommitChanges();
      model.mesh()->DrawSubset(i);
    }

    effect_data->EndPass();
  }
  effect_data->End();
}
void Renderer::RenderRawModel(const gfx::Model3d& model, const Effect& effect, const D3DXMATRIX& model_matrix)
{
  assert(effect.IsCorrect());

  for (auto& data : model.render_data()) {
    D3DXMATRIX full_matrix = model_matrix * view_ * projection_;

    const auto& effect_data = effect.d3d9_effect();
    effect_data->SetMatrix
      ("matrix_world_view_proj", &full_matrix);

    UINT passes;
    D3DXHANDLE tech;
    effect_data->FindNextValidTechnique(0, &tech);
    effect_data->SetTechnique(tech);
    effect_data->Begin(&passes, 0);
    for (UINT pass = 0; pass < passes; ++pass)
    {
      effect_data->BeginPass(pass);

      effect_data->SetTexture("tex0", storage_->FetchTexture(data));
      effect_data->CommitChanges();
      device_->SetFVF(VERTEX_XYZ_FVF);
      device_->SetStreamSource(0, storage_->FetchVertexBuffer(data), 0, sizeof(Vertex_xyz));
      device_->SetIndices(storage_->FetchIndexBuffer(data));
      device_->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, data.vertices_number, 0, data.faces_number);
      effect_data->EndPass();
    }
    effect_data->End();
  }
}