diff --git a/QtMeshViewer/Header/FileInterface.h b/QtMeshViewer/Header/FileInterface.h
index 0d254cae0ee65960d3d722e8520f8afe2fc31e2a..ba7c12f2145f9c56d1201408c488cb1730155436 100644
--- a/QtMeshViewer/Header/FileInterface.h
+++ b/QtMeshViewer/Header/FileInterface.h
@@ -42,12 +42,14 @@ struct Model {
 
 struct Material {
 	QString name;
+	QString textureName;
 	QOpenGLTexture* texture = Q_NULLPTR;
+	QVector4D specularColor = { 1.0, 1.0, 1.0, 1.0 };
+	QVector4D diffuseColor = { 1.0, 0.0, 0.0, 1.0 };
+	QVector4D ambientColor = { 1.0, 1.0, 1.0, 1.0 };
+	float shininess = 80;
+	bool flags[8] = { false };
 	bool transparent = false;
-	float shininess = 80;						//TODO: read from file
-	QVector4D specularColor = {1.0,1.0,1.0, 1.0};	//TODO: read from file, change to 4D
-	QVector4D diffuseColor;
-	QVector4D ambientColor;
 };
 
 class FileInterface : public QObject
@@ -110,8 +112,8 @@ public:
 	virtual QVector<Material>* getMaterials() const { return m_materials; };
 	virtual BoundingBox getBoundingBox() const { return m_sceneBbox; };
 
-	static Material getDefaultMaterial() {
-		Material defMaterial;
+	static Material* getDefaultMaterial() {
+		Material* defMaterial = new Material;
 
 		QImage img(1, 1, QImage::Format_RGB32);
 		img.fill(Qt::red);
@@ -128,7 +130,8 @@ public:
 		// f.ex. texture coordinate (1.1, 1.2) is same as (0.1, 0.2)
 		new_texture->setWrapMode(QOpenGLTexture::Repeat);
 
-		defMaterial.texture = new_texture;
+		defMaterial->texture = new_texture;
+		defMaterial->name = "Default Material";
 
 		return defMaterial;
 	};
diff --git a/QtMeshViewer/Header/GeometryEngine.h b/QtMeshViewer/Header/GeometryEngine.h
index 3a44ac3221985952c72b7c4aa85eab78ce928f81..9cd09b29d3449fad3a5980665336845e8b3dc6a3 100644
--- a/QtMeshViewer/Header/GeometryEngine.h
+++ b/QtMeshViewer/Header/GeometryEngine.h
@@ -28,6 +28,7 @@ private:
 	QVector<Material>* m_materials = Q_NULLPTR;
 	QVector<DrawInformation> m_drawList;
 	BoundingBox m_boundings;
+	Material* m_defaultMaterial;
 
 	void clearData();
 
diff --git a/QtMeshViewer/Resources/fshader.glsl b/QtMeshViewer/Resources/fshader.glsl
index 202dc0cd946452ab38a6fb7bc878c4cdd97f2ba9..c3abb8470f2efbb0da896a30f07e1f3218d60f23 100644
--- a/QtMeshViewer/Resources/fshader.glsl
+++ b/QtMeshViewer/Resources/fshader.glsl
@@ -61,7 +61,6 @@ void main()
 		// final color after gama correction
 		vec3 gamma = vec3(1.0/2.2);
 		gl_FragColor = vec4(pow(linearColor, gamma), surfaceColor.a);
-		//gl_FragColor = vec4(linearColor, surfaceColor.a);
 	}
 	else
 	{
diff --git a/QtMeshViewer/Source/GeometryEngine.cpp b/QtMeshViewer/Source/GeometryEngine.cpp
index fd79dadb921968abce884448dd0861a9fdf27b43..75835db5a8923b225c911e80b871e5ed47615169 100644
--- a/QtMeshViewer/Source/GeometryEngine.cpp
+++ b/QtMeshViewer/Source/GeometryEngine.cpp
@@ -14,11 +14,15 @@ GeometryEngine::GeometryEngine(QObject *parent)
 	, m_indexBuf(QOpenGLBuffer::IndexBuffer)
 {
 	initializeOpenGLFunctions();
+
+	m_defaultMaterial = FileInterface::getDefaultMaterial();
 }
 
 GeometryEngine::~GeometryEngine()
 {
 	clearData();
+	delete m_defaultMaterial->texture;
+	delete m_defaultMaterial;
 }
 
 
@@ -113,9 +117,6 @@ void GeometryEngine::loadFile(QString filePath)
 		m_indexBuf.bind();
 		m_indexBuf.allocate(indexData.data(), indexData.size() * sizeof(GLuint));
 
-		//pushback a default material
-		m_materials->push_back(FileInterface::getDefaultMaterial());
-
 		emit requestUpdate();
 		emit sendMessage("done..", 0);
 		emit sendFileInfo(filePath.right(filePath.size() - filePath.lastIndexOf(QRegExp("/|\\\\")) - 1), m_materials, vertexData.size(), indexData.size() / 3);
@@ -185,12 +186,12 @@ void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program, bool wireframe)
 			m_materials->at(it.textureIndex).texture->bind();
 			tmp_transparent = m_materials->at(it.textureIndex).transparent;
 			shininess = m_materials->at(it.textureIndex).shininess;
-			specularColor = m_materials->at(it.textureIndex).specularColor;
+			specularColor = m_materials->at(it.textureIndex).specularColor.toVector3D();
 		}
 		else
 		{
-			m_materials->last().texture->bind();
-			tmp_transparent = m_materials->last().transparent;
+			m_defaultMaterial->texture->bind();
+			tmp_transparent = m_defaultMaterial->transparent;
 		}
 		// Set model matrix
 		program->setUniformValue("m_matrix", it.modelMatrix);
diff --git a/QtMeshViewer/Source/MshFile.cpp b/QtMeshViewer/Source/MshFile.cpp
index 906e08374d207d41315ab00402e004496865afbf..b654c5c1f6349a94adc5fe393106b2cc5f8de442 100644
--- a/QtMeshViewer/Source/MshFile.cpp
+++ b/QtMeshViewer/Source/MshFile.cpp
@@ -1,5 +1,6 @@
 #include "..\Header\MshFile.h"
 #include "..\Header\tga.h"
+#include <QColor>
 
 // helper function to save data from file to any variable type
 #define F2V(variableName) reinterpret_cast<char*>(&variableName)
@@ -160,7 +161,6 @@ void MshFile::analyseMsh2Chunks(std::list<ChunkHeader*>& chunkList)
 					std::list<ChunkHeader*> tmp_matdChunks;
 					loadChunks(tmp_matdChunks, it->position, it->size);
 
-					//TODO: materialy without texture have null pointer need to fix that
 					m_materials->push_back(Material());
 
 					// analyse MATD subchunks
@@ -217,27 +217,41 @@ void MshFile::analyseMatdChunks(std::list<ChunkHeader*>& chunkList)
 {
 	for (auto& it : chunkList)
 	{
-	    // name
-        if (!strcmp("NAME", it->name))
-        {
+		// name
+		if (!strcmp("NAME", it->name))
+		{
 			m_file.seekg(it->position);
 			char* buffer = new char[it->size + 1];
 			*buffer = { 0 };
 			m_file.read(buffer, it->size);
 			m_materials->back().name = buffer;
 			delete[] buffer;
-        }
-        // TODO: read the data information
-        // data
-        else if(!strcmp("DATA", it->name))
-        {
-            
-            
-        }
-		// TODO: use diffuse color instead of default texture
-		//TODO: get information from flags
+		}
+
+		// data
+		else if(!strcmp("DATA", it->name))
+		{
+			m_file.seekg(it->position);
+
+			// diffuse
+			for (unsigned int i = 0; i < 4; i++)
+				m_file.read(F2V(m_materials->back().diffuseColor[i]), sizeof(float));
+
+			// specular
+			for (unsigned int i = 0; i < 4; i++)
+				m_file.read(F2V(m_materials->back().specularColor[i]), sizeof(float));
+
+			// ambient
+			for (unsigned int i = 0; i < 4; i++)
+				m_file.read(F2V(m_materials->back().ambientColor[i]), sizeof(float));
+
+			// shininess
+			m_file.read(F2V(m_materials->back().shininess), sizeof(float));
+		}
+
+		// TODO: evaluate specular, gloss,.. and save values
 		// attributes
-		if (!strcmp("ATRB", it->name))
+		else if (!strcmp("ATRB", it->name))
 		{
 			// read the attributes
 			m_file.seekg(it->position);
@@ -247,31 +261,21 @@ void MshFile::analyseMatdChunks(std::list<ChunkHeader*>& chunkList)
 			m_file.read(F2V(data[0]), sizeof(data[0]));
 			m_file.read(F2V(data[1]), sizeof(data[1]));
 
-			// specular
-			if (flag >> 7)
-			{
-				std::cout << "specular" << std::endl;
-			}
-			// additive transparency || hard edged transparency || double-sided transparency || single-sided transparency
-			if ((flag << 1) >> 7 || (flag << 3) >> 7 || (flag << 4) >> 7 || (flag << 5) >> 7)
-			{
-				m_materials->back().transparent = true;
-			}
-			// per-pixel lighting
-			if ((flag << 2) >> 7)
-			{
-				std::cout << "per-pixel lighting" << std::endl;
-			}
-			// glow
-			if ((flag << 6) >> 7)
-			{
-				std::cout << "glow" << std::endl;
-			}
-			// emissive
-			if ((flag << 7) >> 7)
-			{
-				std::cout << "emissive" << std::endl;
-			}
+			// flags
+			// 0: emissive
+			// 1: glow
+			// 2: single-sided transparency
+			// 3: double-sided transparency
+			// 4: hard-edged transparency
+			// 5: per-pixel lighting
+			// 6: additive transparency
+			// 7: specular
+
+			for (unsigned int i = 0; i < 8; i++)
+				m_materials->back().flags[i] = (flag << (7 - i)) >> 7;
+
+			m_materials->back().transparent = m_materials->back().flags[2] || m_materials->back().flags[3] || m_materials->back().flags[4] || m_materials->back().flags[6];
+
 		}
 
 		// texture zero
@@ -282,13 +286,12 @@ void MshFile::analyseMatdChunks(std::list<ChunkHeader*>& chunkList)
 			char* buffer = new char[it->size + 1];
 			*buffer = { 0 };
 			m_file.read(buffer, it->size);
-			QString texName(buffer);
+			m_materials->back().textureName = buffer;
 			delete[] buffer;
 
 			// load the texture if the name is not empty
-			// TODO: save filename for the output
-			if (!texName.isEmpty())
-				loadTexture(m_materials->back().texture, m_filepath + "/" + texName);
+			if (!m_materials->back().textureName.isEmpty())
+				loadTexture(m_materials->back().texture, m_filepath + "/" + m_materials->back().textureName);
 		}
 	}
 }
@@ -684,10 +687,21 @@ void MshFile::loadTexture(QOpenGLTexture *& destination, QString filepath)
 	bool loadSuccess(false);
 	QImage img = loadTga(filepath, loadSuccess);
 
+	if (filepath.isEmpty())
+	{
+		loadSuccess = true;
+		img = QImage(1, 1, QImage::Format_RGB32);
+		img.fill(Qt::red);
+	}
+	else
+		img = loadTga(filepath, loadSuccess);
+
 	if (!loadSuccess)
 	{
 		emit sendMessage("WARNING: texture not found or corrupted: " + m_materials->back().name, 1);
-		return;
+		
+		img = QImage(1, 1, QImage::Format_RGB32);
+		img.fill(QColor(m_materials->back().diffuseColor[0] * 255, m_materials->back().diffuseColor[1] * 255, m_materials->back().diffuseColor[2] * 255));
 	}
 	
 	// Load image to OglTexture