Beispiel #1
0
void project1() {
	// Create scene
	Scene scn;
	scn.SetSkyColor(Color(0.8f, 0.9f, 1.0f));

	// Create boxes
    LambertMaterial lambert1;
    lambert1.SetDiffuseColor(Color(0.3f,0.3f,0.3f));

	MeshObject box1;
	box1.MakeBox(5.0f,0.1f,5.0f, &lambert1);
	scn.AddObject(box1);
    
    
    LambertMaterial lambert2;
    lambert2.SetDiffuseColor(Color(0.7f,0.7f,0.7f));
	MeshObject box2;
	box2.MakeBox(1.0f,1.0f,1.0f, &lambert2);
    
	InstanceObject inst1(box2);
	Matrix34 mtx;
	mtx.MakeRotateX(0.5f);
	mtx.d.y=1.0f;
	inst1.SetMatrix(mtx);
	scn.AddObject(inst1);
    
	InstanceObject inst2(box2);
	mtx.MakeRotateY(1.0f);
	mtx.d.Set(-1.0f,0.0f,1.0f);
	inst2.SetMatrix(mtx);
	scn.AddObject(inst2);
    
	// Create lights
	DirectLight sunlgt;
	sunlgt.SetBaseColor(Color(1.0f, 1.0f, 0.9f));
	sunlgt.SetIntensity(0.5f);
	sunlgt.SetDirection(Vector3(-0.5f, -1.0f, -0.5f));
	scn.AddLight(sunlgt);
    
	PointLight redlgt;
	redlgt.SetBaseColor(Color(1.0f, 0.2f, 0.2f));
	redlgt.SetIntensity(2.0f);
	redlgt.SetPosition(Vector3(2.0f, 2.0f, 0.0f));
	scn.AddLight(redlgt);
    
	// Create camera
	Camera cam;
	cam.LookAt(Vector3(2.0f,2.0f,5.0f), Vector3(0.0f,0.0f,0.0f));
	cam.SetResolution(800,600);
	cam.SetFOV(40.0f);
	cam.SetAspect(1.33f);
    
	// Render image
	cam.Render(scn);
	cam.SaveBitmap("project1.bmp");
}
Beispiel #2
0
// Initialization: load and compile shaders, initialize camera(s), load models.
void init() {
  
  // Get handles to the Scene and the Screen.
  Scene *rootScene = Engine::instance()->rootScene();
  Screen *primScreen = Engine::instance()->mainScreen();

  // Load shaders and use the resulting shader program. 
  GLuint gShader = Angel::InitShader( "shaders/vmorph.glsl", "shaders/fmorph.glsl" );

  // Let the other objects know which shader to use by default.
  rootScene->Shader( gShader );
  primScreen->_camList.Shader( gShader );

  // We start with no cameras, by default. Add one and set it "active" by using next().
  primScreen->_camList.addCamera( "Camera1" );
  primScreen->_camList.next();

  // Create an object and add it to the scene with the name "bottle".
  Object *bottle = rootScene->AddObject( "bottle" );

  // Use the object loader to actually fill out the vertices and-so-on of the bottle.
  loadModelFromFile( bottle, "../models/bottle-a.obj" );

  // Scale the bottle down!
  bottle->trans.scale.Set( 0.01 );

  // Buffer the object onto the GPU. This does not happen by default,
  // To allow you to make many changes and buffer only once,
  // or to buffer changes selectively.
  bottle->Buffer();

  // Object class has-a pointer to an object which is the morph target.
  // they are created and buffered as follows:

  // this makes a new object and links it to the source object. it returns the addr of the new obj..
  bottle->genMorphTarget( gShader ) ; 

  // we can get the addr of the morph object like this, also.
  Object *bottleMorphTarget = bottle->getMorphTargetPtr() ; 

  // with this model, we can use all the preexisting Object class functionality
  loadModelFromFile( bottleMorphTarget, "../models/bottle-b.obj" ); 
  bottleMorphTarget->trans.scale.Set( 0.01 );

  // YES THIS IS THE REAL OBJECT, NOT THE TARGET. 
  // IT SENDS THE MORPH VERTICES TO THE SHADER, NOT TO THE DRAW LIST TO BE DRAWN!
  bottle->BufferMorphOnly(); 

  // Generic OpenGL setup: Enable the depth buffer and set a nice background color.
  glEnable( GL_DEPTH_TEST );
  glClearColor( 0.3, 0.5, 0.9, 1.0 );

}
Beispiel #3
0
void PBRMaterialDemo::Init(RasterizedGame &game, Scene &scene)
{
    const string path = AssetLoader::Get().TexturePath("pbr/");
    ifstream in(path + "list.txt");

#ifdef _DEBUG
    const int sphereQuality = 3;
#else
    const int sphereQuality = 5;
#endif

    TriangleMesh sphere = GetSphereMeshSolid(false, sphereQuality, 50.0f);
    scene.mTriMeshes.push_back(sphere);
    const int sphereMeshIdx = static_cast<int>(scene.mTriMeshes.size()) - 1;

    scene.mObjects3D.reserve(50);
    string line;
    while(getline(in, line))
    {
        Material mat;
        mat.mGloss = 1.0f;
        mat.mKs = vec3(1.0f);
        mat.mKd = vec3(1.0f);
        mat.mNeedsForwardRender = false;
        string texPath = path + line + "/" + line;
        mat.mTextureMaps.push_back(Material::TextureInfo(texPath + "-albedo.png", TextureType::DIFFUSE_MAP));
        mat.mTextureMaps.push_back(Material::TextureInfo(texPath + "-normal.png", TextureType::NORMAL_MAP));
        mat.mTextureMaps.push_back(Material::TextureInfo(texPath + "-metal-rough.png", TextureType::SPECULAR_MAP));

        scene.mMaterials.push_back(mat);
        const int matIdx = static_cast<int>(scene.mMaterials.size()) - 1;

        scene.AddObject(AssetLoader::Get().CreateObject(&scene, sphereMeshIdx, matIdx));
        mObjects.push_back(&scene.mObjects3D[scene.mObjects3D.size() - 1]);
        mObjects.back()->mShadowCaster = false;
        mObjects.back()->mVisible = false;
    }

    /*for(float rough = 0.0f; rough < 1.0f; rough += 0.2f) {
    for(float metal = 0.0f; metal < 1.0f; metal += 0.2f) {
    Material mat;
    mat.mGloss = rough;
    mat.mKs = vec3(metal);
    mat.mKd = vec3(0.5f);
    mat.mNeedsForwardRender = false;
    scene.mMaterials.push_back(mat);
    const int matIdx = scene.mMaterials.size() - 1;
    scene.AddObject(AssetLoader::Get().CreateObject(&scene, sphereMeshIdx, matIdx));
    mObjects.push_back(&scene.mObjects3D[scene.mObjects3D.size() - 1]);
    mObjects.back()->mShadowCaster = false;
    mObjects.back()->mVisible = false;
    }
    }*/

    /*for(float x = 0.0f; x <= 1.0f; x += 0.2f) {
    Material mat;
    mat.mGloss = 0.8;
    mat.mKs = vec3(x);
    mat.mKd = vec3(0.5f);
    mat.mNeedsForwardRender = false;
    scene.mMaterials.push_back(mat);
    const int matIdx = scene.mMaterials.size() - 1;
    scene.AddObject(AssetLoader::Get().CreateObject(&scene, sphereMeshIdx, matIdx));
    mObjects.push_back(&scene.mObjects3D[scene.mObjects3D.size() - 1]);
    mObjects.back()->mShadowCaster = false;
    mObjects.back()->mVisible = false;
    }*/


    mObjects[mCurrObjIdx]->mVisible = true;

    // Init Light
    scene.mLights.push_back(&mLight);
    game.mRenderer.SetScene(&scene);
    game.mInputHandler.AddEventListener(this);
}
Beispiel #4
0
void SceneImporter<real>::ReadScene( std::istream& stream, Scene<real>& oScene )
{
	// Read the 'Scene' token
	ReadNextExactToken( stream, "Scene" );
	ReadNextExactToken( stream, "{" );

	// Read scene components
	std::string token = ReadNextToken( stream );

	while( token != "}" )
	{
		if ( token == "SceneInfo" )
		{
			ReadNextExactToken( stream, "(" );
			ReadSceneInfo( stream, oScene );
			ReadNextExactToken( stream, ")" );
			ReadNextExactToken( stream, ";" );
		}
		else if ( token == "TurntableCamera" )
		{
			std::string name = ReadNextToken( stream );
			ReadNextExactToken( stream, "(" );
			Camera<real>* camera = ReadTurntableCamera( stream, name );
			ReadNextExactToken( stream, ")" );
			ReadNextExactToken( stream, ";" );

			oScene.AddObject( camera, true );
		}
		else if ( token == "DirectionalLight" )
		{
			std::string name = ReadNextToken( stream );
			ReadNextExactToken( stream, "(" );
			Light<real>* light = ReadDirectionalLight( stream, name );
			ReadNextExactToken( stream, ")" );
			ReadNextExactToken( stream, ";" );

			oScene.AddObject( light, true );
		}
		else if ( token == "PointLight" )
		{
			std::string name = ReadNextToken( stream );
			ReadNextExactToken( stream, "(" );
			Light<real>* light = ReadPointLight( stream, name );
			ReadNextExactToken( stream, ")" );
			ReadNextExactToken( stream, ";" );

			oScene.AddObject( light, true );
		}
		else if ( token == "SpotLight" )
		{
			std::string name = ReadNextToken( stream );
			ReadNextExactToken( stream, "(" );
			Light<real>* light = ReadSpotLight( stream, name );
			ReadNextExactToken( stream, ")" );
			ReadNextExactToken( stream, ";" );

			oScene.AddObject( light, true );
		}
		else if ( token == "BlinnPhongMaterial" )
		{
			std::string name = ReadNextToken( stream );
			ReadNextExactToken( stream, "(" );
			Material* material = ReadBlinnPhongMaterial( stream, name );
			ReadNextExactToken( stream, ")" );
			ReadNextExactToken( stream, ";" );

			oScene.AddObject( material, true );
		}
		else if ( token == "EnvironmentMaterial" )
		{
			std::string name = ReadNextToken( stream );
			ReadNextExactToken( stream, "(" );
			Material* material = ReadEnvironmentMaterial( stream, name );
			ReadNextExactToken( stream, ")" );
			ReadNextExactToken( stream, ";" );

			oScene.AddObject( material, true );
		}
		else if ( token == "CubeMap" )
		{
			std::string name = ReadNextToken( stream );
			ReadNextExactToken( stream, "(" );
			Texture<real>* cubeMap = ReadCubeMap( stream, name );
			ReadNextExactToken( stream, ")" );
			ReadNextExactToken( stream, ";" );

			oScene.AddObject( cubeMap, true );
		}
		else if ( token == "Texture2D" )
		{
			std::string name = ReadNextToken( stream );
			ReadNextExactToken( stream, "(" );
			Texture<real>* texture = ReadTexture2D( stream, name );
			ReadNextExactToken( stream, ")" );
			ReadNextExactToken( stream, ";" );

			oScene.AddObject( texture, true );
		}
		else if ( token == "Box" )
		{
			std::string name = ReadNextToken( stream );
			ReadNextExactToken( stream, "(" );
			Node<real>* box = ReadBox( stream, name );
			ReadNextExactToken( stream, ")" );
			ReadNextExactToken( stream, ";" );

			oScene.AddObject( box, true );
		}
		else if ( token == "Cone" )
		{
			std::string name = ReadNextToken( stream );
			ReadNextExactToken( stream, "(" );
			Node<real>* cone = ReadCone( stream, name );
			ReadNextExactToken( stream, ")" );
			ReadNextExactToken( stream, ";" );

			oScene.AddObject( cone, true );
		}
		else if ( token == "Cylinder" )
		{
			std::string name = ReadNextToken( stream );
			ReadNextExactToken( stream, "(" );
			Node<real>* cylinder = ReadCylinder( stream, name );
			ReadNextExactToken( stream, ")" );
			ReadNextExactToken( stream, ";" );

			oScene.AddObject( cylinder, true );
		}
		else if ( token == "Plane" )
		{
			std::string name = ReadNextToken( stream );
			ReadNextExactToken( stream, "(" );
			Node<real>* plane = ReadPlane( stream, name );
			ReadNextExactToken( stream, ")" );
			ReadNextExactToken( stream, ";" );

			oScene.AddObject( plane, true );
		}
		else if ( token == "Sphere" )
		{
			std::string name = ReadNextToken( stream );
			ReadNextExactToken( stream, "(" );
			Node<real>* sphere = ReadSphere( stream, name );
			ReadNextExactToken( stream, ")" );
			ReadNextExactToken( stream, ";" );

			oScene.AddObject( sphere, true );
		}
		else if ( token == "TriMesh" )
		{
			std::string name = ReadNextToken( stream );
			ReadNextExactToken( stream, "(" );
			Node<real>* triMesh = ReadTriMesh( stream, name );
			ReadNextExactToken( stream, ")" );
			ReadNextExactToken( stream, ";" );

			oScene.AddObject( triMesh, true );
		}
		else if ( token == "Node" )
		{
			std::string name = ReadNextToken( stream );
			ReadNextExactToken( stream, "(" );
			Node<real>* node = ReadNode( stream, name );
			ReadNextExactToken( stream, ")" );
			ReadNextExactToken( stream, ";" );

			oScene.AddObject( node, true );
		}
		else
		{
			throw ( std::string( "Unknown token: " ) + token ).c_str();
		}

		token = ReadNextToken( stream );
	}

	// Read scene ending token
	ReadNextExactToken( stream, ";" );
}
Beispiel #5
0
// Inicializacio, a program futasanak kezdeten, az OpenGL kontextus letrehozasa utan hivodik meg (ld. main() fv.)
void onInitialization() {
	glViewport(0, 0, screenWidth, screenHeight);

	Color ks = Color(0.4, 0.4, 0.4);
	Color kd = Color(255, 215, 0) / 255;
	Color k = Color(3.1, 2.7, 1.9);
	Color k_1 = Color(1.1, 1.7, 0.9);
	Color n = Color(0.17, 0.35, 1.5);
	Material *material = new Material(ks, Color(255, 200, 50) / 255, n, k,
			Color(), 50, false, false);
	Material *material_2 = new Material(ks, Color(205, 127, 50) / 255, n, k,
			Color(), 50, false, false);
	Material *material_3 = new Material(ks, Color(0, 178, 89) / 255, n, k,
			Color(), 50, true, false);

	Material *material_4 = new Material(ks, Color(0, 144, 244) / 255,
			Color(1.5, 1.5, 1.5), Color(), Color(), 50, false, true);
//	Sphere implementation----------------------------------------------
	Sphere *firstSphere = new Sphere(material_4);

//	Ellipsoid implementation-------------------------------------------
	Ellipsoid *firstEllipsoid = new Ellipsoid(material);
	myMatrix transfom1 = myMatrix(0.3, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 0.3, 0, 0,
			0, 0, 1);
	myMatrix transfom3 = myMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.2, 0,
			0.5, 1);
	myMatrix transfom2 = myMatrix(cos(M_PI / 6), sin(M_PI / 6), 0, 0,
			-sin(M_PI / 6), cos(M_PI / 6), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
	myMatrix transform4 = myMatrix(0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0.3, 0.2,
			1, 1);

	Vector normal = Vector(-0.529863, 0.253724, 0.80924, 1);
	Vector origo = Vector(-0.150579, 0.20029, 0.229974, 0);

	Hit hit = Hit();
	hit.normalVector = normal;
	hit.intersectPoint = origo;

	myMatrix tr1 = myMatrix(0.15, 0, 0, 0, 0, 0.25, 0, 0, 0, 0, 0.15, 0, 0, 0,
			0, 1);
	myMatrix tr3 = myMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0.25, 0, 1);
	myMatrix tr = getTheNewCoordSys(hit);

	Ellipsoid *secondEllipsoid = new Ellipsoid(material);
	myMatrix first_connection_matrix = tr1 * tr3 * tr;
	firstEllipsoid->setTrasformationMatrix(transfom1);
	secondEllipsoid->setTrasformationMatrix(first_connection_matrix);

	Vector normal_2 = normal * first_connection_matrix;
	Vector origo_2 = origo * first_connection_matrix;

	hit.normalVector = normal_2;
	hit.intersectPoint = origo_2;

	tr1 = myMatrix(0.15 , 0, 0, 0, 0, 0.25 , 0, 0, 0, 0,
			0.15 , 0, 0, 0, 0, 1);
	tr3 = myMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0.25 , 0,
			1);
	tr = getTheNewCoordSys(hit);
	Ellipsoid *thirdEllipsoid = new Ellipsoid(material);
	myMatrix second_connection_matrix = first_connection_matrix*tr;
	thirdEllipsoid->setTrasformationMatrix(second_connection_matrix);

//	Cylinder implementation---------------------------------------------
	Cylinder *firstCylinder = new Cylinder(material);
	transfom1 = myMatrix(0.2, 0, 0, 0, 0, 0.2, 0, 0, 0, 0, 0.2, 0, 0, 0, 0, 1);
	transfom3 = myMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.4, 0, -0.6, 1);
	transfom2 = myMatrix(cos(M_PI / 2), sin(M_PI / 2), 0, 0, -sin(M_PI / 2),
			cos(M_PI / 2), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
	firstCylinder->setTrasformationMatrix((transfom1 * transfom2) * transfom3);

//	Paraboloid implemenation--------------------------------------------
	Paraboloid *firstParaboloid = new Paraboloid(material_4);
	transfom1 = myMatrix(0.2, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 0.2, 0, 0, 0, 0, 1);
	transfom3 = myMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.4, 0, -0.6, 1);
	transfom2 = myMatrix(cos(M_PI / 2), sin(M_PI / 2), 0, 0, -sin(M_PI / 2),
			cos(M_PI / 2), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
	firstParaboloid->setTrasformationMatrix((transfom1) * transfom3);

//	Plane implementation------------------------------------------------
	Plane *firstPlane = new Plane(material_2);
	Plane2 *secondPlane = new Plane2(material_2);
	Scene scene = Scene();
	scene.AddObject((Intersectable*) firstPlane);
//	scene.AddObject((Intersectable*) firstCylinder);
//	scene.AddObject((Intersectable*) firstSphere);
	scene.AddObject((Intersectable*) firstEllipsoid);
	scene.AddObject((Intersectable*) secondEllipsoid);
//	scene.AddObject((Intersectable*) thirdEllipsoid);
//	scene.AddObject((Intersectable*) secondPlane);
//	scene.AddObject((Intersectable*) firstParaboloid);

	scene.SetAmbientColor(Color(77, 199, 253) / 255);

	PositionLightSource *light = new PositionLightSource(Vector(-1, 6, 7),
			Color(1, 1, 1));

	scene.AddLight((LightSource*) light);

	MyCamera camera = MyCamera(Vector(1, 2, 3), Vector(0, 0, 0),
			Vector(0, 1, 0));

	scene.SetCamera(camera);

	scene.render();

}
Beispiel #6
0
void project2() {
    // Create scene
    Scene scn;
    scn.SetSkyColor(Color(0.8f, 0.8f, 1.0f));
    
    // Create ground
    MeshObject ground;
    ground.MakeBox(5.0f,0.1f,5.0f);
    scn.AddObject(ground);
    
    // Create dragon
    MeshObject dragon;
    dragon.LoadPLY("dragon.ply");
    dragon.Smooth();
    
    std::chrono::time_point<std::chrono::system_clock> start, end;
    start = std::chrono::system_clock::now();
    
    std::cout <<  "Constructing the tree ..." << std::endl;
    
    BoxTreeObject tree;
    tree.Construct(dragon);
    scn.AddObject(tree);
    
    end = std::chrono::system_clock::now();
    std::chrono::duration<double> elapsed_seconds = end-start;
    
    std::cout << "Tree construcion done in " << elapsed_seconds.count() * 1000 << " milliseconds" <<  std::endl;

    
    // Create instance
    InstanceObject inst(tree);
    Matrix34 mtx;
    mtx.MakeRotateY(PI);
    mtx.d.Set(-0.05f,0.0f,-0.1f);
    inst.SetMatrix(mtx); scn.AddObject(inst);

    // Create lights
    DirectLight sunlgt;
    sunlgt.SetBaseColor(Color(1.0f, 1.0f, 0.9f));
    sunlgt.SetIntensity(1.0f);
    sunlgt.SetDirection(Vector3(2.0f, -3.0f, -2.0f));
    scn.AddLight(sunlgt);

    PointLight redlgt;
    redlgt.SetBaseColor(Color(1.0f, 0.2f, 0.2f));
    redlgt.SetIntensity(0.02f);
    redlgt.SetPosition(Vector3(-0.2f, 0.2f, 0.2f));
    scn.AddLight(redlgt);

    PointLight bluelgt;
    bluelgt.SetBaseColor(Color(0.2f, 0.2f, 1.0f));
    bluelgt.SetIntensity(0.02f);
    bluelgt.SetPosition(Vector3(0.1f, 0.1f, 0.3f));
    scn.AddLight(bluelgt);

    // Create camera
    Camera cam;
    cam.LookAt(Vector3(-0.1f,0.1f,0.2f),Vector3(-0.05f,0.12f,0.0f));
    cam.SetFOV(40.0f);
    cam.SetAspect(1.33f);
    cam.SetResolution(800,600);

    start = std::chrono::system_clock::now();
    std::cout <<  "Rendering the scene ..." << std::endl;
    
    // Render image
    cam.Render(scn);
    cam.SaveBitmap("project2.bmp");
    
    end = std::chrono::system_clock::now();
    elapsed_seconds = end-start;
    
    std::cout << "Scene rendering done in " << elapsed_seconds.count() * 1000 << " milliseconds" <<  std::endl;

}
Beispiel #7
0
void project3() {
    // Create scene
    Scene scn;
    scn.SetSkyColor(Color(0.8f, 0.9f, 1.0f));
    
    // Materials
    const int nummtls=4;
    AshikhminMaterial mtl[nummtls];
    
    // Diffuse
    mtl[0].SetSpecularLevel(0.0f);
    mtl[0].SetDiffuseLevel(1.0f);
    mtl[0].SetDiffuseColor(Color(0.7f,0.7f,0.7f));
    
    // Roughened copper
    mtl[1].SetDiffuseLevel(0.0f);
    mtl[1].SetSpecularLevel(1.0f);
    mtl[1].SetSpecularColor(Color(0.9f,0.6f,0.5f));
    mtl[1].SetRoughness(100.0f,100.0f);
    
    // Anisotropic gold
    mtl[2].SetDiffuseLevel(0.0f);
    mtl[2].SetSpecularLevel(1.0f);
    mtl[2].SetSpecularColor(Color(0.95f,0.7f,0.3f));
    mtl[2].SetRoughness(1.0f,1000.0f);
    
    // Red plastic
    mtl[3].SetDiffuseColor(Color(1.0f,0.1f,0.1f));
    mtl[3].SetDiffuseLevel(0.8f);
    mtl[3].SetSpecularLevel(0.2f);
    mtl[3].SetSpecularColor(Color(1.0f,1.0f,1.0f));
    mtl[3].SetRoughness(1000.0f,1000.0f);
    
    // Load dragon mesh
    MeshObject dragon;
    dragon.LoadPLY("dragon.ply");
    
    // Create box tree
    BoxTreeObject tree;
    tree.Construct(dragon);
    
    // Create ground
    LambertMaterial lambert;
    lambert.SetDiffuseColor(Color(0.3f,0.3f,0.35f));
    MeshObject ground;
    ground.MakeBox(2.0f,0.11f,2.0f,&lambert);
    scn.AddObject(ground);

    
    // Create dragon instances
    Matrix34 mtx;
    for(int i=0;i<nummtls;i++) {
        InstanceObject *inst=new InstanceObject(tree);
        mtx.d.Set(0.0f,0.0f,-0.1f*float(i));
        inst->SetMatrix(mtx);
        inst->SetMaterial(&mtl[i]);
        scn.AddObject(*inst);
    }
    
    // Create lights
    DirectLight sunlgt;
    sunlgt.SetBaseColor(Color(1.0f, 1.0f, 0.9f));
    sunlgt.SetIntensity(1.0f);
    sunlgt.SetDirection(Vector3(2.0f, -3.0f, -2.0f));
    scn.AddLight(sunlgt);
    
    // Create camera
    Camera cam;
    cam.LookAt(Vector3(-0.5f,0.25f,-0.2f),Vector3(0.0f,0.15f,-0.15f));
    cam.SetFOV(40.0f); 
    cam.SetAspect(1.33f); 
    cam.SetResolution(800,600); 
    cam.SetSuperSample(100);
    
    // Render image 
    cam.Render(scn); 
    cam.SaveBitmap("project3.bmp"); 
}