Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h	(revision 3246)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h	(revision 3247)
@@ -6,7 +6,7 @@
 //-- ssao + gi parameters
 
-//#define NUM_SAMPLES 8
+#define NUM_SAMPLES 8
 //#define NUM_SAMPLES 16
-#define NUM_SAMPLES 24
+//#define NUM_SAMPLES 24
 //#define NUM_SAMPLES 48
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/combineSsao.cg
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/combineSsao.cg	(revision 3246)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/combineSsao.cg	(revision 3247)
@@ -162,5 +162,5 @@
 
 		// the filtered ssao value
-		ao.x = DiscontinuityFilter(IN.texCoord, ao, col, ssaoTex, normalsTex, colorsTex, filterOffs, scale, bl, br, tl, tr);
+		//ao.x = DiscontinuityFilter(IN.texCoord, ao, col, ssaoTex, normalsTex, colorsTex, filterOffs, scale, bl, br, tl, tr);
 	}
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ssao.cg
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ssao.cg	(revision 3231)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ssao.cg	(revision 3247)
@@ -22,5 +22,6 @@
 };
 
-
+// this function is inspired from the paper of shamulgaan in order
+// to get a physical expression for the occlusion culling
 inline float occlusionPower(float radius, float dist)
 {
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SampleGenerator.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SampleGenerator.cpp	(revision 3235)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SampleGenerator.cpp	(revision 3247)
@@ -172,5 +172,6 @@
 
 QuadraticDiscSampleGenerator2D::QuadraticDiscSampleGenerator2D(int numSamples, float radius):
-PoissonDiscSampleGenerator2D(numSamples, radius)
+//PoissonDiscSampleGenerator2D(numSamples, radius)
+RandomSampleGenerator2D(numSamples, radius)
 {}
 
@@ -193,5 +194,6 @@
 #else
 
-	PoissonDiscSampleGenerator2D::Generate(samples);
+	//PoissonDiscSampleGenerator2D::Generate(samples);
+	RandomSampleGenerator2D::Generate(samples);
 
 	Sample2 *s = (Sample2 *)samples;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SampleGenerator.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SampleGenerator.h	(revision 3230)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SampleGenerator.h	(revision 3247)
@@ -78,5 +78,6 @@
 	with the distance
 */
-class QuadraticDiscSampleGenerator2D: public PoissonDiscSampleGenerator2D
+//class QuadraticDiscSampleGenerator2D: public PoissonDiscSampleGenerator2D
+class QuadraticDiscSampleGenerator2D: public RandomSampleGenerator2D
 {
 public:
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3246)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3247)
@@ -142,4 +142,6 @@
 ViewCell *viewCell = NULL;
 
+bool useSkylightForIllum = true;
+
 static int globalVisibleId = 0;
 
@@ -456,4 +458,6 @@
 		env.GetBoolParam(string("usePvs"), usePvs);
 
+		env.GetBoolParam(string("useSkylightForIllum"), useSkylightForIllum);
+
 		//env.GetStringParam(string("modelPath"), model_path);
 		//env.GetIntParam(string("numSssaoSamples"), numSsaoSamples);
@@ -488,5 +492,5 @@
 		cout << "use PVS: " << usePvs << endl;
 		cout << "visibilitySolution: " << visibilitySolution << endl;
-		
+		cout << "useSkylightForIllum" << useSkylightForIllum << endl;
 
 		//cout << "model path: " << model_path << endl;
@@ -571,5 +575,4 @@
 
 	//LoadModel("fisch.dem", dynamicObjects);
-	//LoadModel("hbuddha.dem", dynamicObjects);
 
 	//LoadModel("venusm.dem", dynamicObjects);
@@ -577,36 +580,41 @@
 	//LoadModel("toyplane2.dem", dynamicObjects);
 	//LoadModel("elephal.dem", dynamicObjects);
-
+	LoadModel("sibenik.dem", dynamicObjects);
+
+#if 1
+	LoadModel("hbuddha.dem", dynamicObjects);
+
+	buddha = dynamicObjects.back();
+	
+	const Vector3 sceneCenter(470.398f, 240.364f, 181.7f);
+	//const Vector3 sceneCenter(470.398f, 240.364f, 180.3);
+	
+	Matrix4x4 transl = TranslationMatrix(sceneCenter);
+	buddha->GetTransform()->SetMatrix(transl);
+
+	for (int i = 0; i < 10; ++ i)
+	{
+		SceneEntity *ent = new SceneEntity(*buddha);
+		resourceManager->AddSceneEntity(ent);
+
+		Vector3 offs = Vector3::ZERO();
+
+		offs.x = RandomValue(.0f, 50.0f);
+		offs.y = RandomValue(.0f, 50.0f);
+
+		Vector3 newPos = sceneCenter + offs;
+
+		transl = TranslationMatrix(newPos);
+		Transform3 *transform = resourceManager->CreateTransform(transl);
+
+		ent->SetTransform(transform);
+		dynamicObjects.push_back(ent);
+	}
+#endif
+
+	
 	resourceManager->mUseNormalMapping = false;
 	resourceManager->mUseSpecialColors = false;
 
-	/*
-	buddha = dynamicObjects.back();
-	
-	const Vector3 sceneCenter(470.398f, 240.364f, 181.7f);
-	//const Vector3 sceneCenter(470.398f, 240.364f, 180.3);
-	
-	Matrix4x4 transl = TranslationMatrix(sceneCenter);
-	buddha->GetTransform()->SetMatrix(transl);
-
-	for (int i = 0; i < 10; ++ i)
-	{
-		SceneEntity *ent = new SceneEntity(*buddha);
-		resourceManager->AddSceneEntity(ent);
-
-		Vector3 offs = Vector3::ZERO();
-
-		offs.x = RandomValue(.0f, 50.0f);
-		offs.y = RandomValue(.0f, 50.0f);
-
-		Vector3 newPos = sceneCenter + offs;
-
-		transl = TranslationMatrix(newPos);
-		Transform3 *transform = resourceManager->CreateTransform(transl);
-
-		ent->SetTransform(transform);
-		dynamicObjects.push_back(ent);
-	}
-	*/
 
 /*	int cityEntities = LoadModel("vienna_full_hp.dem", dynamicObjects);
@@ -942,26 +950,27 @@
 	Vector3 sunDiffuse;
 
-#if 1
-	preetham->ComputeSunColor(lightDir, sunAmbient, sunDiffuse, !useHDRValues);
-
-	ambient[0] = sunAmbient.x;
-	ambient[1] = sunAmbient.y;
-	ambient[2] = sunAmbient.z;
-
-	diffuse[0] = sunDiffuse.x;
-	diffuse[1] = sunDiffuse.y;
-	diffuse[2] = sunDiffuse.z;
-
-#else
-	
-	ambient[0] = .2f;
-	ambient[1] = .2f;
-	ambient[2] = .2f;
-
-	diffuse[0] = 1.0f;
-	diffuse[1] = 1.0f;
-	diffuse[2] = 1.0f;
-
-#endif
+	if (useSkylightForIllum)
+	{
+		preetham->ComputeSunColor(lightDir, sunAmbient, sunDiffuse, !useHDRValues);
+
+		ambient[0] = sunAmbient.x;
+		ambient[1] = sunAmbient.y;
+		ambient[2] = sunAmbient.z;
+
+		diffuse[0] = sunDiffuse.x;
+		diffuse[1] = sunDiffuse.y;
+		diffuse[2] = sunDiffuse.z;
+	}
+	else
+	{
+
+		ambient[0] = .2f;
+		ambient[1] = .2f;
+		ambient[2] = .2f;
+
+		diffuse[0] = 1.0f;
+		diffuse[1] = 1.0f;
+		diffuse[2] = 1.0f;
+	}
 
 	glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
@@ -1088,5 +1097,5 @@
 #endif
 
-
+/*
 		/////////////////////////
 		//-- update animations
@@ -1096,7 +1105,8 @@
 
 		Matrix4x4 rotMatrix = RotationZMatrix(rotAngle);
-		dynamicObjects[1]->GetTransform()->MultMatrix(rotMatrix);
+		dynamicObjects[2]->GetTransform()->MultMatrix(rotMatrix);
 
 		motionPath->Move(0.01f);
+		*/
 	}
 
@@ -1189,5 +1199,6 @@
 	{
 		if (!viewCellsTree) LoadVisibilitySolution();
-		LoadPvs();	
+
+		LoadPvs();
 	}
 
@@ -1309,7 +1320,14 @@
 		FrameBufferObject::Release();
 
-		if (!deferredShader) deferredShader = 
-			new DeferredRenderer(texWidth, texHeight, camera, ssaoUseFullResolution);
-		
+		if (!deferredShader) 
+		{
+			deferredShader = 
+				new DeferredRenderer(texWidth, texHeight, camera, ssaoUseFullResolution);
+
+			deferredShader->SetKernelRadius(ssaoKernelRadius);
+			deferredShader->SetSampleIntensity(ssaoSampleIntensity);
+			deferredShader->SetSsaoFilterRadius(ssaoFilterRadius);
+		}
+
 		DeferredRenderer::SHADING_METHOD shadingMethod;
 
@@ -1331,7 +1349,5 @@
 		deferredShader->SetShadingMethod(shadingMethod);
 		deferredShader->SetSamplingMethod(samplingMethod);
-		deferredShader->SetKernelRadius(ssaoKernelRadius);
-		deferredShader->SetSampleIntensity(ssaoSampleIntensity);
-		deferredShader->SetSsaoFilterRadius(ssaoFilterRadius);
+		
 		deferredShader->SetUseTemporalCoherence(useTemporalCoherence);
 		//deferredShader->SetSortSamples(sortSamples);
@@ -1475,23 +1491,29 @@
 		ssaoKernelRadius *= 0.8f;
 		cout << "new ssao kernel radius: " << ssaoKernelRadius << endl;
+		if (deferredShader) deferredShader->SetKernelRadius(ssaoKernelRadius);
 		break;
 	case '0':
 		ssaoKernelRadius *= 1.0f / 0.8f;
+		if (deferredShader) deferredShader->SetKernelRadius(ssaoKernelRadius);
 		cout << "new ssao kernel radius: " << ssaoKernelRadius << endl;
 		break;
 	case 'n':
 		ssaoSampleIntensity *= 0.9f;
+		if (deferredShader) deferredShader->SetSampleIntensity(ssaoSampleIntensity);
 		cout << "new ssao sample intensity: " << ssaoSampleIntensity << endl;
 		break;
 	case 'N':
 		ssaoSampleIntensity *= 1.0f / 0.9f;
+		if (deferredShader) deferredShader->SetSampleIntensity(ssaoSampleIntensity);
 		cout << "new ssao sample intensity: " << ssaoSampleIntensity << endl;
 		break;
 	case 'o':
 		ssaoFilterRadius *= 0.9f;
+		if (deferredShader) deferredShader->SetSsaoFilterRadius(ssaoFilterRadius);
 		cout << "new ssao filter radius: " << ssaoFilterRadius << endl;
 		break;
 	case 'O':
 		ssaoFilterRadius *= 1.0f / 0.9f;
+		if (deferredShader) deferredShader->SetSsaoFilterRadius(ssaoFilterRadius);
 		cout << "new ssao filter radius: " << ssaoFilterRadius << endl;
 		break;
@@ -2587,4 +2609,11 @@
 
 	viewCellsTree = visLoader.Load(vis_filename, bvh);
+
+	if (!viewCellsTree)
+	{
+		cerr << "loading pvs failed" << endl;
+		CleanUp();
+		exit(0);
+	}
 }
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 3246)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 3247)
@@ -1426,4 +1426,5 @@
 {
 	mSampleIntensity = sampleIntensity;
+	mRegenerateSamples = true;
 }
 
@@ -1432,4 +1433,5 @@
 {
 	mKernelRadius = kernelRadius;
+	mRegenerateSamples = true;
 }
 
@@ -1438,4 +1440,5 @@
 {
 	mSsaoFilterRadius = ssaoFilterRadius;
+	mRegenerateSamples = true;
 }
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter.cpp	(revision 3246)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter.cpp	(revision 3247)
@@ -154,5 +154,6 @@
 void ObjConverter::LoadShape(const VertexArray &faceVertices,
 							 const VertexArray &faceNormals,
-							 const vector<Texcoord> &faceTexcoords)
+							 const vector<Texcoord> &faceTexcoords,
+							 Material *mat)
 {
 	int numElements = (int)faceVertices.size();
@@ -167,5 +168,7 @@
 	geom->mTexcoordCount = (int)faceTexcoords.size();
 
-	cout << "number of vertices=" << numElements << endl;
+	geom->mMaterial = mat;
+
+	cout << "new geometry #vts=" << numElements << endl;
 
 	for (int i = 0; i < numElements; ++ i)
@@ -244,4 +247,5 @@
 	}
 	
+	Material *currentMat = NULL;
 	VertexArray faceVertices; 
 	VertexArray faceNormals;
@@ -279,5 +283,5 @@
 					sscanf(str + 1, "%f %f %f", &x, &y, &z);
 					//const float scale = 5e-3f;
-					const float scale = 1.0f;
+					const float scale = 5.0f;
 					vertices.push_back(SimpleVec(x * scale, y * scale, z* scale));
 					//cout <<"v " << x << " " << y << " "<< z << " ";
@@ -294,31 +298,32 @@
 					        faceVertices, faceNormals, faceTexcoords);
 
-				if (0 &&
-					(((line % 1000) == 999) && !faceVertices.empty()))
+				break;
+			}   // end face
+		case 'g': // load a new shape
+			{
+				if (!faceVertices.empty())
 				{
 					++ mNumShapes;
 
-					LoadShape(faceVertices, faceNormals, faceTexcoords);
+					LoadShape(faceVertices, faceNormals, faceTexcoords, currentMat);
 
 					faceVertices.clear();
 					faceNormals.clear();
 					faceTexcoords.clear();
+
+					currentMat = NULL;
 				}
-
-				break;
-			}   // end face
-		case 'g': // load a new shape
-			{/*
-				if (!faceVertices.empty())
-				{
-					++ mNumShapes;
-
-					LoadShape(faceVertices, faceNormals, faceTexcoords);
-
-					faceVertices.clear();
-					faceNormals.clear();
-					faceTexcoords.clear();
-				}*/
-			}
+			}
+			break;
+		case 'u': // usemtl => material
+			{
+				string matName(str + 7);
+				// throw away linebreak character
+				matName.resize(matName.size() - 1);
+
+				currentMat = mMaterialTable[matName];
+				cout << "matname: " << matName << endl;
+			}
+
 			break;
 		default:
@@ -334,5 +339,5 @@
 		++ mNumShapes;
 
-		LoadShape(faceVertices, faceNormals, faceTexcoords);
+		LoadShape(faceVertices, faceNormals, faceTexcoords, currentMat);
 
 		faceVertices.clear();
@@ -364,5 +369,5 @@
 	///////
 	//-- texture
-
+/*
 #ifdef USE_TEXTURE
 	int texId = 0;
@@ -401,7 +406,8 @@
 		str.write(reinterpret_cast<char *>(&emm), sizeof(SimpleVec));
 	}
-}
-
-
+*/
+}
+
+#if 0
 bool ObjConverter::WriteFile(const string &filename)
 {
@@ -481,2 +487,190 @@
 	return true;
 }
+#else
+bool ObjConverter::WriteFile(const string &filename)
+{
+	ogzstream ofile(filename.c_str());
+
+	if (!ofile.is_open())
+		return false;
+	
+
+	/////////
+	//-- write textures
+
+	int textureCount = (int)mTextures.size();
+
+	ofile.write(reinterpret_cast<char *>(&textureCount), sizeof(int));
+
+	TextureArray::const_iterator tit, tit_end = mTextures.end();
+	
+	for (tit = mTextures.begin(); tit != tit_end; ++ tit)
+	{
+		const string texName = (*tit);
+
+		int texnameSize = (int)texName.length() + 1;
+		ofile.write(reinterpret_cast<char *>(&texnameSize), sizeof(int));
+
+		ofile.write(texName.c_str(), sizeof(char) * texnameSize);
+
+		int boundS = 1, boundT = 1;
+
+		ofile.write(reinterpret_cast<char *>(&boundS), sizeof(int));
+		ofile.write(reinterpret_cast<char *>(&boundT), sizeof(int));
+	}
+
+
+	///////////
+	//-- write shapes
+
+	ofile.write(reinterpret_cast<char *>(&mNumShapes), sizeof(int));
+
+	vector<Geometry *>::const_iterator it, it_end = mGeometry.end();
+
+	for (it = mGeometry.begin(); it != it_end; ++ it)
+	{
+		WriteGeometry(ofile, *it);
+
+		
+		/////////
+		//-- material
+
+		Material *mat = (*it)->mMaterial;
+
+		ofile.write(reinterpret_cast<char *>(&mat->texture), sizeof(int));
+
+		bool alphaTestEnabled = false;
+		//bool cullFaceEnabled = false;
+		bool cullFaceEnabled = true;
+		
+		ofile.write(reinterpret_cast<char *>(&alphaTestEnabled), sizeof(bool));
+		ofile.write(reinterpret_cast<char *>(&cullFaceEnabled), sizeof(bool));
+
+		// material
+		bool hasMaterial = true;
+		ofile.write(reinterpret_cast<char *>(&hasMaterial), sizeof(bool));
+	
+		SimpleVec ambient, diffuse, spec, emm;
+
+		ambient.x = ambient.y = ambient.z = 0.2f;
+		//diffuse.x = diffuse.y = diffuse.z = 1.0f;
+		diffuse.x = mat->rgb[0]; diffuse.y =mat->rgb[1]; diffuse.z = mat->rgb[2];
+		spec.x = spec.y = spec.z = .0f;
+		emm = spec;
+
+		// only write rgb part of the material
+		ofile.write(reinterpret_cast<char *>(&ambient), sizeof(SimpleVec));
+		ofile.write(reinterpret_cast<char *>(&diffuse), sizeof(SimpleVec));
+		ofile.write(reinterpret_cast<char *>(&spec), sizeof(SimpleVec));
+		ofile.write(reinterpret_cast<char *>(&emm), sizeof(SimpleVec));
+	}
+
+
+	int entityCount = 1;
+	ofile.write(reinterpret_cast<char *>(&entityCount), sizeof(int));
+
+
+	//////////
+	//-- write single scene entity
+
+	// no transformation
+	bool hasTrafo = false;
+	ofile.write(reinterpret_cast<char *>(&hasTrafo), sizeof(bool));
+
+	// a dummy lod
+	int numLODs = 1;
+	ofile.write(reinterpret_cast<char *>(&numLODs), sizeof(int));
+
+	float dist = 0;
+	ofile.write(reinterpret_cast<char *>(&dist), sizeof(float));
+
+	ofile.write(reinterpret_cast<char *>(&mNumShapes), sizeof(int));
+
+	// all shapes belong to this scene entity
+	for (int i = 0; i < mNumShapes; ++ i)
+	{
+		int shapeId = i;
+		ofile.write(reinterpret_cast<char *>(&shapeId), sizeof(int));
+	}
+
+	return true;
+}
+#endif
+
+
+bool ObjConverter::LoadMaterials(const std::string &matFileName)
+{
+	FILE *file;
+
+	if ((file = fopen(matFileName.c_str(), "r")) == NULL)
+	{	
+		return false;
+	}
+	
+	int line = 0;
+	const int len = 10000;
+	char str[len];
+
+	Material *currentMat = NULL;
+
+
+	while (fgets(str, len, file) != NULL)
+	{
+		//sscanf(str + 1, "%f %f %f", &x, &y, &z);
+		vector<string> strings;
+
+		char *next_token;
+
+		// extract the triples of the form v/t/n v/t/n ...
+		char *pch = strtok_s(str, " \n", &next_token);
+
+		while (pch)
+		{
+			string s(pch);
+			//s += "\n",
+			strings.push_back(s);
+
+			pch = strtok_s(NULL, " \n", &next_token);	 
+		}
+
+		cout << endl;
+
+		
+		if ((strings.size() == 2) && (strcmp(strings[0].c_str(),"newmtl") == 0))
+		{
+			currentMat = new Material();
+			mMaterialTable[strings[1].c_str()] = currentMat;
+		}
+
+		if ((strings.size() == 2) && (strcmp(strings[0].c_str(),"map_Kd") == 0))
+		{
+			TextureTable::const_iterator it = mTextureTable.find(strings[1]);
+
+			int id;
+
+			if (it == mTextureTable.end()) // parameter not found
+			{
+				mTextures.push_back(strings[1]);
+				id = (int)mTextures.size();
+				mTextureTable[strings[1]] = id;
+			}
+			else
+			{
+				id = (*it).second;
+			}
+
+			currentMat->texture = id;
+		}
+
+		if ((strings.size() == 4) && (strcmp(strings[0].c_str(),"Kd") == 0))
+		{
+			currentMat->rgb[0] = (float)atof(strings[1].c_str());
+			currentMat->rgb[1] = (float)atof(strings[2].c_str());
+			currentMat->rgb[2] = (float)atof(strings[3].c_str());
+		}
+
+		++ line;
+	}
+
+	return true;
+}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/main.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/main.cpp	(revision 3146)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/main.cpp	(revision 3247)
@@ -14,4 +14,12 @@
 
 	cout << "converting obj to dem format" << endl;
+	
+	if (!converter.LoadMaterials(model_path + argv[3]))
+	{
+		cerr << "loading materials failed" << endl;
+
+		std::cin.get();
+		exit(0);
+	}
 
 	if (!converter.Convert(model_path + argv[1], model_path + argv[2]))
@@ -22,6 +30,7 @@
 		exit(0);
 	}
-	//std::cin.get();
+
 	cout << "conversion successful" << endl;
+	cout << "press any key" << std::cin.get();
 
 	return 0;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter.h	(revision 3012)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter.h	(revision 3247)
@@ -5,15 +5,21 @@
 #include <string>
 #include <vector>
+#include <map>
 
-/*struct SimpleVec
+
+struct Material
 {
-	SimpleVec() {}
-	SimpleVec(float _x, float _y, float _z): x(_x), y(_y), z(_z) {}
+	float rgb[3];
+	int texture;
+};
 
-	float x, y, z;
-};*/
+class Geometry;
 
 typedef std::vector<SimpleVec> VertexArray;
 typedef std::pair<float, float> Texcoord;
+typedef std::map<std::string, Material *> MaterialTable;
+typedef std::map<std::string, int> TextureTable;
+
+typedef std::vector<std::string> TextureArray;
 
 class ogzstream;
@@ -29,5 +35,7 @@
 	bool Convert(const std::string &inputFilename, 
 		         const std::string &outputFilename);
-	// const std::string textureFilename) const;
+	             // const std::string textureFilename) const;
+
+	bool LoadMaterials(const std::string &matFileName);
 
 	~ObjConverter();
@@ -40,4 +48,5 @@
 		SimpleVec *mNormals;
 		Texcoord *mTexcoords;
+		Material *mMaterial;
 
 		int mVertexCount;
@@ -45,7 +54,10 @@
 	};
 
+typedef std::vector<Geometry *> GeometryArray;
+
 	void LoadShape(const VertexArray &faceVertices,
 		           const VertexArray &faceNormals,
-				   const std::vector<Texcoord> &faceTexcoords);
+				   const std::vector<Texcoord> &faceTexcoords, 
+				   Material *mat);
 
 	void WriteGeometry(ogzstream &str, Geometry *geom);
@@ -55,5 +67,9 @@
 
 
-	std::vector<Geometry *> mGeometry;
+	MaterialTable mMaterialTable;
+	TextureTable mTextureTable;
+	
+	TextureArray mTextures;
+	GeometryArray mGeometry;
 
 	int mNumShapes;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env	(revision 3246)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env	(revision 3247)
@@ -8,4 +8,5 @@
 
 #filename=vienna_full_hp
+filename=city
 useLODs=1
 # shadow map size
@@ -23,4 +24,5 @@
 visibilitySolution=vienna_full-8x3-pgv
 
+useSkylightForIllum=0
 
 
@@ -42,5 +44,5 @@
 #keyForwardMotion=5.0f
 #keyRotation=0.5f
-#keyForwardMotion=20.0f
+keyForwardMotion=20.0f
 keyRotation=1.5f
 
@@ -59,11 +61,11 @@
 ## powerplant options
 
-filename=PowerPlantM
+#filename=PowerPlantM
 
-keyForwardMotion=200.0f
-mouseMotion=1.0f;
-visibilitySolution=power-plant-2c-xx-1000b-pgv2
-camPosition=-1320.57 -6306.34 3603
-camDirection=0.292156 0.9556 0.0383878
+#keyForwardMotion=200.0f
+#mouseMotion=1.0f;
+#visibilitySolution=power-plant-2c-xx-1000b-pgv2
+#camPosition=-1320.57 -6306.34 3603
+#camDirection=0.292156 0.9556 0.0383878
 
 
@@ -109,5 +111,5 @@
 
 # use full resolution ssao (vs. half resoltion)
-ssaoUseFullResolution=0
+ssaoUseFullResolution=1
 # ssao kernel radius
 #ssaoKernelRadius=8e-1f
