void init_objects()
    {
      sys::info << "app::COGLDev42PCFShadowMapApp::init_objects()" << sys::endl;
      { // plane
        ogl::CPlaneObjectBuilder* pObjectBuilder = new ogl::CPlaneObjectBuilder;
        pObjectBuilder->setWidth(25.0f);
        pObjectBuilder->setHeight(25.0f);
        pObjectBuilder->setSubdivisions(10);
        pObjectBuilder->setTextureScale(0.5f);
        pObjectBuilder->addOption(ogl::CPlaneObjectBuilder::REPEAT_UV);
        pObjectBuilder->addOption(ogl::CObjectBuilder::TANGENTS);
        // pObjectBuilder->addOption(ogl::CObjectBuilder::INVERTED);
        pObjectP = pObjectBuilder->build();
        
        ogl::CTgaTextureBuilder* pTgaTextureBuilder = new ogl::CTgaTextureBuilder;
        ogl::CDdsTextureBuilder* pDdsTextureBuilder = new ogl::CDdsTextureBuilder;
        pTgaTextureBuilder->setFile("ground/concrete_d.tga");
        pObjectP->getShape(0)->getMaterial()->setTexture(ogl::CTexture::EScope::DIFFUSE, pTgaTextureBuilder->build());
        pTgaTextureBuilder->setFile("ground/concrete_n.tga");
        pObjectP->getShape(0)->getMaterial()->setTexture(ogl::CTexture::EScope::NORMALS, pTgaTextureBuilder->build()); // normals
        pDdsTextureBuilder->setFile("skybox/planet.dds");
        pObjectP->getShape(0)->getMaterial()->setTexture(ogl::CTexture::EScope::ENVIRONMENT, pDdsTextureBuilder->build());
        
        // pObjectP->translate(math::vec3(0.0f, -3.0f, 0.0f));
        
        // TODO: move this inside CObject or in a CObjectBuilder
        ogl::CTransformHistory::getInstance()->set(pObjectP, ogl::CTransform(pObjectP->mScale, pObjectP->mOrientation, pObjectP->mPosition));
        
        glExitIfError();
        
        delete pTgaTextureBuilder;
        delete pDdsTextureBuilder;
        delete pObjectBuilder;
      }
      { // box
        ogl::CBoxObjectBuilder* pObjectBuilder = new ogl::CBoxObjectBuilder;
        pObjectBuilder->setWidth(10.0f);
        pObjectBuilder->setHeight(10.0f);
        pObjectBuilder->setDepth(10.0f);
        pObjectBuilder->addOption(ogl::CObjectBuilder::INVERTED);
        pObjectBuilder->setTextureScale(0.5f);
        //pObjectBuilder->addOption(ogl::CObjectBuilder::FLATFACE);
        
        pObjectB = pObjectBuilder->build();
        
        ogl::CTgaTextureBuilder* pTgaTextureBuilder = new ogl::CTgaTextureBuilder;
        ogl::CDdsTextureBuilder* pDdsTextureBuilder = new ogl::CDdsTextureBuilder;
        pTgaTextureBuilder->setFile("tiles/pavers_d.tga");
        pObjectB->getShape(0)->getMaterial()->setTexture(ogl::CTexture::EScope::DIFFUSE, pTgaTextureBuilder->build());
        pTgaTextureBuilder->setFile("tiles/pavers_n.tga");
        pObjectB->getShape(0)->getMaterial()->setTexture(ogl::CTexture::EScope::NORMALS, pTgaTextureBuilder->build()); // normals
        pDdsTextureBuilder->setFile("skybox/skydome.dds");
        pObjectB->getShape(0)->getMaterial()->setTexture(ogl::CTexture::EScope::ENVIRONMENT, pDdsTextureBuilder->build());
        
        pObjectB->translate(math::vec3(0.0f, 5.0f, 0.0f));
        
        glExitIfError();

        delete pTgaTextureBuilder;
        delete pDdsTextureBuilder;
        delete pObjectBuilder;
      }
      { // boblampclean
        ogl::CMd5ObjectBuilder* pObjectBuilder = new ogl::CMd5ObjectBuilder;
        pObjectBuilder->setFile("boblampclean/boblampclean.md5mesh");
        pObjectBuilder->addOption(ogl::CObjectBuilder::NORMALIZED);
        //pObjectBuilder->addOption(ogl::CObjectBuilder::ADJACENCY); // TODO: unfuck up the MD5 parser
        pObject0 = pObjectBuilder->build();
        
        ogl::CTgaTextureBuilder* pTextureBuilder = new ogl::CTgaTextureBuilder;
        pTextureBuilder->setFile("boblampclean/guard1_body_n.tga");
        // sys::info << sys::tab << "set normal to shape: " << pObject0->getShape(0)->getName() << sys::endl;
        pObject0->getShape(0)->getMaterial()->setTexture(ogl::CTexture::EScope::NORMALS, pTextureBuilder->build());
        
        // TODO: need better normalization
        pObject0->scale(2.0f);
        pObject0->rotate(math::quat(-90.0f, math::X) * math::quat(180.0f, math::Z));
        
        // Remember previous transformation
        ogl::CTransformHistory::getInstance()->set(pObject0, ogl::CTransform(pObject0->mScale, pObject0->mOrientation, pObject0->mPosition));
        
        glExitIfError();
        
        delete pObjectBuilder;
        delete pTextureBuilder;
      }
      { // another box
        ogl::CMd5ObjectBuilder* pObjectBuilder = new ogl::CMd5ObjectBuilder;
        pObjectBuilder->setFile("cube.md5mesh");
        pObjectBuilder->addOption(ogl::CObjectBuilder::NORMALIZED);
        pObject1 = pObjectBuilder->build();
        
        pObject1->scale(0.5f);
        pObject1->translate(math::vec3(4.0f, 5.0f, 1.0f));
        
        ogl::CTransformHistory::getInstance()->set(pObject1, ogl::CTransform(pObject1->mScale, pObject1->mOrientation, pObject1->mPosition));
        
        delete pObjectBuilder;
      }
    }